【问题标题】:glVertexAttribPointer in OpenGL and in OpenGLESOpenGL 和 OpenGLES 中的 glVertexAttribPointer
【发布时间】:2013-03-13 08:44:33
【问题描述】:

我正在阅读有关 OpenGL 和 OpenGLES 的教程,我对在这两个 API 中使用函数 glVertexAttribPointer 有点困惑。

OpenGL 教程中,此函数使用数字偏移作为最后一个参数(通过转换为 const GLVoid*),我认为顶点直接取自当前数组缓冲区。

glVertexAttribPointer(vs_position, 2, GL_FLOAT, GL_TRUE, 5 * sizeof(GLfloat), (const GLvoid*) (3*sizeof(GLfloat)) );

OpenGLES 教程中,最后一个参数直接指向表示顶点的结构:

GLFloat vertices[] = {...definition};
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);

我不明白这两个函数是如何工作的。它们是完全不同的功能吗?

【问题讨论】:

    标签: java opengl opengl-es


    【解决方案1】:

    它们是相同的功能,以两种不同的方式使用。我会解释为什么它会这样工作,但你不会在意,而且这是出于非常愚蠢和无关紧要的原因。

    重要的是他们在做什么。他们正在做什么取决于您没有显示的内容:绑定到 GL_ARRAY_BUFFER 的内容。

    看,glVertexAttribPointer 的行为 变化 取决于此。如果在调用glVertexAttribPointer 时没有绑定到GL_ARRAY_BUFFER 的缓冲区对象,则该函数将假定最终值是一个指针(如函数名称所述:glVertexAttribPointer)。具体来说,它是指向客户端拥有的内存的指针。

    到了渲染的时候,顶点属性数据会来自之前提供的指针。因此,第二个示例只是使用以标准 C 样式声明的客户端数据数组作为源数据。不涉及缓冲区对象。

    注意:OpenGL 3.1+ 的核心配置文件移除了使用客户端内存的能力;在那里,您必须使用缓冲区对象,如下所述。

    如果在调用glVertexAttribPointer 时将缓冲区对象绑定到GL_ARRAY_BUFFER,那么会发生一些特殊情况。 OpenGL 将假装指针(就 C/C++ 而言,这是最终参数)实际上是绑定到GL_ARRAY_BUFFER 的缓冲区的字节偏移量。它将指针转换为整数,然后存储该整数偏移量和当前绑定到GL_ARRAY_BUFFER 的缓冲区对象。

    所以上面的代码采用3*sizeof(GLfloat),字节偏移量,并将其转换为指针。 OpenGL 将获取指针并将其转换回偏移量,再次产生3*sizeof(GLfloat)

    当需要渲染时,OpenGL 将使用之前给定的偏移量从之前给定的缓冲区对象中读取。

    第一个示例将顶点数据放入 GPU 内存中的缓冲区对象中。第二个示例将顶点数据放在 CPU 内存中的常规 C/C++ 数组中。

    【讨论】:

    • 完美解释!谢谢你。 - 你从哪里得到这些信息的?!我找不到关于那个的文档。 - 你所说的 OpenGL3.1 和不使用内存客户端对 OpenGLEs 2.0 也有效?
    • @MatterGoal:一般来说,应用程序要么总是使用客户端内存或缓冲区对象。所以没有人需要谈论它们之间的区别。并且大部分桌面 OpenGL 文档已经转移到核心配置文件行为,所以它也没有谈论它。但它就在man pages for GL ES 中。只需阅读说明的第二段。
    • @MatterGoal:this answer 在相关问题中也有解释。
    • 很好的解释。我想我通过了&offset,其中int offset=(3*sizeof(GLfloat)) 几次,然后才弄清楚是的,你的普通整数将作为指向内存地址12 的指针传递给OpenGL强制转换..。我不能将这个糟糕的 API 完全归结为“作为不支持重载的 C API 的结果……”在我看来,这只是糟糕的设计,实际上应该是 2 个独立的函数。
    • @bobobobo:哦,这与 C API 无关。它与向后兼容性有关。当 ARB_VBO 出现时,他们想制作它,以便用户可以很容易地调整他们的代码来适应它。因此,您所要做的就是将指针更改为偏移量并在设置指针之前发出绑定调用。当然,10 多年后,它使 API 看起来非常愚蠢。但 ARB 似乎喜欢做出短视的 API 决定。这也不例外。
    【解决方案2】:

    GL spec 明确提到了这一点:

    案例 1:如果一个非零命名缓冲区对象绑定到 GL_ARRAY_BUFFER 目标,同时指定了一个通用顶点属性数组,则指针被视为缓冲区对象数据存储中的字节偏移量。

    case 2:指定指向数组中第一个通用顶点属性的第一个组件的指针。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多