绘图时,OpenGL ES Framebuffer奇怪的镜像

时间:2010-01-06 23:31:32

标签: iphone opengl-es framebuffer fbo

我真的无法理解这个:

Previously我无法让Framebuffers工作,但我现在已经开始了。然而,这种令人难以置信的奇怪镜像正在从帧缓冲器生成纹理,我不知道为什么。基本上,我将尝试使用GL_TRIANGLE_FAN在0,0处绘制纹理,并且纹理在右上角显示为正常(或多或少),但出现在左下角,镜像。如果我用相同的纹理填充我的视口区域的大部分或全部,结果是一个丑陋的z-fighting重叠。

屏幕截图会更加正义。

原始图片:

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

在(0,0)

处绘制80x80

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

在(0,0)

处绘制100x180

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

在(0,0)

绘制320x480

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

这是我的代码:

设置视图:

//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];

创建纹理缓冲区。

- (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...");
    }   
}

运行渲染循环。

- (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];
}

在第一遍中,渲染循环将图像绘制到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;
    }
}

1 个答案:

答案 0 :(得分:5)

texcoords中的- (void)drawView似乎错了

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