glCheckFramebufferStatusOES

glCheckFramebufferStatusOES

本文介绍了尝试使用framebuffer渲染到纹理总是会产生白色纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在StackOverflow中使用了几个帖子,我使用帧缓冲创建了一个简单的渲染到纹理。

Using a couple of posts here in StackOverflow, I created what is supposed to be a simple render-to-texture using a framebuffer.

这里的问题是它不起作用。混合中有些东西被打破了,因为我的最终纹理只是一个白色方块。我没有得到任何gl错误。这是我的代码。

The problem here is that it's not working. Something is broken in the mix, as my final texture is just a white square. I am not getting any gl errors whatsoever. Here is my code.

声明实例变量。

GLuint texture;
GLuint textureFrameBuffer;

生成纹理和帧缓冲。

    glGetError();

    //Generate the texture that we will draw to (saves us a lot of processor).
    glEnable(GL_TEXTURE_2D);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // Use OpenGL ES to generate a name for the texture.
    // Pass by reference so that our texture variable gets set.
    glGenTextures(1, &texture);

    // Bind the texture name.
    glBindTexture(GL_TEXTURE_2D, texture);

    // Specify a 2D texture image, providing a pointer to the image data in memory.
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    //Create a frame buffer to draw to. This will allow us to directly edit the texture.
    GLint oldFBO;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
    glGenFramebuffersOES(1, &textureFrameBuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

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

在帧缓冲区中绘制一个大字符串。

Draw a big string into the framebuffer.

glGetError();

GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);

//Bind our frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);

//Clear out the texture.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

//Draw the letters to the frame buffer. (calls glDrawArrays a bunch of times, binds various textures, etc.) Does everything in 2D.
[self renderDialog:displayString withSprite:displaySprite withName:displaySpriteName];

//Unbind the frame buffer.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);

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

画出来。

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    glGetError();

    //Draw the text.
    [EAGLView enable2D];

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

    //Store the coordinates/dimensions from the rectangle.
    float x = 0;
    float y = [Globals getPlayableHeight] - dialogRect.size.height;
    float w = [Globals getPlayableWidth];
    float h = dialogRect.size.height;

    // 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,          h / 128,
        w / 512,    h / 128,
        w / 512,    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);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    //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.
    [EAGLView bindTexture: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);
    }

我调用的任何外部事物在其他情况下都能正常工作。有任何想法吗?我几乎不了解framebuffers,所以任何帮助故障排除都会很棒。

Any external things I called work just fine in other contexts. Any ideas? I know almost nothing about framebuffers, so any help troubleshooting would be great.

推荐答案

纹理参数是基于每个纹理设置的。在您要渲染的纹理已创建或绑定之前,您发布的代码似乎设置了 GL_TEXTURE_MIN_FILTER 。如果您没有在其他地方设置过滤器,并且您没有为剩余的等级指定纹理图像,那么您的纹理可能不完整,这就是为什么你变白了。

Texture parameters are set on a per-texture basis. The code you posted appears to be setting GL_TEXTURE_MIN_FILTER before the texture you’re rendering to has been created or bound. If you’re not setting the filter anywhere else, and you haven’t specified texture images for the remaining levels, your texture is likely incomplete, which is why you’re getting white.

为了将来参考,在帧缓冲设置之后没有GL错误并不意味着帧缓冲可用于渲染。您还应通过调用 glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)并验证是否返回 GL_FRAMEBUFFER_COMPLETE_OES 来检查帧缓冲是否完整。

For future reference, the absence of GL errors after framebuffer setup does not mean that the framebuffer is usable for rendering. You should also check that the framebuffer is complete by calling glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) and verifying that GL_FRAMEBUFFER_COMPLETE_OES is returned.

这篇关于尝试使用framebuffer渲染到纹理总是会产生白色纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 15:22