OpenGL ES 2.0渲染为多个纹理
问题描述:
我正在使用OpenGL ES 2.0构建iPad应用程序。我需要做的是渲染多个纹理,然后渲染所有纹理进行查看。我使用基于用户触摸位置的GL_POINTS进行绘制。我的代码,我现在已经是:OpenGL ES 2.0渲染为多个纹理
生成帧缓冲,纹理和渲染缓存:
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];
上述工程OK,但是当我想渲染到我的应用程序停止绘制任何新内容的新纹理。我绑定这样的新纹理:
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);
然后再次调用绘图方法。我的代码在渲染到第一个纹理时起作用,但当我尝试生成要渲染的新纹理时,应用程序停止绘制。任何人都可以帮忙吗?
答
我让我的代码工作。我的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];
+0
谢谢!在找到你的帖子之前,我很难得到两个纹理。这很好。 – 2014-12-07 22:33:04
最有可能无关您的问题,但没有任何理由,你为什么要使用部分的FBO切入点和定义扩展(OES)版本? – 2014-09-04 05:10:48
@ReetoKoradi不知道为什么那里。我从苹果的GLPaint接下来的教程,就是这样做的。我将GL_FRAMEBUFFER_OES更改为GL_FRAMEBUFFER,但问题仍然存在。有什么建议么? – Amendale 2014-09-04 11:03:01
你做这个新的附件后,你检查帧缓冲区状态?在执行该行之前,正确的帧缓冲区必须被绑定不仅仅是纹理(但最可能已经是这样)。无论如何,我不知道你甚至可以做到这一点,但如果你做的没问题,我会期望这两个纹理都附加到帧缓冲区,所以它应该画到两者。无论如何,为什么你甚至试图做到这一点,你可以简单地生成一个新的帧缓冲区并附加纹理。至于渲染缓冲区,如果我没有记错,你不需要它,如果你有纹理附加.. – 2014-09-05 07:29:09