Reputation: 11
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 ?
Upvotes: 1
Views: 1303
Reputation: 210889
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
}
Upvotes: 2