在OpenGL 3.x中使用索引顶点数组时,如何指定每面颜色?

Won*_*nko 27 opengl

我正在尝试使用8个顶点的数组和24(4 *6)个索引的索引数组渲染一个立方体到顶点数组中.但是如何在不使用弃用函数的情况下指定每个变量(如颜色和法线)?为此,我需要一组单独的索引,但是当我指定两个索引数组(GL_ELEMENT_ARRAY_BUFFERs)并将它们指向不同的着色器变量(两次调用glVertexAttribPointer)时出现问题,并且它不会呈现任何内容(但不会t报告任何错误 - 用glGetError检查).我是否必须为每个面使用不同的glDrawElements调用,颜色和法线加载到统一变量中?

为了澄清,当8个顶点中的每一个都是不同面的一部分并且需要不同的颜色和法线值时,就会出现问题.

Jon*_*ley 41

对是否使用数组索引感兴趣的人可以在我创建的图表中找到一些实用程序,以图形方式总结不同OpenGL调用的行为,以便您可以看到,例如哪些绘制了连续的顶点数据块,相对于哪些那些'跳过'使用指数.

OpenGL绘制调用.

我在Creative Commons BY-SA下发布了这张图片,正如此消息来源所述.


Bah*_*bar 32

首先是实际答案:
见Goz的答案.保留24个独立的顶点.

一些命名法第二:
顶点是一组顶点属性.阅读以下内容时请记住这一点:

您误以为使用已弃用的API可以帮助您解决问题.不是这种情况.OpenGL处理​​(并且始终处理)每个顶点作为一组唯一的属性.如果您仔细阅读原始规格,您会注意到:

glNormal()
glVertex()
glVertex()
glVertex()
Run Code Online (Sandbox Code Playgroud)

规范明确规定glNormal设置current normal state,并glVertex 引发一个新的顶点,复制传递所有current state,包括current normal state.也就是说,即使你只通过了一个法线,GL仍然会看到3.

因此,GL没有"per-face"属性.

此外,你混合索引数组GL_ELEMENT_ARRAY_BUFFER时,从使用的glDrawElements(..., pointer),其中pointer的一个索引数组内的偏移,以及顶点属性阵列GL_ARRAY_BUFFER时,从使用glVertexAttribPointer(和所有过时的glVertexPointer/glNormalPointer...

索引缓冲区中的每个索引都将用作每个属性的索引,但您只能为每个顶点指定一个索引.因此,设置GL_ELEMENT_ARRAY_BUFFER然后调用glVertexAttribPointer,根本不会做你认为它做的事情.它要么使用您设置的最后一个数组来GL_ARRAY_BUFFER定义顶点属性,要么如果没有保留一个边界,则将偏移量解释为指针(并且可能会崩溃).

GL不支持您为每个顶点属性设置索引数组所做的操作.让我重申一下:每次绘制只有1个索引数组.

包含历史的一些额外花絮:

glVertex有点用词不当.它仅指定Vertex 位置.但是,这就是它的名字,它也引发了一个传递给GL的顶点.为了让API完全干净,您可能会想到必须进行2次调用:

// not valid code
glPosition(1,2,3); // specifies the current vertex position
glProvoke(); // pass the current vertex to GL
Run Code Online (Sandbox Code Playgroud)

但是,当首次指定GL时,总是需要位置,因此融合那些2以激发顶点是有意义的(如果只是为了减少API调用计数).

快进vertex_program_arb:试图摆脱固定功能模型,同时保持兼容意味着glVertex的特殊性质必须继续发扬光大.这是通过制作vertex attribute 0挑衅和glVertex的同义词来实现的.

快进到GL3.2:开始/结束模型消失了,所有这些引发顶点的规范最终都会消失,同时还有管理current state.所有语义API(glVertex*,glNormal*...)也是如此,因为所有输入现在都只是顶点属性.


Goz*_*Goz 6

您需要超过8个顶点.Verts可以共享位置,但除非顶点中的其他所有内容都是唯一的,否则它不是唯一的顶点.法线是在多维数据集定义中需要超过8个顶点的另一个经典原因.


小智 6

有趣的解释,但它们似乎掩盖了原始问题包含其自己的答案的事实:"我是否必须对每个面使用不同的glDrawElements调用,颜色和法线加载到均匀变量中?" - 如果必须将相同的顶点位置数据馈送到图形处理器三次,而一次应该足以冒犯一个人的美感(并且它应该),那么这是肯定的.

最初的提问者不想知道OpenGL不能做他想做的事情,并且他需要为立方体维护二十四个顶点,标准数学和常识告诉我们只需要八个.他已经知道他可以做他想做的事了,他甚至知道如何做.他只是想确认他提出的方法确实有意义,并且没有更好的方法去做他忽略的方法.

调用每个面孔确实增加了它自己的开销,但是在绘制一个立方体时这几乎不重要.当绘制很多时,所有相同属性的面都可以一起进行批处理,例如所有朝向南方的所有西方,或者所有红色然后全部绿色或其他.