且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在 iOS OpenGL ES 上渲染到纹理——适用于模拟器,但不适用于设备

更新时间:2023-01-05 22:40:16

我在我的项目中使用MSAA,发现禁用后问题消失了.这让我发现其他问题 讨论相同的问题(但未解决).

I was using MSAA in my project, and have found out that the problem disappeared when I disabled it. This has lead me to discover this other question where the same problem is discussed (but not solved).

问题似乎是,如果为您的主帧缓冲区启用了多重采样,那么您的所有自定义 FBO 也必须使用多重采样.您无法渲染到普通的非多重采样 GL_TEXTURE_2D,并且多重采样 GL_TEXTURE_2D_MULTISAMPLE 在 OpenGL ES 2 上不可用.

The problem seems to be that if multisampling is enabled for your main framebuffer, all of your custom FBOs have to use multisampling as well. You cannot render to a normal non-multisampled GL_TEXTURE_2D, and a multi-sampled GL_TEXTURE_2D_MULTISAMPLE is not available on OpenGL ES 2.

为了解决这个问题,我修改了我的渲染到纹理代码,就像我修改我的主渲染代码以启用多重采样一样.除了问题代码中创建的三个缓冲区对象之外,我还为多采样渲染创建了三个:

In order to fix the problem, I modified my render-to-texture code the same way I modified my main rendering code to enable multisampling. In addition to the three buffer objects created in the code from the question, I create three more for the multi-sampled rendering:

glGenFramebuffersOES(1, &wmBuffer);
glGenRenderbuffersOES(1, &wmColor);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmColor);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_RGBA8_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, wmColor);
glGenRenderbuffersOES(1, &wmDepth);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, wmDepth);
glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, 4, GL_DEPTH_COMPONENT16_OES, width, height);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, wmDepth);

在渲染到纹理之前,我绑定了新的 MSAA 缓冲区:

Before rendering to the texture, I bind the new MSAA buffer:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, wmBuffer);

最后,在渲染之后,我将 MSAA FBO 解析为纹理 FBO,就像我对主渲染帧缓冲区所做的那样:

Finally, after rendering, I resolve the MSAA FBO into the texture FBO the same way I do for my main rendering framebuffer:

glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, wmBuffer);
glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, wBuffer);
glResolveMultisampleFramebufferAPPLE();
GLenum attachments[] = {GL_DEPTH_ATTACHMENT_OES, GL_COLOR_ATTACHMENT0_OES, GL_STENCIL_ATTACHMENT_OES};
glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, attachments);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

现在可以正确渲染纹理(而且性能很棒!)

The textures are now rendered correctly (and the performance is great!)