| Autor |
Nachricht |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
16:11:29 20.03.2012 Titel: |
OpenGL/OpenCL: glDrawPixels |
Zitieren |
Hi Leute,
ich hätte da mal ne Frage, und zwar folgendes:
Ich will eine OpenGL/OpenGL Anwendung schreiben, in der ich die Hitzeverteilung auf einer Platte mittels OpenCL berechne und dann mit OpenGL auf dem Bildschirm darstellen lasse.
Der Anfang soll eine BMP-Datei sein, die ich einlese und dann eben mit den Berechnungen beginne.
Das Einlesen der BMP Datei läuft auch ohne Probleme in ein GLubyte array der Form pixels[HOEHE][BREITE][3].
Jetzt gibt es allerdings einige Sachen, die ich gern wüsste, bzw. mir atm irgendwie grad zu blöd für bin und auf dem Schlauch steh.
Ich lass mir das ganze ja mit glDrawPixels zeichnen. Gibt es irgendwelche Anforderungen an das Array, welches ich übergebe? Hab dazu in der man nichts gefunden -.-
Im Moment sieht das ja so aus bei mir:
| C++: | | glDrawPixels (BREITE, HOEHE, GL_RGB, GL_UNSIGNED_BYTE, pixels); | |
Für die Sache, die ich machen will, wäre es ja sinnig, GL_FLOAT zu verwenden. Das sollte dann ja auch mit GLfloat statt GLubyte auch problemlos funktionieren oder? (Mir ist klar, das ich dann 1.0 statt 255 hab als Maximalwert, oder wird die Normierung automatisch übernommen?)
Muss ich aber unbedingt ein 3D-array verwenden, oder kann ich auch ein 1D array verwenden, was mir jetzt SEHR helfen würde.
Oder noch besser, kann ich glDrawPixels auch so verwenden, das ich die 3 Farbkanäle nacheinander zeichne? Glaub in GL gibts doch eine Accumulation funktion oder nicht?
Der Knackpunkt am Ende ist aber, wie kann ich den Buffer in OpenGL und OpenCL verwenden?
Wäre aus Performancesicht halt sehr gut, wenn ich mir das hin und her kopieren sparen könnte.
Danke schon mal für eure Hilfe! |
|
|
|
 |
dot
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 5618
|
dot Mitglied
16:22:45 20.03.2012 Titel: |
|
Zitieren |
glDrawPixels() erwartet einen Pointer auf die Pixeldaten in einem genau spezifizierten Format. Nirgendwo steht, dass das ein Pointer in ein 3D Array sein muss. Man könnte es eigentlich sogar fast als Zufall betrachten, dass das Memory Layout von Arrays in C mit diesem Format übereinstimmt...
Abgesehen davon würd ich dir aber sehr empfehlen, nicht glDrawPixels() zu verwenden, sondern deine Daten in einer Textur abzulegen und einfach ein bildschirmfüllendes Quad mit der Textur drauf zu rendern.
Nicht nur weil glDrawPixels() hoffnungslos veraltet ist (ist in aktuellen Versionen von OpenGL gar nicht mehr vorhanden und ich wär mir jetzt nicht sicher dass das mit float Daten überhaupt funktionieren würde), sondern vor allem auch weil du so sehr viel mehr Kontrolle über deine Ausgabe hast (du kannst z.B. per Shader sehr einfach irgendwelche Filter, Farbtransformationen etc. drauf anwenden).
Außerdem sparst du dir das ganze Rumkopieren, da du in OpenCL direkt auf die OpenGL Textur zugreifen kannst: http://www.khronos.org/re ....... reateFromGLTexture2D.html |
_________________ one point of view will never reveal the entire scene.
Zuletzt bearbeitet von dot am 16:27:31 20.03.2012, insgesamt 7-mal bearbeitet |
|
 |
rapso
Moderator
Benutzerprofil
Anmeldungsdatum: 17.06.2002
Beiträge: 7727
|
rapso Moderator
16:48:34 20.03.2012 Titel: |
|
Zitieren |
ich empfehle dir andersrum anzufangen, lade eine datei, uebergib sie opencl, mache deine berechnungen, lad sie von opencl runter und speicher dir dein bild (oder raw daten).
spaeter kannst du opengl zur visualisierung einbauen, aber fuer dein eigentliches vorhaben ist opengl doch nicht noetig. zudem kannst du opencl die float daten als array uebergeben, so wie du das ja moechtest. |
_________________ Kilo Byte=1000,Kilobyte=1024 ANSI/IEEE Standard 1084-1986
-Mod im Spiele-/Grafikprogrammierung| rapsoo@hotmail.com | #dionysos irc.quakenet.org | amazon stole my PS3
|
|
 |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
16:54:55 20.03.2012 Titel: |
|
Zitieren |
Naja, ich brauch jetzt erst mal was zum vorzeigen, daher hab ich mit dem OpenGL Teil angefangen, zumal das eventuell als Vorlage dienen soll, um das Studenten in die Hand zu drücken, damit man sich nicht mit QT etc. rum schlagen muss.
Wichtig ist mir eigentlich nur, was ich mir das expliziete kopieren der Daten zwischen OpenGL und OpenCL spare. Ohne diese Anforderung wüsste ich ja genau was ich tun kann, bzw. hätte ich halt deutlich mehr Freiheiten, was die Sache dann trivial macht.
PS: Dot
Das glPixelDraw ist noch im OpenGL drin
Wenn ich das Ding aber in ne Textur speichere, dann kann ich nicht mehr beliebig drauf zugreifen. Das ist scheise.
Irgendwelche Filter etc. will ich auch nicht drauf anwenden in OpenGL.
Mehr als zoomen, verschieben und Kanäle auswählen muss in OpenGL nicht möglich sein.
Eventuell später noch, das man mit der Maus rein zeichnet, aber das ist erst mal egal.
EDIT:
Ihr habt mich grad noch auf eine Idee gebracht!
Ich hab jetzt die zwei Funktionen gefunden:
clEnqueueCopyImageToBuffer und clEnqueueCopyBuffertoImage
Wenn ich dann noch die CL<->GL Austauschfunktionen für Images nutze, sollte es eigentlich funktionieren, oder was meint ihr?
Da sollten dann ja auch hauptsächlich pointer ausgetauscht werden, bzw für die Darstellung muss ich halt einmal hin und her kopieren... |
Zuletzt bearbeitet von Skysnake am 17:04:27 20.03.2012, insgesamt 2-mal bearbeitet |
|
 |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
02:18:30 24.03.2012 Titel: |
|
Zitieren |
Ok Leute, ich verzweifle hier noch
Ich bin von GLubyte auf GLfloat umgestiegen, jetzt muss ich nur einmal unsigned char in float umwandeln, wenn ich das BMP einlese, und das wars dann auch.
Es funktioniert auch alles. Sprich ich kann einzelne Farbkanäle an und aus machen, ich lad meine BMPs der Reihe nach, der OpenCL-Part läuft auch fehlerfrei durch. Sprich alles sieht gut aus.
Jetzt kommt aber der Hacken -.- Der OpenCL Kernel wird ausgeführt, ich setz auch alles, ich hab auch READ_WRITE für die Buffer usw. usw. Ich kopier auch das Ergebnis erfolgreich aus dem GPU-RAM in den RAM der CPU zurück.
Nur mein Kernel macht nichts :ugly: Bzw. der Kernel wird ausgeführt, aber wenn ich die Daten zurück kopiere aus der GPU, dann ändert sich nichts auf dem Bildschirm...
Hier mal einige Programmteile:
EDIT CODE ENTFERNT:
Eigentlich stimmt jeder einzelne Programmteil.... Irgendwo muss da der Wurm drin sein -.-
Kann doch nicht sein, das sich das Bild nicht verändert, obwohl ich die Sachen ja im Kernel berechne...
Was auch verwunderlich ist, ist, das ich unter GLuByte noch ein sich änderndes Bild gesehen habe, wenn ich +1 im Kernel gerechnet habe auf jeden Wert. Das funktioniert jetzt nicht mehr. Egal was ich im Kernel mache, es hat keine Auswirkung mehr -.-
Irgendwo muss da der Wurm drin sein...
EDIT:
Wenn ich
| C++: | | out[gid0+size_x+3+gid1*(size_x+2)]=0.1; | |
In meinen Kernel einfüge, dann wird das dargestellte Bild grau, je nach dem welchen Wert ich nehme....
Der Kernel funktioniert also, nur rechne ich irgendwie nichts aus :ugly: |
Zuletzt bearbeitet von Skysnake am 20:07:28 24.03.2012, insgesamt 2-mal bearbeitet |
|
 |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
03:52:04 24.03.2012 Titel: |
|
Zitieren |
Ok, wie es scheint, klappt irgendwas mit dem Update nicht.....
Die Daten werden aus irgend einem Grund nicht dargestellt -.-
Ich glaub ich muss am Ende doch noch den BMP writer fertig schreiben, und meine Ergebnisse raus schreiben, um zu sehen, wo denn jetzt der Hacken genau liegt...
Wäre echt nett, wenn mal noch jemand drüber schauen könnte. Ich find den Fehler einfach nicht |
|
|
|
 |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
20:14:30 24.03.2012 Titel: |
|
Zitieren |
Ok, ich habs jetzt fast. Die Sache funktioniert. Aus irgend einem Grund, hat er mir einen Parameter meines OpenCL Kernels immer auf 0 gesetzt, obwohl sonst alles ging... -.-
Ich hab noch keinen Schimmer, warum er da rum zickt. eigentlich sollte es funktionieren
Naja, wird sich sicherlich auch bald noch herausstellen, was los ist. Daher hat es auch funktioniert, wenn ich +1 gerechnet habe.
Was leider blöd war, und mir einiges an Zeit gekostet hat, um den Fehlr zu finden, und alles am Ende zum laufen zu bekommen, war beim Umstieg auf Float. Ich hab die Skalierung auf 0-255 nicht raus genommen, weil ich dachte, ok, normierste den größten float wert auf 1...
Schlechte idee. Ich hab die Ränder nicht expliziet initialisiert. Ergo waren da SEHR hohe Werte dabei. Meist was mit 10^x mit x>5 Da wurde das Bild dann natürlich sofort schwarz, weil die anderen Werte ja im Bereich 0-1 lagen -.-
Das war ein blöder Fehler, der mich sehr viel Zeit gekostet hat
Ich muss die mal noch auf 1 oder 0 initialisieren...
Naja, was willste machen. Jetzt funktionierts auf jeden Fall, bis auf die Übergabe eines Kernel-Parameters, wo ich noch immer rätsel.
Ich schaff jetzt bei 448x448 Bildpunkten und 10 Iterationen pro Bildausgabe ca 340 FPS und bei 896*896 sind es noch immer 150 FPS.
Leider hab ich nur eine Auslastung von rund 40%. Nutze im Moment aber auch noch keinen local Memory, und keine Vektor-Datentypen. Da geht also noch einiges. |
|
|
|
 |
Andreas XXL
Mitglied
Benutzerprofil
Anmeldungsdatum: 12.01.2004
Beiträge: 1011
|
Andreas XXL Mitglied
20:42:53 24.03.2012 Titel: |
|
Zitieren |
Du kanst ein OpenGL Texturobjekt auch mit OpenCL verwenden (vorher umwandeln).
Dann kanst du die Textur mit OpenCl bearbeiten und mit OpenGL einfach mit den üblichen Mechanismen zum Zeichnen von Texturen darstellen.
Dann brauchst du kein extrem langsames Pixeldraw.
Du brauchst die Ergebnisse nicht mal über den Bus schicken.
Mir kommt gerade ne Idee
Ich baue mir ein nur GPU Game of Life |
Zuletzt bearbeitet von Andreas XXL am 20:51:09 24.03.2012, insgesamt 2-mal bearbeitet |
|
 |
dot
Mitglied
Benutzerprofil
Anmeldungsdatum: 20.05.2004
Beiträge: 5618
|
dot Mitglied
20:46:09 24.03.2012 Titel: |
|
Zitieren |
| Skysnake schrieb: | Das glPixelDraw ist noch im OpenGL drin  |
Nicht in aktuellen Versionen von OpenGL. Natürlich wird es aus Gründen der Abwärtskompatibilität noch unterstützt.
| Skysnake schrieb: | | Wenn ich das Ding aber in ne Textur speichere, dann kann ich nicht mehr beliebig drauf zugreifen. Das ist scheise. |
Was genau meinst du damit? |
_________________ one point of view will never reveal the entire scene.
Zuletzt bearbeitet von dot am 20:50:50 24.03.2012, insgesamt 4-mal bearbeitet |
|
 |
Skysnake
Mitglied
Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
|
Skysnake Mitglied
23:02:22 25.03.2012 Titel: |
|
Zitieren |
| dot schrieb: | | Skysnake schrieb: | Das glPixelDraw ist noch im OpenGL drin  |
Nicht in aktuellen Versionen von OpenGL. Natürlich wird es aus Gründen der Abwärtskompatibilität noch unterstützt.
|
Also ist es noch drin :ugly:
Ich kann es verwenden, in der aktuellsten Version, also ist es noch drin.
| Zitat: |
| Skysnake schrieb: | | Wenn ich das Ding aber in ne Textur speichere, dann kann ich nicht mehr beliebig drauf zugreifen. Das ist scheise. |
Was genau meinst du damit? |
Du kannst in einem OpenCL kernel entweder lesend, oder schreibend auf ein Image zugreifen, aber nicht beides. Das ist schlecht, wobei es hier sogar noch gehen würde in der aktuellen Implementierung, die ich verwende. Wenn ich dann aber zu einer anderen Methode wechsle, dann muss ich ein LGS lösen, und dann hilft mir das kein Stück weiter.
Aber nochmal kurz zu glDrawPixels. Was könnte ich denn ansonsten noch verwenden? Klar ne Textur, aber würde das einen Performanceunterschied machen, wenn ich da so oft die Textur ändern muss?
Wäre wirklich gut zu wissen, wie man das elegant und performant lösen kann. Die >>100 FPS sind zwar ok, aber mehr ist immer besser
EDIT:
| Andreas XXL schrieb: | Du kanst ein OpenGL Texturobjekt auch mit OpenCL verwenden (vorher umwandeln).
Dann kanst du die Textur mit OpenCl bearbeiten und mit OpenGL einfach mit den üblichen Mechanismen zum Zeichnen von Texturen darstellen.
Dann brauchst du kein extrem langsames Pixeldraw.
Du brauchst die Ergebnisse nicht mal über den Bus schicken.
Mir kommt gerade ne Idee
Ich baue mir ein nur GPU Game of Life  |
Btw. das umwandeln geht nicht -.- laut der OpenCL DeviceInfo wird diese Erweiterung von meiner 5870 nicht unterstützt. Ich sollte aber diese Woche zum programmieren/testen ne 7970 bekommen. Vielleicht kann die das dann.
Wobei ich mich schon frag, in wie weit das am Ende alles noch schneller ist. |
Zuletzt bearbeitet von Skysnake am 23:04:37 25.03.2012, insgesamt 1-mal bearbeitet |
|
 |
|
Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben. Sie können auf Beiträge in diesem Forum antworten. Sie können Ihre Beiträge in diesem Forum nicht bearbeiten. Sie können Ihre Beiträge in diesem Forum nicht löschen. Sie können an Umfragen in diesem Forum nicht mitmachen.
|
|
|
|
|