1

我正在开发一个供个人使用的小型 2D 图形/游戏库,目前我正在尝试想办法在绘制平铺地图时提高性能。目前我正在为地图中的每个图块创建一个静态 GL_QUADS VBO,然后将其绘制到屏幕上。每个 VBO 都引用加载到内存中的纹理,该纹理被子图像化并映射到 VBO。

目前,我正在测试一个 20 x 20 的平铺地图。在我当前的实现中,由于我必须绘制每个单独的图块,即每帧调用 400 次 glDraw*。

有没有办法,例如,使瓦片映射的每一行一个 VBO?对于本示例,这会将 glDraw* 调用减少到 20。我将如何映射子图像?单个瓷砖可以旋转。

我看过一些关于使用纹理图集的参考资料。那会是一个很好的选择吗?有关如何在 opengl 中实现此功能的任何有用链接?

代码:

当前渲染方法:

public void render() {
    texture.bind();

    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    for (SpriteSheet spriteSheet : spriteSheets) {
        VBO vbo = spriteSheet.getVBO();
        float angle = spriteSheet.getAngle();

        vbo.bind();
        if (angle != 0) {
            glPushMatrix();

            Vector2f position = spriteSheet.getPosition();

            glTranslatef(position.x, position.y, 0);
            glRotatef(angle, 0.0f, 0.0f, 1);
            glTranslatef(-position.x, -position.y, 0);

            glVertexPointer(Vertex.positionElementCount, GL_FLOAT, Vertex.stride, Vertex.positionByteOffset);
            glColorPointer(Vertex.colorElementCount, GL_FLOAT, Vertex.stride, Vertex.colorByteOffset);
            glTexCoordPointer(Vertex.textureElementCount, GL_FLOAT, Vertex.stride, Vertex.textureByteOffset);

            glDrawArrays(vbo.getMode(), 0, Vertex.elementCount);

            glPopMatrix();
        }
        else {
            glVertexPointer(Vertex.positionElementCount, GL_FLOAT, Vertex.stride, Vertex.positionByteOffset);
            glColorPointer(Vertex.colorElementCount, GL_FLOAT, Vertex.stride, Vertex.colorByteOffset);
            glTexCoordPointer(Vertex.textureElementCount, GL_FLOAT, Vertex.stride, Vertex.textureByteOffset);

            glDrawArrays(vbo.getMode(), 0, Vertex.elementCount);
        }
        vbo.unbind();
    }

    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);

    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);

    texture.unbind();
}
4

1 回答 1

1

您可以做几件事。

纹理图集是一个选项,但您也可以使用 a GL_TEXTURE_2D_ARRAY,使用第 3 个纹理坐标来选择要使用的图层。

接下来要考虑的是实例化:在缓冲区中有一个四边形并让 OpenGL 多次绘制它,使用额外的缓冲区根据绘制的实例选择纹理层和旋转。

于 2013-06-27T17:53:59.100 回答