2010-01-06 21 views
1

Je ne peux pas envelopper mon esprit autour de ceci:mirroring bizarre OpenGL ES Framebuffer lors de l'élaboration

Previously je ne pouvais pas travailler Mémoire tampon, mais je l'ai maintenant va. Cependant, il y a cette mise en miroir incroyablement bizarre qui se passe avec la texture générée par le framebuffer, et je ne sais pas pourquoi. Fondamentalement, je vais essayer de dessiner une texture à 0,0 en utilisant GL_TRIANGLE_FAN, et la texture apparaît comme normale (plus ou moins) dans le coin supérieur droit, mais aussi apparaît dans le coin inférieur gauche, en miroir. Si je remplis la plus grande partie ou la totalité de ma zone de fenêtre avec la même texture, le résultat est un chevauchement de z-combat laid.

Captures d'écran feront plus de justice.

l'image d'origine:

Original http://img301.imageshack.us/img301/1518/testsprite.png

80x80 étiré à (0,0)

80x80 http://img407.imageshack.us/img407/8339/screenshot20100106at315.png

étiré 100x180 à (0,0)

100x180 http://img503.imageshack.us/img503/2584/screenshot20100106at316.png

Dr Awn 320x480 à (0,0)

320x480 http://img85.imageshack.us/img85/9172/screenshot20100106at317.png

Et voici mon code:

configurer la vue:

//Apply the 2D orthographic perspective. 
glViewport(0,0,320,480); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrthof(0, 320, 480, 0, -10000.0f, 100.0f); 

//Disable depth testing. 
glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 
glDisable(GL_DEPTH_TEST); 

//Enable vertext and texture coordinate arrays. 
glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

glShadeModel(GL_SMOOTH); 

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

glGetError(); // Clear error codes 

sprite = [Sprite createSpriteFromImage:@"TestSprite.png"]; 
[sprite retain]; 

[self createTextureBuffer]; 

Créer le tampon de texture.

- (void) createTextureBuffer 
{ 
    // generate texture 
    glGenTextures(1, &bufferTexture); 
    glBindTexture(GL_TEXTURE_2D, bufferTexture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);  // check if this is right 

    // generate FBO 
    glGenFramebuffersOES(1, &framebuffer); 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); 
    // associate texture with FBO 
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, bufferTexture, 0); 

    // clear texture bind 
    glBindTexture(GL_TEXTURE_2D,0); 

    // check if it worked (probably worth doing :)) 
    GLuint status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 
    if (status != GL_FRAMEBUFFER_COMPLETE_OES) 
    { 
     printf("FBO didn't work..."); 
    } 
} 

Exécutez la boucle de rendu.

- (void)drawView 
{ 
    [self drawToTextureBuffer]; 

    // Make sure that you are drawing to the current context 
    [EAGLContext setCurrentContext:context]; 

    //Bind the GLView's buffer. 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    glViewport(0, 0, 320, 480); 

    //Clear the graphics context. 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    //Push the matrix so we can keep it as it was previously. 
    glPushMatrix(); 

    //Rotate to match landscape mode. 
    glRotatef(90.0, 0, 0, 1); 
    glTranslatef(0.0f, -320.0f, 0.0f); 

    //Store the coordinates/dimensions from the rectangle. 
    float x = 0.0f; 
    float y = 0.0f; 
    float w = 480.0f; 
    float h = 320.0f; 

    // Set up an array of values to use as the sprite vertices. 
    GLfloat vertices[] = 
    { 
     x, y, 
     x, y+h, 
     x+w, y+h, 
     x+w, y 
    }; 

    // Set up an array of values for the texture coordinates. 
    GLfloat texcoords[] = 
    { 
     0, 0, 
     0, 1, 
     1, 1, 
     0, 1 
    }; 

    //Render the vertices by pointing to the arrays. 
    glVertexPointer(2, GL_FLOAT, 0, vertices); 
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 

    // Set the texture parameters to use a linear filter when minifying. 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

    //Enable 2D textures. 
    glEnable(GL_TEXTURE_2D); 

    //Bind this texture. 
    glBindTexture(GL_TEXTURE_2D, bufferTexture); 

    //Finally draw the arrays. 
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

    //Restore the model view matrix to prevent contamination. 
    glPopMatrix(); 

    GLenum err = glGetError(); 
    if (err != GL_NO_ERROR) 
    { 
     NSLog(@"Error on draw. glError: 0x%04X", err); 
    } 


    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

Lors de la première passe, la boucle de rendu dessine l'image dans le FBO.

- (void)drawToTextureBuffer 
{ 
    if (!bufferWasCreated) 
    { 
     // render to FBO 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer); 
     // set the viewport as the FBO isn't be the same dimension as the screen 
     glViewport(0, 0, 512, 512); 

     glPushMatrix(); 



     //Store the coordinates/dimensions from the rectangle. 
     float x = 0.0f; 
     float y = 0.0f; 
     float w = 320.0f; 
     float h = 480.0f; 

     // Set up an array of values to use as the sprite vertices. 
     GLfloat vertices[] = 
     { 
      x, y, 
      x, y+h, 
      x+w, y+h, 
      x+w, y 
     }; 

     // Set up an array of values for the texture coordinates. 
     GLfloat texcoords[] = 
     { 
      0, 0, 
      0, 1, 
      1, 1, 
      1, 0 
     }; 

     //Render the vertices by pointing to the arrays. 
     glVertexPointer(2, GL_FLOAT, 0, vertices); 
     glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 

     // Set the texture parameters to use a linear filter when minifying. 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 

     //Allow transparency and blending. 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

     //Enable 2D textures. 
     glEnable(GL_TEXTURE_2D); 

     //Bind this texture. 
     glBindTexture(GL_TEXTURE_2D, sprite.texture); 

     //Finally draw the arrays. 
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

     //Restore the model view matrix to prevent contamination. 
     glPopMatrix(); 

     GLenum err = glGetError(); 
     if (err != GL_NO_ERROR) 
     { 
      NSLog(@"Error on draw. glError: 0x%04X", err); 
     } 

     //Unbind this buffer. 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); 

     bufferWasCreated = YES; 
    } 
} 

Répondre

5

Votre texcoords en - (void)drawView semblent se tromper

GLfloat texcoords[] = 
{ 
    0, 0, 
    0, 1, 
    1, 1, 
    0, 1  << HERE should be 1, 0 
}; 
+0

HA HA HA Ils sont. Merci beaucoup. Hahaha. Wow, quelle erreur stupide. Si je n'étais pas nouveau aux FBO, j'aurais réalisé que le problème ne pouvait pas être lié aux FBO. Maintenant je sais! – Eli