【问题标题】:OpenGL ES 2.0 rendering to multiple texturesOpenGL ES 2.0 渲染到多个纹理
【发布时间】:2014-10-28 16:45:25
【问题描述】:

我正在使用 OpenGL ES 2.0 构建一个 iPad 应用程序。我需要做的是渲染多个纹理,然后渲染所有纹理以查看。我根据用户触摸位置使用 GL_POINTS 进行绘制。我现在拥有的代码是:

生成帧缓冲区、纹理和渲染缓冲区:

glGenFramebuffers(1, &viewFramebuffer);
glGenRenderbuffers(1, &viewRenderbuffer);
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);

glGenTextures(1, layers);
glBindTexture(GL_TEXTURE_2D, layers[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  self.bounds.size.width, self.bounds.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[0], 0);

画:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
....
glDrawArrays(GL_POINTS, 0, (int)vertexCount);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER];

以上工作正常,但是当我想渲染到新纹理时,我的应用程序会停止绘制任何新内容。我像这样绑定一个新纹理:

glGenTextures(1, &layers[1]);
glBindTexture(GL_TEXTURE_2D, layers[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  self.bounds.size.width, self.bounds.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[1], 0);

然后再次调用绘图方法。我的代码在渲染到第一个纹理时有效,但是当我尝试生成要渲染到的新纹理时,应用程序停止绘制。有人可以帮忙吗?

【问题讨论】:

  • 很可能与您的问题无关,但您是否有任何理由部分使用 FBO 入口点和定义的扩展 (OES) 版本?
  • @RetoKoradi 不知道为什么会这样。我正在关注 Apple 的 GLPaint 教程,这就是它的完成方式。我将 GL_FRAMEBUFFER_OES 更改为 GL_FRAMEBUFFER 但问题仍然存在。有什么建议吗?
  • 您在执行此新附件后检查帧缓冲区状态吗?此外,在执行此行之前,不仅必须绑定正确的帧缓冲区(但很可能已经绑定)。无论如何,我不确定你甚至可以做到这一点,但如果你做的没问题,我希望这两个纹理都附加到帧缓冲区,所以它应该绘制到两者。无论如何你为什么要尝试这样做,你可以简单地生成一个新的帧缓冲区并附加纹理。至于渲染缓冲区,如果我没记错的话,如果您附加了纹理,则不需要它..
  • @MaticOblak 我想要实现的是分层绘图,其中我可以控制各个图层。我正在遵循here 提供的建议。我的绘制周期包括1)绑定textureFrameBuffer 2)将纹理附加到textureFrameBuffer 3)绘制到纹理4)重复不同的纹理5)绑定viewFrameBuffer 6)将纹理绘制到viewFrameBuffer 7)从viewFrameBuffer渲染视图。你认为这是错误的做法吗?

标签: ios objective-c opengl-es opengl-es-2.0 framebuffer


【解决方案1】:

我的代码可以工作了。我的 frameBuffers 没有正确生成并且我的纹理没有准确绑定有几个问题。经验教训 - 生成后始终检查 frameBuffer 的状态!这里是:

设置帧缓冲区:

// Generate textureFrameBuffer for handling drawing to textures
glGenFramebuffers(1, &textureFrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);

// Generate renderBufferer for drawing to screen
glGenRenderbuffers(1, &viewRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id<EAGLDrawable>)self.layer];
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);

//Generate first texture and bind to textureFrameBuffer
glGenTextures(1, &layers[0]);
glBindTexture(GL_TEXTURE_2D, layers[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  backingWidth, backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[0], 0);

//check if frameBuffer is OK
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
    NSLog(@"failed to make complete framebuffer objects %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    return NO;
}

//Generate viewFrameBuffer for drawing to view
glGenFramebuffers(1, &viewFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);

if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
    NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
}

绘制到第一个纹理:

glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[0], 0);
....
glDrawArrays(GL_POINTS, 0, (int)vertexCount);

生成和绑定第二个纹理:

glGenTextures(1, &layers[1]);
glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);
glBindTexture(GL_TEXTURE_2D, layers[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,  backingWidth, backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[1], 0);  

绘制到第二个纹理:

glBindFramebuffer(GL_FRAMEBUFFER, textureFrameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, layers[1], 0);
....
glDrawArrays(GL_POINTS, 0, (int)vertexCount);

将所有纹理绘制到屏幕上:

// Bind view buffer
glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
//clear screen every frame
glClear(GL_COLOR_BUFFER_BIT);
//bind layer texture
for (int i=0; i<= layerCount; i++) {
    glBindTexture(GL_TEXTURE_2D, layers [i]);
    ....
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

[context presentRenderbuffer:viewFramebuffer];

【讨论】:

  • 谢谢!在我找到你的帖子之前,我很难获得两个纹理来渲染。这效果很好。
猜你喜欢
  • 2012-01-16
  • 1970-01-01
  • 2016-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
相关资源
最近更新 更多