7

我正在尝试清除在三角形条带顶点缠绕方向(顺时针和逆时针)中看到的一些不一致。我正在 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 表示法,那么这些三角形都会以相同的方向缠绕,但我已经在几个不同的地方看到了不同的缠绕。我想这只是语义问题,因为结果形状是相同的,但实际的缠绕顺序是什么?

4

2 回答 2

7

所以从我的代码中,第一个三角形是 ABC,第二个是 BCD,第三个 CDE,第四个 DEF。但是,这篇文章(在 OpenGL 编程指南的引文中)说它将把它们绘制为 ABC、CBD、CDE、EDF(假设 v0 - A、v1 - B 等),这意味着它们都以相同的逆时针方向缠绕方向。

他们俩说的都是真的。从某种角度来看;)

您引用的教程从顶点提供给光栅化器的顺序的角度来讨论它。这正是所说的。光栅化器看到单个 ABCDEF... 顶点流。因此,从这个角度来看,光栅化器必须每隔一个三角形切换其内部缠绕顺序,以匹配用户的意图。

你引用的那本书是从你如何看待这些三角形的顺序的角度来谈论它的。当您按该顺序提供它们时,您希望绕组像 ABC、CBD、CDE 等一样工作。为了实现这一点,您按 ABCDEF... 顺序提供它们。

于 2013-08-01T17:42:15.913 回答
5

请放心,由三角形条产生的三角形都以相同的顺序缠绕(否则它会一团糟,你根本不能使用背面剔除或双面渲染等简单的东西),这是一部分三角形带的魔力以及为什么只从每个连续的顶点开始绘制一个简单的三角形是行不通的(嗯,它会,但它会导致交替的缠绕顺序,这从来都不是一个好主意)。所以第二篇文章(来自 OpenGL 编程指南)是正确的,而第一篇文章要么是错误的,要么是语义混乱,要么是被你误解了(虽然我猜后者,鉴于该教程的质量,但也许是Nicol波拉斯本人可以对此有所了解)。

编辑:好的,看看第一篇文章的结尾:

注意它是如何在顺时针和逆时针之间交替的。这意味着,无论您认为什么脸是正面的,以及您剔除什么脸,您总是会丢失大约一半的脸。

然而,OpenGL 在这方面相当聪明。三角形条确实以不同的方式面对剔除。对于每第二个三角形,缠绕顺序与第一个三角形顺序相反的三角形,出于剔除目的,缠绕顺序被认为是向后的。

因此,如果您将正面设置为顺时针方向,并通过面剔除剔除背面三角形,那么只要第一个三角形的顺序正确,一切都会按照您的预期进行。如果每个偶数编号的三角形具有顺时针缠绕,则将被剔除,而每个奇数编号的三角形如果具有逆时针缠绕,则将被剔除。

它实际上说,虽然缠绕顺序在理论上是交替的,但 OpenGL 对此进行了解释,并为三角形条“修复”了它,导致实际上的缠绕顺序(对于所有面临的考虑,如剔除或gl_FrontFacing片段着色器变量)对于每个三角形。所以两篇文章都是正确的,你只是没有读到最后一篇。虽然这篇文章本可以更清楚地表明它不仅仅是为了剔除目的,而是为了所有面向目的,因此实际上你不会注意到。

于 2013-08-01T17:33:34.207 回答