【问题标题】:Why do I need to specify data for both the VBO and while calling glVertexAttribPointer?为什么我需要同时为 VBO 和调用 glVertexAttribPointer 指定数据?
【发布时间】:2021-01-21 01:47:09
【问题描述】:

在使用 OpenGl 时,我通常会创建一个 VBO 并将顶点数据传递给它

glBufferData();

我最近一直在阅读this的源代码,请允许我引用其中的一部分:

在创建新存储时,所有预先存在的数据存储都会被删除。新数据存储以指定的字节大小和使用情况创建。如果 data 不为 NULL,则使用来自该指针的数据初始化数据存储。在其初始状态下,新的数据存储没有被映射,它有一个 NULL 映射指针,它的映射访问是 GL_READ_WRITE。

由此我得出结论,在设置缓冲区数据功能时,缓冲区中的数据被复制到 VBO。
现在,当调用glVertexAttribPointer() 时,我必须再次传递指向数据的指针。

我了解属性指针的用途 - 它们告诉 OpenGL 状态机数据在 VBO 中的组织方式。
但是,将指针同时传递给 VBO 和 glVertexAttribPointer 函数似乎是多余的,因为无论如何 VAO 都会保存属性指针配置,并且调用 glVertexAttribPointer 无论如何都必须将顶点数据存储在程序内存中 - 所以内存被复制(一个原始副本和由glBufferData() 制作的副本)。

为什么会出现这种明显的冗余?或者,也许我理解错误的方式? 也许我误解了文档并且数据没有复制到 VBO,但是 VBO 的目的到底是什么?

【问题讨论】:

    标签: opengl shader vbo


    【解决方案1】:

    您不必这样做。如果命名缓冲区对象绑定到 ARRAY_BUFFER 目标,则 glVertexAttribPointer 的最后一个参数(pointer)被视为缓冲区对象数据存储的字节偏移量。

    任一(仅兼容性配置文件):

    float *data;
    
    glBindBuffer(GL_ARRAY_BUFFER, 0); // 0 is default
    glVertexAttribPointer(..., data);
    

    float *data;
    
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, ..., data, ...);
    
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(..., (void*)0);
    

    【讨论】:

    • 谢谢!实际上我之前一直在盲目地这样做,但现在我开始查看 QT opengl 包装器,他们似乎没有选择不在 glVertexAttribPointer 中指定指针 - 这让我出错了。
    猜你喜欢
    • 1970-01-01
    • 2015-09-28
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2014-11-25
    • 2020-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多