Многослойная рендеринг куба карты за один проход - PullRequest
0 голосов
/ 16 декабря 2018

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

Здесь я инициализирую свою текстуру и fbo:

void init(void) {
    //Triangle test
    GLfloat data[] = {
            0, 0, 0,
            1, 0, 0,
            0, 1, 0
    };

    glGenVertexArrays(1, &_vaoTriangles);
    glBindVertexArray(_vaoTriangles);
    glEnableVertexAttribArray(0);
    glGenBuffers(1, &_vboPoints);
    glBindBuffer(GL_ARRAY_BUFFER, _vboTriangles);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
    glBindBuffer(GL_ARRAY_BUFFER ,0);
    glBindVertexArray(0);

    const GLfloat skybox[] = {
            // positions
            -1.0f,  1.0f, -1.0f,
            -1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            1.0f,  1.0f, -1.0f,
            -1.0f,  1.0f, -1.0f,

            -1.0f, -1.0f,  1.0f,
            -1.0f, -1.0f, -1.0f,
            -1.0f,  1.0f, -1.0f,
            -1.0f,  1.0f, -1.0f,
            -1.0f,  1.0f,  1.0f,
            -1.0f, -1.0f,  1.0f,

            1.0f, -1.0f, -1.0f,
            1.0f, -1.0f,  1.0f,
            1.0f,  1.0f,  1.0f,
            1.0f,  1.0f,  1.0f,
            1.0f,  1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,

            -1.0f, -1.0f,  1.0f,
            -1.0f,  1.0f,  1.0f,
            1.0f,  1.0f,  1.0f,
            1.0f,  1.0f,  1.0f,
            1.0f, -1.0f,  1.0f,
            -1.0f, -1.0f,  1.0f,

            -1.0f,  1.0f, -1.0f,
            1.0f,  1.0f, -1.0f,
            1.0f,  1.0f,  1.0f,
            1.0f,  1.0f,  1.0f,
            -1.0f,  1.0f,  1.0f,
            -1.0f,  1.0f, -1.0f,

            -1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f,  1.0f,
            1.0f, -1.0f, -1.0f,
            1.0f, -1.0f, -1.0f,
            -1.0f, -1.0f,  1.0f,
            1.0f, -1.0f,  1.0f
    };

    glGenVertexArrays(1, &_vao);
    glBindVertexArray(_vao);
    glEnableVertexAttribArray(0);
    glGenBuffers(1, &_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, _vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skybox), skybox, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
    glBindBuffer(GL_ARRAY_BUFFER ,0);
    glBindVertexArray(0);

    glGenTextures(1, &texture_cubemap);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture_cubemap);
    int face;
    for(face = 0; face < 6; face++)
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+face, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    glGenFramebuffers(1, &_fbo);
    glBindFramebuffer(1, _fbo);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_cubemap, 0);

//    glGenRenderbuffers(1, &_depthFbo);
//    glBindRenderbuffer(GL_RENDERBUFFER, _depthFbo);
//    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 256, 256);
//    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthFbo);

//    GLenum drawBuffers[1] = {GL_COLOR_ATTACHMENT0};
//    glDrawBuffers(1, drawBuffers);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

Вот рендер:

void render(void) {
    glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
    glViewport(0, 0, 256, 256);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.2, 0.2, 0.2, 0);
    glUseProgram(pIdTriangles);
    glBindVertexArray(_vaoTriangles);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
    glUseProgram(0);

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, width, height);
    glClearColor(0, 0, 0, 1.0);
    glUseProgram(pId);
//...Matrices stuff
    glBindVertexArray(_vao);
    gl4duSendMatrices();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture_cubemap);
    glUniform1i(glGetUniformLocation(pId, "skybox"), 0);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glUseProgram(0);

Мои шейдеры для скайбокса:

//Vertex shader
#version 330


layout(location=0) in vec3 positionSkybox;

uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
out vec3 UV;

void main() {
    vec4 pos = projectionMatrix * viewMatrix /* modelMatrix */* vec4(positionSkybox, 1);
    gl_Position = pos.xyww;
    UV = positionSkybox;
}

//Fragment shader
#version 330

//layout(location=0) in vec4 outColor;

out vec4 fragColor;
uniform samplerCube skybox;
in vec3 UV;

void main() {
    fragColor = texture(skybox, UV);
}

И шейдеры для модели:

//Vertex shader
#version 330

layout(location=0) in vec3 positionTriangles;

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;

void main() {
    gl_Position = /*projectionMatrix */ /*viewMatrix */ modelMatrix * vec4(positionTriangles, 1);
}

//Geometry shader
#version 330

layout(triangles) in;
layout(triangle_strip, max_vertices=18) out;

uniform mat4 projectionMatrix;

out vec4 colors;
void main() {
    int i, layer;
    for(layer = 0; layer < 6; ++layer){
        gl_Layer = layer;
        for(i = 0; i < gl_in.length(); i++){
            gl_Position = /*projectionMatrix */ gl_in[0].gl_Position;
            colors = vec4(0, 1, 0, 1);
            EmitVertex();
        }
    }
    EndPrimitive();
}

//Fragment shader 
#version 330

out vec4 fragColor;

in vec4 colors;
void main() {
    fragColor = colors;//vec4(1, 0, 0, 1);
}

Спасибо за помощь ...

РЕДАКТИРОВАТЬ: Мой скайбоксработает только в том случае, если:

    glBindFramebuffer(GL_FRAMEBUFFER, **0**);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, 256, 256);
    glClearColor(0.2, 0.2, 0.2, 0);
    glUseProgram(pIdTriangles);
    glBindVertexArray(_vaoTriangles);
//Draw the triangles

    glBindFramebuffer(GL_FRAMEBUFFER, **_fbo**);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, width, height);
    glClearColor(0, 1, 0, 1);
    glUseProgram(pId);
//Draw the skybox

Но это тот небесный луч, который должен отображаться в буфере кадров по умолчанию, я прав?

1 Ответ

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

Вы должны выполнить примитив для каждого слоя, переместиться EndPrimitive() в цикл, который перебирает слои.

Далее, в вашем коде 1-я вершина треугольника используется трираз, но 2-я и 3-я координаты пропущены.Измените gl_in[0].gl_Position на gl_in[i].gl_Position.

Чтобы отобразить разные стороны кубической карты, вам понадобится различная матрица представления для каждой стороны кубической карты.Вы должны «смотреть» в каждом направлении (вправо, влево, спереди, сзади, вверх и вниз).
Матрица проекции должна быть перспективной, с углом обзора 90 градусов и соотношением сторон:1.0: См. Также учебное пособие "OpenGL: однопроходное рендеринг на карту куба" , для получения более подробной информации.

например, usnig glm :: lookAt и glm::perspective

glm::mat4 cubeView[6] =
{ 
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 1.0f, 0.0f, 0.0f), glm::vec3(0.0f,-1.0f, 0.0f)), // +X
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f,-1.0f, 0.0f)), // -X
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)), // +Y
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f,-1.0f, 0.0f), glm::vec3(0.0f, 0.0f,-1.0f)), // -Y
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, 0.0f, 1.0f), glm::vec3(0.0f,-1.0f, 0.0f)), // +Z
    glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3( 0.0f, 0.0f,-1.0f), glm::vec3(0.0f,-1.0f, 0.0f)), // -Z
};

glm::mat4 cubeProj = glm::perspective(glm::radians(90.0f), 1.0f, near_plane, far_plane);
uniform mat4 cubeProjMatrix;
uniform mat4 cubeViewMatrix[6];

void main() {
    int i, layer;
    for(layer = 0; layer < 6; ++layer){
        gl_Layer = layer;
        for(i = 0; i < gl_in.length(); i++)
        {
            gl_Position = cubeProjMatrix * cubeViewMatrix[layer] * gl_in[i].gl_Position;
            colors = vec4(0, 1, 0, 1);
            EmitVertex();
        }
        EndPrimitive(); // <---- insert 
    }
    //EndPrimitive();   // <---- delete
}
...