2012-04-08 4 views
3

すべてのフレームを変更しているPygletを使ってメッシュを作りたいと思います。したがって、私は非常に頻繁に頂点を更新する必要があり、私はVBOがここに行く最速の方法であると思っていました。ポイントの例の下。これは正しい方法ですか?私は、glBindBuffer呼び出しの数を最小限に抑える必要があると読んでいますが、ここではすべてのフレームと呼ばれています。 GL_DYNAMIC_DRAWも有効ですが、GL_STATIC_DRAWに変更してもまだ動作しています。 (setup_initial_pointsを参照)のみglBufferSubDataでそれを更新し作成して、一度VBOを埋める - これはあなたがアップデートで毎回glBufferDataを呼び出す必要はありません高速計算VBOと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() 

答えて

9

の正しい設定であるなら、私は思っています。 1つのVBOのみで作業する場合は、update()glBindBufferコールをコメントアウトすることもできます(下記のコードを参照)。 GL_DYNAMIC_DRAW vs GL_STATIC_DRAWは、GPUにデータをほとんどプッシュしていないため、この例では大きな違いはありません。

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

これは*非常に役に立ちます。あなたの助けが大いにありがとう! – apfz

+0

私は確かに私が評判を得たとき、ちょっとユーザーとしてちょっと新しいだろう! :D。 – apfz

+0

この行には 'glBufferData(GL_ARRAY_BUFFER、sizeof(data)、0、GL_DYNAMIC_DRAW)'の間違いがあります。 私は、第3引数は 'data'を意味すると思います – mofr

関連する問題