首页 > 解决方案 > 使用 GLUT 优化四边形的再现?

问题描述

我正在制作一个类似于 Minecraft 的 3d 体素引擎。我有一些世界生成和块逻辑工作,但是当我有 12 个块的渲染距离(例如,这对于 Minecraft 来说似乎相当典型)时,(2*12*12*16*16*2),我看到有一个可能需要渲染超过 150,000 个面孔。在尝试将引擎作为一个整体进行优化之前,我运行了一个测试,我只将一张脸渲染了 150,000 次。理论上,由于不必每次都在 3d 空间中计算点,因此该任务实际上应该是引擎必须进行的计算成本最低的再现。尽管如此,运行以下

glBegin(GL_QUADS);
glColor3f(1, 0, 0);
for (int i = 0; i < 150000;i++) {
    glVertex3fv(renderp1);
    glVertex3fv(renderp2);
    glVertex3fv(renderp3);
    glVertex3fv(renderp4);
}
glEnd();

即使没有纹理并且点都相同,我仍然得到一个非常破旧的 fps,这使得引擎无法使用。

我知道现代游戏有超过 100,000 个多边形的网格,并且运行得非常好。这让我想知道这里的代码怎么这么慢?使用这种技术进行渲染是一种可怕的方法吗?我怎样才能实现这样的渲染?

标签: copenglgame-engineglutopengl-compat

解决方案


您应该做的第一件事(在任何着色器内容之前)是停止使用 glBegin/glEnd 并开始使用 glDrawArrays 或 glDrawElements。

例如

// define data structures

struct vec3 { GLfloat x, y, z; };
struct vertex_t {
    vec3 position, color;
};

// define data (just a single triangle with RGB colors)
static const vertex_t vertices[] = {
    { { 0.0f,  0.5f, 0.0f }, { 1, 0, 0 } },
    { { 0.5f, -0.5f, 0.0f }, { 0, 1, 0 } },
    { { -0.5f, -0.5f, 0.0f }, { 0, 0, 1 } }
};

...

// setup the arrays
glVertexPointer(3, GL_FLOAT, sizeof(vertex_t), (char*)vertices + offsetof(vertex_t, position) );
glColorPointer(3, GL_FLOAT, sizeof(vertex_t), (char*)vertices + offsetof(vertex_t, color) );
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

...

// draw
glDrawArrays(GL_TRIANGLES, 0, 3);

这是 OpenGL 1.1 的东西。它可以通过需要 OpenGL 1.5 的 VBO(顶点缓冲区对象)进一步改进

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// now replace vertices with nullptr in calls to glVertexPointer and glColorPointer

我们甚至还没有接触到着色器。

对于 OpenGL 2.x 风格的着色器,上面的代码可以保持原样,或者您可以通过将 glVertexPointer/glColorPointer 替换为 glVertexAttribPointer 并将 glEnableClientState 替换为 glEnableVertexAttribArray 来进一步“现代化”它,以使“现代 OpenGL”的人们感到高兴。

但是仅仅使用 OpenGL 1.1 风格的 glDrawArrays 应该足以解决性能问题。这样您就不会调用 glVertex/glColor 100000 次,但是对 glDrawArrays 的一次调用可以一次绘制 100000 个顶点(如果使用 VBO,它们已经在 GPU 内存中)。

哦,从 3.0 开始不推荐使用四边形。我们应该从三角形构建一切。


推荐阅读