在OpenGL ES中绘制一个立方体需要多少个顶点?

12

我在不同的在线网站上看到了用OpenGL ES表示相同立方体时顶点数目不同的情况。例如这个:

float vertices[] = { -width, -height, -depth, // 0
                              width, -height, -depth, // 1
                              width,  height, -depth, // 2
                             -width,  height, -depth, // 3
                             -width, -height,  depth, // 4
                              width, -height,  depth, // 5
                              width,  height,  depth, // 6
                             -width,  height,  depth // 7
        };  
  short indices[] = { 0, 2, 1,
                0, 3, 2,

                1,2,6,
                6,5,1,

                4,5,6,
                6,7,4,

                2,3,6,
                6,3,7,

                0,7,3,
                0,4,7,

                0,1,5,
                0,5,4
                         };

这里还有一个:

float vertices[] = {
            //Vertices according to faces
                -1.0f, -1.0f, 1.0f, //Vertex 0
                1.0f, -1.0f, 1.0f,  //v1
                -1.0f, 1.0f, 1.0f,  //v2
                1.0f, 1.0f, 1.0f,   //v3

                1.0f, -1.0f, 1.0f,  //...
                1.0f, -1.0f, -1.0f,         
                1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, -1.0f,

                1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f, -1.0f,            
                1.0f, 1.0f, -1.0f,
                -1.0f, 1.0f, -1.0f,

                -1.0f, -1.0f, -1.0f,
                -1.0f, -1.0f, 1.0f,         
                -1.0f, 1.0f, -1.0f,
                -1.0f, 1.0f, 1.0f,

                -1.0f, -1.0f, -1.0f,
                1.0f, -1.0f, -1.0f,         
                -1.0f, -1.0f, 1.0f,
                1.0f, -1.0f, 1.0f,

                -1.0f, 1.0f, 1.0f,
                1.0f, 1.0f, 1.0f,           
                -1.0f, 1.0f, -1.0f,
                1.0f, 1.0f, -1.0f,
                                    };

在OpenGL ES(注意是OpenGL ES而不是OpenGL)中哪种表示方式的性能最高?当我想要指定法线来进行光照时,哪一种表示方式最好?在我的另一个SO问题中,我得到了这样的印象:对于一个立方体,我需要指定24个顶点,另一个说我需要36个顶点,还有另一个说我需要不同数量的顶点,这让我对同一个问题得到了矛盾的答案。无论如何,我希望知道一个正确的、技术上正确的单一答案。

我知道有三角形带或三角形扇等绘图概念,但在我的情况下,我正在使用:

gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
                GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);

所以这应该清楚地阐明了我所要问的问题。

1个回答

27

如果使用索引,在OpenGL ES中只需要提供8个不同的顶点来定义一个立方体。例如:

static const GLfloat cubeVertices[] = {
    -1.0, -1.0,  1.0,
    1.0, -1.0,  1.0,
    -1.0,  1.0,  1.0,
    1.0,  1.0,  1.0,
    -1.0, -1.0, -1.0,
    1.0, -1.0, -1.0,
    -1.0,  1.0, -1.0,
    1.0,  1.0, -1.0,
};

static const GLushort cubeIndices[] = {
    0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1
};

使用三角形带来定义几何体时,只需要提供14个索引即可指定立方体。如果您愿意,可以按顺序删除上述索引并提供顶点。
genpfault描述了向OpenGL ES提供纯三角形的情况,在这种情况下,您需要36个顶点。正如您所看到的,其中许多顶点是冗余的,因此带或索引可以减少需要发送的几何体数量。
Eric在他的评论中提出了一个很好的观点,即如果您需要为每个面提供纹理或颜色(似乎是您的目标),则需要使用24个顶点或索引。这样可以单独处理每个面。
对于您特定应用程序的最高性能取决于您运行此应用程序的硬件。例如,在iOS设备内部的PowerVR芯片上,苹果公司有这样的说法
为了获得最佳性能,您的模型应该作为单个未索引的三角形带提交,使用尽可能少的重复顶点,使用glDrawArrays进行绘制。如果您的模型需要复制许多顶点(因为许多顶点由不按顺序出现在三角形带中的三角形共享,或者因为您的应用程序合并了许多较小的三角形带),则可以使用单独的索引缓冲区,并调用glDrawElements来获得更好的性能。这是一个权衡:未索引的三角形带必须周期性地复制整个顶点,而索引的三角形列表需要额外的内存用于索引,并增加了查找顶点的开销。为了获得最佳效果,请使用索引和未索引的三角形带测试您的模型,并使用执行速度最快的那个。

1
如果立方体在每个面上不同,可能需要额外的顶点。例如,每个面颜色不同的立方体可能需要24个顶点和36个索引才能用glTriangles绘制。如果不是立方体的所有面都可见,则可以通过不绘制不可见的面来优化绘图,从而减少索引计数。 - Mr. Berna
@Mr. Berna - 很好的观点。我已经在我的答案中整合了这个观点,因为他似乎正在寻找魔方面的不同颜色。 - Brad Larson
3
抱歉在这个旧帖子里发帖,但我认为指数应该是{0,1,2,3,7,1,6,4,7,5,2,4,0,1}才能组成一个正确的立方体。至少你的立方体对我来说不起作用。 =) - Dafen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接