Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 我需要尽量减少glDraw*呼叫的次数_Performance_Opengl_Lwjgl_Vbo - Fatal编程技术网

Performance 我需要尽量减少glDraw*呼叫的次数

Performance 我需要尽量减少glDraw*呼叫的次数,performance,opengl,lwjgl,vbo,Performance,Opengl,Lwjgl,Vbo,我正在开发一个供个人使用的小2D图形/游戏库,目前我正试图想出一种方法来提高绘制平铺地图时的性能。目前,我正在为地图中的每个瓷砖创建一个静态GL_QUADS VBO,然后将其绘制到屏幕上。每个VBO都引用加载到内存中的纹理,该纹理被子映像并映射到VBO 目前,我有一个20 x 20的瓷砖地图,我正在测试。在我当前的实现中,由于我必须绘制每个单独的分幅,即每帧400个glDraw*调用 例如,有没有办法使平铺贴图的每一行都成为一个VBO?在本例中,这将把glDraw*调用减少到20个。如何映射子图

我正在开发一个供个人使用的小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();
}

你可以做几件事

纹理图集是一个选项,但您也可以使用
GL\u texture\u 2D\u数组
,使用第三个纹理坐标选择要使用的层


接下来要考虑的是实例化:在缓冲区中放置一个四边形,让OpenGL绘制几次,使用附加缓冲区根据绘制的实例选择纹理层和旋转。

您可以做几件事

纹理图集是一个选项,但您也可以使用
GL\u texture\u 2D\u数组
,使用第三个纹理坐标选择要使用的层


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

这3个选项中哪一个最容易实现?我不熟悉这些,因为我不久前才开始使用OpenGL。@cstuts:GL\u TEXTURE\u 2D\u数组是最容易访问的。使用它将给您带来巨大的性能提升,因为您同时摆脱了三个瓶颈:大量gldraw调用、小批量和纹理切换。其中每一个都会对渲染性能产生不利影响,因此,将它们排除在外将大大帮助您。纹理阵列无疑是一条可行之路。这3个选项中哪一个最容易实现?我不熟悉这些,因为我不久前才开始使用OpenGL。@cstuts:GL\u TEXTURE\u 2D\u数组是最容易访问的。使用它将给您带来巨大的性能提升,因为您同时摆脱了三个瓶颈:大量gldraw调用、小批量和纹理切换。每一种方法都会对渲染性能产生不利影响,因此,将它们排除在外将有助于提高渲染性能。纹理阵列无疑是一种可行的方法。