我需要最小化glDraw *调用的次数

时间:2013-06-27 17:46:03

标签: performance opengl lwjgl vbo

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

目前,我正在测试一张20 x 20的瓷砖地图。在我当前的实现中,因为我必须绘制每个单独的tile,即每帧400 glDraw *调用。

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

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

CODE:

当前渲染方法:

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();
}

1 个答案:

答案 0 :(得分:1)

你可以做几件事。

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

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