I was trying to implement normal mapping on a simple cube but since i had troubles with my normals i wanted to try to display them using a geometry shader. Following learnopengl tutorial, it basically calls mesh.render() twice, the first time to draw the model and the second time to display normals. When i try to do the same i get this
The cube seems well drawn but it has a weird white rectangle in front of it and i don't know why. I don't know if it's a problem of drawings or if it's the geometry shader, so i'll post both.
My code:
glutDisplayFunc(MyRenderScene);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glGenVertexArrays(1,&global.gVAO);
glGenBuffers(1, &global.VBO);
glBindVertexArray(global.VAO);
glBindBuffer(GL_ARRAY_BUFFER, global.VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &global.IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, global.IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glGenVertexArrays(1,&global.gVAO);
glGenBuffers(1, &global.gVBO);
glBindVertexArray(global.gVAO);
glBindBuffer(GL_ARRAY_BUFFER, global.gVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &global.gIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, global.gIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
Here i'm basically passing the same structure to both buffers. Buffers are istantiated in a global struct.
This is MyRenderScene() :
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
global.shaders.enable(); // glUseProgram
global.shaders.set_sampler(0); // setting textures
global.shaders.set_sampler(1);
global.sceneT.set_camera(
global.camera.position(),
global.camera.lookat(),
global.camera.up()
);
glm::mat4 model = glm::mat4(1.0f);
glm::vec3 vaxis = glm::vec3(0.0,1.0,0.0);
glm::vec3 haxis = glm::vec3(1.0,0.0,0.0);
model = glm::rotate(model,glm::radians(global.gradX),haxis);
model = glm::rotate(model,glm::radians(global.gradY),vaxis);
glm::mat4 projection = glm::perspective(glm::radians(40.0f), (float)global.WINDOW_WIDTH/(float)global.WINDOW_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = glm::lookAt(global.camera.position(),global.camera.lookat()+ global.camera.position(),global.camera.up());
global.shaders.set_model(model);
global.shaders.set_view(view);
global.shaders.set_projection(projection);
global.shaders.set_viewPos(global.camera.position());
global.shaders.set_lightPos(lightPos);
global.shaders.update_uniforms();
glBindVertexArray(global.VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, position)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, textcoord)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, normal)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, tangent)));
glBindBuffer(GL_ARRAY_BUFFER, global.VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, global.IBO);
global.brickwall.Bind(GL_TEXTURE0+0); // binding textures
global.brickwall_normals.Bind(GL_TEXTURE0+1);
glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
global.geometryShader.enable(); // setting up geometry shader
global.geometryShader.set_projection(projection);
global.geometryShader.set_model(model);
global.geometryShader.set_view(view);
global.geometryShader.update_uniforms();
glBindVertexArray(global.gVAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, position)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, textcoord)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, normal)));
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<GLvoid*>(offsetof(struct Vertex, tangent)));
glBindBuffer(GL_ARRAY_BUFFER, global.gVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, global.gIBO);
glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_INT,0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glutSwapBuffers();
glutPostRedisplay();***
I even tried calling the same vertexArrays and vertexArrayBuffer but i get the same result. Here are vertex shader:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 textcoord;
layout (location = 2) in vec3 normal;
layout (location = 3) in vec3 tangent;
out VS_OUT {
vec3 newNormal;
} vs_out;
uniform mat4 view;
uniform mat4 model;
void main() {
mat3 normalMatrix = mat3(transpose(inverse(view * model)));
newNormal = vec3(vec4(normalMatrix * normal, 0.0));
gl_Position = view * model * vec4(position, 1.0);
}
And geometryShader:
#version 330 core
layout (triangles) in;
layout (line_strip, max_vertices = 6) out;
in VS_OUT {
vec3 newNormal;
} gs_in[];
const float MAGNITUDE = 0.2;
uniform mat4 projection;
void GenerateLine(int index) {
gl_Position = projection * gl_in[index].gl_Position;
EmitVertex();
gl_Position = projection * (gl_in[index].gl_Position + vec4(gs_in[index].newNormal,0.0) * MAGNITUDE);
EmitVertex();
EndPrimitive();
}
void main() {
GenerateLine(0); // first vertex normal
GenerateLine(1); // second vertex normal
GenerateLine(2); // third vertex normal
}
Feel free to correct me on everything possible and imaginable.
The reason for the issue is, that the shader program with the geometry shader fails to compile or link. Hence the geometry is drawn by the default shader program instead of the program with the geometry shader.
There is (at least) one error in the vertex shader:
newNormal = vec3(vec4(normalMatrix * normal, 0.0));