2011-04-29 120 views
2

当我尝试将纹理附加到帧缓冲区时,glCheckFramebufferStatus会为特定纹理尺寸报告GL_FRAMEBUFFER_UNSUPPORTED。我已经在第二代和第四代iPod Touch上进行了测试。两种模型之间的纹理大小不一致。glFramebufferTexture2D在某些纹理尺寸的iPhone上失败

这里有一些有趣的结果:

第二代 - 8x8的失败,16×8的失败,但8×16成功了!

第4代 - 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个像素,然后一切正常,两个设备就OK了。但是,困扰我的事情是,我没有看到有关附加到帧缓冲区对象的纹理大小要求的任何内容。目前,一种解决方案是将我的纹理尺寸限制为至少16像素,但是可能会在未来出现这种情况,或者在某些尚未尝试过的设备上已经损坏了。我也可以在启动时执行这个测试代码,以便动态地确定哪些纹理尺寸是允许的,但这似乎有点麻烦。

回答

1

当我尝试在iPod touch 4上渲染纹理尺寸为480x320(全屏无分辨率缩放比例)的纹理时,我遇到过类似问题。当我拨打glCheckFramebufferStatus()时,它会返回GL_FRAMEBUFFER_UNSUPPORTED。我的代码:

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_FILTERGL_NEARESTGL_LINEAR(默认值为GL_NEAREST_MIPMAP_LINEAR)以使用此纹理。

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

+0

即使将换行模式设置为GL_CLAMP_TO_EDGE并将最小过滤器设置为最近,我仍然会收到错误。当你说你对16x8纹理没有问题时,你的意思是我的示例代码可以在你的设备上以16x8的纹理工作吗?或者你的意思是它在你自己的代码中工作?也许你可以发布一个类似于我的样本的小样本,它适用于16x8纹理。谢谢! – 2011-07-06 20:05:15

+0

我也有纹理16x8的问题。它也不适用于我。但16x9和17x8正常工作!这很奇怪。我刚刚注意到,如果你想把它附加到framebuffer,纹理对象应该有有效的参数。 – 2011-07-12 05:25:10

+0

很奇怪!我认为我的解决方案是不尝试从我的纹理中读取数据。我正在使用附加到帧缓冲区的纹理结合glReadPixels将纹理数据恢复到内存中。这对我在做什么并不重要,所以我可以解决它。 – 2011-07-12 20:45:04

相关问题