【问题标题】:OpenGL(GLSL) Not writing to correct FrameBuffer TextureOpenGL(GLSL)未写入正确的帧缓冲区纹理
【发布时间】:2015-09-15 11:30:56
【问题描述】:

我有一个附加了两个纹理的帧缓冲区,读取调用:

Occlusion = texture2D(OcclusionTexture, TexCoord);
FragColor = texture2D(ColourTexture, TexCoord);

返回相同的东西。它们返回驻留在纹理OcclusionTexture 中的数据。任何帮助请,对不起代码墙。

着色器代码: 附件

 subroutine void RenderPassType();
    subroutine uniform RenderPassType RenderPass;

    uniform sampler2D ColourTexture;
    uniform sampler2D OcclusionTexture;
    layout(location = 0) out vec4 FragColor; // Actual fragment colour;
    layout(location = 1) out vec3 OutColour;
    layout(location = 2) out vec3 OcclusionColour;

写作和阅读

    subroutine (RenderPassType) void Write()
    {
        // Writing
        OcclusionColour = vec3(m_Light[0].Intensity);
        OutColour = vec3(ApplyFog(ViewPos, Colour, fogColour,                   fogDistance)); 
    } 

    subroutine (RenderPassType) void Read()
    {
        // Reading
        vec4 Occlusion = texture2D(OcclusionTexture, TexCoord);
        FragColor = texture2D(ColourTexture, TexCoord);
    }

生成帧缓冲区和纹理的代码:

// Create and bind the FBO
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);

// The depth buffer
glGenRenderbuffers(1, &DepthBuff);
glBindRenderbuffer(GL_RENDERBUFFER, DepthBuff);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 
    settings::GameSettings::GetSingleton()->Screen.x, settings::GameSettings::GetSingleton()->Screen.y);

// The color buffer
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &ScreenTex);
glBindTexture(GL_TEXTURE_2D, ScreenTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, settings::GameSettings::GetSingleton()->Screen.x
    , settings::GameSettings::GetSingleton()->Screen.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// The occlusion buffer
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &OcclusionTex);
glBindTexture(GL_TEXTURE_2D, OcclusionTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, settings::GameSettings::GetSingleton()->Screen.x
    , settings::GameSettings::GetSingleton()->Screen.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

// Attach the images to the framebuffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, DepthBuff);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ScreenTex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, OcclusionTex, 0);

GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};

glDrawBuffers(3, drawBuffers);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

SetUniform("ColourTexture", ScreenTex);
SetUniform("OcclusionTexture", OcclusionTex);

/////////////////////////////////////// /////// 编辑 ///////////////////////////////////////// ////

第一遍我将场景渲染到纹理。在第二遍中,我只读取纹理并进行体积光照计算,然后将最终的碎片颜色推送到附件 0。

【问题讨论】:

  • 您不能同时读取和写入纹理。如果这不是您在这里所做的,那么请清楚地标记哪些代码行属于哪个着色器调用。
  • 没有渲染通道 1 我直接到纹理,渲染通道 2 我从纹理中读取。
  • SetUniform 是如何实现的?
  • void Shader::SetUniform(char* string, int type) { GLuint varLocation = glGetUniformLocation(m_shaderProgramHandle, string); glUniform1iv(varLocation, 1, &type); }
  • 那么问题正是@dari 在 hist answer 中所写的

标签: opengl glsl framebuffer


【解决方案1】:

你的纹理绑定是错误的。它应该看起来像这样:

SetUniform("ColourTexture", 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ScreenTex);

SetUniform("OcclusionTexture", 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, OcclusionTex);
//draw stuff

注意:重要的部分在这里,活动纹理单元的编号被传递给制服而不是纹理ID。

【讨论】:

  • 我进行了这些更改,但仍然遇到同样的问题。从看起来哪个纹理位于位置 2 layout(location = 2) out vec3 OcclusionColour; 来看,是当您对两个绑定纹理中的任何一个进行采样时返回的纹理信息。
【解决方案2】:

纹理的问题在于我正在绑定和取消绑定着色器程序。

glUseProgram(m_shaderProgramHandle); //bind program
glUseProgram(0); //unbind a program

纹理仅在着色器启动时绑定到它们的纹理单元,因为着色器被解除绑定,它也解除了纹理单元的绑定。解决方法是:

void StandardLightingShader::Begin() 
{
    glUseProgram(m_shaderProgramHandle);

    // Set up Pass
    glBindFramebuffer(GL_FRAMEBUFFER, FBO);
    glEnable(GL_DEPTH_TEST);
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, 1, &pass1Index);
    SetUniform("ScreenSize", settings::GameSettings::GetSingleton()->Screen);
    SetUniform("ScreenOffSet", settings::GameSettings::GetSingleton()->ScreenPosition);

    // Bind the textures to texture units.
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, ScreenTex);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, OcclusionTex);

}

因此,基本上,如果您取消绑定程序,则需要将纹理重新绑定到纹理单元,但实际的统一变量将通过着色器更改持续存在。

SetUniform("ColourTexture", 0);

【讨论】:

  • 您可能已经通过更改呼叫顺序修复了您的症状,但解释没有意义。纹理绑定状态完全独立于当前绑定的程序。您确实不必在绑定新程序后重新绑定纹理。
猜你喜欢
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 2014-01-06
  • 1970-01-01
  • 2012-07-26
  • 2014-12-05
  • 1970-01-01
相关资源
最近更新 更多