feat: directional lighting

This commit is contained in:
Cat Flynn 2023-08-03 10:26:01 +02:00 committed by ktyl
parent abb990b9d4
commit 20658ba15a
4 changed files with 90 additions and 27 deletions

View File

@ -1,15 +1,29 @@
#version 330 core
in vec3 Normal;
in vec3 FragPos;
out vec4 FragColor;
void main()
{
vec3 objectColor = vec3(1.0, 0.5, 0.2);
vec3 lightColor = vec3(1.0, 1.0, 1.0);
vec3 result;
// Ambient lighting
vec3 ambientLightColor = vec3(1.0, 1.0, 1.0);
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * ambientLightColor;
vec3 ambient = ambientStrength * lightColor;
vec3 result = ambient * objectColor;
// Directional lighting
vec3 directionalLightColor = vec3(1.0, 1.0, 1.0);
vec3 lightPos = vec3(10.0, 7.0, -8.0);
vec3 normal = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(normal, lightDir), 0.0);
vec3 diffuse = diff * directionalLightColor;
FragColor = vec4(ambient, 1.0);
result = (ambient + diffuse) * objectColor;
FragColor = vec4(result, 1.0);
}

View File

@ -60,6 +60,9 @@ int initGraphics(GLFWwindow** window)
std::cerr << "Failed to initialize GLFW" << std::endl;
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
*window = glfwCreateWindow(640, 480, "Hello Astro", NULL, NULL);
if (!window)
@ -93,22 +96,37 @@ GLint getShaderUniformLocation(GLuint shaderProgram, const std::string& uniformN
return location;
}
void updateModelViewProjectionMatrix(GLuint shaderProgram, float time)
void updateProjectionMatrix(GLuint shaderProgram)
{
// Calculate matrices
float left = -1.0, right = 1.0, bottom = -1.0, top = 1.0, near = -1.0, far = 1.0;
glm::mat4 projection = glm::ortho(left, right, bottom, top, near, far);
GLint projectionLocation = getShaderUniformLocation(shaderProgram, "_Projection");
glUniformMatrix4fv(projectionLocation, 1, GL_FALSE, &projection[0][0]);
}
void updateModelMatrix(GLuint shaderProgram, float time)
{
constexpr float angle = glm::radians(10.0);
glm::vec3 axis = glm::vec3(0.0, 1.0, 0.0);
glm::mat4 model = glm::rotate(glm::mat4(1.0), angle * time, axis);
GLint modelLocation = getShaderUniformLocation(shaderProgram, "_Model");
glUniformMatrix4fv(modelLocation, 1, GL_FALSE, &model[0][0]);
}
void updateViewMatrix(GLuint shaderProgram)
{
glm::mat4 view = glm::mat4(1.0);
GLint viewLocation = getShaderUniformLocation(shaderProgram, "_View");
glUniformMatrix4fv(viewLocation, 1, GL_FALSE, &view[0][0]);
}
glm::mat4 mvp = projection * model * view;
GLint mvpLocation = getShaderUniformLocation(shaderProgram, "_ModelViewProjectionMatrix");
glUniformMatrix4fv(mvpLocation, 1, GL_FALSE, &mvp[0][0]);
void updateModelViewProjectionMatrix(GLuint shaderProgram, float time)
{
// Calculate matrices
updateProjectionMatrix(shaderProgram);
updateModelMatrix(shaderProgram, time);
updateViewMatrix(shaderProgram);
}
int main()

View File

@ -22,28 +22,43 @@ Icosphere::Icosphere(int subdivisions)
glBindVertexArray(_vao);
for (const auto& v : vertices)
{
_vertices.push_back(v[0]);
_vertices.push_back(v[1]);
_vertices.push_back(v[2]);
}
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
size_t vboBufferSize = _vertices.size() * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, vboBufferSize, &_vertices[0], GL_STATIC_DRAW);
for (const auto& tri : triangles)
{
_indices.push_back(tri.vertex[0]);
_indices.push_back(tri.vertex[1]);
_indices.push_back(tri.vertex[2]);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
size_t egoBufferSize = _indices.size() * sizeof(unsigned int);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, egoBufferSize, &_indices[0], GL_STATIC_DRAW);
for (const auto& v : vertices)
{
// Vertex Data
_vertices.push_back(v[0]);
_vertices.push_back(v[1]);
_vertices.push_back(v[2]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
// Normal data
// The normal at each vertex is actually going to just be the vertex again, but
// normalised, because this is a sphere.
glm::vec3 normal = normalize(v);
_vertices.push_back(normal[0]);
_vertices.push_back(normal[1]);
_vertices.push_back(normal[2]);
}
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
size_t vboBufferSize = _vertices.size() * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, vboBufferSize, &_vertices[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo);
size_t eboBufferSize = _indices.size() * sizeof(unsigned int);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, eboBufferSize, &_indices[0], GL_STATIC_DRAW);
// Vertex position attribute
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
// Vertex normal attribute
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
@ -116,4 +131,5 @@ Icosphere::~Icosphere()
{
glDeleteVertexArrays(1, &_vao);
glDeleteBuffers(1, &_vbo);
glDeleteBuffers(1, &_ebo);
}

View File

@ -1,12 +1,27 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
uniform mat4x4 _ModelViewProjectionMatrix;
uniform mat4x4 _Model;
uniform mat4x4 _View;
uniform mat4x4 _Projection;
out vec3 Normal;
out vec3 FragPos;
void main()
{
vec4 pos = vec4(aPos.x, aPos.y, aPos.z, 1.0);
gl_Position = _ModelViewProjectionMatrix * pos;
}
vec4 pos = vec4(aPos, 1.0);
mat4x4 mvp = _Projection * _Model * _View;
gl_Position = mvp * pos;
FragPos = vec3(_Model * pos);
// Convert the normal from model to world space
mat3 normalMatrix = mat3(mvp);
normalMatrix = inverse(normalMatrix);
normalMatrix = transpose(normalMatrix);
Normal = normalize(normalMatrix * aNormal);
//Normal = normalize(_Model * aNormal);
}