OpenGL-ES - 渲染2D游戏的正确方法

时间:2013-12-04 19:00:08

标签: opengl-es 2d rendering vbo

我正在制作一款带2D图形的Android游戏,我需要一个如何正确的建议 渲染它以获得良好的性能。目前表现非常糟糕。 此外,我想知道如何正确地使用VBO渲染许多精灵。 以下是一些可能对实施造成限制的事实:

  1. 游戏中的每个对象都有自己的类,它有自己的onDraw()函数。
  2. 游戏画面包含100,000个需要渲染的纹理四边形。非常小的纹理。
  3. 那些100,000个四边形可能会改变位置或消失。
  4. 绘制某些对象非常复杂(需要更改混合模式和像素测试),并且需要正确绘制对象数据中的大量信息。
  5. 我已经阅读了几乎所有关于加快性能的现有文章,我意识到了 转向VBO是一个好主意(因为现在它使用顶点数组)。然而他们都是 要么太简单也不能解释得太好,要么不能满足我的所有需求。

    这是我的问题开始的地方: 1.将所有内容保存在一个VBO中还是保持每个对象或类的VBO更好? 2.当对象改变位置时,我是否修改纹理坐标并再次将VBO重新复制到GPU(这只能从gl线程中完成),或者在任何对象绘制之前调用glTranslatef()并指定这是VBO的索引?他们还建议减少gl调用次数,使其无法一起工作。 3.在绘制每个对象之前,如果有很多gl函数调用,如何快速渲染帧?

    目前的方法可能是您能找到的最差方法:

        private float vertices[] = 
        {
                -1.0f, -1.0f,  0.0f,        // V1 - bottom left
                -1.0f,  1.0f,  0.0f,        // V2 - top left
                 1.0f, -1.0f,  0.0f,        // V3 - bottom right
                 1.0f,  1.0f,  0.0f         // V4 - top right
        };
    
        private FloatBuffer textureBuffer;  
        private float texture[] = 
        {           
    
                0.0f, 1.0f,     // top left     (V2)
                0.0f, 0.0f,     // bottom left  (V1)
                1.0f, 1.0f,     // top right    (V4)
                1.0f, 0.0f      // bottom right (V3)
        };
        ...
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
    
        vertexBuffer = byteBuffer.asFloatBuffer();
    
        vertexBuffer.put(vertices);
    
        vertexBuffer.position(0);
    
        byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        textureBuffer = byteBuffer.asFloatBuffer();
        textureBuffer.put(texture);
        textureBuffer.position(0);
    

    绘图代码:

            gl.glBindTexture(GL11.GL_TEXTURE_2D,  MainProgram.glSurfaceView.renderer.ResourceIdToTexture(resourceId));
            gl.glEnableClientState(GL11.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
            gl.glFrontFace(GL11.GL_CW);
            gl.glVertexPointer(3, GL11.GL_FLOAT, 0, vertexBuffer);
            gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, textureBuffer);
            gl.glPushMatrix();
            gl.glTranslatef(glPos[0], glPos[1], -1.0f);
            gl.glScalef(glDim[0], glDim[1], 1.0f);
            gl.glRotatef(rotation, 0,0,-1);
            if(maskColor != null) maskColor.apply(gl);
            gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
            if(maskColor != null) maskColor.restore(gl);
            gl.glPopMatrix();
            gl.glDisableClientState(GL11.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
    

0 个答案:

没有答案