Skip to content

Commit

Permalink
Support of multiple light sources
Browse files Browse the repository at this point in the history
  • Loading branch information
dorosch committed Sep 16, 2022
1 parent 8a659f5 commit 5584974
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 82 deletions.
3 changes: 2 additions & 1 deletion include/core/render/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <memory>

#include <fmt/format.h>
#include <GL/glew.h>

#include "tools/logger.hpp"
Expand Down Expand Up @@ -39,7 +40,7 @@ namespace Engine {
void Startup();
void Shutdown();
void RenderScene(Engine::Scene::Scene *, glm::mat4, glm::mat4, glm::vec3);
void RenderObject(Engine::Object *, glm::mat4, glm::mat4, glm::vec3, Graphics::Lighting::Light *);
void RenderObject(Engine::Object *, glm::mat4, glm::mat4, glm::vec3, std::vector<std::shared_ptr<Graphics::Lighting::Light>>);
};
}
}
Expand Down
8 changes: 4 additions & 4 deletions include/core/render/shader/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ namespace Engine {
virtual void Linking() = 0;
virtual std::optional<uint32_t> Compile(Shader, std::string) = 0;
virtual void Build(std::filesystem::path, std::filesystem::path) = 0;
virtual void UniformFloat(const char *, float) = 0;
virtual void UniformInt(const char *, int) = 0;
virtual void UniformVector(const char *, glm::vec3) = 0;
virtual void UniformMatrix(const char *, glm::mat4) = 0;
virtual void UniformFloat(const std::string &, float) = 0;
virtual void UniformInt(const std::string &, int) = 0;
virtual void UniformVector(const std::string &, glm::vec3) = 0;
virtual void UniformMatrix(const std::string &, glm::mat4) = 0;
};
}
}
Expand Down
8 changes: 4 additions & 4 deletions include/core/render/shader/opengl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ namespace Engine {
void Use();
void Linking();
void Build(std::filesystem::path, std::filesystem::path);
void UniformInt(const char *, int);
void UniformFloat(const char *, float);
void UniformVector(const char *, glm::vec3);
void UniformMatrix(const char *, glm::mat4);
void UniformInt(const std::string &, int);
void UniformFloat(const std::string &, float);
void UniformVector(const std::string &, glm::vec3);
void UniformMatrix(const std::string &, glm::mat4);
};
}
}
Expand Down
2 changes: 1 addition & 1 deletion include/meta.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef __META_HPP__
#define __META_HPP__

#define ENGINE_VERSION "0.1.2"
#define ENGINE_VERSION "0.1.3"
#define GLSL_VERSION "#version 420"

#endif
29 changes: 18 additions & 11 deletions resources/shaders/default.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#version 420 core

#define MAX_LIGHT_SOURCES 32

#define DIRECTIONAL 0
#define POINT 1
#define SPOT 2
Expand Down Expand Up @@ -31,8 +33,9 @@ in vec3 FragPos;

out vec4 color;

uniform Light light;
uniform vec3 viewPosition;
uniform int lightSourcesCount;
uniform Light lights[MAX_LIGHT_SOURCES];


vec3 calculateDirectionLight(Light, vec3, vec3);
Expand All @@ -41,22 +44,26 @@ vec3 calculateSpotLight(Light, vec3, vec3, vec3);


void main() {
vec3 result;
vec3 result = vec3(0.0f);
vec3 defaultColor = vec3(0.66f);
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPosition - FragPos);

if (light.type == DIRECTIONAL) {
result = calculateDirectionLight(light, norm, viewDir);
}
else if (light.type == POINT) {
result = calculatePointLight(light, norm, FragPos, viewDir);
}
else if (light.type == SPOT) {
result = calculateSpotLight(light, norm, FragPos, viewDir);
for(int index = 0; index < lightSourcesCount; index++) {
Light light = lights[index];

if (light.type == DIRECTIONAL) {
result += calculateDirectionLight(light, norm, viewDir) * light.intensity;
}
else if (light.type == POINT) {
result += calculatePointLight(light, norm, FragPos, viewDir) * light.intensity;
}
else if (light.type == SPOT) {
result += calculateSpotLight(light, norm, FragPos, viewDir) * light.intensity;
}
}

color = vec4(result * defaultColor * light.intensity, 1.0f);
color = vec4(result * defaultColor, 1.0f);
}


Expand Down
33 changes: 20 additions & 13 deletions resources/shaders/material.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#version 420 core

#define MAX_LIGHT_SOURCES 32

#define DIRECTIONAL 0
#define POINT 1
#define SPOT 2
Expand Down Expand Up @@ -37,11 +39,12 @@ struct Material {
in vec3 Normal;
in vec3 FragPos;

uniform Light light;
out vec4 color;

uniform Material material;
uniform vec3 viewPosition;

out vec4 color;
uniform int lightSourcesCount;
uniform Light lights[MAX_LIGHT_SOURCES];


vec3 calculateDirectionLight(Light, Material, vec3, vec3);
Expand All @@ -50,21 +53,25 @@ vec3 calculateSpotLight(Light, Material, vec3, vec3, vec3);


void main() {
vec3 result;
vec3 result = vec3(0.0f);
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPosition - FragPos);

if (light.type == DIRECTIONAL) {
result = calculateDirectionLight(light, material, norm, viewDir);
}
else if (light.type == POINT) {
result = calculatePointLight(light, material, norm, FragPos, viewDir);
}
else if (light.type == SPOT) {
result = calculateSpotLight(light, material, norm, FragPos, viewDir);
for(int index = 0; index < lightSourcesCount; index++) {
Light light = lights[index];

if (light.type == DIRECTIONAL) {
result += calculateDirectionLight(light, material, norm, viewDir) * light.intensity;
}
else if (light.type == POINT) {
result += calculatePointLight(light, material, norm, FragPos, viewDir) * light.intensity;
}
else if (light.type == SPOT) {
result += calculateSpotLight(light, material, norm, FragPos, viewDir) * light.intensity;
}
}

color = vec4((result * material.color) * light.intensity, 1.0f);
color = vec4(result * material.color, 1.0f);
}


Expand Down
81 changes: 44 additions & 37 deletions src/core/render/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,34 +58,36 @@ void Render::Shutdown() {
void Render::RenderScene(Engine::Scene::Scene *scene, glm::mat4 projection, glm::mat4 view, glm::vec3 cameraPosition) {
// TODO: Only for opengl backend

std::shared_ptr<Graphics::Lighting::Light> lighting = scene->lighting[0];

// TODO: Add logger warning if more lights are added than the shader supports
for (std::shared_ptr<Object> object : scene->root->entities) {
RenderObject(object.get(), projection, view, cameraPosition, lighting.get());
RenderObject(object.get(), projection, view, cameraPosition, scene->lighting);
}

if (lighting->HasComponent(Ecs::Component::Type::LIGHT)) {
for (std::shared_ptr<Graphics::Lighting::Light> light : scene->lighting) {
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, lighting->transform->position);
model = glm::rotate(model, glm::radians(180.0f), lighting->transform->rotation);
model = glm::scale(model, lighting->transform->scale);
model = glm::translate(model, light->transform->position);
model = glm::rotate(model, glm::radians(180.0f), light->transform->rotation);
model = glm::scale(model, light->transform->scale);

lightingShader->Use();
lightingShader->UniformMatrix("model", model);
lightingShader->UniformMatrix("view", view);
lightingShader->UniformMatrix("projection", projection);

// If the editor is enabled, then draw where the light source is
lighting->mesh->VAO->bind();
glDrawArrays(GL_TRIANGLES, 0, lighting->mesh->vertices.size() / 6);
lighting->mesh->VAO->unbind();
light->mesh->VAO->bind();
glDrawArrays(GL_TRIANGLES, 0, light->mesh->vertices.size() / 6);
light->mesh->VAO->unbind();
}

scene->environment->skybox->update(projection * view);
}


void Render::RenderObject(Object *object, glm::mat4 projection, glm::mat4 view, glm::vec3 cameraPosition, Graphics::Lighting::Light *lighting) {
void Render::RenderObject(
Object *object, glm::mat4 projection, glm::mat4 view, glm::vec3 cameraPosition,
std::vector<std::shared_ptr<Graphics::Lighting::Light>> lights
) {
if (object->HasComponent(Ecs::Component::Type::MESH)) {
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, object->transform->position);
Expand All @@ -104,34 +106,39 @@ void Render::RenderObject(Object *object, glm::mat4 projection, glm::mat4 view,
shader->UniformMatrix("model", model);
shader->UniformMatrix("view", view);
shader->UniformMatrix("projection", projection);

shader->UniformVector("viewPosition", cameraPosition);

shader->UniformVector("light.position", lighting->transform->position);
shader->UniformVector("light.color", lighting->light->color);
shader->UniformVector("light.ambient", lighting->light->ambient);
shader->UniformVector("light.diffuse", lighting->light->diffuse);
shader->UniformVector("light.specular", lighting->light->specular);
shader->UniformFloat("light.intensity", lighting->light->intensity);

if (lighting->light->lightType == Graphics::Lighting::Type::DIRECTIONAL) {
shader->UniformInt("light.type", Graphics::Lighting::Type::DIRECTIONAL);
shader->UniformVector("light.direction", lighting->light->direction);
}
else if (lighting->light->lightType == Graphics::Lighting::Type::POINT) {
shader->UniformInt("light.type", Graphics::Lighting::Type::POINT);
shader->UniformFloat("light.constant", lighting->light->constant);
shader->UniformFloat("light.linear", lighting->light->linear);
shader->UniformFloat("light.quadratic", lighting->light->quadratic);
}
else if (lighting->light->lightType == Graphics::Lighting::Type::SPOT) {
shader->UniformInt("light.type", Graphics::Lighting::Type::SPOT);
shader->UniformVector("light.direction", lighting->light->direction);
shader->UniformFloat("light.constant", lighting->light->constant);
shader->UniformFloat("light.linear", lighting->light->linear);
shader->UniformFloat("light.quadratic", lighting->light->quadratic);
shader->UniformFloat("light.cutOff", glm::cos(glm::radians(lighting->light->cutOff)));
shader->UniformFloat("light.outerCutOff", glm::cos(glm::radians(lighting->light->outerCutOff)));
shader->UniformInt("lightSourcesCount", lights.size());

for (size_t index = 0; index < lights.size(); index++) {
std::shared_ptr<Graphics::Lighting::Light> light = lights[index];

shader->UniformVector(fmt::format("lights[{}].position", index), light->transform->position);
shader->UniformVector(fmt::format("lights[{}].color", index), light->light->color);
shader->UniformVector(fmt::format("lights[{}].ambient", index), light->light->ambient);
shader->UniformVector(fmt::format("lights[{}].diffuse", index), light->light->diffuse);
shader->UniformVector(fmt::format("lights[{}].specular", index), light->light->specular);
shader->UniformFloat(fmt::format("lights[{}].intensity", index), light->light->intensity);

if (light->light->lightType == Graphics::Lighting::Type::DIRECTIONAL) {
shader->UniformInt(fmt::format("lights[{}].type", index), Graphics::Lighting::Type::DIRECTIONAL);
shader->UniformVector(fmt::format("lights[{}].direction", index), light->light->direction);
}
else if (light->light->lightType == Graphics::Lighting::Type::POINT) {
shader->UniformInt(fmt::format("lights[{}].type", index), Graphics::Lighting::Type::POINT);
shader->UniformFloat(fmt::format("lights[{}].constant", index), light->light->constant);
shader->UniformFloat(fmt::format("lights[{}].linear", index), light->light->linear);
shader->UniformFloat(fmt::format("lights[{}].quadratic", index), light->light->quadratic);
}
else if (light->light->lightType == Graphics::Lighting::Type::SPOT) {
shader->UniformInt(fmt::format("lights[{}].type", index), Graphics::Lighting::Type::SPOT);
shader->UniformVector(fmt::format("lights[{}].direction", index), light->light->direction);
shader->UniformFloat(fmt::format("lights[{}].constant", index), light->light->constant);
shader->UniformFloat(fmt::format("lights[{}].linear", index), light->light->linear);
shader->UniformFloat(fmt::format("lights[{}].quadratic", index), light->light->quadratic);
shader->UniformFloat(fmt::format("lights[{}].cutOff", index), glm::cos(glm::radians(light->light->cutOff)));
shader->UniformFloat(fmt::format("lights[{}].outerCutOff", index), glm::cos(glm::radians(light->light->outerCutOff)));
}
}

if (object->HasComponent(Ecs::Component::Type::MATERIAL)) {
Expand Down
18 changes: 9 additions & 9 deletions src/core/render/shader/opengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,25 +126,25 @@ void OpenglShaderProgram::Use() {
}


void OpenglShaderProgram::UniformFloat(const char *attribute, float value) {
GLint variable = glGetUniformLocation(this->object, attribute);
void OpenglShaderProgram::UniformFloat(const std::string &attribute, float value) {
GLint variable = glGetUniformLocation(this->object, attribute.c_str());
glUniform1f(variable, value);
}


void OpenglShaderProgram::UniformInt(const char *attribute, int value) {
GLint variable = glGetUniformLocation(this->object, attribute);
void OpenglShaderProgram::UniformInt(const std::string &attribute, int value) {
GLint variable = glGetUniformLocation(this->object, attribute.c_str());
glUniform1i(variable, value);
}


void OpenglShaderProgram::UniformVector(const char *attribute, glm::vec3 vector){
GLint variable = glGetUniformLocation(this->object, attribute);
void OpenglShaderProgram::UniformVector(const std::string &attribute, glm::vec3 vector){
GLint variable = glGetUniformLocation(this->object, attribute.c_str());
glUniform3fv(variable, 1, glm::value_ptr(vector));
}


void OpenglShaderProgram::UniformMatrix(const char *attribure, glm::mat4 matrix) {
GLuint targetAttribute = glGetUniformLocation(this->object, attribure);
glUniformMatrix4fv(targetAttribute, 1, GL_FALSE, glm::value_ptr(matrix));
void OpenglShaderProgram::UniformMatrix(const std::string &attribute, glm::mat4 matrix) {
GLuint variable = glGetUniformLocation(this->object, attribute.c_str());
glUniformMatrix4fv(variable, 1, GL_FALSE, glm::value_ptr(matrix));
}
17 changes: 15 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ class UserApplication : public Engine::EngineApplication {
std::shared_ptr<Engine::Geometry::Cube> cube = std::make_shared<Engine::Geometry::Cube>();
std::shared_ptr<Engine::Geometry::Cube> cube2 = std::make_shared<Engine::Geometry::Cube>();

plane->transform->position = {0.0f, 0.1f, 0.0f};
plane->transform->rotation = {0.0f, 1.0f, 1.0f};
plane->transform->scale = {20.0f, 20.0f, 1.0f};

Expand All @@ -207,6 +208,11 @@ class UserApplication : public Engine::EngineApplication {
// Add sun to the scene
std::shared_ptr<Engine::Graphics::Lighting::SpotLight> sun =
std::make_shared<Engine::Graphics::Lighting::SpotLight>();
std::shared_ptr<Engine::Graphics::Lighting::PointLight> point =
std::make_shared<Engine::Graphics::Lighting::PointLight>();
std::shared_ptr<Engine::Graphics::Lighting::PointLight> point2 =
std::make_shared<Engine::Graphics::Lighting::PointLight>();


sun->name = "Sun";
sun->light->intensity = 2.0f;
Expand All @@ -217,7 +223,14 @@ class UserApplication : public Engine::EngineApplication {
sun->transform->position = {-3.0f, 3.0f, -3.0f};
sun->transform->scale = {0.1f, 0.1f, 0.1f};

point->transform->position = {3.0f, 3.0f, 3.0f};
point->transform->scale = {0.1f, 0.1f, 0.1f};
point2->transform->position = {4.0f, 2.0f, 2.0f};
point2->transform->scale = {0.1f, 0.1f, 0.1f};

scene->lighting.push_back(sun);
scene->lighting.push_back(point);
scene->lighting.push_back(point2);
// End sun light

this->debugAxes = Tool::Debug::DebugAxes::GetInstance();
Expand Down Expand Up @@ -264,9 +277,9 @@ int main() {
UserApplication *application = new UserApplication();
Engine::Engine engine(application);

engine.Startup();

try {
engine.Startup();

engine.Run();
} catch (const std::exception& error) {
std::cerr << error.what() << std::endl;
Expand Down

0 comments on commit 5584974

Please sign in to comment.