我想在我的FBO中加载两个纹理,一个纹理包含HDR图像,我的第一个目标是将图像从第一个纹理“复制”到第二个(这是空的),并称为“ DownSamplingTex < / em>的”。
所以我创建了FBO,在COLOR_ATTACHMENT_0中加载我想写的纹理,然后绑定它;然后初始化我的着色器程序并渲染一个四边形,我想在GL_TEXTURE_0中读取绑定的纹理。
然后我取消绑定FBO并绑定' DownSamplingTex ',并绘制四边形。
我不知道这个过程是否正确,我的输出是黑屏。
这是渲染代码:
glBindFramebuffer(GL_FRAMEBUFFER, fboA);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
FBOtex->bind(); // Set read texture bound in GL_TEXTURE_0
glDrawBuffer(GL_COLOR_ATTACHMENT0); // draw to write texture (DownSamplingTex)
fboShad->bind(); // use program of FBO shader
fboShad->setUniformValue4f("MVP", glm::value_ptr(MVP)); // Shader attribute
drawQuad(); // Draw
fboShad->unbind();
FBOtex->unbind();
// Main FB rendering
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
fboShad->bind();
fboShad->setUniformValue4f("MVP", glm::value_ptr(MVP));
DownSamplingTex->bind();
drawQuad();
DownSamplingTex->unbind();
fboShad->unbind();
顶点着色器:
#version 420
in vec4 vUV;
in vec4 vVertex;
smooth out vec2 vTexCoord;
uniform mat4 MVP;
void main()
{
vTexCoord = vUV;
gl_Position = MVP*vVertex;
}
片段着色器:
#version 420
smooth in vec2 vTexCoord;
layout(location = 0) out vec4 color;
layout(binding=0) uniform sampler2D texHDR;
void main(void)
{
color = texture(texHDR,vTexCoord);
}
在' drawQuad()'里面我用 glGetAttribLocation()和 glVertexAttribPointer()设置 vVertex 值。
std::vector<GLfloat> quadVerts = {
-1, -1, 0, 0, 1,
-1, 1, 0, 0, 0,
1, 1, 0, 1, 0,
-1, -1, 0, 0, 1,
1, 1, 0, 2, 0,
1, -1, 0, 1, 1 };
GLuint quadVbo;
glGenBuffers(1, &quadVbo);
glBindBuffer(GL_ARRAY_BUFFER, quadVbo);
glBufferData(GL_ARRAY_BUFFER, 6*3*4, &quadVerts[0], GL_STATIC_DRAW);
GLuint vVertex = fboShad->getLocation("vVertex");
GLuint vUV = fboShad->getLocation("vUV");
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), NULL);
glEnableVertexAttribArray(vVertex);
glVertexAttribPointer(vVertex, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);
glEnableVertexAttribArray(vUV);
glVertexAttribPointer(vUV, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (void*)(3 * sizeof(GLfloat)));
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(vVertex);
glDisableVertexAttribArray(vUV);
我不知道这个过程中是否存在错误,或者在片段着色器中使用属性可能不正确(我认为' layout(binding = 1)',如果你使用带有FBO绑定的着色器,采用GL_COLOR_ATTACHMENT_1纹理);或者使用'vTexCoords'作为顶点的.xy值。
答案 0 :(得分:1)
我认为您将采样器绑定与片段数据输出位置混淆。虽然可以使用layout (...)
限定符分配这两个内容,但它们非常不同。
layout (location = X) out vec3 color
将输出color
分配给 GL_COLOR_ATTACHMENT0 + X
layout (binding = Y) sampler2D texHDR
告诉GLSL使用纹理图像单元 GL_TEXTURE0 + Y
您的片段着色器仅写入单个输出,因此在这种情况下没有实际的理由可以拥有多个颜色附件。您将图像附加到FBO,以便从片段着色器写入它们,而不是从它们作为纹理读取它们。实际上,在不使用特殊扩展(例如 GL_NV_texture_barrier
)的情况下,连接到FBO进行写入的同时从纹理读取是未定义的行为。
#version 420
smooth in vec2 vTexCoord;
//out vec4 vFragColor;
layout(location=0) out vec3 color; // Fragment Data Output Location
layout(binding=0) uniform sampler2D texHDR; // Texture Image Unit Binding
void main(void)
{
//vFragColor = texture(textureMap, vTexCoord);
//color = vec4(1.0,0.5,0.5,0.5);
color = texture(texHDR,vTexCoord);
}
现在,你想要阅读的纹理应绑定到GL_TEXTURE0
(这是默认设置,除非你手动调用glActiveTexture (...)
somehwere)并且你要输出的纹理应该附加到你的Framebuffer对象GL_COLOR_ATTACHMENT0
。
这里要记住的最重要的事情是binding
和location
限定符是完全独立的:颜色附件0与纹理图像单元0不对应。