【问题标题】:How to update data with a VBO and Pyglet如何使用 VBO 和 Pyglet 更新数据
【发布时间】:2012-04-21 09:05:26
【问题描述】:

我想用 Pyglet 制作一个每一帧都在变化的网格。因此我需要经常更新顶点,我认为 VBO 是最快的方式(如果我错了,请纠正我)。下面是一个点的例子。这是正确的做法吗?我读到应该尽量减少 glBindBuffer 调用的数量,但这里每帧都调用它。 GL_DYNAMIC_DRAW 也已启用,但如果我将其更改为 GL_STATIC_DRAW 它仍然有效。这让我想知道这是否是快速计算的正确设置

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()

【问题讨论】:

    标签: python opengl vbo pyglet


    【解决方案1】:

    您无需在更新中每次都调用glBufferData - 创建并填充 VBO 一次(请参阅setup_initial_points)并仅使用glBufferSubData 更新它。如果您只使用单个 VBO,您还可以注释掉 update() 中的 glBindBuffer 调用(参见下面的代码)。 GL_DYNAMIC_DRAWGL_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()
    

    【讨论】:

    • 非常很有帮助。非常感谢您的帮助!
    • 我一定会在我赢得声誉后,作为一个新用户在这里! :D.
    • 你在glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_DYNAMIC_DRAW)这行有一个错误。我认为,第三个参数应该是 data
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多