我正在努力消除我在三角形带顶点缠绕方向(顺时针和逆时针)上看到的一些不一致。我正在OpenGL中绘制一个逆时针旋转90度的梯形。这是相关代码:
unsigned char mIndices[] = { 0, 1, 2, 3, 4, 5 };
signed short mVertices[] = {
-50, 100, 0, // A
-85, 65, 0, // B
-50, 65, 0, // C
-85, -65, 0, // D
-50, -65, 0, // E
-50, -100, 0, // F
};
...
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_SHORT, 0, mVertices);
...
glDrawElements(GL_TRIANGLE_STRIP, sizeof(mVertices)/sizeof(mVertices[0]), GL_UNSIGNED_BYTE, mIndices);
根据我在这里读到的内容,OpenGL中的默认正面是逆时针的,这意味着我的条形图中的第一个三角形的顶点应该是逆时针排列的。此外,当绘制三角形条带时,绕组在从一个三角形到另一个三角形的逆时针和顺时针之间切换方向,因此我的顶点是以这种方式排列的。因此,根据我的代码,第一个三角形是ABC,第二个是BCD,第三个CDE和第四个DEF。然而,这篇文章(引用OpenGL编程指南)说,它将把它们画成ABC、CBD、CDE、EDF(假设v0-A、v1-B等),这意味着它们都以相同的逆时针方向缠绕。
如果我从OpenGL规范中正确理解了A/B表示法,三角形都会朝着同一个方向缠绕,但我在一些不同的地方看到了不同的缠绕。我想这只是一个语义问题,因为得到的形状是一样的,但实际的缠绕顺序是什么?
因此,根据我的代码,第一个三角形是ABC,第二个是BCD,第三个CDE和第四个DEF。然而,这篇文章(引用OpenGL编程指南)说,它将把它们画成ABC、CBD、CDE、EDF(假设v0-A、v1-B等),这意味着它们都以相同的逆时针方向缠绕。
他们俩说的都是真的。从某种角度来看;)
您引用的教程是从顶点提供给光栅化器的顺序的角度来讨论它的。这正是所说的。光栅化器看到单个ABCDEF流。。。vertcies。因此,从这个角度来看,光栅化器必须在每隔一个三角形上切换其内部缠绕顺序,以符合用户的意图。
你引用的这本书是从你如何看待这些三角形的顺序的角度来谈论它的。当你按照这个顺序提供它们时,你希望绕组像ABC、CBD、CDE等一样工作。为了实现这一点,你在ABCDEF中提供它们。。。顺序
请放心,三角形条带产生的三角形都是按相同的顺序缠绕的(否则会一团糟,根本无法使用简单的东西,如背面剔除或双面渲染),这就是三角形条的魔力所在,也是为什么仅仅从每个连续的顶点开始绘制一个简单的三角形是行不通的(好吧,会的,但它会导致交替的缠绕顺序,这从来都不是一个好主意)。因此,第二篇文章(来自OpenGL编程指南)是正确的,而第一篇文章要么是错误的,要么是语义混乱,要么是被你误解了(尽管考虑到教程的质量,我猜是后者,但也许Nicol Bolas自己可以对此有所了解)。
编辑:好的,看第一篇文章的结尾:
注意它是如何在顺时针和逆时针之间交替的。这意味着,不管你认为正面是什么如果你剔除,你总是会失去大约一半的脸。
然而,OpenGL在这方面相当聪明。三角带做面部剔除不同。对于每一秒的三角形绕组的顺序与第一个三角形的顺序相反出于剔除的目的,订单被认为是向后的。
所以,如果你把前面设置为顺时针方向剔除剔除后向三角形,一切将完全按照只要第一个三角形的顺序是正确的,你就可以期待。如果每个偶数三角形具有顺时针方向,则它将被剔除绕组,并且如果每个奇数三角形具有逆时针绕组。
它实际上说,虽然缠绕顺序理论上是交替的,但OpenGL解释了这一点,并为三角形条带"修复"了它,导致每个三角形的缠绕顺序实际上是相同的(对于所有面临的考虑,如剔除或gl_FrontFacing
碎片着色器变量)。所以这两篇文章都是正确的,你只是直到最后才读到第一篇。尽管这篇文章本可以更清楚地表明,这不仅仅是为了剔除,而是为了所有面向的目的,因此你几乎不会注意到。