如何让YUV转RGB着色器渲染到自定义纹理而非FragColor?
问题:如何让YUV转RGB着色器直接渲染到指定纹理,避免额外拷贝?
我有一段实现YUV与RGB格式转换的GLSL ES 3.0着色器代码,目前通过FragColor = rgba;将结果输出到默认帧缓冲。现在需要把转换后的RGB结果直接渲染到C++侧(Flutter提供)生成的纹理上,不想采用从帧缓冲读取后调用glTexImage2D写入的方式,想问能否直接在渲染流程中实现?
着色器代码如下:
#version 300 es #ifdef GL_ES // Set default precision to medium, this is needed for GL_ES (android) precision mediump int; precision mediump float; #endif uniform sampler2D tex_y; uniform sampler2D tex_u; uniform sampler2D tex_v; in vec2 TexCoord; out vec4 FragColor; void main() { vec3 yuv; vec4 rgba; yuv.r = texture(tex_y, TexCoord).r - 0.0625; yuv.g = texture(tex_u, TexCoord).r - 0.5; yuv.b = texture(tex_v, TexCoord).r - 0.5; rgba.r = yuv.r + 1.596 * yuv.b; rgba.g = yuv.r - 0.813 * yuv.b - 0.391 * yuv.g; rgba.b = yuv.r + 2.018 * yuv.g; rgba.a = 1.0; FragColor = rgba; }
解决方案:使用帧缓冲对象(FBO)绑定目标纹理作为颜色附件
不需要修改着色器代码,通过OpenGL的帧缓冲对象(FBO)就能直接把着色器输出写入目标纹理,完全省去额外拷贝步骤,具体流程如下:
创建并绑定帧缓冲对象
在Flutter提供的OpenGL上下文(C++侧)中,创建FBO并将目标纹理绑定为FBO的颜色附件:// textureId 为Flutter提供的目标纹理ID GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); // 将目标纹理绑定到FBO的颜色附件0 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);必须检查FBO完整性:调用
glCheckFramebufferStatus(GL_FRAMEBUFFER),返回值需为GL_FRAMEBUFFER_COMPLETE,确保绑定有效。切换渲染目标到FBO
执行着色器渲染前,绑定该FBO,此时着色器的FragColor输出会直接写入绑定的目标纹理,而非默认帧缓冲:glBindFramebuffer(GL_FRAMEBUFFER, fbo); // 执行渲染流程(例如绘制全屏四边形,触发YUV转RGB的着色器计算) glBindFramebuffer(GL_FRAMEBUFFER, 0); // 渲染完成后解绑FBO,恢复默认帧缓冲着色器无需修改
现有着色器的FragColor输出逻辑保持不变,FBO会自动将输出结果写入绑定的目标纹理,全程没有额外的内存拷贝操作。
内容的提问来源于stack exchange,提问作者Poperton
相关产品推荐
相关产品推荐

