【问题标题】:glEnableClientState with modern OpenGL (glVertexAttribPointer etc)glEnableClientState 与现代 OpenGL(glVertexAttribPointer 等)
【发布时间】:2011-12-18 06:18:33
【问题描述】:

我想列出一些我认为我学到的东西,但不确定:

  • VBO 是要走的路。它们是使用 glGenBuffersglBufferData 创建的。
  • 为了获得最大的灵活性,最好使用glVertexAttribPointer 而不是glVertexglNormal 等将通用顶点属性传递给着色器。
  • glDrawElements 可以与顶点缓冲区和索引缓冲区一起使用,以有效地渲染具有大量共享顶点的几何图形,例如景观网格。

假设到目前为止所有这些都是正确的,这是我的问题。我读过的所有关于现代 OpenGL 的教程都完全省略了glEnableClientState。但是 OpenGL 手册页说没有 glEnableClientStateglDrawElements 将无能为力:

http://www.opengl.org/sdk/docs/man/xhtml/glDrawElements.xml

关键段落是:“如果不启用GL_VERTEX_ARRAY,则不构造几何图元。”

这导致我提出以下问题:

  • 在调用glDrawElements 之前,所有教程均未使用glEnableClientState。这是否意味着手册页错误或过时?
  • 如果您要使用glVertexPointerGL_VERTEX_ARRAY 似乎是您启用的东西,同样您将使用GL_NORMAL_ARRAYglNormalPointer,等等。但如果我不使用这些函数,而是使用带有glVertexAttribPointer 的通用顶点属性,那么为什么需要启用GL_VERTEX_ARRAY

【问题讨论】:

    标签: opengl


    【解决方案1】:

    如果未启用 GL_VERTEX_ARRAY,则不构造几何图元。

    那是因为手册页错误。手册页涵盖 GL 2.1(它仍然是错误的),无论出于何种原因,更新手册页的人拒绝更新旧 GL 版本以修复错误。

    在 GL 2.1 中,您必须使用通用属性索引 0 或 GL_VERTEX_ARRAY。在 GL 3.1+ 中,您不需要使用任何特定的属性索引。

    这是因为,在 3.1 之前的 GL 版本中,所有数组渲染函数都是根据对 glArrayElement 的调用定义的,它使用基于即时模式的渲染。这意味着您需要一些东西来激发顶点。回想一下,在立即模式下,调用glVertex*() 不仅设置顶点位置,还会导致顶点与其他属性一起发送。调用glVertexAttrib*(0, ...) 做同样的事情。这就是为什么旧版本要求您使用属性 0 或 GL_VERTEX_ARRAY

    在 GL 3.1+ 中,一旦他们取消了立即模式,他们必须以不同的方式指定数组渲染。因此,他们不必限制自己使用属性 0。

    如果您希望核心 GL 3.3 的 API 文档有效,我建议您查看 the actual API docs for core GL 3.3。虽然老实说,如果您想要准确信息,我只会查看规范。这些文档中有很多错误信息。而且由于它们实际上不是 wiki 页面,因此这些信息永远不会得到更正。

    【讨论】:

    • "在 GL 2.1 中,您必须使用任一通用属性索引 0"--也就是说,如果我的 GLSL 程序没有使用属性 0,那么“没有构造几何图元”,种类就像手册页说的那样?顺便说一句,我使用 2.1 来实现 Mac 兼容性,并且我的程序在没有 glEnableClientState 的情况下运行良好。但是,我知道我使用的是通用属性 0,我想这可以解释为什么我的几何图形仍在被渲染。
    【解决方案2】:

    您的前 3 点是正确的。为了回答你问题的后半部分,不要将glEnableClientState 用于现代 OpenGL。开始编码!

    【讨论】:

      【解决方案3】:

      VBOS 是要走的路。它们是用 glGenBuffers 和 glBufferData.

      VBO 通常用于高性能应用。您可能想先做一些更简单的事情。顶点数组是快速入门的好方法。因为 VBO 无论如何都位于顶点数组之上,所以当您切换到 VBO 时,您将使用大部分相同的代码,并且最好先使用顶点数组或索引顶点数组运行测试。

      为了获得最大的灵活性,最好传递通用顶点属性 到带有 glVertexAttribPointer 的着色器,而不是 glVertex、glNormal、 等等。

      这是一个很好的方法。

      glDrawElements 可以与顶点缓冲区和索引缓冲区一起使用 有效地渲染具有许多共享顶点的几何图形,例如 景观网格。

      也许吧。不过,您必须确保顶点确实是共享的。位于同一位置但具有不同法线(例如,用于平面着色)的顶点并未真正共享。

      【讨论】:

      • 所有有用的信息,但都没有真正回答问题
      • 是的,尼科尔是对的。但感谢您的信息!这绝对是有帮助的。我确实有 VBO 和 glVertexAttribPointer 工作,所以我会坚持使用这些。你关于 glDrawElements 的观点是正确的——我理解你的意思,即顶点需要具有完全相同的属性才能使这种方法起作用。
      • 哦,对,问题。 “有人可以让我知道我是否错了”部分让我偏离了方向。对不起。
      猜你喜欢
      • 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
      相关资源
      最近更新 更多