Я довольно новичок в OpenGL. Мне показалось, что я понимаю FBO, но мне трудно заставить их работать.
Моя программа использует базовую графическую информацию fbo (colorFbo) с несколькими выборками.
От colorFbo я блясь до постпроцесса Fbo.
Затем есть counterFbo с беззнаковыми значениями int, где я просто заполняю силуэт каждого объекта идентификатором объекта.
Я бы хотел постобработать 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);
}