java - Opengl - 后处理多个 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);
推荐阅读
- javascript - 首次加载时 .htaccess 未设置 Cookie
- java - 如何在 Quarkus Panache 的选择查询中使用 LocalTime
- java - Java TextToSpeech - 如何让我的文本听起来像一个问题?
- kotlin - 如何为以下回收器视图编写适配器类?
- javascript - 如何在模拟器中打开 react-native 应用程序?
- python - 在 Python 模式下使用处理 PGraphics?
- java - 未找到注释处理器“org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor”
- html - 垂直对齐单选按钮
- python - 用 Python 合并多个 csv 文件
- android - 在 Flutter 中使用 Navigator.push() 时出现黑屏