Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: Spiele-/Grafikprogrammierung ::  OpenGL/OpenCL: glDrawPixels  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
Skysnake
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag 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
Beitrag Skysnake Mitglied 02:18:30 24.03.2012   Titel:              Zitieren

Ok Leute, ich verzweifle hier noch :mad:

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
Beitrag 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 :mad:
Skysnake
Mitglied

Benutzerprofil
Anmeldungsdatum: 29.09.2010
Beiträge: 34
Beitrag 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 :rolleyes:

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 :mad:

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
Beitrag 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 :D


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
Beitrag 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
Beitrag 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 :D

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
c++.de :: Spiele-/Grafikprogrammierung ::  OpenGL/OpenCL: glDrawPixels  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




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.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.