Hed*_*din 5 c++ optimization android vbo opengl-es-2.0
What I need to do is to render a relatively huge isometric map on a mobile device (OpenGL ES2.0, Android 4.2). I'm using 1 VBO for the terrain, 1 VBO for the shadow layer, and 1 VBO for the objects layer. The performance is the issue, even with the very first VBO.
Here we go, I have the data type for filling the VBO:
typedef struct _ovlndVertex
{
    GLshort x;
    GLshort y;
} ovlndVertex;
typedef struct _ovlndTexture {
    GLfloat u;
    GLfloat v;
} ovlndTexture;
typedef struct _TexturedVertex
{
    ovlndVertex        vertices;
    ovlndTexture       texCoords;
    GLshort textureId;
} TexturedVertex;
Run Code Online (Sandbox Code Playgroud)
Let's say we are rendering a 256x256 sized map, 4 vertices per tile, this gives us 256x256x4 = 262144 vertices in the VBO. Given the sizeof(TexturedVertex) == 16, this is 4194304 bytes of raw VBO data (around 4MB).
The main rendering job is done in the shaders. Here is their code:
The vertex shader:
attribute vec4 a_position;                            
attribute vec2 a_texCoord;                            
//attribute vec4 a_color;
attribute vec2 a_textureId;                              
uniform        mat4 u_MVPMatrix;                        
#ifdef GL_ES                                        
//varying lowp vec4 v_fragmentColor;                    
varying lowp vec2 v_texCoord;
#else                                                
//varying vec4 v_fragmentColor;                        
varying vec2 v_texCoord;
#endif                                                
varying float v_textureId;
void main()                                            
{                                                    
    gl_Position = u_MVPMatrix * a_position;            
//  v_fragmentColor = a_color;
    v_texCoord = a_texCoord;                        
    v_textureId = a_textureId.x;
}                                                    
Run Code Online (Sandbox Code Playgroud)
The fragment shader:
#ifdef GL_ES                                
precision lowp float;
precision lowp int;
precision lowp sampler2D;
#endif                                        
//varying vec4 v_fragmentColor;                
varying vec2 v_texCoord;
//uniform sampler2D u_texture0, u_texture1, u_texture2;
uniform sampler2D u_textures[16];
varying float v_textureId;
uniform int u_idxOffset;
void main()                                    
{                                  
    // strange enough, but binary search below works WAY faster than
    // plain texture array referencing by index like:
//    int idx = int(v_textureId) - u_idxOffset;
//    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[idx], v_texCoord);
    int index = int(v_textureId) - u_idxOffset;
    if(index < 8) //0-7
    {
        if(index < 4) // 0-4
        {
            if(index < 2) //0-1
            {
                if(index < 1)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[0], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[1], v_texCoord);
                }
            } else // 2-3
            {
                if(index < 3)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[2], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[3], v_texCoord);
                }
            }
        } else //4-7
        {
            if(index < 6) //4-5
            {
                if(index < 5)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[4], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[5], v_texCoord);
                }
            } else // 6-7
            {
                if(index < 7)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[6], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[7], v_texCoord);
                }
            }
        }
    } else //8-15
    {
        if(index < 12) //8-11
        {
            if(index < 10) //8-9
            {
                if(index < 9)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[8], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[9], v_texCoord);
                }
            } else // 10-11
            {
                if(index < 11)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[10], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[11], v_texCoord);
                }
            }
        } else //12-15
        {
            if(index < 14) //12-13
            {
                if(index < 13)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[12], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[13], v_texCoord);
                }
            } else // 14-15
            {
                if(index < 15)
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[14], v_texCoord);
                }
                else
                {
                    gl_FragColor = /*v_fragmentColor * */texture2D(u_textures[15], v_texCoord);
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
Yes, I'm aware of OpenGL ES culling of the vertices outside the viewport, and it works perfectly. On a high zoom level it renders smoothly showing 60FPS on the device, however, if I zoom out to view all the map (this is the primary point) the FPS drops to 20-30 even without object rendering and to 4-5 with object rendering (2 additional similar VBOs).
Here is the ADT's OpenGL ES Tracer output for a typical slow-to-render frame: (Wall Clock time: 0.49ms, Thread Time 0.37ms)
glClear(mask = 16640)
glUseProgram(program = 22)
glBindTexture(target = GL_TEXTURE_2D, texture = 2)
glActiveTexture(texture = GL_TEXTURE1)
glActiveTexture(texture = GL_TEXTURE2)
glActiveTexture(texture = GL_TEXTURE3)
glActiveTexture(texture = GL_TEXTURE4)
glActiveTexture(texture = GL_TEXTURE5)
glActiveTexture(texture = GL_TEXTURE6)
glActiveTexture(texture = GL_TEXTURE7)
glActiveTexture(texture = GL_TEXTURE8)
glActiveTexture(texture = GL_TEXTURE9)
glActiveTexture(texture = GL_TEXTURE10)
glActiveTexture(texture = GL_TEXTURE11)
glActiveTexture(texture = GL_TEXTURE12)
glUniform1i(location = 1, x = 0)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 123)
glVertexAttribPointer(indx = 0, size = 2, type = GL_SHORT, normalized = false, stride = 16, ptr = 0x0)
glEnableVertexAttribArray(index = 1)
glEnableVertexAttribArray(index = 2)
glEnableVertexAttribArray(index = 0)
glEnableVertexAttribArray(index = 3)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 16, ptr = 0x0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x4)
glVertexAttribPointer(indx = 3, size = 1, type = GL_SHORT, normalized = false, stride = 16, ptr = 0xc)
glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 124)
glDrawElements(mode = GL_TRIANGLES, count = 469374, type = GL_UNSIGNED_INT, indices = 0x0)
glBindBuffer(target = GL_ARRAY_BUFFER, buffer = 0)
glBindBuffer(target = GL_ELEMENT_ARRAY_BUFFER, buffer = 0)
glActiveTexture(texture = GL_TEXTURE0)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775470c0)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775470e0)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 0)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530800)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530810)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753080c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775295f8)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529608)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529604)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529878)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529888)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529884)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
eglSwapBuffers
Run Code Online (Sandbox Code Playgroud)
FYI, here is the typical fast-rendering GUI frame (main menu actually, that gives me 60FPS): (Wall Clock time: 1.10MS, Thread Time 0.70MS)
glClear(mask = 16640)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x77538880)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775388a0)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, 0.093229175, -0.17300725, 0.0, 1.0])
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 1)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77546f08)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77546f18)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77546f14)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.23489577, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538cb0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538cc0)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77538cbc)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.20677078, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538f00)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538f10)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77538f0c)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.15572912, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77539150)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77539160)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753915c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.1057291, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775393a0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775393b0)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x775393ac)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.0567708, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537bc0)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537bd0)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77537bcc)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -0.020312428, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537e10)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77537e20)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77537e1c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, 0.02239585, -0.17300725, 0.0, 1.0])
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538060)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77538070)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753806c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 7)
glDisableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x77533090)
glVertexAttribPointerData(indx = 0, size = 2, type = GL_FLOAT, normalized = false, stride = 8, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 16, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_FLOAT, normalized = false, stride = 0, ptr = 0x775330b0)
glBlendFunc(sfactor = GL_SRC_ALPHA, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glUseProgram(program = 1)
glUniformMatrix4fv(location = 0, count = 1, transpose = false, value = [0.0010416667, 0.0, 0.0, 0.0, 0.0, 0.0018115942, 0.0, 0.0, 0.0, 0.0, -9.765625E-4, 0.0, -1.0, -1.0, 0.0, 1.0])
glBlendFunc(sfactor = GL_LINES, dfactor = GL_ONE_MINUS_SRC_ALPHA)
glBindTexture(target = GL_TEXTURE_2D, texture = 0)
glEnableVertexAttribArray(index = 2)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530800)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77530810)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x7753080c)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x775295f8)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529608)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529604)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
glVertexAttribPointer(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529878)
glVertexAttribPointer(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x77529888)
glVertexAttribPointer(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x77529884)
glVertexAttribPointerData(indx = 0, size = 3, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 1, size = 4, type = GL_UNSIGNED_BYTE, normalized = true, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glVertexAttribPointerData(indx = 2, size = 2, type = GL_FLOAT, normalized = false, stride = 24, ptr = 0x??, minIndex = 0, maxIndex = 4)
glDrawArrays(mode = GL_TRIANGLE_STRIP, first = 0, count = 4)
eglSwapBuffers
Run Code Online (Sandbox Code Playgroud)
This renders OpenGL Tracers useless for me, because a faster-rendering frame shows more time (both Wall clock & Thread) than the slow one. Does this mean the problem is hidden somewhere in shaders? How do I profile them?
到目前为止我尝试了什么:
有什么建议可以优化吗?
你已经做得很好了。可能没有更多的空间进行更多的微观优化。
因为绘制调用的数量很少,所以使用 VAO/VertexArrays 从渲染循环中删除 glVertexAttribPointer 应该没有太大帮助。
每个图块 4 个顶点
为什么使用 GL_TRIANGLE_STRIP 和 glDrawArrays ?带有索引的 glDrawElements 将为您提供更大的灵活性(见下文......)。
即使没有对象渲染,也可以达到 20-30,而使用对象渲染则可以达到 4-5(另外 2 个类似的 VBO)。
好的。所以你最终会得到大约 800k 个顶点。正确的 ?去年我也遇到过类似的问题(1000k 个顶点)。我最终选择发送更多的绘制调用而不是使用复杂的着色器。是的,绑定大量数据(16 个纹理绑定!)会减慢此类设备上的一切速度。
如果我缩小以查看所有地图(这是主要点),FPS 会下降
在 iPad 2 上,屏幕上 1000k 个顶点(每个顶点的数据比您多得多)应该渲染速度更快:超过 20 fps。
看来您的大部分数据都是静态的。您可以尝试构建一个 vbo 或每个纹理的索引列表(我不知道哪个更快),大大简化您的片段着色器。
您可以将索引存储在缓冲区中: glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...) 或者您可以将索引直接传递给 glBindBuffer(如果它们是动态的)。它可能比你想象的要快。
最后一个细节:到处都是低气压是危险的。尝试中p。
祝你好运,您正在触及设备限制!
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           240 次  |  
        
|   最近记录:  |