对于某些纹理大小,glFramebufferTexture2D无法在iPhone上使用

问题描述

|| 当我尝试将纹理附加到帧缓冲区时,glCheckFramebufferStatus报告GL_FRAMEBUFFER_UNSUPPORTED以获取某些纹理大小。我已经在第二代和第四代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,GL_RGBA,width,height,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!\",status);
    else
        NSLog(@\"%dx%d Failed: %x %x %d %d\",status,error,framebuffer);

    // Cleanup
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,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像素,则在这两个设备上一切正常。不过,令我困扰的是,我还没有看到任何有关附加到帧缓冲区对象的纹理大小要求的文章。目前,一种解决方案是将我的纹理大小限制为至少16个像素,但是将来是否会出现这种情况或者在我没有尝试过的某些设备上已经发生这种情况?我也可以在启动时执行此测试代码,以便动态找出允许的纹理大小,但这似乎有点棘手。     

解决方法

我在iPod touch 4上尝试以480x320(无分辨率的全屏显示)尺寸渲染纹理时遇到了类似的问题。当我呼叫“ 1”时,它会返回“ 2”。我的代码:
glGenTextures(1,&texture);    
glBindTexture(GL_TEXTURE_2D,texture);        
glTexImage2D(GL_TEXTURE_2D,GL_RGB,480,320,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
}
研究此问题后,我发现如果要在“渲染到纹理”机制中使用“ 4”,它必须是有效的OpenGL ES对象。这意味着纹理应准备好绑定和使用。因此,要修复错误,我必须设置一些纹理参数。因为我使用非POT纹理,所以必须将have5ѭ设置为
GL_CLAMP_TO_EDGE
(默认值为
GL_REPEAT
),将set8ѭ设置为
GL_NEAREST
GL_LINEAR
(默认值是
GL_NEAREST_MIPMAP_LINEAR
)才能使用此纹理。 我找不到16x8的问题,但如果设置了此参数,则16x9和17x8可以正常工作。希望这些信息对您有所帮助。