# Messdaten in Echtzeit darstellen in OpenGL



## Kooneybert (4. Jun 2018)

Hallo liebe Community,

ich habe hier eine 320x240 große Matrix an Daten (Messdaten des Tiefensensors einer Kinect) und würde diese gerne möglichst effizient mithilfe von OpenGL als eine 2D-Fläche darstellen. Die Entfernung soll durch eine Farbe bestimmt werden, also beispielsweise sollen nahe Objekte weiß und entfernte Objekte schwarz dargestellt werden. 

*Mein bisheriger* *Ansatz* ist, mithilfe des immediate-modes ein Quad nach dem anderen zu zeichnen - die Farbe wird dabei für jedes Quad einzeln von der CPU berechnet. Dieser Ansatz funktioniert, aber ist ziemlich langsam. Insbesondere die Berechnung der Farbe durch die CPU frisst sehr viel Rechenzeit.
*
Daher die Frage: Was wäre ein geschickterer Ansatz?* 

Ich habe bereits versucht, das ganze mit VBOs zu implementieren. D.h. ich erstelle zu Beginn ein VBO mit den Quads (als Dreiecke, da die sich laut so ziemlich allen Tutorials viel schneller rendern lassen) und ein VBO mit den Farben. Das zweite VBO wird während der Laufzeit aktualisiert. Damit vermeide ich zwar den immediate mode, aber um die Berechnung der Farbe muss sich weiterhin die CPU kümmern. Die Farbberechnung benötigt übrigens >90% der Zeit jeden Frame. Auch dieser Ansatz funktioniert zwar, aber da das eigentliche Problem nicht gelöst wird, ist auch diese Variante ziemlich langsam.
Nun wollte ich als nächsten Schritt die Farbberechnung von der Grafikkarte durchführen lassen, d.h. mithilfe eines Shader-Programms. Die Idee wäre jetzt, dass ich das Farb-VBO weglasse und stattdessen ein VBO nur mit den rohen, unverarbeiteten Messdaten erstelle, welches dann vom Shader verarbeitet wird, sodass den einzelnen Quads/Triangles Farben zugewiesen werden können.

*Ist dieser Ansatz sinnvoll?* Wenn ja, könnt ihr mir ein paar Stichworte geben, in welche Richtung ich weiterlesen muss? 

Ich hoffe, ihr könnt mir helfen. Für konkrete Lösungsansätze und/oder Literaturhinweise wäre ich euch sehr dankbar.
Kooneybert


----------



## httpdigest (4. Jun 2018)

Ich hätte es so gemacht:
Einmalig:
1. Eine 2D Textur erzeugt (eventuell als 16- oder 32-bit Floating Point, je nachdem, wie diskret die Messdaten sind)
2. Ein Shaderprogramm mit einem Fragmentshader schreiben, der entsprechend die Textur an der jeweiligen Stelle ausliest und in einen Farbwert kodiert
dann pro Frame:
1. Aktuelle Messdaten in Textur hochladen (per glTexSubImage2D)
2. Ein einzelnes Quad rendern (kann dann auch mit glBegin/glEnd Immediate Mode passieren)
Das sollte seeehr schnell sein.


----------



## Kooneybert (4. Jun 2018)

Danke für deine Antwort schonmal!



httpdigest hat gesagt.:


> je nachdem, wie diskret die Messdaten sind


Die Kinect liefert mir ein 76800 langes Short-Array mit den Messdaten. 



httpdigest hat gesagt.:


> Ein einzelnes Quad rendern


Wieso würde ich einzelne Quads rendern? Bei jedem Frame kann davon ausgegangen werden, dass sich alle 76800 Werte ändern (wie bei einer Kamera halt). Wäre es nicht schon effizienter, die Textur jeden Frame komplett neu zu berechnen?


----------



## httpdigest (4. Jun 2018)

Kooneybert hat gesagt.:


> Wieso würde ich einzelne Quads rendern?


Ich sagte: *Ein einzelnes Quad rendern*
nur ein einziges, ever...
Auch "full screen quad" genannt, wenn es denn über den ganzen viewport geht.
Du mappst natürlich die Textur dann auf das eine *einzige* quad.


----------



## Kooneybert (4. Jun 2018)

Achsoo, jetzt kapier ich die Idee! 

Danke für die Tipps soweit, ich muss jetzt in den nächsten Tagen erstmal ausprobieren, wie man eine Textur erstellt und sie im Shader nutzt.


----------

