✨ Add lighting system with shaders, light structs, and material support
This commit is contained in:
parent
579d5ec483
commit
cae53dca8b
52
include/Lighting.h
Normal file
52
include/Lighting.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef LIGHTING_H
|
||||
#define LIGHTING_H
|
||||
|
||||
namespace djalim {
|
||||
class ShaderProgram;
|
||||
}
|
||||
|
||||
#include "Camera.h"
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct DirectionalLight {
|
||||
glm::vec3 direction;
|
||||
glm::vec3 ambient;
|
||||
glm::vec3 diffuse;
|
||||
glm::vec3 specular;
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
glm::vec3 position;
|
||||
glm::vec3 ambient;
|
||||
glm::vec3 diffuse;
|
||||
glm::vec3 specular;
|
||||
float constant;
|
||||
float linear;
|
||||
float exponent;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
glm::vec3 position;
|
||||
glm::vec3 direction;
|
||||
glm::vec3 ambient;
|
||||
glm::vec3 diffuse;
|
||||
glm::vec3 specular;
|
||||
float cosInnerCone;
|
||||
float cosOuterCone;
|
||||
float constant;
|
||||
float linear;
|
||||
float exponent;
|
||||
bool on;
|
||||
};
|
||||
|
||||
class Lighting {
|
||||
public:
|
||||
Lighting();
|
||||
void update(djalim::ShaderProgram& shader, FPSCamera& camera);
|
||||
|
||||
DirectionalLight sunLight;
|
||||
PointLight pointLights[3];
|
||||
SpotLight spotLight;
|
||||
};
|
||||
|
||||
#endif // LIGHTING_H
|
||||
@ -21,6 +21,7 @@ namespace djalim {
|
||||
void setUniform(const std::string& name, const glm::vec3& value);
|
||||
void setUniform(const std::string& name, const glm::vec4& value);
|
||||
void setUniform(const std::string& name, const glm::mat4& value);
|
||||
void setUniformSampler(const std::string& name, int value);
|
||||
|
||||
GLuint getProgram() const { return mHandle; }
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "Mesh3D.h"
|
||||
#include "Lighting.h"
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
@ -48,6 +49,7 @@ namespace djalim {
|
||||
int frameCount = 0;
|
||||
ShaderProgram shaderProgram;
|
||||
FPSCamera Camera = FPSCamera(glm::vec3(0.0f, 2.0f, 10.0f));
|
||||
Lighting lighting;
|
||||
|
||||
Objects3D objects;
|
||||
|
||||
|
||||
101
src/core/Lighting.cpp
Normal file
101
src/core/Lighting.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "Lighting.h"
|
||||
#include "ShaderProgram.h"
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
Lighting::Lighting() {
|
||||
// Directional light
|
||||
sunLight.direction = glm::vec3(0.0f, -0.9f, -0.17f);
|
||||
sunLight.ambient = glm::vec3(0.1f, 0.1f, 0.1f);
|
||||
sunLight.diffuse = glm::vec3(0.1f, 0.1f, 0.1f);
|
||||
sunLight.specular = glm::vec3(0.1f, 0.1f, 0.1f);
|
||||
|
||||
// Point Light 1
|
||||
pointLights[0].position = glm::vec3(-5.0f, 3.8f, 0.0f);
|
||||
pointLights[0].ambient = glm::vec3(0.2f, 0.2f, 0.2f);
|
||||
pointLights[0].diffuse = glm::vec3(0.0f, 1.0f, 0.1f);
|
||||
pointLights[0].specular = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
pointLights[0].constant = 1.0f;
|
||||
pointLights[0].linear = 0.22f;
|
||||
pointLights[0].exponent = 0.20f;
|
||||
|
||||
// Point Light 2
|
||||
pointLights[1].position = glm::vec3(0.5f, 3.8f, 0.0f);
|
||||
pointLights[1].ambient = glm::vec3(0.2f, 0.2f, 0.2f);
|
||||
pointLights[1].diffuse = glm::vec3(1.0f, 0.1f, 0.0f);
|
||||
pointLights[1].specular = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
pointLights[1].constant = 1.0f;
|
||||
pointLights[1].linear = 0.22f;
|
||||
pointLights[1].exponent = 0.20f;
|
||||
|
||||
// Point Light 3
|
||||
pointLights[2].position = glm::vec3(5.0f, 3.8f, 0.0f);
|
||||
pointLights[2].ambient = glm::vec3(0.2f, 0.2f, 0.2f);
|
||||
pointLights[2].diffuse = glm::vec3(0.0f, 0.1f, 1.0f);
|
||||
pointLights[2].specular = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
pointLights[2].constant = 1.0f;
|
||||
pointLights[2].linear = 0.22f;
|
||||
pointLights[2].exponent = 0.20f;
|
||||
|
||||
// Spot light
|
||||
spotLight.ambient = glm::vec3(0.1f, 0.1f, 0.1f);
|
||||
spotLight.diffuse = glm::vec3(0.8f, 0.8f, 0.8f);
|
||||
spotLight.specular = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
spotLight.cosInnerCone = glm::cos(glm::radians(15.0f));
|
||||
spotLight.cosOuterCone = glm::cos(glm::radians(20.0f));
|
||||
spotLight.constant = 1.0f;
|
||||
spotLight.linear = 0.07f;
|
||||
spotLight.exponent = 0.017f;
|
||||
spotLight.on = true;
|
||||
}
|
||||
|
||||
void Lighting::update(djalim::ShaderProgram& shader, FPSCamera& camera) {
|
||||
shader.use();
|
||||
|
||||
// Directional light
|
||||
shader.setUniform("sunLight.direction", sunLight.direction);
|
||||
shader.setUniform("sunLight.ambient", sunLight.ambient);
|
||||
shader.setUniform("sunLight.diffuse", sunLight.diffuse);
|
||||
shader.setUniform("sunLight.specular", sunLight.specular);
|
||||
|
||||
// Point Light 1
|
||||
shader.setUniform("pointLights[0].position", pointLights[0].position);
|
||||
shader.setUniform("pointLights[0].ambient", pointLights[0].ambient);
|
||||
shader.setUniform("pointLights[0].diffuse", pointLights[0].diffuse);
|
||||
shader.setUniform("pointLights[0].specular", pointLights[0].specular);
|
||||
shader.setUniform("pointLights[0].constant", pointLights[0].constant);
|
||||
shader.setUniform("pointLights[0].linear", pointLights[0].linear);
|
||||
shader.setUniform("pointLights[0].exponent", pointLights[0].exponent);
|
||||
|
||||
// Point Light 2
|
||||
shader.setUniform("pointLights[1].position", pointLights[1].position);
|
||||
shader.setUniform("pointLights[1].ambient", pointLights[1].ambient);
|
||||
shader.setUniform("pointLights[1].diffuse", pointLights[1].diffuse);
|
||||
shader.setUniform("pointLights[1].specular", pointLights[1].specular);
|
||||
shader.setUniform("pointLights[1].constant", pointLights[1].constant);
|
||||
shader.setUniform("pointLights[1].linear", pointLights[1].linear);
|
||||
shader.setUniform("pointLights[1].exponent", pointLights[1].exponent);
|
||||
|
||||
// Point Light 3
|
||||
shader.setUniform("pointLights[2].position", pointLights[2].position);
|
||||
shader.setUniform("pointLights[2].ambient", pointLights[2].ambient);
|
||||
shader.setUniform("pointLights[2].diffuse", pointLights[2].diffuse);
|
||||
shader.setUniform("pointLights[2].specular", pointLights[2].specular);
|
||||
shader.setUniform("pointLights[2].constant", pointLights[2].constant);
|
||||
shader.setUniform("pointLights[2].linear", pointLights[2].linear);
|
||||
shader.setUniform("pointLights[2].exponent", pointLights[2].exponent);
|
||||
|
||||
// Spot light
|
||||
glm::vec3 spotlightPos = camera.getPosition();
|
||||
spotlightPos.y -= 0.5f;
|
||||
shader.setUniform("spotLight.position", spotlightPos);
|
||||
shader.setUniform("spotLight.direction", camera.getLook());
|
||||
shader.setUniform("spotLight.ambient", spotLight.ambient);
|
||||
shader.setUniform("spotLight.diffuse", spotLight.diffuse);
|
||||
shader.setUniform("spotLight.specular", spotLight.specular);
|
||||
shader.setUniform("spotLight.cosInnerCone", spotLight.cosInnerCone);
|
||||
shader.setUniform("spotLight.cosOuterCone", spotLight.cosOuterCone);
|
||||
shader.setUniform("spotLight.constant", spotLight.constant);
|
||||
shader.setUniform("spotLight.linear", spotLight.linear);
|
||||
shader.setUniform("spotLight.exponent", spotLight.exponent);
|
||||
shader.setUniform("spotLight.on", spotLight.on);
|
||||
}
|
||||
@ -105,6 +105,19 @@ void djalim::Mesh3D::loadOBJFile(const std::string& filepath) {
|
||||
meshVertices.push_back(v.y);
|
||||
meshVertices.push_back(v.z);
|
||||
|
||||
// Si le fichier ne contient pas de vn, on met des normales par défaut (0,0,0)
|
||||
int vnIndex = face.vertices[j].vn;
|
||||
if (vnIndex >= 0 && vnIndex < (int)vertexNormal.size()) {
|
||||
const objVertex& vn = vertexNormal[vnIndex];
|
||||
meshVertices.push_back(vn.x);
|
||||
meshVertices.push_back(vn.y);
|
||||
meshVertices.push_back(vn.z);
|
||||
} else {
|
||||
meshVertices.push_back(0.0f);
|
||||
meshVertices.push_back(0.0f);
|
||||
meshVertices.push_back(0.0f);
|
||||
}
|
||||
|
||||
// Si le fichier ne contient pas de vt, on met des coordonnées par défaut (0,0)
|
||||
int vtIndex = face.vertices[j].vt;
|
||||
if (vtIndex >= 0 && vtIndex < (int)vertexTexture.size()) {
|
||||
|
||||
@ -93,3 +93,7 @@ void djalim::ShaderProgram::setUniform(const std::string& name, float value) {
|
||||
void djalim::ShaderProgram::setUniform(const std::string& name, const glm::vec3& value) {
|
||||
glUniform3f(glGetUniformLocation(mHandle, name.c_str()), value.x, value.y, value.z);
|
||||
}
|
||||
|
||||
void djalim::ShaderProgram::setUniformSampler(const std::string& name, int value) {
|
||||
glUniform1i(glGetUniformLocation(mHandle, name.c_str()), value);
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "engine.h"
|
||||
#include "Lighting.h"
|
||||
#include "Mesh3D.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <cstdlib>
|
||||
@ -44,7 +45,7 @@ djalim::OpenGlEngine::OpenGlEngine(const char* title, int width, int height) {
|
||||
|
||||
loadCallbacks();
|
||||
|
||||
bool loaded = shaderProgram.loadShaders("../assets/shaders/vertex.glsl", "../assets/shaders/fragment.glsl");
|
||||
bool loaded = shaderProgram.loadShaders("../assets/shaders/lighting.vert", "../assets/shaders/lighting.frag");
|
||||
if (!loaded) {
|
||||
std::cerr << "Failed to load shaders correctly" << std::endl;
|
||||
exit(1);
|
||||
@ -92,11 +93,14 @@ void djalim::OpenGlEngine::createObject(std::string name, std::string textures,
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*(objects[name])->meshVertices.size(), (objects[name])->meshVertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
// Attribut de position
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Attribut de coordonnée de texture
|
||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
// Attribut de normale
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
// Attribut de coordonnée de texture
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
}
|
||||
|
||||
djalim::OpenGlEngine::~OpenGlEngine() {
|
||||
@ -140,6 +144,12 @@ void djalim::OpenGlEngine::draw(djalim::Mesh3D* object){
|
||||
|
||||
shaderProgram.setUniform("model", model);
|
||||
|
||||
// Set material properties
|
||||
shaderProgram.setUniform("material.ambient", glm::vec3(0.1f, 0.1f, 0.1f));
|
||||
shaderProgram.setUniformSampler("material.diffuseMap", 0);
|
||||
shaderProgram.setUniform("material.specular", glm::vec3(0.8f, 0.8f, 0.8f));
|
||||
shaderProgram.setUniform("material.shininess", 32.0f);
|
||||
|
||||
glBindVertexArray(object->VAO);
|
||||
glDrawArrays(GL_TRIANGLES, 0, object->numFaces * 3);
|
||||
}
|
||||
|
||||
@ -6,12 +6,15 @@ void djalim::OpenGlEngine::onCreate(){
|
||||
|
||||
stbi_set_flip_vertically_on_load(true);
|
||||
|
||||
shaderProgram.loadShaders("../assets/shaders/lighting.vert", "../assets/shaders/lighting.frag");
|
||||
lighting = Lighting();
|
||||
|
||||
createObject("mimikyu",
|
||||
"../assets/textures/crate.jpg",
|
||||
"../assets/models/destiny island.obj",
|
||||
glm::vec3(0.0,0.0,0.0),
|
||||
glm::vec3(0.0,0.0,0.0),
|
||||
glm::vec3(.1,.1,.1)
|
||||
glm::vec3(.01,.01,.01)
|
||||
);
|
||||
createObject("cube",
|
||||
"../assets/textures/crate.jpg",
|
||||
|
||||
@ -7,7 +7,7 @@ void djalim::OpenGlEngine::onUpdate(){
|
||||
showFps();
|
||||
|
||||
shaderProgram.use();
|
||||
shaderProgram.setUniform("ourTexture", 0);
|
||||
shaderProgram.setUniform("material.diffuseMap", 0);
|
||||
|
||||
glm::mat4 model(1.0), view(1.0), projection(1.0);
|
||||
|
||||
@ -21,6 +21,8 @@ void djalim::OpenGlEngine::onUpdate(){
|
||||
shaderProgram.setUniform("projection", projection);
|
||||
shaderProgram.setUniform("view", view);
|
||||
|
||||
lighting.update(shaderProgram, Camera);
|
||||
|
||||
draw((objects["cube"]).get());
|
||||
draw((objects["mimikyu"]).get());
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user