Para mejorar el rendimiento de mi aplicación OpenGL ES para el iPad, estaba planeando dibujar un elemento raramente actualizado pero muy pesado en una textura , entonces puedo usar la textura a menos que el elemento tenga que volver a dibujarse. Sin embargo, aunque la textura está asignada correctamente tanto en el simulador como en el dispositivo, solo en el simulador se representa algo realmente en la textura.Rendering a la textura en iOS OpenGL ES-funciona en el simulador, pero no en el dispositivo
El siguiente es el código que agregué al proyecto. Si bien la creación de la escena, puedo crear los tampones y la textura necesaria:
int width = 768;
int height = 270;
// Prepare texture for off-screen rendering.
glGenTextures(1, &wTexture);
glBindTexture(GL_TEXTURE_2D, wTexture);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
glClearColor(.9f, .3f, .6f, 1.0f); // DEBUG
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// Depth attachment buffer, always needed.
glGenRenderbuffersOES(1, &wDepth);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wDepth);
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES,
width, height);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0);
// Create FBO for render-to-texture.
glGenFramebuffersOES(1, &wBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, wTexture, 0);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wDepth);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
Un glFramebufferStatusOES
en el nuevo FBO (antes de que no está consolidado, por supuesto) se obtiene un valor de retorno 'framebuffer completa' tanto en el simulador y el dispositivo. Tenga en cuenta que establezco el color rosa claro para la textura a fin de confirmar que la textura realmente se representa, y el problema es, de hecho, simplemente que la textura nunca se dibuja.
Siempre que la textura tiene que ser redibujado, hago esto antes de representar el elemento:
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wBuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width, height);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
// ...
y la siguiente después de la representación real:
// ...
glPopMatrix();
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
Por último, cada vez que la pantalla se vuelve a dibujar Asigné la textura a un cuadrángulo en la posición adecuada en la pantalla, así:
float Vertices[] = {
-65.0f, -100.0f, .0f,
-65.0f, 100.0f, .0f,
-10.0f, -100.0f, .0f,
-10.0f, 100.0f, .0f};
float Texture[] = {.0f, .0f, 1.0f, .0f, .0f, 1.0f, 1.0f, 1.0f};
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, wTexture);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glVertexPointer(3, GL_FLOAT, 0, Vertices);
glTexCoordPointer(2, GL_FLOAT, 0, Texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
En los simuladores de iPhone e iPad (4.2, 4.3), el código funciona como se esperaba. Veo la textura presentada de forma dinámica en la posición correspondiente, por supuesto con un fondo de color rosa en lugar de transparente debido a mi declaración de depuración. En mi dispositivo iPad 4.2, sin embargo, solo se representa el rectángulo rosa, no lo que debería haberse dibujado en él durante el paso de renderizar a textura. Por lo tanto, la textura se representa correctamente en la pantalla, pero por alguna razón, en el dispositivo, el código de renderizar a textura no puede representar nada en la textura.
Supongo que estoy usando alguna funcionalidad que no está disponible en el dispositivo, o hago una suposición errónea en alguna parte, pero no puedo entender cuál es. También intenté ejecutarlo a través del OpenGL ES Analyzer, pero no me brinda más que algunos consejos básicos de optimización del rendimiento. ¿Dónde debo buscar el problema?