Reputation: 93
I'm writing a OpenGL 3.3 program which displays some primitives. The lighting is simple, just diffuse and ambient.
Cube vertex shader.
#version 440 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 a_normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 normal;
out vec3 fragpos;
void main(void)
{
fragpos = vec3(model * vec4(position, 1.0));
gl_Position = projection * view * vec4(fragpos, 1.0);
normal = a_normal;
}
Cube fragment shader.
#version 440 core
out vec4 frag_color;
in vec3 normal;
in vec3 fragpos;
uniform vec4 color;
struct light_source
{
vec3 position;
vec3 color;
bool enable;
};
uniform light_source light0;
vec3 calc_diffuse_light(vec3 light_position, vec3 light_color)
{
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * light_color;
// diffuse
vec3 norm = normalize(normal);
vec3 light_dir = normalize(light_position - fragpos);
float diff = max(dot(norm, light_dir), 0.0);
vec3 diffuse = diff * light_color;
return (ambient + diffuse) * color.xyz;
}
void main(void)
{
vec3 result = vec3(0.0);
if (light0.enable)
result += calc_diffuse_light(light0.position, light0.color);
frag_color = vec4(result, 1.0);
}
Cube setup.
#include "gl_cube_model.h"
#include "gl_lights.h"
cube_model::cube_model(float size, const glm::vec3& position, const glm::vec4& color) :
model_base(position),
m_color(color)
{
float halfwidth = size / 2.0f;
float vertices[] =
{
// Three position components + normals.
// front face
-halfwidth, -halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front bottom left
-halfwidth, halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front top left
halfwidth, halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front top right
halfwidth, -halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front bottom right
-halfwidth, -halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front bottom left
halfwidth, halfwidth, halfwidth, 0.0f, 0.0f, 1.0f, // front top right
// back face
-halfwidth, -halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back bottom left
-halfwidth, halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back top left
halfwidth, halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back top right
halfwidth, -halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back bottom right
-halfwidth, -halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back bottom left
halfwidth, halfwidth, -halfwidth, 0.0f, 0.0f, -1.0f, // back top right
// left face
-halfwidth, -halfwidth, -halfwidth, -1.0f, 0.0f, 0.0f, // back bottom left
-halfwidth, halfwidth, -halfwidth, -1.0f, 0.0f, 0.0f, // back top left
-halfwidth, halfwidth, halfwidth, -1.0f, 0.0f, 0.0f, // front top left
-halfwidth, -halfwidth, halfwidth, -1.0f, 0.0f, 0.0f, // front bottom left
-halfwidth, -halfwidth, -halfwidth, -1.0f, 0.0f, 0.0f, // back bottom left
-halfwidth, halfwidth, halfwidth, -1.0f, 0.0f, 0.0f, // front top left
// right face
halfwidth, -halfwidth, halfwidth, 1.0f, 0.0f, 0.0f, // front bottom right
halfwidth, halfwidth, halfwidth, 1.0f, 0.0f, 0.0f, // front top right
halfwidth, halfwidth, -halfwidth, 1.0f, 0.0f, 0.0f, // back top right
halfwidth, -halfwidth, -halfwidth, 1.0f, 0.0f, 0.0f, // back bottom right
halfwidth, -halfwidth, halfwidth, 1.0f, 0.0f, 0.0f, // front bottom right
halfwidth, halfwidth, -halfwidth, 1.0f, 0.0f, 0.0f, // back top right
// top face
-halfwidth, halfwidth, halfwidth, 0.0f, 1.0f, 0.0f, // front top left
-halfwidth, halfwidth, -halfwidth, 0.0f, 1.0f, 0.0f, // back top left
halfwidth, halfwidth, -halfwidth, 0.0f, 1.0f, 0.0f, // back top right
halfwidth, halfwidth, halfwidth, 0.0f, 1.0f, 0.0f, // front top right
-halfwidth, halfwidth, halfwidth, 0.0f, 1.0f, 0.0f, // front top left
halfwidth, halfwidth, -halfwidth, 0.0f, 1.0f, 0.0f, // back top right
// bottom face
-halfwidth, -halfwidth, halfwidth, 0.0f, -1.0f, 0.0f, // front bottom left
-halfwidth, -halfwidth, -halfwidth, 0.0f, -1.0f, 0.0f, // back bottom left
halfwidth, -halfwidth, -halfwidth, 0.0f, -1.0f, 0.0f, // back bottom right
halfwidth, -halfwidth, halfwidth, 0.0f, -1.0f, 0.0f, // front bottom right
-halfwidth, -halfwidth, halfwidth, 0.0f, -1.0f, 0.0f, // front bottom left
halfwidth, -halfwidth, -halfwidth, 0.0f, -1.0f, 0.0f, // back bottom right
};
glDisable(GL_CULL_FACE);
// Generate VAO.
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
// Generate VBO.
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Vertex position attribute.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)0);
glEnableVertexAttribArray(0);
// Vertex normal attribute.
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
string vert_source;
if (!read_file_text(SHADER_DIR + "pos_norm.vert", vert_source))
throw runtime_error("error loading vert shader");
string frag_source;
if (!read_file_text(SHADER_DIR + "flat_shade_light.frag", frag_source))
throw runtime_error("error loading frag shader");
m_sha.init_from_str(vert_source, frag_source);
}
cube_model::~cube_model()
{
glDeleteVertexArrays(1, &m_vao);
glDeleteBuffers(1, &m_vbo);
}
void cube_model::render(const glm::mat4& projection, const glm::mat4& view, const std::shared_ptr<gl_lights>& lights)
{
m_sha.use();
glBindVertexArray(m_vao);
glUniformMatrix4fv(m_sha.get_uniform("model"), 1, GL_FALSE, glm::value_ptr(m_model));
glUniformMatrix4fv(m_sha.get_uniform("view"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(m_sha.get_uniform("projection"), 1, GL_FALSE, glm::value_ptr(projection));
glUniform4fv(m_sha.get_uniform("color"), 1, glm::value_ptr(m_color));
glUniform3fv(m_sha.get_uniform("light0.position"), 1, glm::value_ptr(lights->position(0)));
glUniform3fv(m_sha.get_uniform("light0.color"), 1, glm::value_ptr(lights->color(0)));
int enabled = (lights->is_enabled(0) ? 1 : 0);
glUniform1iv(m_sha.get_uniform("light0.enable"), 1, &enabled);
glDrawArrays(GL_TRIANGLES, 0, 6 * 6);
glFinish();
}
Note glDisable(GL_CULL_FACE);
in there. It seems like the back and front face culling is not to blame for this, and in the code that calls cube_model::render, the depth buffer is cleared so I can't blame depth buffering either.
Upvotes: 0
Views: 520
Reputation: 26
You need to use Depth Testing. just call
glEnable(GL_DEPTH_TEST)
before your loop starts.
Then you need to clear the depth buffer every frame otherwise it would be using the same depth buffer every time it renders even if the scene changed. Use this inside the main loop:
glClear(GL_DEPTH_BUFFER_BIT);
Upvotes: 0
Reputation: 210878
You missed to enable the Depth Test.
glEnable(GL_DEPTH_TEST)
Once the depth test is enabled, you have to clear the depth buffer, too:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Upvotes: 1