2012-04-08 58 views
3

我想用Pyglet製作一個網格來改變每一幀。因此我需要經常更新頂點,我認爲VBO是最快的方法(如果我錯了,請糾正)。下面是Points的例子。這是做這件事的正確方法嗎?我讀過glBindBuffer調用的數量應該最小化,但是在這裏它被稱爲每一幀。也啓用了GL_DYNAMIC_DRAW,但是如果我將其更改爲GL_STATIC_DRAW,它仍然有效。這讓我想如果這是快速計算如何使用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

正確設置你並不需要調用glBufferData在更新每一次 - 創建並填寫VBO一次(見setup_initial_points),並只與glBufferSubData更新。如果您只使用一個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 2012-04-10 17:56:27

+0

我肯定會在我贏得聲譽的時候,在這裏成爲一名新用戶! :d。 – apfz 2012-04-16 20:02:50

+0

您在此行'glBufferData(GL_ARRAY_BUFFER,sizeof(data),0,GL_DYNAMIC_DRAW)''有錯誤。 我認爲,第三個參數意味着數據 – mofr 2016-03-20 08:30:36