Визуализация OpenGL в кубическую карту с использованием DSA (прямой доступ к состоянию) - PullRequest
2 голосов
/ 14 марта 2019

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

Я понял идею простой 2D-текстуры для рендеринга за пределами экрана.

Вот как я это делаю. Я вставляю только минимальный и эффективный код.

// 1. Initialization code
{
    // FBO (Frame Buffer Object)
    GLuint FBO;
    glCreateFramebuffers(1, &FBO);

    // Texture2D for color buffer
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_2D, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_RGB8, 1024, 1024);

        glNamedFramebufferTexture(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0);
    }

    // RBO (Render Buffer Object) for depth buffer.
    {
        GLuint depthBuffer;
        glCreateRenderbuffers(1, &depthBuffer);
        glNamedRenderbufferStorage(depthBuffer, GL_DEPTH_COMPONENT24, 1024, 1024);

        glNamedFramebufferRenderbuffer(FBO, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
    }

    if ( glCheckNamedFramebufferStatus(m_identifier, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
        exit(1);
}





// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
    glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

    // Draw stuffs ...

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

Итак, для рендеринга в кубическую карту моя идея состоит в том, чтобы заменить "GL_TEXTURE_2D" на "GL_TEXTURE_CUBEMAP". Я знаю, что мне нужно продолжать использовать glTextureStorage2D () для создания хранилища.

Тогда я не знаю, будет ли RBO обрабатывать рендеринг кубической карты ... Я думаю использовать его повторно для каждого лица.

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

Один из моих первых подсказок - использовать "glNamedFramebufferDrawBuffer (FBO, GL_COLOR_ATTACHMENT0 + face)", но это не работает.

Я видел другое решение при создании буфера кадров с помощью glNamedFramebufferTextureLayer (), но я не уверен, правильно ли это.

Я искал решение в Интернете, но я нашел много способов сделать это, некоторые не совместимы с DSA.

Есть ли кто-то, кто достигнет этого? Мне просто нужна основная идея.

1 Ответ

1 голос
/ 14 марта 2019

У вас есть два варианта:

Несколько проходов с рендерингом буфера

Вы не можете создать буфер рендеринга карты куба. Таким образом, если вы используете рендер-буферы для буфера глубины, то вам нужно сделать шесть проходов рендеринга, по одному для каждого лица. Чтобы по очереди прикрепить каждую грань текстуры к цветному буферу, вы используете glNamedFramebufferTextureLayer:

// 1. Initialization code
    // ...
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_SRGB8_ALPHA8, 1024, 1024);
    }

// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    for(int cube_map_face = 0; cube_map_face < 6; ++cube_map_face)
    {
        glNamedFramebufferTextureLayer(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0, cube_map_face);
        glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
        glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

        // Draw cub_map_face
    }
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

Один проход с геометрическим шейдером

В качестве альтернативы вы можете использовать карту кубов текстуры глубины с геометрическим шейдером для отправки примитивов на каждую из (соответствующих) граней.

// 1. Initialization code
{
    // FBO (Frame Buffer Object)
    GLuint FBO;
    glCreateFramebuffers(1, &FBO);

    // Texture for color buffer
    {
        GLuint colorBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &colorBuffer);
        glTextureStorage2D(colorBuffer, 1, GL_SRGB8_ALPHA8, 1024, 1024);
        glNamedFramebufferTexture(FBO, GL_COLOR_ATTACHMENT0, colorBuffer, 0);
    }

    // Texture for depth buffer.
    {
        GLuint depthBuffer;
        glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &depthBuffer);
        glTextureStorage2D(depthBuffer, 1, GL_DEPTH24_STENCIL8, 1024, 1024);
        glNamedFramebufferTexture(FBO, GL_DEPTH_ATTACHMENT, depthBuffer, 0);
    }

    if ( glCheckNamedFramebufferStatus(m_identifier, GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
        exit(1);
}  

// 2. Drawing code
{
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);

    glClearNamedFramebufferfv(FBO, GL_COLOR, 0, m_clearColor.data());
    glClearNamedFramebufferfv(FBO, GL_DEPTH, 0, &m_clearDepth);

    // Draw stuffs ... (one pass)

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...