From 25a54bab1b45a12d9dd9bb954135cb133ffdf664 Mon Sep 17 00:00:00 2001 From: acetheking987 Date: Thu, 27 Nov 2025 11:37:56 +0000 Subject: [PATCH] basic lighting --- inc/engine/shaders.hpp | 1 + shaders/triangle.frag | 33 ++++++++++++++++--- shaders/triangle.vert | 10 +++--- shaders/triangle_light_source.frag | 7 ++++ src/engine/shaders.cpp | 4 +++ src/main.cpp | 52 ++++++++++++++++++++++++------ 6 files changed, 88 insertions(+), 19 deletions(-) create mode 100644 shaders/triangle_light_source.frag diff --git a/inc/engine/shaders.hpp b/inc/engine/shaders.hpp index ef989d5..a807994 100644 --- a/inc/engine/shaders.hpp +++ b/inc/engine/shaders.hpp @@ -17,6 +17,7 @@ public: void setInt(const std::string &name, int value) const; void setFloat(const std::string &name, float value) const; void setMat4(const std::string &name, const glm::mat4 &mat) const; + void setVec3(const std::string &name, const glm::vec3 &vec) const; ~Shader(); private: const char* read_file(const char* filePath); diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 85efae4..4d990b5 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -1,11 +1,34 @@ #version 330 core - out vec4 FragColor; -in vec3 Color; // Input color from the vertex shader -in vec2 TexCoord; // Input texture coordinate from the vertex shader +in vec3 FragPos; +in vec3 Normal; +in vec2 TexCoord; +uniform vec3 objectColor; +uniform vec3 lightColor; +uniform vec3 lightPos; +uniform vec3 viewPos; uniform sampler2D Texture1; -void main() { - FragColor = texture(Texture1, TexCoord); +void main() +{ + // ambient + float ambientStrength = 0.1; + vec3 ambient = ambientStrength * lightColor; + + // diffuse + vec3 norm = normalize(Normal); + vec3 lightDir = normalize(lightPos - FragPos); + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = diff * lightColor; + + // specular + float specularStrength = 0.5; + vec3 viewDir = normalize(viewPos - FragPos); + vec3 reflectDir = normalize(reflect(-lightDir, norm)); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0); + vec3 specular = specularStrength * spec * lightColor; + + vec3 result = (ambient + diffuse + specular) * texture(Texture1, TexCoord).rgb; + FragColor = vec4(result, 1.0); } \ No newline at end of file diff --git a/shaders/triangle.vert b/shaders/triangle.vert index 7eba2d3..b1d809f 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -3,8 +3,9 @@ layout(location = 0) in vec3 position; // Vertex position layout(location = 1) in vec3 normal; // Vertex normal layout(location = 2) in vec2 texCoord; // Vertex texture coordinate -out vec3 Color; // Output color to the fragment shader -out vec2 TexCoord; // Output texture coordinate to the fragment shader +out vec3 Normal; +out vec3 FragPos; +out vec2 TexCoord; uniform mat4 model; uniform mat4 view; @@ -12,6 +13,7 @@ uniform mat4 projection; void main() { gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices - Color = normal * 0.5 + 0.5; // Simple coloring based on normal - TexCoord = texCoord; // Pass through the texture coordinate + FragPos = vec3(model * vec4(position, 1.0)); + Normal = mat3(transpose(inverse(model))) * normal; + TexCoord = texCoord; } \ No newline at end of file diff --git a/shaders/triangle_light_source.frag b/shaders/triangle_light_source.frag new file mode 100644 index 0000000..1c649f4 --- /dev/null +++ b/shaders/triangle_light_source.frag @@ -0,0 +1,7 @@ +#version 330 core +out vec4 FragColor; + +void main() +{ + FragColor = vec4(1.0); // set all 4 vector values to 1.0 +} \ No newline at end of file diff --git a/src/engine/shaders.cpp b/src/engine/shaders.cpp index 0fb0765..f040853 100644 --- a/src/engine/shaders.cpp +++ b/src/engine/shaders.cpp @@ -92,6 +92,10 @@ void Shader::setMat4(const std::string &name, const glm::mat4 &mat) const { glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]); } +void Shader::setVec3(const std::string &name, const glm::vec3 &vec) const { + glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &vec[0]); +} + Shader::~Shader() { if (ID != 0) { glDeleteProgram(ID); diff --git a/src/main.cpp b/src/main.cpp index 63d3eaf..6eb123c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#define GL_GLEXT_PROTOTYPES #include "engine/sdl.hpp" #include "engine/opengl.hpp" #include "engine/obj_loader.hpp" @@ -10,7 +11,7 @@ int main(int argc, char* argv[]) { glEnable(GL_DEPTH_TEST); Camera camera( - glm::vec3(3.0f, 4.0f, 6.0f), // Position + glm::vec3(5.0f, 2.0f, 4.0f), // Position glm::vec3(0.0f, 1.0f, 0.0f), // Target glm::vec3(0.0f, 1.0f, 0.0f) // Up vector ); @@ -22,17 +23,24 @@ int main(int argc, char* argv[]) { 100.0f // Far Plane ); - Shader shader_program("shaders/triangle.vert", "shaders/triangle.frag"); + Shader cubeShader("shaders/triangle.vert", "shaders/triangle.frag"); + Shader lightShader("shaders/triangle.vert", "shaders/triangle_light_source.frag"); - OBJLoader objLoader("assets/models/Sci-fi_Container_Game.obj"); - if (!objLoader.isLoaded()) { + OBJLoader mainObj("assets/models/Sci-fi_Container_Game.obj"); + if (!mainObj.isLoaded()) { + SDL_Log("Failed to load OBJ model."); + return -1; + } + + OBJLoader lightObj("assets/models/cube.obj"); + if (!lightObj.isLoaded()) { SDL_Log("Failed to load OBJ model."); return -1; } VertexArrayObject VAO; - VAO.bufferVertexData(objLoader.getVertexData(), objLoader.getVertexCount() * sizeof(float) * 8); - VAO.bufferElementData(objLoader.getIndexData(), objLoader.getIndexCount() * sizeof(unsigned int)); + VAO.bufferVertexData(mainObj.getVertexData(), mainObj.getVertexCount() * sizeof(float) * 8); + VAO.bufferElementData(mainObj.getIndexData(), mainObj.getIndexCount() * sizeof(unsigned int)); VAO.setAttributePointer(0, 3, GL_FLOAT, false, 8 * sizeof(float), 0); // position VAO.setAttributePointer(1, 3, GL_FLOAT, false, 8 * sizeof(float), 3 * sizeof(float)); // normal VAO.setAttributePointer(2, 2, GL_FLOAT, false, 8 * sizeof(float), 6 * sizeof(float)); // texCoord @@ -40,6 +48,15 @@ int main(int argc, char* argv[]) { Texture texture("assets/textures/Sci-fi_Container_Base_Color.png"); texture.bind(GL_TEXTURE0); + VertexArrayObject lightCubeVAO; + lightCubeVAO.bufferVertexData(lightObj.getVertexData(), lightObj.getVertexCount() * sizeof(float) * 8); + lightCubeVAO.bufferElementData(lightObj.getIndexData(), lightObj.getIndexCount() * sizeof(unsigned int)); + lightCubeVAO.setAttributePointer(0, 3, GL_FLOAT, false, 8 * sizeof(float), 0); // position + lightCubeVAO.setAttributePointer(1, 3, GL_FLOAT, false, 8 * sizeof(float), 3 * sizeof(float)); // normal + lightCubeVAO.setAttributePointer(2, 2, GL_FLOAT, false, 8 * sizeof(float), 6 * sizeof(float)); // texCoord + + glm::vec3 lightPos(6.0f, 3.0f, 3.0f); + window.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); window.showWindow(); @@ -49,13 +66,28 @@ int main(int argc, char* argv[]) { glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - shader_program.use(); - shader_program.setMat4("view", camera.getViewMatrix()); - shader_program.setMat4("projection", camera.getProjectionMatrix()); - shader_program.setMat4("model", glm::mat4(1.0f)); + cubeShader.use(); + cubeShader.setMat4("view", camera.getViewMatrix()); + cubeShader.setMat4("projection", camera.getProjectionMatrix()); + cubeShader.setMat4("model", glm::mat4(1.0f)); + cubeShader.setVec3("objectColor", glm::vec3(1.0f, 0.5f, 0.31f)); + cubeShader.setVec3("lightColor", glm::vec3(1.0f, 1.0f, 1.0f)); + cubeShader.setVec3("lightPos", lightPos); + cubeShader.setVec3("viewPos", camera.getPosition()); VAO.draw(); + glm::mat4 model = glm::mat4(1.0f); + model = glm::translate(model, lightPos); + model = glm::scale(model, glm::vec3(0.2f)); + + lightShader.use(); + lightShader.setMat4("view", camera.getViewMatrix()); + lightShader.setMat4("projection", camera.getProjectionMatrix()); + lightShader.setMat4("model", model); + + lightCubeVAO.draw(); + glContext.swapBuffers(); }