【问题标题】:is VertexAttribPointer needed after each BindBuffer?每个 BindBuffer 之后是否需要 VertexAttribPointer?
【发布时间】:2011-04-09 14:28:50
【问题描述】:

我注意到除非我重新调用 VertexAttribPointer,否则在 BindBuffer 之后不会有着色器的输入。那有必要吗?着色器在写入时可能不会改变,而只会改变使用的缓冲区。

【问题讨论】:

    标签: opengl opengl-3


    【解决方案1】:

    tibur 已经回答了实际问题,但我想我应该添加一些上下文。

    glBindBuffer(GL_ARRAY_BUFFER, ...) 本身不会任何事情。将其视为glVertexAttribPointer 的额外参数。

    请记住,您可以将多个缓冲区绑定到不同的属性(例如 attrib 0 使用 vbo 1,而 attrib 1 和 2 使用 vbo 2)。对于该设置,您会看到什么 API 顺序?

    使用实际的 API,它类似于:

    glBindBuffer(GL_ARRAY_BUFFER, 1);
    glVertexAttribPointer(0, ...)
    glBindBuffer(GL_ARRAY_BUFFER, 2);
    glVertexAttribPointer(1, ...)
    glVertexAttribPointer(2, ...)
    
    glDraw*(...)
    

    为什么规范会这样工作?好吧,它的向后兼容性正在抬头。当引入 VBO 时,glVertexPointer 等。没有任何参数来传递要使用的缓冲区对象。要么是每个语义的许多新入口点(VertexPointer/NormalPointer/TexCoordPointer...),要么它本身就是一个额外的入口点,它只是充当 *Pointer 调用的额外参数。他们选择了后者(作为旁注,这也是为什么您必须将缓冲区内的偏移量作为指针传递的原因)。

    【讨论】:

      【解决方案2】:

      根据OpenGLOpenGL specifications,第51页(缓冲区对象状态),数组指针对应的状态存储缓冲区ID。这意味着,如果您想更改用于绘制的缓冲区对象,您需要调用glVertexAttribPointer 函数。

      glBindBuffer(1);
      glVertexPointer(...);
      glDrawArrays(...); /// Drawing will use buffer 1
      
      glBindBuffer(2);
      glDrawArrays(...); /// Drawing will still use buffer 1
      
      glVertexPointer(...);
      glDrawArrays(...); /// Drawing will now use buffer 2
      

      【讨论】:

        猜你喜欢
        • 2018-07-03
        • 1970-01-01
        • 2014-11-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多