Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenGL ES Framebuffer weird mirroring when drawing
    primarykey
    data
    text
    <p>I really can't wrap my mind around this:</p> <p><a href="https://stackoverflow.com/questions/1950232/trying-to-render-to-texture-using-framebuffer-always-results-in-white-texture">Previously</a> I couldn't get Framebuffers to work, but I've got it going now. However, there is this incredibly weird mirroring going on with the texture generated from the framebuffer, and I have no idea why. Basically, I will try to draw a texture at 0,0 using GL_TRIANGLE_FAN, and the texture appears as normal (more or less) in the top right corner, but <em>also</em> appears in the bottom left corner, mirrored. If I fill up most or all of my viewport area with the same texture, the result is an ugly z-fighting overlap.</p> <p>Screenshots will do this more justice.</p> <p>Original image:</p> <p><a href="http://img301.imageshack.us/img301/1518/testsprite.png" rel="nofollow noreferrer">Original http://img301.imageshack.us/img301/1518/testsprite.png</a></p> <p>Drawn 80x80 at (0,0)</p> <p><a href="http://img407.imageshack.us/img407/8339/screenshot20100106at315.png" rel="nofollow noreferrer">80x80 http://img407.imageshack.us/img407/8339/screenshot20100106at315.png</a></p> <p>Drawn 100x180 at (0,0)</p> <p><a href="http://img503.imageshack.us/img503/2584/screenshot20100106at316.png" rel="nofollow noreferrer">100x180 http://img503.imageshack.us/img503/2584/screenshot20100106at316.png</a></p> <p>Drawn 320x480 at (0,0)</p> <p><a href="http://img85.imageshack.us/img85/9172/screenshot20100106at317.png" rel="nofollow noreferrer">320x480 http://img85.imageshack.us/img85/9172/screenshot20100106at317.png</a></p> <p>And here is my code:</p> <p>Set up the view:</p> <pre><code>//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]; </code></pre> <p>Create the texture buffer.</p> <pre><code>- (void) createTextureBuffer { // generate texture glGenTextures(1, &amp;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, &amp;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..."); } } </code></pre> <p>Run the render loop.</p> <pre><code>- (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]; } </code></pre> <p>On the first pass, the render loop will draw the image into the FBO.</p> <pre><code>- (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; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload