2012-04-08 4 views
3

Ich möchte ein Netz mit Pyglet machen, das jeden Rahmen ändert. Daher muss ich die Eckpunkte sehr oft aktualisieren und ich dachte, dass ein VBO der schnellste Weg wäre, um hierher zu kommen (korrigiere mich, wenn ich falsch liege). Unten ein Beispiel für Punkte. Ist das der richtige Weg? Ich habe gelesen, dass die Anzahl der glBindBuffer-Aufrufe minimiert werden sollte, aber hier wird jedes Frame aufgerufen. Auch GL_DYNAMIC_DRAW ist aktiviert, aber wenn ich es in GL_STATIC_DRAW ändere, funktioniert es immer noch. Es macht mich fragen, ob dies eine richtige Setup für eine schnelle Berechnung istWie aktualisiere ich Daten mit einem VBO und Pyglet

import pyglet 
import numpy as np 
from pyglet.gl import * 
from ctypes import pointer, sizeof 

vbo_id = GLuint() 
glGenBuffers(1, pointer(vbo_id)) 

window = pyglet.window.Window(width=800, height=800) 

glClearColor(0.2, 0.4, 0.5, 1.0) 

glEnableClientState(GL_VERTEX_ARRAY) 

c = 0 

def update(dt): 
    global c 
    c+=1 
    data = (GLfloat*4)(*[500+c, 100+c,300+c,200+c]) 
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id) 
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_DYNAMIC_DRAW) 
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data) 


pyglet.clock.schedule(update) 

glPointSize(10) 

@window.event 
def on_draw(): 

    glClear(GL_COLOR_BUFFER_BIT) 
    glColor3f(0, 0, 0) 

    glVertexPointer(2, GL_FLOAT, 0, 0) 
    glDrawArrays(GL_POINTS, 0, 2) 


pyglet.app.run() 

Antwort

9

Sie brauchen nicht glBufferData jedes Mal in Aktualisierung aufrufen - erstellen und die VBO einmal füllen (siehe setup_initial_points) und nur aktualisieren mit glBufferSubData . Wenn Sie nur mit einem einzelnen VBO arbeiten, können Sie auch den glBindBuffer Anruf in update() auskommentieren (siehe Code unten). GL_DYNAMIC_DRAW vs GL_STATIC_DRAW wird in diesem Beispiel keinen großen Unterschied machen, da Sie sehr wenige Daten auf die GPU schieben.

import pyglet 
from pyglet.gl import * 
from ctypes import pointer, sizeof 

window = pyglet.window.Window(width=800, height=800) 

''' update function ''' 
c = 0 
def update(dt): 
    global c 
    c+=1 
    data = calc_point(c) 
    # if there's only on VBO, you can comment out the 'glBindBuffer' call 
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id) 
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data) 

pyglet.clock.schedule(update) 


''' draw function ''' 
@window.event 
def on_draw(): 

    glClear(GL_COLOR_BUFFER_BIT) 
    glColor3f(0, 0, 0) 

    glVertexPointer(2, GL_FLOAT, 0, 0) 
    glDrawArrays(GL_POINTS, 0, 2) 


''' calculate coordinates given counter 'c' ''' 
def calc_point(c): 
    data = (GLfloat*4)(*[500+c, 100+c, 300+c, 200+c]) 
    return data 


''' setup points ''' 
def setup_initial_points(c): 
    vbo_id = GLuint() 
    glGenBuffers(1, pointer(vbo_id)) 

    data = calc_point(c) 
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id) 
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_DYNAMIC_DRAW) 

    return vbo_id 


############################################ 

vbo_id = setup_initial_points(c) 

glClearColor(0.2, 0.4, 0.5, 1.0) 
glEnableClientState(GL_VERTEX_ARRAY) 

glPointSize(10) 
pyglet.app.run() 
+0

Das ist * extrem * hilfreich. Deine Hilfe ist sehr Willkommen! – apfz

+0

Ich werde auf jeden Fall, wenn ich den Ruf verdient habe, ein bisschen neu hier als Benutzer! : D. – apfz

+0

Sie haben einen Fehler bei dieser Zeile 'glBufferData (GL_ARRAY_BUFFER, sizeof (data), 0, GL_DYNAMIC_DRAW)'. Ich denke, das dritte Argument sollte "Daten" sein – mofr