0

在 OpenGL 上绘制动态移动对象的最佳方法是什么?

目前,我正在这样做:我有一个 class 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 专家,但在我看来效率很低。难道没有另一种更有效的方法吗?

4

2 回答 2

4

不推荐使用的方法是使用 glTransform。更好的方法是使用着色器。

您真的不需要每帧都将所有顶点发送到 gpu。你的假设是正确的,它是低效的。创建actor时,只需创建一次网格并将所有顶点发送到显卡。然后每个画框,你所要做的就是绑定缓冲区并调用glDrawArrays。像这样的东西。

要应用转换,您将 x、y、z 偏移量发送到顶点着色器并将其与顶点相乘。该站点提供了一些关于如何使用未弃用的 opengl 功能执行此操作的优秀教程。

于 2013-06-12T19:56:31.247 回答
2

如果您以相同的方式变换所有顶点,则只传递 4x4 变换矩阵的统一变量,即每帧重新计算。

如果您需要独立更改顶点,则必须更改属性数组并在每一帧中上传它,但是您应该考虑使用 option GL_DYNAMIC_DRAW。请参阅bufferData - 使用参数差异以获得更多说明。

希望这可以帮助。

于 2013-06-12T19:46:17.870 回答