在OpenGL上绘制动态移动对象的最佳方法是什么?
目前,我正在执行以下操作:我有一个类Actor
,其中构造函数我生成一个缓冲区:
Actor::Actor(float x, float y): xpos(x),
ypos(y),
width(1),
height(1) {
glGenBuffers(1, &buffer);
}
所有其他处理都在每一帧中完成:
for(auto const &a: actors) {
float x = (a.xpos / tiles_x) * 2 - 1.0f + (1 / tiles_x);
float y = -((a.ypos / tiles_y) * 2 - 1.0f + (1 / tiles_y));
float w = a.width / (tiles_x);
float h = a.height / (tiles_y);
const GLfloat vertex[] {
x - w, y - h, 1.0f,
x - w, y + h, 1.0f,
x + w, y + h, 1.0f,
x - w, y - h, 1.0f,
x + w, y - h, 1.0f,
x + w, y + h, 1.0f,
};
glBindBuffer(GL_ARRAY_BUFFER, a.buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
}
我不是OpenGL专家,但在我看来效率非常低。是不是还有另一种更有效的方法呢?
答案 0 :(得分:4)
不推荐使用的方法是使用glTransform。更好的方法是使用着色器。
你真的不需要每帧都将所有顶点发送到gpu。你的假设是正确的,这是低效的。创建actor时,只需创建一次网格并将所有顶点发送到图形卡。然后每个绘制框架,你所要做的就是绑定缓冲区并调用glDrawArrays。 Something like this.
要应用变换,您可以将x,y,z偏移发送到顶点着色器并将其与顶点相乘。 This site offers一些关于如何使用不推荐的opengl功能执行此操作的优秀教程。
答案 1 :(得分:2)
如果以相同的方式变换顶点,则只传递4x4变换矩阵的统一变量,即每帧重新计算。
如果您需要单独更改顶点,则必须更改属性数组并在每个帧中上传它,但是您应该考虑使用选项GL_DYNAMIC_DRAW
。有关详细说明,请参阅bufferData - usage parameter differences。
希望这有帮助。