java - Opengl - 后处理多个 FBO - 我做错了什么?

标签 java opengl graphics lwjgl fbo

我对 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);
}

最佳答案

您似乎缺少将纹理单元分配给纹理名称。因此,当我加载纹理时,我通常在初始化中执行此操作...

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);

关于java - Opengl - 后处理多个 FBO - 我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51198631/

相关文章:

java - 无法在 Qpid 配置中加载 KeyStore 文件

opengl - 把四边形变成长方形?

java - PaintComponent 从未被调用

java - Libgdx Gwt 使用补间引擎编译错误

java - 迭代映射并将其值放入 java 中

java - Android Studio 显示错误加载 : id=gralloc ! = hmi->id=gralloc

c++ - 我应该缓存 OpenGL 状态,例如当前绑定(bind)的缓冲区,还是 OpenGL 会这样做?

opengl - 使用像素缓冲区对象将纹理从 GPU 复制到 CPU

java - 在 Java 中旋转 BufferedImage

java图形库