1

I am trying to make a dynamic cubemap with geometry shader and gl_Layer where each face have is own texture but it doesn't work like expected. Or I have a black cubemap with nothing or I have nothing...

this is where I initialize my texture and 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);

Here the render :

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

My shaders for the skybox:

//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);
}

And shaders for the model :

//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);
}

Thanks for the help ...

EDIT : My skybox works only if :

    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

But it's the skybow that must render on the default framebuffer, am I right ?

Bomu
  • 11
  • 4
  • Sorry It was pIdTriangles ... pIdTriangles is the pId where I draw my triangles and have the vertex, geometry, and fragment shaders. And pId is the skybox. – Bomu Dec 16 '18 at 19:32

1 Answers1

1

You have to complete a primitive per layer, move EndPrimitive() in the loop which iterates the layers.

Further, in your code the 1st vertex of the triangle is used three times, but the 2nd and 3rd coordinate are missed. Change gl_in[0].gl_Position to gl_in[i].gl_Position.

To render the different sides of the cubemap you'll need a different view matrix for each side of the cubemap. You have to "look" in each direction (right, left, front, back, up and down).
The projection matrix has to be a perspective projection, with a filed of view angle of 90 degrees and an aspect ratio of 1.0: See also the tutorial "OpenGL: One-pass rendering to a cube map", for more a detailed information.

e.g. by usnig glm::lookAt and 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
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thank you for you answer. I did what you say but nothing changed. My screen is full grey from the glClearColor in the framebuffer and that's all... – Bomu Dec 16 '18 at 16:36
  • EDIT : I had GL_DEPTH_TEST and GL_CULL_FACE enable but when I commented I obtained a black cube ... Why ... ? – Bomu Dec 16 '18 at 16:53
  • Ok, but nothing changed too, and in a desperate act, I switched the fbo id (bind fbo for the skybox and 0 for triange) and I obtained the green from the geometry shader but without triangles. – Bomu Dec 16 '18 at 17:05
  • I have a triangle but only if I set him a view and model matrices. And It's not on each face of the cube ... I think I did something weird. EDIT : do I have to leave the bindFramebuffer to bind to the fbo for the skybox et the models to 0 ? If not I still get a black cube... I really don't understand why – Bomu Dec 16 '18 at 17:24
  • Thank you very much, I will try it ... But last question, The skybox I have to bind it to 0 in the framebuffer, right ? Because the few tutorials I saw it's on 0 and in my case if I bind it to 0 I have only a black cube... – Bomu Dec 16 '18 at 18:24
  • I'm sorry, it was not what I meant. I meant : for the skybox I have to do : `glBindFramebuffer(GL_FRAMEBUFFER, _fbo);` and for the triangles : ` glBindFramebuffer(GL_FRAMEBUFFER, 0);` it's not supposed to be reversed ? If yes, why in my case it's like this that it work ? – Bomu Dec 16 '18 at 18:35
  • Yes, I agree, but it's not supposed to be the skybox that we render to the default frame buffer instead the objects that we draw on each face ? – Bomu Dec 16 '18 at 18:40
  • Sorry for my poor english x), please see my edit I hope you will understand what I am saying – Bomu Dec 16 '18 at 19:04
  • @Bomu Do you use a perspective projection in the geometry shader? Slight change the z coordinates of the triangle, so that it is not clipped by the near plane of the perspective projection. – Rabbid76 Dec 16 '18 at 19:38
  • Yes, i tried it but i have nothing... I know that I messed up somewhere but I don't know I'm going to cry x) – Bomu Dec 16 '18 at 20:09