OpenGL ES Framebuffer 绘图时出现奇怪的镜像

发布于 2024-08-16 16:57:21 字数 6596 浏览 8 评论 0原文

我真的无法理解这一点:

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

屏幕截图会更公正地体现这一点。

原始图像:

原始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;
    }
}

I really can't wrap my mind around this:

Previously 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 also 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.

Screenshots will do this more justice.

Original image:

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

Drawn 80x80 at (0,0)

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

Drawn 100x180 at (0,0)

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

Drawn 320x480 at (0,0)

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

And here is my code:

Set up the view:

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

Create the texture buffer.

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

Run the render loop.

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

On the first pass, the render loop will draw the image into the 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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

放飞的风筝 2024-08-23 16:57:21

您的 - (void)drawView 中的 texcoords 似乎是错误的

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

Your texcoords in - (void)drawView seem to be wrong

GLfloat texcoords[] =
{
    0,  0,
    0,  1,
    1,  1,
    0,  1     << HERE should be 1, 0
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文