ios - OpenGL ES 2.0 渲染到多个纹理

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

我正在使用 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];

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

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 没有正确生成,我的纹理没有准确绑定(bind)。经验教训 - 生成后始终检查 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);

生成并绑定(bind)第二个纹理:

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

关于ios - OpenGL ES 2.0 渲染到多个纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25656925/

相关文章:

iOS - 只显示后退按钮而不显示导航栏的正确方法是什么?

ios - XmmpFramework + Openfire : manage offline messages

objective-c - 如何启用 Guard Malloc

java - android opengl 游戏

iphone - 在cocos2d中绘制连续的渐变线

Java 将 .obj 转换为适用于 Android 的 OpenGL

ios - 需要像 UISearchDisplayController 一样使用没有 UITableViewController 的 UISearchController

ios - 前台弹出通知

objective-c - EXC_BAD_ACCESS 发送有效对象时

objective-c - ARC是否可以降低我的峰值内存占用量?