【问题标题】:Opengl - Postprocessing multiple FBOs - What am I doing wrong?Opengl - 后处理多个 FBO - 我做错了什么?
【发布时间】:2018-07-05 19:31:17
【问题描述】:

我对 OpenGL 还是很陌生。我以为我了解 FBO,但我无法让它们发挥作用。

我的程序使用多重采样的 fbo 基本图形信息 (colorFbo)。 从 colorFbo 我 blit 到 postprocessFbo。 然后是带有 unsigned int 值的 counterFbo,我只是用对象的 id 填充每个对象的轮廓。

我想对 postprocessFbo 和 counterFbo 进行后处理,但是,我看不到 counterFbo 的任何效果...请问哪里出了问题? 以下是我的部分代码:

初始化:

colorFbo = new Framebuffer(true, false);   //multisampled, rgba
counterFbo = new Framebuffer(false, true); //not MS, red

...seting polygonmode, viewport, depthtest, blending...   

modelProgram = loadProgram("model");
counterProgram = loadProgram("counter");
...
postprocessProgram = loadProgram("postprocess");
...        
postprocessFbo = new Framebuffer(false, false); //not MS, rgba

渲染循环:

glBindFramebuffer(GL_FRAMEBUFFER, colorBuffer.fbo());
Main.clear(0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);        
drawing objects using model program...

glBindFramebuffer(GL_FRAMEBUFFER, counterBuffer.fbo());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_MULTISAMPLE);        
drawing objects using counter program...

blit colorFbo to postprocessFbo...

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
glUseProgram(postprocessProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postprocessFbo.fboColorTexture());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, counterFbo.fboColorTexture());

glBindVertexArray(screenQuadArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);        

计数器片段着色器:

#version 330

out uint counter;

in vec3 vPosition;

uniform uint id;

void main() {
    counter = id;
}

后处理片段着色器:

#version 330

uniform sampler2D colorTex;
uniform usampler2D counterTex;

out vec4 finalColor;

in vec2 texCoord;

void main() {
    finalColor = texture(colorTex, vec2(tex));
    uint id = texture(counterTex, vec2(tex)).s;
    if (id > 0) {
        finalColor = black;
    }
}

帧缓冲构造函数:

public Framebuffer(boolean multisampled, boolean redOnly) {
    int internalFormat = redOnly ? GL_R32UI : GL_RGBA;
    int format = redOnly ? GL_RED_INTEGER : GL_RGBA;
    int dataType = redOnly ? GL_UNSIGNED_INT : GL_UNSIGNED_BYTE;
    int interpolation = redOnly ? GL_NEAREST : GL_LINEAR;

    int textureType = multisampled ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
    // Prepare FBO textures
    fboColorTexture = glGenTextures();
    fboDepthStencilTexture = glGenTextures();
    if (multisampled) {
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboColorTexture);
        glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SAMPLES, internalFormat, Main.width(), Main.height(), false);
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, fboDepthStencilTexture);
        glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, SAMPLES, GL_DEPTH24_STENCIL8, Main.width(), Main.height(), false);            
        glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, 0);
    } else {
        glBindTexture(GL_TEXTURE_2D, fboColorTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, Main.width(), Main.height(), 0, format, dataType, (float[]) null);            
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolation);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolation);
        glBindTexture(GL_TEXTURE_2D, fboDepthStencilTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, Main.width(), Main.height(), 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, (float[]) null);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glBindTexture(GL_TEXTURE_2D, 0);
    }        

    fbo = glGenFramebuffers();
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureType, fboColorTexture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, textureType, fboDepthStencilTexture, 0);
    glDrawBuffers(GL_COLOR_ATTACHMENT0);
    int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE) {
        System.err.println("Framebuffer not complete.");
        System.exit(1);
    }
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

【问题讨论】:

  • 我在写问题的时候误删了,在原代码中是可以的。抱歉弄乱了。

标签: java opengl graphics lwjgl fbo


【解决方案1】:

您似乎缺少将纹理单元分配给纹理名称。所以当我加载纹理时,我通常会在初始化时这样做......

uColorTex = glGetUniformLocation(shaders.shaderProgram, "colorTex");
uCounterTex = glGetUniformLocation(shaders.shaderProgram, "counterTex");

...和绘制时...

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postprocessFbo.fboColorTexture());
glUniform1i(uColourTex, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, counterFbo.fboColorTexture());
glUniform1i(uCounterTex, 1);

【讨论】:

  • 感谢您的回复,我在初始化的第一部分(三个点),我跳过了那部分,因为我觉得我已经觉得我显示了太多的代码。
  • 其实这两个部分,很抱歉混淆。请记住,colorTex 工作得很好,只是我无法工作的 counterTex。
  • 包括 glUniform1i 位?只是问,因为我让你的代码运行良好,只是缺少了
  • 我是在初始化部分做的,我也尝试将它移到渲染中,但没有任何改变。我看到了来自 postprocessFbo 的对象,但由于 counterFbo,它们应该全是黑色的,而且它们不是......
  • 哼,换个纹理单元试试,所以计数器纹理是 GL_TEXTURE0
【解决方案2】:

问题在于计数器程序本身(glVertexAttribPointer),我没有写过。 我只需要在计数器程序中的位置,所以我写了这个:

glVertexAttribPointer(positionAttribLoc, 3, GL_FLOAT, false, FLOAT_VEC3_SIZE, 0);

但我忘了,数据总是在同一个位置,所以我不能“节省空间”,因为我只是绑定,顶点数据保持不变:

glVertexAttribPointer(positionAttribLoc, 3, GL_FLOAT, false, SIZEOF_MODEL_VERTEX, 0);

感谢您的回答,很抱歉我没有显示更多代码,我认为问题可能出在任何地方,并且不想让阅读过多代码的人不知所措。

【讨论】:

  • 您没有在问题中显示这部分代码。所以无法回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-11
  • 2011-01-13
  • 1970-01-01
  • 2021-12-10
  • 2011-06-01
  • 1970-01-01
相关资源
最近更新 更多