OpenGL ES 2.0 Framebuffer 渲染到纹理 iOS:没有显示

Posted

技术标签:

【中文标题】OpenGL ES 2.0 Framebuffer 渲染到纹理 iOS:没有显示【英文标题】:OpenGL ES 2.0 Framebuffer with render to texture iOS: nothing shown 【发布时间】:2015-06-09 19:47:08 【问题描述】:

我正在使用帧缓冲区进行后期处理。 创建并绘制到缓冲区(通过glReadPixelsglCheckFramebufferStatus 测试)工作正常。 但现在我想用四边形将这个纹理渲染到屏幕上。但屏幕仍然是黑色的。

相同的代码(用于绘图)在 android、windows、OSX 等其他平台上运行良好。

使用模板和纹理初始化帧缓冲区::

//framebuffer
glGenFramebuffers(1, &fb);
glBindFramebuffer(GL_FRAMEBUFFER, fb);

//texture
glGenTextures(1, &color);
glBindTexture(GL_TEXTURE_2D, color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

//width and height: screen size
glTexImage2D(GL_TEXTURE_2D ,0, GL_RGBA, width, height,0,GL_RGBA,GL_UNSIGNED_BYTE,NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);

//depth and stencil
glGenRenderbuffers(1, &depthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencil);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencil);

将内容绘制到帧缓冲区:

glBindFramebuffer(GL_FRAMEBUFFER, fb);

glViewport(0, 0, width, height);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0.0f,0.0f,0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// ....

glBindFramebuffer(GL_FRAMEBUFFER, 0);

绘制帧缓冲内容:

//unbind framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);

std::vector<GLfloat> vertices = 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f;
std::vector<GLfloat> texCoords = 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f;
std::vector<GLushort> indices = 0,1,2,0,2,3;

glm::mat4 projection = glm::ortho(0.0f, 1.0f, 0.0f, 1.0f, -10.0f, 10.0f);

//clear
glEnable(GL_DEPTH_TEST, true);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

//shader
glUseProgram(shader);
auto aPosition = glGetAttribLocation(shader,"aPosition");
auto aTexCoord = glGetAttribLocation(shader,"aTexCoord");
auto uTex = glGetUniformLocation(shader,"uTex");
auto uMVP = glGetUniformLocation(shader,"uMVP");

//blending
glEnable(GL_BLEND, true);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

//binding texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, color);
glUniform1i(uTex, 0);

//set attributes
glUniformMatrix4fv(uMVP, 1, GL_FALSE, glm::value_ptr(projection));

glVertexAttribPointer(aPosition, 3, GL_FLOAT, GL_FALSE, 0, &vertices[0]);
glEnableVertexAttribArray(aPosition);
glVertexAttribPointer(aTexCoord, 2, GL_FLOAT, GL_FALSE, 0, &texCoords[0]);
glEnableVertexAttribArray(aTexCoord);

//draw
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);

顶点着色器:

attribute vec4 aPosition;
attribute vec2 aTexCoord;
varying vec2 vTexCoord;
varying vec3 vPosition;
uniform mat4 uMVP;

void main()

    gl_Position = uMVP * aPosition;

    vTexCoord = aTexCoord;
    vPosition = gl_Position.xyz;

片段着色器:

varying vec2 vTexCoord;
varying vec3 vPosition;
uniform sampler2D uTex;

void main()

    vec4 texCol = texture2D(uTex, vTexCoord.xy);
    gl_FragColor = texCol;

【问题讨论】:

有一点需要注意,至少如果您使用 GLKView,它不会默认渲染到帧缓冲区 0。因此,如果您调用 glBindFramebuffer(GL_FRAMEBUFFER, 0),则不会呈现到您的视图中。 我在帧缓冲内容绘图之前已经有了这个。我忘了在这里添加这个。我编辑了我的帖子。 您的视图设置必须不同。我知道绑定帧缓冲区0 后,我在 ios 上完全没有显示任何内容。 好的,我必须将帧缓冲区绑定到哪个 id?有什么提示吗?谢谢 在我的drawInRect 中的[((GLKView *) self.view) bindDrawable]; 呼叫之后,我立即与glGetIntegerv(GL_FRAMEBUFFER_BINDING, &amp;defaultFBO); 一起工作。感谢您的提示! 【参考方案1】:

0不是 iOS 上的默认帧缓冲区 ID。

获取默认帧缓冲ID:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect

    [((GLKView *) self.view) bindDrawable];

    GLint defaultFBO;
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFBO);

    //draw ...

【讨论】:

以上是关于OpenGL ES 2.0 Framebuffer 渲染到纹理 iOS:没有显示的主要内容,如果未能解决你的问题,请参考以下文章

Framebuffer FBO渲染到纹理很慢,在Android上使用OpenGL ES 2.0,为啥?

OPENGL ES 2.0 知识串讲――OPENGL ES 2.0 概括

OPENGL ES 3.1是否比OPENGL ES 2.0慢?

如何在Android上使用OpenGL ES 2.0绘制点

如何在Android上将OpenGL ES 1.0代码转换为OpenGL Es 2.0?

OpenGL ES 2.0 符点精度