使用 GLUT 优化四边形的再现?
Optimising the rendition of quads using GLUT?
我正在制作一个类似于 Minecraft 的 3d 体素引擎。我有一些世界生成和块逻辑工作,但是当我有 12 个块的渲染距离(例如,这对于 Minecraft 来说似乎相当典型),(2 * 12 * 12 * 16 * 16 * 2),我看到有一个需要渲染超过 150,000 张面孔的潜力。在尝试优化整个引擎之前,我 运行 进行了一项测试,我只渲染了一张脸 150,000 次。从理论上讲,由于不必每次都在 3d space 中计算点,因此该任务实际上应该是引擎必须进行的计算成本最低的再现。
尽管如此,运行宁以下
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 个多边形的网格,而且 运行 非常棒。这让我想知道这段代码怎么这么慢?使用这种技术进行渲染是一种可怕的方式吗?我怎样才能实现这样的渲染?
您应该做的第一件事(在任何着色器之前)是停止使用 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 的东西。可以通过VBO(Vertex Buffer Object)进一步改进,需要OpenGL 1.5
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”让人开心。
但仅使用 glDrawArrays,OpenGL 1.1 风格,应该足以解决性能问题。
这样您就不会调用 glVertex/glColor 100000 次,但一次调用 glDrawArrays 可以一次绘制 100000 个顶点(如果使用 VBO,它们已经在 GPU 内存中)。
哦,四边形自 3.0 以来已弃用。我们应该从三角形构建一切。
我正在制作一个类似于 Minecraft 的 3d 体素引擎。我有一些世界生成和块逻辑工作,但是当我有 12 个块的渲染距离(例如,这对于 Minecraft 来说似乎相当典型),(2 * 12 * 12 * 16 * 16 * 2),我看到有一个需要渲染超过 150,000 张面孔的潜力。在尝试优化整个引擎之前,我 运行 进行了一项测试,我只渲染了一张脸 150,000 次。从理论上讲,由于不必每次都在 3d space 中计算点,因此该任务实际上应该是引擎必须进行的计算成本最低的再现。 尽管如此,运行宁以下
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 个多边形的网格,而且 运行 非常棒。这让我想知道这段代码怎么这么慢?使用这种技术进行渲染是一种可怕的方式吗?我怎样才能实现这样的渲染?
您应该做的第一件事(在任何着色器之前)是停止使用 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 的东西。可以通过VBO(Vertex Buffer Object)进一步改进,需要OpenGL 1.5
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”让人开心。
但仅使用 glDrawArrays,OpenGL 1.1 风格,应该足以解决性能问题。 这样您就不会调用 glVertex/glColor 100000 次,但一次调用 glDrawArrays 可以一次绘制 100000 个顶点(如果使用 VBO,它们已经在 GPU 内存中)。
哦,四边形自 3.0 以来已弃用。我们应该从三角形构建一切。