Opengl - постобработка нескольких FBO - что я делаю не так? - PullRequest
0 голосов
/ 05 июля 2018

Я довольно новичок в 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);
}

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Проблема была в самой программе счетчика (в glVertexAttribPointer), о которой я не писал. Мне нужна была только позиция в программе счетчика, поэтому я написал это:

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

Но я забыл, что данные всегда находятся в одной и той же позиции, поэтому я не могу "сэкономить место", потому что я только привязываю, данные вершин остаются прежними:

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

Спасибо за ответы, и извините, я не показывал больше кода, я думал, что проблема может быть где угодно, и не хотел подавлять любого, кто читает слишком много кода.

0 голосов
/ 05 июля 2018

Кажется, вам не хватает назначения текстурного блока на имя текстуры. Поэтому, когда я загружаю текстуры, я обычно делаю это при инициализации ...

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