glFramebufferTexture2D在iPhone上对某些纹理尺寸失效[英] glFramebufferTexture2D fails on iPhone for certain texture sizes

本文是小编为大家收集整理的关于glFramebufferTexture2D在iPhone上对某些纹理尺寸失效的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

当我尝试将纹理附加到框架缓冲器上时,GlCheckFrameBufferstatus报告GL_FRAMEBUFMED_UNSUPPPORTERS的某些纹理大小.我已经在第二代和第四代iPod Touch上进行了测试.两种模型之间的纹理大小并不相同.

这是一些有趣的结果:

第二代-8x8失败,16x8失败,但8x16成功!

第四代-8x8成功,8x16成功,但16x8失败了!

这是我用来测试不同尺寸纹理的一些代码:

void TestFBOTextureSize(int width, int height)
{
    GLuint framebuffer, texture;

    // Create framebuffer
    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    // Create texture
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D,0);

    // Attach texture to framebuffer
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
    GLenum error = glGetError();
    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if (status==GL_FRAMEBUFFER_COMPLETE_OES)
        NSLog(@"%dx%d Succeeded!",width,height,status);
    else
        NSLog(@"%dx%d Failed: %x %x %d %d",width,height,status,error,texture,framebuffer);

    // Cleanup
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, 0, 0);
    glDeleteTextures(1, &texture);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    glDeleteFramebuffersOES(1, &framebuffer);   
}

void TestFBOTextureSizes()
{
    int width,height;
    for (width=1; width<=1024; width<<=1)
    {
        for (height=1; height<=1024; height<<=1)
            TestFBOTextureSize(width,height);
    }
}

看来,只要两个维度至少为16个像素,那么两个设备上的一切都可以.不过,令我困扰的是,我还没有看到有关将纹理大小要求附加到Framebuffer对象的文章.目前,一种解决方案是将我的纹理大小限制为至少16个像素,但是将来会断裂或在我没有尝试过的某些设备上破裂?我还可以在启动时执行此测试代码,以便动态地弄清楚允许哪些纹理大小,但这似乎有点hokey.

推荐答案

我遇到了类似的问题,当我试图渲染iPod touch 4上的尺寸为480x320(全屏w/o分辨率刻度)时.我的代码:

glGenTextures(1, &texture);    
glBindTexture(GL_TEXTURE_2D, texture);        
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 480, 320, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
    // report error
}

研究这个问题,我发现GL_TEXTURE_2D如果我们希望将其用于渲染到文本机制,则必须是有效的opengl es对象.这意味着纹理应准备好绑定和使用.因此,要解决错误,我必须设置一些纹理参数.因为我使用的非pot纹理必须将GL_TEXTURE_WRAP_设置为GL_CLAMP_TO_EDGE(默认值为GL_REPEAT)和GL_TEXTURE_MIN_FILTER to GL_NEAREST或GL_NEAREST或GL_LINEAR(默认值为GL_NEAREST_MIPMAP_LINEAR)才能使用此纹理.

我找不到16x8的问题,但是如果设置了此参数,那么16x9和17x8的工作正常.希望这些信息对您有所帮助.

本文地址:https://www.itbaoku.cn/post/2091203.html

问题描述

When I try to attach a texture to a framebuffer, glCheckFramebufferStatus reports GL_FRAMEBUFFER_UNSUPPORTED for certain texture sizes. I've tested on both a 2nd and 4th generation iPod Touch. The sizes of texture that fail are not identical between the two models.

Here are some interesting results:

2nd generation - 8x8 failed, 16x8 failed, but 8x16 succeeded!

4th generation - 8x8 succeeded, 8x16 succeeded, but 16x8 failed!

Here's some code I used to test attaching textures of different sizes:

void TestFBOTextureSize(int width, int height)
{
    GLuint framebuffer, texture;

    // Create framebuffer
    glGenFramebuffersOES(1, &framebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, framebuffer);

    // Create texture
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glBindTexture(GL_TEXTURE_2D,0);

    // Attach texture to framebuffer
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture, 0);
    GLenum error = glGetError();
    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
    if (status==GL_FRAMEBUFFER_COMPLETE_OES)
        NSLog(@"%dx%d Succeeded!",width,height,status);
    else
        NSLog(@"%dx%d Failed: %x %x %d %d",width,height,status,error,texture,framebuffer);

    // Cleanup
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, 0, 0);
    glDeleteTextures(1, &texture);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
    glDeleteFramebuffersOES(1, &framebuffer);   
}

void TestFBOTextureSizes()
{
    int width,height;
    for (width=1; width<=1024; width<<=1)
    {
        for (height=1; height<=1024; height<<=1)
            TestFBOTextureSize(width,height);
    }
}

It seems that as long as both dimensions are at least 16 pixels then everything works ok on both devices. The thing that bothers me, though, is that I haven't seen anything written about texture size requirements for attaching to a framebuffer object. One solution, for now, would be to restrict my texture sizes to be at least 16 pixels, but might this break in the future or already be broken on some device I haven't tried? I could also perform this test code at startup in order to dynamically figure out which texture sizes are allowed, but that seems a bit hokey.

推荐答案

I have experienced similar problem, when I'm trying to render to texture with size 480x320 (full screen w/o resolution scale) on iPod touch 4. When I call glCheckFramebufferStatus() it returns GL_FRAMEBUFFER_UNSUPPORTED. My code:

glGenTextures(1, &texture);    
glBindTexture(GL_TEXTURE_2D, texture);        
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 480, 320, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
glBindTexture(GL_TEXTURE_2D, 0);

glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
    // report error
}

Investigating this problem I have found that GL_TEXTURE_2D has to be a valid OpenGL ES object if we want it to use in render-to-texture mechanism. This means texture should be ready for bound and use. So to fix an error I have to set some texture parameters. Because I use non-POT texture I have to set GL_TEXTURE_WRAP_ to GL_CLAMP_TO_EDGE (default value is GL_REPEAT) and GL_TEXTURE_MIN_FILTER to GL_NEAREST or GL_LINEAR (default value is GL_NEAREST_MIPMAP_LINEAR) to use this texture.

I couldn't find what's the problem with 16x8, but 16x9 and 17x8 works fine if this parameters are set. I hope this information will be helpful for you.