在 iPhone 上渲染为非二次方纹理

发布于 2024-10-13 05:17:44 字数 146 浏览 2 评论 0原文

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

也许在 ES 1.1 上不能完成?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

未蓝澄海的烟 2024-10-20 05:17:44

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

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

没有额外的程序或
由此引入的枚举API
扩展除了
导出的实现
扩展字符串将允许
应用程序传入 2D 纹理
尺寸可能是也可能不是
2 的幂。

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

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

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

不幸的是,这个示例应用程序,我使用 OpenGL ES 2.0 渲染到非二次幂纹理,所以我不确定在这种情况下这会对你有帮助。

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.

笑红尘 2024-10-20 05:17:44

这是可以做到的,你需要做的就是得到下一个比非 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 时,它将绘制到纹理。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文