C++ 使用一个GL元素\数组\缓冲区引用0中的每个属性? 问题:

C++ 使用一个GL元素\数组\缓冲区引用0中的每个属性? 问题:,c++,opengl-4,C++,Opengl 4,OpenGL 4.4,C++11 通过将顶点属性设置为元素数组缓冲区和数组缓冲区,我是否有能力从0开始为每个属性使用元素数组缓冲区中的索引 数据布局 数据使用 问题 我写我的索引,这样我就可以引用第一个顶点,UV,和0/0/0的法线。是否可以将其映射到元素数组缓冲区中并使用它?或者我的解决方案是将nPositions添加到纹理索引中,将nPositions+nTextures添加到法线索引中?OpenGL不支持每个顶点单独的索引属性。为顶点属性使用缓冲区时,需要为每个唯一的顶点属性组合创建一个

OpenGL 4.4,C++11

通过将顶点属性设置为元素数组缓冲区和数组缓冲区,我是否有能力从0开始为每个属性使用元素数组缓冲区中的索引

数据布局 数据使用
问题
我写我的索引,这样我就可以引用第一个顶点,UV,和0/0/0的法线。是否可以将其映射到元素数组缓冲区中并使用它?或者我的解决方案是将nPositions添加到纹理索引中,将nPositions+nTextures添加到法线索引中?

OpenGL不支持每个顶点单独的索引属性。为顶点属性使用缓冲区时,需要为每个唯一的顶点属性组合创建一个顶点

典型的例子是一个以位置和法线为顶点属性的立方体。立方体有8个角,因此它的“位置”属性有8个不同的值。它有6条边,因此法线属性有6个不同的值。立方体有多少个顶点?在OpenGL中,答案是24

至少有两种方法可以导出为什么在这种情况下顶点数为24:

  • 这个立方体有6条边。我们不能在边之间共享顶点,因为它们具有不同的法线。每边有4个角,因此每边需要4个顶点。6*4=24
  • 这个立方体有8个角。在这8个角的每个角上,有3条边相交。因为这三条边有不同的法线,所以我们需要为每一条边指定不同的顶点。8*3=24
现在,由于您专门询问了OpenGL4.4,因此可以考虑其他选项。例如,可以将顶点属性的值指定为索引而不是坐标。由于您当然可以使用多个顶点属性,因此每个顶点都可以有多个索引。然后,顶点着色器将这些索引作为顶点属性的值获取。然后,它可以从不同的源检索实际属性值。这些来源的可能性包括:

  • 统一缓冲区
  • 纹理缓冲区
  • 纹理
我不相信这些方法中的任何一种都会像以更传统的方式简单地使用顶点属性那样有效。但是如果你想探索你所有的选择,那就值得一试


实例化渲染是另一种方法,有时可以帮助渲染顶点属性的不同组合,而无需枚举所有组合。但这只有在几何体重复的情况下才有效。例如,如果您希望通过一次绘制调用渲染多个立方体,并对每个立方体使用不同的颜色,则实例化渲染将非常有效。

我想在我的例子中,目标是在客户端查找每个索引的三元组,将它们混合到一个大VBO中,然后用gldrawArray缓冲并渲染它们?这几乎是标准的方法。对另一个问题的回答概述了如何组合单独的索引:。作为一个小的旁注:有一个扩展确实以有限的方式支持不同的元素索引。然而,它不太可能成为一个标准的扩展,而且我从来没有在非AMD GPU上看到过对它的支持。
VAO      
 Buffer(array_buffer)      
   PositionFloat * n  
   TextureFloat  * n
   NormalFloat   * n
 Buffer(element_array_buffer)      
   PositionIndex * 1
   TextureIndex  * 1
   NormalIndex   * 1
//gen
glBindVertexArray(VAO);

glBindBuffer(array_buffer, vbo);
glBufferData(array_buffer, size(vertices), data(vertices), access(vertices));
glVertexAttribPointer(POSITIONS, 3, float, offset(0));
glVertexAttribPointer(UVS,       2, float, offset(positions));
glVertexAttribPointer(NORMALS,   3, float, offset(normals));

glBindBuffer(element_array_buffer, ebo);
glBufferData(element_array_buffer, size(elements), data(elements), access(elements)); 
...?! /*Cannot set element attributes!  
If I could, I would set a strided, offset attribPointer for each attribute, 
so that if 0 appears in the NORMALS attribute, it will look up the first normal, 
and not the first element in the buffer. */