c - 使用 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 个多边形的网格,并且运行得非常好。这让我想知道这里的代码怎么这么慢?使用这种技术进行渲染是一种可怕的方法吗?我怎样才能实现这样的渲染?
解决方案
您应该做的第一件事(在任何着色器内容之前)是停止使用 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 开始不推荐使用四边形。我们应该从三角形构建一切。
推荐阅读
- javascript - 如何单击没有选择器、类或名称的按钮
- ansible - 如何编写多行 Ansible Jinja2 变量?
- jquery - 在 jQuery 数据表插件行中添加下拉列表
- java - java中Json结构的多级映射
- ruby-on-rails - rbenv 找不到时如何使用 Ruby 2.6.6?
- python - 尝试通过 cut 创建 bin 列时出错
- numpy - Pytorch 张量到 numpy 的转换不精确
- sql-server - 如何使用分区将最小值/最大值转换为 SQL Server 中的列?
- java - Jersey 从空响应中获取标头
- javascript - 搜索数组并将结果存储在新数组中的问题