kostenloser Webspace werbefrei: lima-city


PyOpengl: Objekte effizient aus Datei lesen?

lima-cityForumProgrammiersprachenPython

  1. Autor dieses Themas

    krisi12345

    Kostenloser Webspace von krisi12345

    krisi12345 hat kostenlosen Webspace.

    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?
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. 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.
  4. Autor dieses Themas

    krisi12345

    Kostenloser Webspace von krisi12345

    krisi12345 hat kostenlosen Webspace.

    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
    glBufferData(GL_ARRAY_BUFFER, array(self.ver, dtype=float32), GL_STATIC_DRAW)
    als Numpy Array übergebn.
    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
  5. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!