GL_DEPTH_TEST вызывает мерцание - PullRequest
0 голосов
/ 19 декабря 2018

У меня странная проблема в OpenGL.Сначала немного предыстории: в моей программе я реализую эффект цветения, используя две текстуры с полным набором мипмапов.Каждый уровень mipmap привязан к FBO, так что я могу выполнить гауссово размытие из двух частей на каждом уровне, прежде чем объединять их, чтобы создать цветение.Эта часть работает хорошо, и я мог визуализировать красивый вращающийся светящийся объект.

Проблема началась, когда я попытался выполнить тестирование глубины.

Я добавил карту глубины в FBO, соответствующиеуровень 0 каждой текстуры.Затем я включил GL_DEPTH_TEST.Как только я включил GL_DEPTH_TEST, экран начал мерцать, и объект больше не вращался.

Я сократил код до его самого простого, и, кажется, это происходит, только когда я рендеринг в FBO с GL_DEPTH_TESTвключен.Проблема не произойдет, если я выполню рендеринг в кадровый буфер по умолчанию с включенным GL_DEPTH_TEST.Проблема не произойдет, если я выполню рендеринг в FBO с отключенным GL_DEPTH_TEST.

Приведенный ниже код является упрощенной версией моего кода, просто чтобы проиллюстрировать последовательность вызовов OpenGL, которая, кажется, воссоздает эту проблему.Пожалуйста

Правильно ли я добавляю буфер глубины в FBO?

// Create a set of framebuffers, one for each mipmap level of a texture.
void FrameBuffer::Initialise(int xs, int ys)
{    
    xSizeTexture = PowerOfTwoAboveOrEqualTo(xs);
    ySizeTexture = PowerOfTwoAboveOrEqualTo(ys);
    numLevels = Log2(max(xSizeTexture, ySizeTexture));

    // Generate one FB for each texture level
    glGenFramebuffers(numLevels, frameBufferID);

    glGenTextures(1, &textureID);
    glBindTexture(  GL_TEXTURE_2D, textureID);
    glTexImage2D(   GL_TEXTURE_2D, 0, GL_RGB, xSizeTexture, ySizeTexture, 0, GL_RGB, GL_BYTE, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, numLevels-1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
    glGenerateMipmap(GL_TEXTURE_2D);

    // Bind each texture level to one FB
    for (int i = 0; i < numLevels; i++)
    {
        glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[i]);
        glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, textureID, i);
    }

    attachment = GL_COLOR_ATTACHMENT0;
    glDrawBuffers(1, &attachment);

    // Add a depth buffer to the top FB
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[0]);
    glGenRenderbuffers(1, &depthrenderbufferID);
    glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbufferID);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, xSizeTexture, ySizeTexture);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbufferID);


    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        cout << "Failed to create frame buffer" << endl;
    else
        cout << "Created buffer OK" << endl;

    // Also initialise vertex array VAO
    // ...
}

void FrameBuffer::Use()
{
    glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID[0]);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void FrameBuffer::CopyToMain()
{
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, textureID);

    glViewport(0, 0, 1024, 1024);
    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glBindVertexArray(0);
}

void MainClass::Initialise()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    framebuffer.Initialise(1024, 1024);
}

void MainClass::Render()
{
    if (!initialised)
    {
        Initialise();
        initialised = true;
    }

    framebuffer.Use();
    glViewport(0, 0, 1024, 1024);
    glUseProgram(0);
    glEnable(GL_DEPTH_TEST);        // Causes problems
    //glDisable(GL_DEPTH_TEST);     // Works fine

    t += 0.05;
    glLoadIdentity();
    glRotatef(sin(t) * 10, 0, 0, 1);
    glLineWidth(2.0);

    glBegin(GL_LINE_LOOP);
        glColor3f(1.0, 0.1, 0.1); glVertex3f(-0.5, -0.5, 0.0);
        glColor3f(0.1, 1.0, 0.1); glVertex3f( 0.5, -0.5, 0.0);
        glColor3f(0.1, 0.1, 1.0); glVertex3f( 0.5,  0.5, 0.0);
        glColor3f(0.1, 0.1, 0.1); glVertex3f(-0.5,  0.5, 0.0);
    glEnd();

    framebuffer.CopyToMain();
}

Я не получаю ошибок, о которых сообщает glGetError ().

Пожалуйста, простите за слегка псевдокодприрода кода C ++.Он просто предназначен для иллюстрации последовательности вызовов OpenGL.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Вы забыли включить:

glDepthFunc(GL_LEQUAL);
0 голосов
/ 19 декабря 2018

Вы пробовали отладочные функции opengl?

Здесь вы связываете указатель (имя массива), а не имя gl, должен быть frameBufferID [0], я полагаю.

glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
...