Rendering to non-power-of-two texture on iPhone

爷,独闯天下 提交于 2019-11-26 03:39:22

问题


Is it possible to render to texture with OpenGL ES 1.1 on the iPhone (2G and older)? If I bind a texture as a render buffer, it has to be the size of the render buffer, which isn\'t POT-sized. But OpenGL ES 1.1 requires textures to be POT.

Maybe it can\'t be done on ES 1.1?


回答1:


While OpenGL ES 1.1 does not support non-power-of-two textures, newer iOS device models have the extension GL_APPLE_texture_2D_limited_npot, which states:

Conventional OpenGL ES 1.X texturing is limited to images with power-of-two (POT) dimensions. APPLE_texture_2D_limited_npot extension relaxes these size restrictions for 2D textures. The restrictions remain in place for cube map and 3D textures, if supported.

There is no additional procedural or enumerant API introduced by this extension except that an implementation which exports the extension string will allow an application to pass in 2D texture dimensions that may or may not be a power of two.

In the absence of OES_texture_npot, which lifts these restrictions, neither mipmapping nor wrap modes other than CLAMP_TO_EDGE are supported in conjunction with NPOT 2D textures. A NPOT 2D texture with a wrap mode that is not CLAMP_TO_EDGE or a minfilter that is not NEAREST or LINEAR is considered incomplete. If such a texture is bound to a texture unit, it is as if texture mapping were disabled for that texture unit.

You can use the following code to determine if this extension is supported on your device (drawn from Philip Rideout's excellent iPhone 3D Programming book):

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

On these devices, you should then be able to use non-power-of-two textures as long as you set the proper texture wrapping:

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

Unfortunately, this example application that I have which renders to a non-power-of-two texture uses OpenGL ES 2.0, so I'm not sure that will help you in this case.




回答2:


It can be done, all you need to do is get the next power of 2 bigger than the non-POT.

Then generate a framebuffer:

GLuint aFramebuffer;
glGenFramebuffersOES(1, &aFramebuffer);

And a texture:

GLuint aTexturebuffer;
glGenTextures(1, &aTexturebuffer);

Then you do the same texture like things:

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);

Here I used the draw_texture extension. textureWidth and textureHeight are the power of 2 bigger, and renderWidth and renderHeight are the the rendere's width and height. Then when you bind to aFramebuffer it will draw to texture.



来源:https://stackoverflow.com/questions/4760174/rendering-to-non-power-of-two-texture-on-iphone

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!