PyOpengl: Objekte effizient aus Datei lesen?
lima-city → Forum → Programmiersprachen → Python
aktuellen buffer
anfang
array
binden
code
datum
druck
durchlauf
fehler
file
funktion
grafikkarte
objekt
pointer
position
rang
rutsch
schritt
speichern
url
-
Ich hab einen kleinen exporter geschrieben um Objekte aus Blender in ein in PyOpenGL wiederverwendbares Format zu speichern. In zwei Zeilen werden je die Polygonen und Normalen gespeichert. Die Datei wird dann am Anfang des skripts geöffnet und gelesen. Danach wird in einer Schleife bei jedem Frame (Durchlauf) die Funktion ausgeführt um das Objekt zu drucken. Da dies "viel" Zeit erfordert da in der Funktion z.B. range Schleifen ausgeführt werden müssen ist das nicht besonders effizient. Würde ich aber OpenGL Funktionen am Anfang des scriptes in einer Liste speichern würden sie ja bei dem Listen aufruf nicht jedes mal ausgeführt wodurch nix auf dem Bildschirm erscheint.
Die Funktion zum drucken des Objekts:
def obj(data): glRotate(rot[0], 1, 0, 0) glRotate(rot[2], 0, 0, 1) glPushMatrix() glMaterialfv(GL_FRONT, GL_DIFFUSE, [0.8, 0.8, 0.8, 0.5]) glMaterialfv(GL_FRONT, GL_SPECULAR, [0.0, 0.0, 0.0, 1.0]) glBegin(GL_TRIANGLES) glColor(150, 150, 150) for i in range(len(ver)/3): a = i*3 glNormal3f(float(nor[a]), float(nor[a+1]), float(nor[a+2])) glVertex3f(float(ver[a]), float(ver[a+1]), float(ver[a+2])) glEnd() glPopMatrix()
Wie kann man den script effizienter gestalten? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Hm also effizient wäre an der stelle die Verwendung von Vertexarrays und VBOs. Damit lädts du sowohl die Vertices als auch die Normalen in einem rutsch.
Hier mal eine kleine Anleitung zum VBO:
1. Schritt Daten auf die Grafikkarte laden
#Gibt 2 VBOs zurück vbo = glGenBuffers(2) #Setzt VBO[0] als aktuellen Buffer für die Vertexdaten glBindBuffer(vbo[0]) #Übermitteln der Vertexdaten an die Grafikkarte glBufferData(GL_ARRAY_BUFFER, ver, GL_STATIC_DRAW) #Setzt VBO[1] als aktuellen Buffer für die Normalen glBindBuffer(vbo[1]) #Übertragen der Normalendaten #GL_STATIC_DRAW bedeuted, dass du die Daten nur selten aktualisieren wirst #und sie nicht von der Grafikkarte lesen willst glBufferData(GL_ARRAY_BUFFER, nor, GL_STATIC_DRAW) #Zurücksetzen des Buffers glBindBuffer(0)
2. Schritt Daten anzeigen
#Anschalten der Array unterstützung glEnable(GL_VERTEX_ARRAY) glEnable(GL_NORMAL_ARRAY) #Binden des Normalenbuffers glBindBuffer(GL_ARRAY_BUFFER,vbo[1]) #Die normalen sind als GL_FLOAT gespeichert, #ohne Lücken(siehe interleaved Array) und fangen an der Position 0 an glNormalPointer(GL_FLOAT,0,0) #Binden des Vertexbuffers glBindBuffer(GL_ARRAY_BUFFER,vbo[0] #3 Koordinaten per Vertex vom Typ float, keine Lücken, anfangsposition 0 glVertexPointer(3,GL_FLOAT,0,0) #Und jetzt das Zeichnen selbst #Zeichne len(ver)/3 Dreiecke ab Position 0 im Array glDrawArrays(GL_TRIANGLES,0,len(ver)/3) #Danach noch den Buffer freigeben: glBindBuffer(GL_ARRAY_BUFFER,0)
Das wärs gewesen. Damit lläuft das besonders bei großen Arrays hundertmal schneller!
Was die gl...Pointer Funktionen angeht. Die sind für die neuesten GL versionen als deprecated angemeldet allerdings weiß ich nicht, wodurch sie zu ersetzen sind. -
Ich habs jetzt einigermaßen hinbekommen aber beim glVertexPointer() Pointer teil (glVertexPointer(3, GL_FLOAT, 0, 0)) bzw. beim NormalPointer bekomm ich ein Fehler:
... cArguments = tuple(calculate_cArguments( cArgs )) File "/usr/lib/pymodules/python2.6/OpenGL/wrapper.py", line 378, in calculate_cArguments yield converter( cArgs[i] ) File "/usr/lib/pymodules/python2.6/OpenGL/arrays/arraydatatype.py", line 47, in voidDataPointer return ctypes.c_void_p( cls.dataPointer( value )) TypeError: ('cannot be converted to pointer', <bound method type.voidDataPointer of <class 'OpenGL.arrays.arraydatatype.ArrayDatatype'>>)
Die Vertex/Normal daten hab ich mit
als Numpy Array übergebn.glBufferData(GL_ARRAY_BUFFER, array(self.ver, dtype=float32), GL_STATIC_DRAW)
Ist das überhaupt richtig?
Und wo liegt der Fehler?
Edit: hat sich schon erledit: "Zero is not NULL" - statt einer 0 musste beim vertexpointer beim letztem parameter eine None hin. Die Permance steigerung ist unglaublich!!! Bei 250.00 Polygonen ist die Framerate nicht niedriger als bei 50!
Beitrag zuletzt geändert: 24.4.2010 14:45:08 von krisi12345 -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage