在iPhone上渲染到非2次幂纹理

时间:2011-01-21 14:51:51

标签: iphone opengl-es render-to-texture

是否可以在iPhone(2G及更早版本)上使用OpenGL ES 1.1渲染纹理?如果我将纹理绑定为渲染缓冲区,则它必须是渲染缓冲区的大小,而不是POT大小。但OpenGL ES 1.1要求纹理为POT。

也许在ES 1.1上无法完成?

2 个答案:

答案 0 :(得分:27)

虽然OpenGL ES 1.1不支持非二次幂纹理,但较新的iOS设备型号具有扩展名GL_APPLE_texture_2D_limited_npot,其中指出:

  

传统的OpenGL ES 1.X纹理   仅限于具有2的幂的图像   (POT)尺寸。   APPLE_texture_2D_limited_npot   扩展放松这些大小   2D纹理的限制。该   立方体的限制仍然存在   地图和3D纹理(如果支持)。

     

没有额外的程序或   由此引入的枚举API   扩展除了一个   出口的实施   扩展字符串将允许   应用程序传递2D纹理   尺寸可能是也可能不是   两个人的力量。

     

在没有OES_texture_npot的情况下,   这解除了这些限制,   既不是mipmapping也不是wrap模式   支持CLAMP_TO_EDGE以外的其他内容   与NPOT 2D纹理结合使用。   具有环绕模式的NPOT 2D纹理   那不是CLAMP_TO_EDGE或者是   minfilter,不是最近的或   LINEAR被认为是不完整的。如果   这样的纹理绑定到纹理   单位,就像纹理映射一样   被禁用的纹理单元。

您可以使用以下代码来确定您的设备是否支持此扩展程序(摘自Philip Rideout的优秀iPhone 3D Programming书籍):

const char* extensions = (char*) glGetString(GL_EXTENSIONS); 
bool npot = strstr(extensions, "GL_APPLE_texture_2D_limited_npot") != 0;

在这些设备上,只要设置了正确的纹理包装,就应该能够使用非二次幂纹理:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

不幸的是,我所拥有的this example application渲染到非二次幂纹理使用的是OpenGL ES 2.0,所以我不确定在这种情况下它会对你有所帮助。

答案 1 :(得分:2)

可以做到,你需要做的就是获得比非POT更大的2的幂。

然后生成一个帧缓冲:

GLuint aFramebuffer;
glGenFramebuffersOES(1, &aFramebuffer);

纹理:

GLuint aTexturebuffer;
glGenTextures(1, &aTexturebuffer);

然后你做同样的纹理:

glBindTexture(GL_TEXTURE_2D, aTexturebuffer);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);
glColor4ub(0, 0, 0, 255);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

int area[] = {0.0, 0.0, renderWidth, renderHeight};

glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, area);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, aFramebuffer);
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, aTexturebuffer, 0);

这里我使用了draw_texture扩展名。 textureWidthtextureHeight是2更大的力量,renderWidthrenderHeight是渲染的宽度和高度。 然后当你绑定到aFramebuffer时,它将绘制到纹理。