当前位置: 首页 > 知识库问答 >
问题:

使用FBO和着色器OpenGL渲染纹理

东方栋
2023-03-14

我想在FBO中加载两个纹理,其中一个纹理包含HDR图像,我的第一个目标是将图像从第一个纹理“复制”到第二个纹理(该纹理为空),并称为“下采样纹理”。

所以我创建FBO,加载我想用颜色_附件_0书写的纹理,并绑定它;然后初始化我的着色器程序并渲染一个四边形,其中包含我要在GL\u texture\u 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);
}

在“draquad()”中,我使用glGetAttribloce()和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);

我不知道错误是在这个过程中,还是在片段着色器中使用的属性不正确(我假设“布局(绑定=1)”,如果使用FBO绑定的着色器,tooks GL_COLOR_ATTACHMENT_1纹理);或者使用“vTexCoords”作为。顶点的xy值。

共有1个答案

林俊晖
2023-03-14

我认为您混淆了采样器绑定和片段数据输出位置。而这两件事都可以通过布局来分配(…) 限定符,它们非常不同。

layout(location=X)out vec3 color将输出颜色分配给GL\u color\u 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)和要输出到的纹理应该附加到帧缓冲区对象的GL_COLOR\u ATTACHMENT0

这里需要记住的最重要的一点是,绑定位置限定符是完全独立的:颜色附件0与纹理图像单元0不对应。

 类似资料:
  • 我有一个非常简单的OpenGL应用程序,只渲染一个带纹理的四边形。这是我的代码,效果很好(带纹理的四边形看起来很好): 然后我想介绍一个简单的着色器。所以我稍微修改了我的代码: 顶点着色器: 片段着色器: 现在我得到的只是一个黑色的四边形:-( 我已经尝试并测试了很多东西: 着色器编译良好(无错误) 有人知道为什么我在使用着色器时看不到我的纹理吗?

  • 在一个教程之后,我将尝试使用FreeType在OpenGL中渲染文本。因此,灰度8位图像用作每个字符的纹理,使图像的每个字节对应于纹理的红色分量。 为了以其他颜色呈现文本,建议您使用着色器。但是,当使用提供的着色器时,我看到的不是彩色字母,而是彩色框,好像根本没有纹理。 以下是没有着色器时的效果: 这是它在着色器中的外观: (盒子的位置也会发生变化) 以下是顶点着色器代码: 这是片段着色器代码:

  • 执行以下操作的正确方法是什么: 使用FBO(fbo-a)将场景渲染为纹理 然后使用纹理(tex-a)应用效果并使用相同的fbo(fbo-a)将其渲染为另一个纹理(tex-b) 然后渲染这第二个纹理,应用效果(tex-b)为全屏四边形。 我的方法是这样的,但这给了我一个在应用效果窗口上充满“噪音”的纹理(所有像素都是随机着色的红、绿、蓝、白、黑)。 我使用的是一个FBO,两个纹理分别设置为GL_CO

  • 我一直在尝试渲染到一个FBO,并将两个FBO渲染到屏幕上,但在合并两个FBO时进行深度测试失败。我尝试使用计算着色器合并纹理,但无法读取深度纹理的值(所有值都是值1,但渲染到FBO时深度测试有效)。有人知道我做错了什么,或者知道其他方法来合并两个FBO吗? 以下是我创建FBO的方式: 以下是我向FBO渲染的方式: 我尝试用glBindTexture绑定纹理(所有值均为1): 计算着色器: 我已尝试

  • 我正在渲染很多轴对齐的3D立方体。每个立方体的中心位置和/或颜色可能不同于其他立方体。这就是我现在渲染它的方式 My DrawCube()使用和存储在VBO中的顶点数据,简单地渲染立方体每一侧对应的6个四边形。glVertexPointer和glColorPointer用于设置属性元素。 这是可行的,但是我想通过使用可能是glDrawElementsInst的()来使用即时渲染。但是由于项目的一些

  • 我是OpenGL的新手,在整理如何将纹理和着色器绑定到VBOs时遇到了困难。 我正在使用Cinder的纹理和着色器类。以下是我绘制方法的一部分: 在上面的代码中,如果我注释掉对mShader的调用。bind(),我的球体VBO将显示纹理(myImage)。我的着色器适用于普通(无纹理)形状,但当我在绘制任何带有包裹纹理的形状之前绑定着色器时,它会阻止纹理显示。 这是我使用的着色器的问题,还是我不理