basic lighting

This commit is contained in:
2025-11-27 11:37:56 +00:00
parent bb7a3bafd2
commit 25a54bab1b
6 changed files with 88 additions and 19 deletions

View File

@@ -17,6 +17,7 @@ public:
void setInt(const std::string &name, int value) const; void setInt(const std::string &name, int value) const;
void setFloat(const std::string &name, float value) const; void setFloat(const std::string &name, float value) const;
void setMat4(const std::string &name, const glm::mat4 &mat) const; void setMat4(const std::string &name, const glm::mat4 &mat) const;
void setVec3(const std::string &name, const glm::vec3 &vec) const;
~Shader(); ~Shader();
private: private:
const char* read_file(const char* filePath); const char* read_file(const char* filePath);

View File

@@ -1,11 +1,34 @@
#version 330 core #version 330 core
out vec4 FragColor; out vec4 FragColor;
in vec3 Color; // Input color from the vertex shader in vec3 FragPos;
in vec2 TexCoord; // Input texture coordinate from the vertex shader in vec3 Normal;
in vec2 TexCoord;
uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform sampler2D Texture1; uniform sampler2D Texture1;
void main() { void main()
FragColor = texture(Texture1, TexCoord); {
// 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);
} }

View File

@@ -3,8 +3,9 @@
layout(location = 0) in vec3 position; // Vertex position layout(location = 0) in vec3 position; // Vertex position
layout(location = 1) in vec3 normal; // Vertex normal layout(location = 1) in vec3 normal; // Vertex normal
layout(location = 2) in vec2 texCoord; // Vertex texture coordinate layout(location = 2) in vec2 texCoord; // Vertex texture coordinate
out vec3 Color; // Output color to the fragment shader out vec3 Normal;
out vec2 TexCoord; // Output texture coordinate to the fragment shader out vec3 FragPos;
out vec2 TexCoord;
uniform mat4 model; uniform mat4 model;
uniform mat4 view; uniform mat4 view;
@@ -12,6 +13,7 @@ uniform mat4 projection;
void main() { void main() {
gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices gl_Position = projection * view * model * vec4(position, 1.0); // Apply transformation matrices
Color = normal * 0.5 + 0.5; // Simple coloring based on normal FragPos = vec3(model * vec4(position, 1.0));
TexCoord = texCoord; // Pass through the texture coordinate Normal = mat3(transpose(inverse(model))) * normal;
TexCoord = texCoord;
} }

View File

@@ -0,0 +1,7 @@
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0); // set all 4 vector values to 1.0
}

View File

@@ -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]); 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() { Shader::~Shader() {
if (ID != 0) { if (ID != 0) {
glDeleteProgram(ID); glDeleteProgram(ID);

View File

@@ -1,3 +1,4 @@
#define GL_GLEXT_PROTOTYPES
#include "engine/sdl.hpp" #include "engine/sdl.hpp"
#include "engine/opengl.hpp" #include "engine/opengl.hpp"
#include "engine/obj_loader.hpp" #include "engine/obj_loader.hpp"
@@ -10,7 +11,7 @@ int main(int argc, char* argv[]) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
Camera camera( 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), // Target
glm::vec3(0.0f, 1.0f, 0.0f) // Up vector glm::vec3(0.0f, 1.0f, 0.0f) // Up vector
); );
@@ -22,17 +23,24 @@ int main(int argc, char* argv[]) {
100.0f // Far Plane 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"); OBJLoader mainObj("assets/models/Sci-fi_Container_Game.obj");
if (!objLoader.isLoaded()) { 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."); SDL_Log("Failed to load OBJ model.");
return -1; return -1;
} }
VertexArrayObject VAO; VertexArrayObject VAO;
VAO.bufferVertexData(objLoader.getVertexData(), objLoader.getVertexCount() * sizeof(float) * 8); VAO.bufferVertexData(mainObj.getVertexData(), mainObj.getVertexCount() * sizeof(float) * 8);
VAO.bufferElementData(objLoader.getIndexData(), objLoader.getIndexCount() * sizeof(unsigned int)); VAO.bufferElementData(mainObj.getIndexData(), mainObj.getIndexCount() * sizeof(unsigned int));
VAO.setAttributePointer(0, 3, GL_FLOAT, false, 8 * sizeof(float), 0); // position 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(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 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 texture("assets/textures/Sci-fi_Container_Base_Color.png");
texture.bind(GL_TEXTURE0); 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.setPosition(SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
window.showWindow(); window.showWindow();
@@ -49,13 +66,28 @@ int main(int argc, char* argv[]) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
shader_program.use(); cubeShader.use();
shader_program.setMat4("view", camera.getViewMatrix()); cubeShader.setMat4("view", camera.getViewMatrix());
shader_program.setMat4("projection", camera.getProjectionMatrix()); cubeShader.setMat4("projection", camera.getProjectionMatrix());
shader_program.setMat4("model", glm::mat4(1.0f)); 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(); 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(); glContext.swapBuffers();
} }