在OpenGL中给一个立方体贴图的最佳方法

8

如何以最低的内存消耗和最快的速度为一个立方体上色?经过一段时间的研究,我找到了以下解决方案:

数据结构:

GLfloat Cube::vertices[] =
 {-0.5f, 0.0f, 0.5f,   0.5f, 0.0f, 0.5f,   0.5f, 1.0f, 0.5f,  -0.5f, 1.0f, 0.5f,
  -0.5f, 1.0f, -0.5f,  0.5f, 1.0f, -0.5f,  0.5f, 0.0f, -0.5f, -0.5f, 0.0f, -0.5f,
  0.5f, 0.0f, 0.5f,   0.5f, 0.0f, -0.5f,  0.5f, 1.0f, -0.5f,  0.5f, 1.0f, 0.5f,
  -0.5f, 0.0f, -0.5f,  -0.5f, 0.0f, 0.5f,  -0.5f, 1.0f, 0.5f, -0.5f, 1.0f, -0.5f
  };

 GLfloat Cube::texcoords[] = { 0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0,
                               0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0,
                               0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0,
                               0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0
                             };

 GLubyte Cube::cubeIndices[24] = {0,1,2,3, 4,5,6,7, 3,2,5,4, 7,6,1,0,
                                  8,9,10,11, 12,13,14,15};

绘制函数:
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, texture);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glColor3f(1.0f, 1.0f, 1.0f);

        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnableClientState(GL_VERTEX_ARRAY);

        glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
        glVertexPointer(3, GL_FLOAT, 0, vertices);

        glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, cubeIndices);
        glDisableClientState(GL_VERTEX_ARRAY);
        //glDisableClientState(GL_COLOR_ARRAY);
        glDisable(GL_TEXTURE_2D);

如您所见,结果是正确的:cube

但是,为了达到这个结果,我不得不重新定义一些顶点(vertices数组中有16个3D点),否则纹理将无法在DrawElement函数中映射。

有人知道在顶点数组中更好的纹理立方体的方法吗?


3
为什么你需要"最快/最低内存",你打算在屏幕上放置十亿个立方体吗?另外,你所说的“重新定义一些顶点”是什么意思? - Luke B.
设置了立方体纹理后,帧率下降了(从60降到40)。我重新定义了“vertices”数组中的一些顶点,如果你仔细看,这个数组中有16个点(3D),但是为了定义一个立方体,只需要8个就足够了。 - Luca
2
如果你遇到了问题,那就是你做错了什么。这很可能不是因为方块的缘故,因为8个或16个顶点基本没有太大区别。同时还需要考虑每个顶点连接着三个面,而它们都有不同的UV坐标,因此你需要这些“额外”的顶点。我不确定你是否只调用了一次glTexParameteri,当你创建纹理时这个操作只用执行一次,如果在你的循环中重复执行它会导致速度变慢。 - Luke B.
2个回答

2

我之前在使用OpenGL ES时遇到了同样的问题。我的研究表明,这是因为每个顶点只能关联一个纹理坐标,所以没有其他方法可以解决这个问题。


你说得对。我从我的GPU教科书上读到,GPU的局限之一是我们几乎无法与其他并行顶点通信,因此每个面应该有一些重复的顶点。 - Seideun

0

嗯,你可以在顶点着色器中使用立方体贴图纹理来处理纹理坐标。要生成纹理坐标,你只需要在顶点着色器中添加这行代码:

out vec2 texcoords;
texcoords=normalize(vertex_data.xy)

无需重新定义顶点,您还可以通过使用顶点缓冲对象来提高性能。


现在使用着色器还为时过早。 - Luca
1
我不明白你所说的“对我来说太早”是什么意思? - debonair
5
那不是借口。你应该从着手学习着色器开始。如今,着色器不是“高级”的,而是标准 - Nicol Bolas

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