2011-04-08 13 views
6

Estoy bastante desconcertado con el pobre rendimiento que estoy viendo al dibujar un fondo de pantalla completa usando una malla de triángulo texturizado en OpenGL: dibujando solo el fondo y nada más se maximiza en 40 fps usando el sombreador más básico y 50 fps usando la tubería predeterminada.Textura de fondo de pantalla completa con problema de rendimiento OpenGL (iPad)

Mientras que 40 fps no parece tan malo, agregar algo más encima de eso hace que los fps caigan, y teniendo en cuenta que necesito dibujar 100-200 mallas adicionales encima de eso, termino con un miserable 15 fps eso simplemente no es utilizable

me han aislado el código correspondiente a un proyecto de XCode disponibles here, pero la esencia de la misma es el ejemplo de mapa de textura canónica:

static const GLfloat squareVertices[] = { 
    -1.0f, -1.0f, 
    1.0f, -1.0f, 
    -1.0f, 1.0f, 
    1.0f, 1.0f, 
}; 
static const GLfloat texCoords[] = { 
    0.125, 1.0, 
    0.875, 1.0, 
    0.125, 0.0, 
    0.875, 0.0 
}; 


glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

if ([context API] == kEAGLRenderingAPIOpenGLES2) { 
    // Use shader program. 
    glUseProgram(program); 

    glActiveTexture(GL_TEXTURE0); 
    glUniform1i(uniforms[UNIFORM_TEXTURE], 0); 
    glBindTexture(GL_TEXTURE_2D, texture); 

    // Update attribute values. 
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); 
    glEnableVertexAttribArray(ATTRIB_VERTEX); 
    glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); 
    glEnableVertexAttribArray(ATTRIB_TEXCOORD); 
} else { 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 

    glVertexPointer(2, GL_FLOAT, 0, squareVertices); 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
} 

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

El vertex shader:

attribute lowp vec4 position; 
attribute lowp vec2 tex; 

varying lowp vec2 texCoord; 

uniform float translate; 

void main() 
{ 
    gl_Position = position; 
    texCoord = tex; 
} 

El fragment shader :

varying lowp vec2 texCoord; 
uniform sampler2D texture; 

void main() 
{ 
    gl_FragColor = texture2D(texture, texCoord); 
} 

División del tamaño del rectángulo en dos duplica la velocidad de cuadros, por lo que el tiempo de renderización depende claramente de la propiedad inmobiliaria que el dibujo adopta en la pantalla. Esto tiene sentido, pero lo que no tiene sentido para mí es que no parece posible cubrir toda la pantalla con mallas con textura de OpenGL a más de 15 fps.

Sin embargo, hay cientos de juegos que lo hacen, por lo que es posible y debo estar haciendo algo mal, pero ¿qué es?

+0

FWIW, ¿por qué está habilitando el estado del cliente después de realizar las llamadas pertinentes? (Por ejemplo, llamar al puntero vértice antes de habilitar matrices vert) –

+0

En realidad, la mayor parte del código pertenece a la plantilla predeterminada para una aplicación para iPad OpenGL ES, lo que no significa que sea un buen código, pero siempre que funcionó, no me pregunté si tiene sentido hacerlo de esta manera u otra :-) –

Respuesta

7

Desafortunadamente, todo lo que tengo es mi iPad 2 para probar esto en este momento (mi unidad de prueba iPad 1 está en casa), y tiene un procesamiento de fragmentos ridículamente rápido. Está siendo vinculado a 60 FPS, con 1400 FPS teóricos en su registro.

Sin embargo, lo ejecuté a través de instrumentos que utilizan los instrumentos OpenGL ES Driver y Time Profiler, junto con el nuevo y fresco OpenGL ES Analyzer (que viene con Xcode 4). Esto es lo que los resultados de la OpenGL ES Analizador ven como:

OpenGL ES Analyzer

Mirando la estadística de utilización de solador en el controlador de OpenGL ES muestra el solador apenas se utiliza en absoluto, pero el procesador de tener algún uso (de nuevo , solo el 5% en mi iPad 2). Esto indica que las sugerencias para usar VBO e índices para su geometría probablemente no le servirán de mucho.

El que sobresale es la advertencia acerca de las llamadas redundantes:

OpenGL ES redundant calls

A mantener la unión del uso de este dispositivo y la configuración de la vista cada cuadro, que según Time Profiler está representando el 10% de la carga de trabajo en su aplicación. Comentando la línea

[(EAGLView *)self.view setFramebuffer]; 

cerca del comienzo de su dibujo de tramas debido a la tasa de fotogramas teórico para saltar de 1.400 a 27.000 FPS FPS en mi iPad 2 (Dicho sea de paso, se debe probablemente measure using milliseconds for your rendering).

Una vez más, este soy yo corriendo pruebas en la GPU realmente potente en el iPad 2, pero debería poder repetir estos pasos similares en el iPad original o cualquier otro dispositivo para verificar este cuello de botella de rendimiento y resaltar potencialmente otros.He descubierto que el nuevo OpenGL ES Analyzer es muy útil para detectar problemas de rendimiento relacionados con el sombreado.

+0

"Desafortunadamente, todo lo que tengo es mi iPad 2 para probar esto ahora mismo". Me gustaría ser tan desafortunado como usted :-) ¡Gracias por poner la aplicación de prueba a su alcance en un iPad 2! De su respuesta, deduzco que no ve nada malo en la forma en que dibujo el fondo. –

+0

@Guy - Acabo de probar esto en mi ahora obsoleto iPad 1 y todavía recibía 60 FPS, con 1400 FPS teóricos en ese hardware anterior, incluso antes de eliminar la llamada redundante anterior. Puede haber algo roto en la configuración de compilación de Xcode, porque tu caso de prueba se ejecuta bastante rápido como está en mi hardware. Además, esto está usando iOS 4.3.1 en ese hardware. Si estás en 3.2, podría ser más lento. –

+0

gracias un montón para el control de cordura, voy a investigar aún más! –

0

salvaje conjetura siguiente, no tengo ninguna experiencia IPAD:

de acuerdo con esta benchmark, se puede esperar a tener alrededor de 214fps en la tasa de relleno puro, a una resolución de fondo.

¿Intentó desactivar la textura, para comprobar si está limitado por su textura?

¿Su textura es una 'potencia no de dos texturas'? En este caso, ¿intentó eliminar el GL_REPEAT de GL_TEXTURE_WRAP_*, reemplazando por GL_CLAMP(_TO_EDGE)? Repetir un NPOT puede costar cierto rendimiento en algún hardware.

En última instancia, podría intentar establecer filtros mínimos/máximos para GL_NEAREST también.

+0

La imagen no tiene una potencia de 2 dimensiones, pero la cargo en una textura de 512x512, y también he probado GL_NEAREST, pero no GL_CLAMP. Lo haré, gracias por los consejos. –

Cuestiones relacionadas