当我尝试将纹理附加到帧缓冲区时,glCheckFramebufferStatus会针对某些纹理大小报告GL_FRAMEBUFFER_UNSUPPORTED。我已经在第二代和第四代iPod Touch上进行了测试。失败的纹理大小在两个模型之间并不相同。
以下是一些有趣的结果:
第2代 - 8x8失败,16x8失败,但8x16成功!
第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像素,那么两种设备上的一切都能正常工作。但令我困扰的是,我没有看到任何关于附加到帧缓冲对象的纹理大小要求的文章。现在的一个解决方案是将我的纹理大小限制为至少16像素,但是可能会在将来中断,或者已经在我未尝试过的某些设备上破坏了?我也可以在启动时执行这个测试代码,以便动态地确定允许哪些纹理大小,但这看起来有点过分。
答案 0 :(得分: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_FILTER
设置为GL_NEAREST
或GL_LINEAR
(默认值为GL_NEAREST_MIPMAP_LINEAR
)以使用此纹理。
我无法找到16x8的问题,但如果设置了此参数,则16x9和17x8可以正常工作。我希望这些信息对您有所帮助。