gpt4 book ai didi

c++ - OpenGL Qt : problem using framebuffers for bloom effect

转载 作者:行者123 更新时间:2023-11-28 01:26:14 30 4
gpt4 key购买 nike

我正在关注这个 tutorial用于绽放效果。

我正在使用 Qt,我尝试渲染的场景由五个立方体和五个随机放置的灯组成,类似于这样。

不幸的是,当我尝试使用帧缓冲区时,渲染的场景完全是空的(只有背景颜色)。

这些是代码的相关部分。

初始化GL方法:

void initializeGL()
{
initializeOpenGLFunctions();

// ...

// hdr framebuffer

glGenFramebuffers(1, &(FBOs[0]));

glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);

glGenTextures(2, &(textures[0]));

for (int i = 0; i < 2; i++)
{
glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, geometry().width(), geometry().height(), 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i], 0);
}

GLuint rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, geometry().width(), geometry().height());
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);

GLuint attachments[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, attachments);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "framebuffer NOT complete";
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

paintGL 方法:

void paintGL()
{
view.setToIdentity();
view.lookAt(camera.eye, camera.center, camera.up);

glClearColor(background.redF(), background.greenF(), background.blueF(), background.alphaF());
glEnable(GL_DEPTH_TEST);

// draw scene

glBindFramebuffer(GL_FRAMEBUFFER, FBOs[0]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

for (auto position : positions)
{
drawCube(position);
}

for (auto light : lights)
{
drawLightMarker(light);
}

// draw frame

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

drawQuad();

// draw next frame
update();
}

drawQuad 方法:

void drawQuad()
{
GLuint* vao = &VAOs[BLOOM];

if (*vao == 0)
{
glGenVertexArrays(1, vao);

float l = 1.0f;
QVector2D LD(-l, -l); // left-down
QVector2D LU(-l, +l); // left-up
QVector2D RD(+l, -l); // right-down
QVector2D RU(+l, +l); // right-up

QVector<QVector2D> vertices = { LD, RD, LU, LU, RD, RU };

QVector<QVector2D> texcoords;

for (auto v : vertices)
{
texcoords += (v + QVector2D(l, l)) / (2.0f * l);
}

// bind vao
glBindVertexArray(*vao);
// vertices
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(QVector2D), &(vertices[0]), GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), static_cast<void*>(nullptr));
glEnableVertexAttribArray(0);
// texcoords
GLuint tbo;
glGenBuffers(1, &tbo);
glBindBuffer(GL_ARRAY_BUFFER, tbo);
glBufferData(GL_ARRAY_BUFFER, texcoords.size()*sizeof(QVector2D), &(texcoords[0]), GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(QVector2D), static_cast<void*>(nullptr));
glEnableVertexAttribArray(1);
// unbind buffer object
glBindBuffer(GL_ARRAY_BUFFER, 0);
// unbind vao
glBindVertexArray(0);
}

GLuint program = programs[BLOOM];
glUseProgram(program);

glUniform1i(glGetUniformLocation(program, "scene"), 0);
glUniform1i(glGetUniformLocation(program, "bloom"), 1);

glUniform1i(glGetUniformLocation(program, "effect"), true);

glBindVertexArray(*vao);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textures[1]);

glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}

立方体片段着色器:

#version 450 core

layout (location = 0) out vec4 pixel;
layout (location = 1) out vec4 bloom;

struct Material
{
// material properties
};

uniform Material material;

struct Light
{
// light properties
};

uniform Light[5] lights;

uniform vec3 eye;

in FragData
{
vec3 position;
vec3 normal;
} data;

vec3 point(Light light, vec3 position, vec3 normal, vec3 eye)
{
// lighting computation
}

void main()
{
vec3 color = vec3(0.0f);

for (int i = 0; i < 5; i++)
{
color += point(lights[i], data.position, data.normal, eye);
}

pixel = vec4(color, 1.0f);

vec3 weights = vec3(0.2126f, 0.7152f, 0.0722f);
float brightness = dot(pixel.rgb, weights);

if (brightness > 1.0f)
{
bloom = vec4(pixel.rgb, 1.0f);
}
else
{
bloom = vec4(vec3(0.0f), 1.0f);
}
}

光标记片段着色器:

#version 450 core

layout (location = 0) out vec4 pixel;
layout (location = 1) out vec4 bloom;

struct Light
{
// light properties
};

uniform Light light;

void main()
{
pixel = vec4(light.diffuse, 1.0f);

vec3 weights = vec3(0.2126f, 0.7152f, 0.0722f);
float brightness = dot(pixel.rgb, weights);

if (brightness > 1.0f)
{
bloom = vec4(light.diffuse, 1.0f);
}
else
{
bloom = vec4(vec3(0.0f), 1.0f);
}
}

最终顶点着色器:

#version 450 core

layout (location = 0) in vec2 position;
layout (location = 1) in vec2 texcoord;

out FragData
{
vec2 texcoord;
} data;

void main()
{
data.texcoord = texcoord;
gl_Position = vec4(position, 0.0f, 1.0f);
}

最终片段着色器:

#version 450 core

in FragData
{
vec2 texcoord;
} data;

out vec4 pixel;

uniform sampler2D scene;
uniform sampler2D bloom;

uniform bool effect;

void main()
{
vec3 hdr = texture(scene, data.texcoord).rgb;

if (effect)
{
hdr += texture(bloom, data.texcoord).rgb;
}

// tone mapping
float exposure = 1.0f;
pixel = vec4(vec3(1.0f) - exp(-hdr * exposure), 1.0f);
// gamma correction
float gamma = 2.2f;
pixel = vec4(pow(pixel.rgb, vec3(1.0 / gamma)), 1.0f);
}

目前,我还没有实现模糊来获得光晕效果,但我只是从渲染场景中提取了两张图像并将它们相加。

我哪里做错了?非常感谢您的帮助!

最佳答案

你不应该使用

glBindFramebuffer(GL_FRAMEBUFFER, 0);

因为 Qt 可能在您背后使用 FBO 而不是 GL 的默认帧缓冲区。您可以使用 QOpenGLContext::defaultFramebufferObject查询 Qt 用作默认帧缓冲区的 FBO 名称,它可能是也可能不是 0

关于c++ - OpenGL Qt : problem using framebuffers for bloom effect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53693579/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com