c - OpenGL 仅在 fb0 中进行第一次纹理渲染
问题描述
我正在尝试将两个高斯模糊纹理附加到 fbo,以便在着色器中减去它们(在 dog 中返回 c2-c),但第一个纹理给出了奇怪的结果。我试图找到问题,但我看不到问题出在哪里。如果有人能启发我,我将不胜感激。先感谢您。
这是C代码:
static void draw(void) {
static int b1 = 0;
static int b2 = 50;
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
blur(_vao, b1, _tId, _fboTex[0], 1, 0);
glUseProgram(0);
blur(_vao, b2, _tId, _fboTex[0], 1, 1);
glUseProgram(0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, _dim[0], _dim[1], 0, 0, _dim[0], _dim[1], GL_COLOR_BUFFER_BIT, GL_NEAREST);
//glBlitFramebuffer(0, 0, _dim[0], _dim[1], _dim[0]/2, 0, _dim[0], _dim[1], GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void tex_to_shader(GLuint tid, char * sampler_name, GLuint num_tex){
glActiveTexture(!num_tex ? GL_TEXTURE0 : GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glUniform1i(glGetUniformLocation(blurPId, sampler_name), num_tex);
glBindTexture(GL_TEXTURE_2D, tid);
}
void blur(GLuint plate_vao, GLuint radius, GLuint in, GLuint out, GLuint nb_iterations, GLuint current_texture) {
int i, n;
GLuint temp, rin = in;
glGenTextures(1, &temp);
glBindTexture(GL_TEXTURE_2D, temp);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
radius = radius > MAX_RADIUS ? MAX_RADIUS : radius;
for(n = 0; n < (int)nb_iterations; n++) {
for(i = 0; i < 2; i++) {
glFramebufferTexture2D(GL_FRAMEBUFFER, !current_texture ? GL_COLOR_ATTACHMENT0 : GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, i == 0 ? temp : out, 0);
glUseProgram(blurPId);
glUniform1i(glGetUniformLocation(blurPId, "inv"), i ? 1 : 0);
glUniform1fv(glGetUniformLocation(blurPId, "weight"), MAX_RADIUS, &weights[(radius * (radius - 1)) >> 1]);
glUniform2fv(glGetUniformLocation(blurPId, "offset"), MAX_RADIUS, (i % 2) ? offsetH : offsetV);
glUniform1i(glGetUniformLocation(blurPId, "nweights"), radius);
glDisable(GL_DEPTH_TEST);
glBindVertexArray(plate_vao);
tex_to_shader(rin, !current_texture ? "blur0" : "blur1", current_texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
rin = out;
}
glDeleteTextures(1, &temp);
}
这是我们的片段着色器:
#version 330
uniform sampler2D blur0;
uniform sampler2D blur1;
uniform int current_texture;
uniform int nweights;
uniform float weight[128];
uniform vec2 offset[128];
in vec2 vsoTexCoord;
out vec4 fragColor;
vec4 dog(sampler2D a, sampler2D b){
vec4 c = texture(a, vsoTexCoord.st) * weight[0];
vec4 c2 = texture(b, vsoTexCoord.st) * weight[0];
for (int i = 1; i < nweights; i++) {
c += texture(a, vsoTexCoord.st + offset[i]) * weight[i];
c += texture(a, vsoTexCoord.st - offset[i]) * weight[i];
c2 += texture(b, vsoTexCoord.st + offset[i]) * weight[i];
c2 += texture(b, vsoTexCoord.st - offset[i]) * weight[i];
}
return c;
}
vec4 gray(vec4 c){
float moyenne = 0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b;
return vec4(moyenne, moyenne, moyenne, 1.0);
}
void main(void) {
fragColor = dog(blur0,blur1);
//fragColor = gray(fragColor);
}
解决方案
如果您使用具有多个颜色附件的帧缓冲区,则必须指定应写入的颜色附件。应该在其中绘制的颜色缓冲区可以由 指定glDrawBuffers
。
例如 If only 应该在GL_COLOR_ATTACHMENT1
this 上绘制,可以这样指定:
GLenum attachment = GL_COLOR_ATTACHMENT1;
glDrawBuffers(1, &attachment);
在您的情况下,您必须在函数开始时选择正确的颜色附件blur
:
void blur(GLuint plate_vao, GLuint radius, GLuint in, GLuint out,
GLuint nb_iterations, GLuint current_texture) {
GLenum attachment = !current_texture ? GL_COLOR_ATTACHMENT0 : GL_COLOR_ATTACHMENT1;
glDrawBuffers(1, &attachment);
.....
}
推荐阅读
- linux - 如何使用 GREP 确定文件中的每一行是否与我的模式匹配?
- spring - 为什么在启动期间创建存储库 bean 需要数据源 bean
- elasticsearch - 汇总作业使日期字段的最大聚合为浮动而不是日期
- c# - 响应式 .NET (RX) 通过返回相同的 Observable 嵌套捕获
- python - 使用多处理池时,在 Docker 中运行 python 会卡住
- python - 加快python中的for循环
- python - 在 python 中,如何查找随机字符串 (AB122340) 是否位于从 AB120000 到 AB125000 的字符串系列之间
- python - 使用给定的“时区”字符串从 UTC 时间戳转换为本地时间
- python - 编写函数后在命令行中编辑函数的定义
- java - 填充数组中的空白值