gpt4 book ai didi

c++ - OpenGL 3.30/GLSL 3.30 - MRT 输出黑色纹理

转载 作者:搜寻专家 更新时间:2023-10-31 01:08:25 25 4
gpt4 key购买 nike

我已经被这个问题困扰了大约四天了。我正在尝试将我的几何图形渲染到具有三种纹理(反照率、法线、深度)的 FBO(G 缓冲区)中。到目前为止,我已经“有点”实现了 MRT 功能,但是当我使用 gDEBugger 检查纹理时,它们只是显示为黑色。无论我改变什么,它们都会变成纯黑色。输出的实际值是正确的,我通过禁用 MRT 使片段着色器输出到后台缓冲区来检查。纹理正在正确初始化,gDEBugger 正确显示我为它们设置的参数。但它们都只有纯黑色 (0, 0, 0, 255) 填充。

几乎没有任何关于 GLSL 3.30 的 MRT 的详细信息。我完全依赖此处回答的问题,以及网络上的 OpenGL/GLSL 文档和教程(已过时,但我更新了代码)。我可能花了一整天的时间在谷歌上寻找这个问题的解决方案。如果代码顺序或语法有问题,请指出。我什至不知道这个实现是否正确了......

我正在使用 Visual C++ 2010、OpenGL 3.30 和 GLSL 3.30(如标题中所述)。对于我的库,GLFW 3.0 用于窗口、输入和 OpenGL 上下文,GLEW 1.10.0 用于扩展。

请记住,所有这些代码都取 self 的包装器类。代码的顺序是它在运行时如何运行(换句话说,就好像我没有包装类,所有代码都在 main () 中)。

初始化阶段

// Initialize textures
glGenTextures (3, tex_ids);

glEnable (GL_TEXTURE_2D);

glBindTexture (GL_TEXTURE_2D, tex_ids[0]); // Diffuse
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glBindTexture (GL_TEXTURE_2D, tex_ids[1]); // Normal
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

glBindTexture (GL_TEXTURE_2D, tex_ids[2]); // Depth
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_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);
glTexImage2D (GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, res.x, res.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

glBindTexture (GL_TEXTURE_2D, 0);
glDisable (GL_TEXTURE_2D);


// Initialize FBO
glEnable (GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_ids[0]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
tex_ids[0],
0 ); // diffuse

glBindTexture(GL_TEXTURE_2D, tex_ids[1]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT1,
GL_TEXTURE_2D,
tex_ids[1],
0 ); // normal

glBindTexture(GL_TEXTURE_2D, tex_ids[2]);
glFramebufferTexture2D ( GL_FRAMEBUFFER,
GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D,
tex_ids[2], 0 ); // depth
glBindFramebuffer (GL_FRAMEBUFFER, 0);
glDisable (GL_TEXTURE_2D);

// Initialize shaders

// Snipped out irrelevant code relating to getting shader source & compiling shaders
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT0, "diffuse_out");
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT1, "normal_out");
glBindFragDataLocation (renderer_1prog, GL_DEPTH_ATTACHMENT, "depth_out");
// More snipped out code relating to linking programs and finalizing

Draw Stage - 在每一帧调用

// Bind everything
glUseProgram (renderer_1prog);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, fbo_id);
GLenum targ [3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT };
glDrawBuffers (3, targ);

// Draw mesh
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);

teshmesh.draw ();

// Unbind fbo
glDisable (GL_CULL_FACE);
glDisable (GL_DEPTH_TEST);

glBindFramebuffer (GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0);

顶点着色器

#version 330
layout(location = 0)in vec4 v;
layout(location = 1)in vec3 c;
layout(location = 2)in vec3 n;
out vec4 pos;
out vec3 col;
out vec3 nrm;
uniform mat4 projection;
uniform mat4 view;
uniform mat4 world;
void main () {
gl_Position = projection * view * world * v;
pos = view * world * v;
pos.z = -pos.z / 500.0;
col = c.xyz;
nrm = n;
}

片段着色器

#version 330
in vec3 col;
in vec3 nrm;
in vec4 pos;
layout(location = 0) out vec3 diffuse_out;
layout(location = 1) out vec3 normal_out;
layout(location = 2) out vec3 depth_out;
out vec3 o;
void main () {
diffuse_out = col;
normal_out = (nrm / 2.0) + 0.5;
depth_out = vec3 (pos.z, pos.z, pos.z);
}

最佳答案

这里有一些问题。从最小的开始:

glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT0, "diffuse_out");
glBindFragDataLocation (renderer_1prog, GL_COLOR_ATTACHMENT1, "normal_out");
glBindFragDataLocation (renderer_1prog, GL_DEPTH_ATTACHMENT, "depth_out");

这些毫无意义。您在着色器中使用了 layout(location) 语法来指定它,并且 that takes priority over OpenGL-provided location settings .

此外,这些都是错误的。您不要将 FBO 缓冲区附件名称放入该位置;您将 索引 放入该位置。因此,即使您没有使用 layout(location),这也是不正确的。 glBindFragDataLocation将发出 OpenGL 错误,因为该位置肯定会大于 GL_MAX_DRAW_BUFFERS

考虑到您的代码应该发出多少 OpenGL 错误,我很惊讶您对 gDEBugger 的使用没有告诉您任何这些错误。


glTexImage2D  (GL_TEXTURE_2D, 0, GL_RGB8, res.x, res.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

GL_RGB8 不是 required image formats for render targets 之一.因此,不需要实现支持它;它可能但它不必。既然你从来没有费心 check the completeness of the FBO (仅供引用:您应该始终这样做),您没有测试这种格式组合是否有效。

切勿渲染为 3 分量图像。选择 4、2 或 1。


GLenum targ [3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_DEPTH_ATTACHMENT };
glDrawBuffers (3, targ);

这可能是您的主要问题:您的 glDrawBuffers call fails . glDrawBuffers sets the color buffer outputs .深度缓冲区不是颜色缓冲区。深度缓冲只有一个,无需设置。

要写入深度缓冲区...好吧,您不应该将用户计算的值写入深度缓冲区。只需让常规深度缓冲区写入处理它即可。但是如果你想(让我再次提醒你,你不会),你写到 gl_FragDepth。这就是它的用途。

关于c++ - OpenGL 3.30/GLSL 3.30 - MRT 输出黑色纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18025311/

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