【问题标题】:OpenGL instanced rendering slower than glBegin/glEndOpenGL 实例化渲染比 glBegin/glEnd 慢
【发布时间】:2017-02-07 21:49:34
【问题描述】:

我正在将使用 glBegin()/glEnd()(上图)的旧程序移植到 glDrawArraysInstanced()(下图)。我期待一些性能改进,但我得到了相反的结果。现在这是我第一次尝试使用 glDrawArraysInstanced(),所以我想我一定是搞砸了。

两者基本相同,唯一的区别是画圆的方式。

我做错了什么?如果没有,是什么让它变慢了?

// This runs once at startup
std::vector<glm::mat4> transforms;
glGenBuffers(NUM_BUFFERS, VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO[TRANSFORM]);
for (int i = 0; i < 4; ++i) {
  glEnableVertexAttribArray(1 + i);
  glVertexAttribPointer(1 + i, 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4),
                      (GLvoid *)(i * sizeof(glm::vec4)));
  glVertexAttribDivisor(1 + i, 1);
} // ---------


// This runs every frame
if (num_circles > transforms.size()) transforms.resize(num_circles);
int i = 0;
for (const auto &circle : circle_vec) {
  transforms[i++] = circle.transform.getModel();
}

glBindBuffer(GL_ARRAY_BUFFER, VBO[TRANSFORM]);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * num_circles,    &transforms[0], GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(VAO);
glDrawArraysInstanced(GL_LINE_LOOP, 0, CIRCLE_NUM_VERTICES, num_circles);
glBindVertexArray(0);
// ---------


// And this is the vertex shader
#version 410

in vec3 position;
in mat4 transform;

void main()
{
   gl_Position = transform * vec4(position, 1.0);
}

【问题讨论】:

  • 线框对性能非常不利。我看到您的较慢版本仅绘制轮廓,这可能是一个促成因素。
  • @DavidLively 我正在使用 GL_LINE_LOOP。与 GL_TRIANGLE_FAN 的性能完全相同。
  • 这意味着问题出在其他地方。 @OnurA 关于向量的回答是一个很好的起点。每帧重新分配包含这么多元素的向量很快就会成为瓶颈。

标签: c++ opengl glsl shader instance


【解决方案1】:

我第一眼看到的是,您在每一帧上都创建了一个新矢量。考虑缓存它。

// This runs every frame
std::vector<glm::mat4> transforms;

【讨论】:

  • @MarcusMathiassen 他说的是:在帧之间保持矢量,每次都清除它。 (不要重置,因为这会释放内存,这会破坏目的。)
  • 将向量放在外面并仅在需要时调整其大小可提供完全相同的性能。我想它一定是别的东西。
  • 抱歉不够清楚,感谢 DavidLively 说清楚@DavidLively,谢谢你的伙伴!
  • @MarcusMathiassen 好的,是时候打开分析器了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-05
相关资源
最近更新 更多