[FEATURE] single light support
This commit is contained in:
@@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
namespace entities
|
namespace entities
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This class represents a movable model in the game
|
||||||
|
*/
|
||||||
|
|
||||||
class Entity
|
class Entity
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|||||||
25
src/entities/light.h
Normal file
25
src/entities/light.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glm/vec3.hpp>
|
||||||
|
|
||||||
|
namespace entities
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This class represents a light in the game
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Light
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::vec3 color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Light(const glm::vec3& position, const glm::vec3& color) : position(position), color(color) { }
|
||||||
|
|
||||||
|
glm::vec3 GetPosition() const { return position; }
|
||||||
|
void setPosition(const glm::vec3& position) { this->position = position; }
|
||||||
|
glm::vec3 GetColor() const { return color; }
|
||||||
|
void setColor(const glm::vec3& color) { this->color = color; }
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -48,8 +48,12 @@ int main(void)
|
|||||||
|
|
||||||
models::RawModel raw_model = LoadObjModel("res/Tree.obj");
|
models::RawModel raw_model = LoadObjModel("res/Tree.obj");
|
||||||
models::ModelTexture texture = { render_engine::loader::LoadTexture("res/TreeTexture.png") };
|
models::ModelTexture texture = { render_engine::loader::LoadTexture("res/TreeTexture.png") };
|
||||||
|
texture.shine_damper = 10;
|
||||||
|
texture.reflectivity = 1;
|
||||||
models::TexturedModel model = { raw_model, texture };
|
models::TexturedModel model = { raw_model, texture };
|
||||||
entities::Entity entity(model, glm::vec3(0, -5, -20), glm::vec3(0, 0, 0), 1);
|
entities::Entity entity(model, glm::vec3(0, -25, -50), glm::vec3(0, 0, 0), 1);
|
||||||
|
|
||||||
|
entities::Light light(glm::vec3(0, 0, -30), glm::vec3(1, 1, 1));
|
||||||
|
|
||||||
shaders::StaticShader shader;
|
shaders::StaticShader shader;
|
||||||
shader.Init();
|
shader.Init();
|
||||||
@@ -68,6 +72,7 @@ int main(void)
|
|||||||
// Render
|
// Render
|
||||||
render_engine::renderer::Prepare();
|
render_engine::renderer::Prepare();
|
||||||
shader.Start();
|
shader.Start();
|
||||||
|
shader.LoadLight(light);
|
||||||
shader.LoadViewMatrix(camera);
|
shader.LoadViewMatrix(camera);
|
||||||
|
|
||||||
render_engine::renderer::Render(entity, shader);
|
render_engine::renderer::Render(entity, shader);
|
||||||
|
|||||||
@@ -19,10 +19,15 @@ namespace models
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Structure for storing a texture (texture_id) to apply to a RawModel.
|
Structure for storing a texture (texture_id) to apply to a RawModel.
|
||||||
|
|
||||||
|
shine_damper = A damper for the angle the model needs to be look at to see reflections
|
||||||
|
reflectivity = The amount of light the model reflects
|
||||||
*/
|
*/
|
||||||
struct ModelTexture
|
struct ModelTexture
|
||||||
{
|
{
|
||||||
GLuint texture_id;
|
GLuint texture_id;
|
||||||
|
float shine_damper = 1;
|
||||||
|
float reflectivity = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -17,12 +17,13 @@ namespace render_engine
|
|||||||
/*
|
/*
|
||||||
This function will generate a Model from vertex positions, textureCoordinates and indices.
|
This function will generate a Model from vertex positions, textureCoordinates and indices.
|
||||||
*/
|
*/
|
||||||
struct models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<unsigned int>& indices)
|
models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices)
|
||||||
{
|
{
|
||||||
GLuint vao_id = CreateVao();
|
GLuint vao_id = CreateVao();
|
||||||
BindIndicesBuffer(indices);
|
BindIndicesBuffer(indices);
|
||||||
StoreDataInAttributeList(0, 3, positions);
|
StoreDataInAttributeList(0, 3, positions);
|
||||||
StoreDataInAttributeList(1, 2, texture_coords);
|
StoreDataInAttributeList(1, 2, texture_coords);
|
||||||
|
StoreDataInAttributeList(2, 3, normals);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
return { vao_id, static_cast<int>(indices.size()) };
|
return { vao_id, static_cast<int>(indices.size()) };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace render_engine
|
|||||||
/*
|
/*
|
||||||
This function generates a model from model data.
|
This function generates a model from model data.
|
||||||
*/
|
*/
|
||||||
struct models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<unsigned int>& indices);
|
models::RawModel LoadToVAO(std::vector<float>& positions, std::vector<float>& texture_coords, std::vector<float>& normals, std::vector<unsigned int>& indices);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Loads a texture from a file into openGL using stb_image.h
|
Loads a texture from a file into openGL using stb_image.h
|
||||||
|
|||||||
@@ -17,9 +17,14 @@ namespace render_engine
|
|||||||
*/
|
*/
|
||||||
void Init(shaders::StaticShader& shader)
|
void Init(shaders::StaticShader& shader)
|
||||||
{
|
{
|
||||||
|
// Faces which are not facing the camera are not rendered
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
glCullFace(GL_BACK);
|
||||||
|
|
||||||
const glm::mat4 projectionMatrix =
|
const glm::mat4 projectionMatrix =
|
||||||
glm::perspective(glm::radians(FOV), (WINDOW_WIDTH / WINDOW_HEIGT), NEAR_PLANE, FAR_PLANE);
|
glm::perspective(glm::radians(FOV), (WINDOW_WIDTH / WINDOW_HEIGT), NEAR_PLANE, FAR_PLANE);
|
||||||
|
|
||||||
|
// Load the projectionmatrix into the shader
|
||||||
shader.Start();
|
shader.Start();
|
||||||
shader.LoadProjectionMatrix(projectionMatrix);
|
shader.LoadProjectionMatrix(projectionMatrix);
|
||||||
shader.Stop();
|
shader.Stop();
|
||||||
@@ -41,26 +46,31 @@ namespace render_engine
|
|||||||
void Render(entities::Entity& entity, shaders::StaticShader& shader)
|
void Render(entities::Entity& entity, shaders::StaticShader& shader)
|
||||||
{
|
{
|
||||||
const models::TexturedModel model = entity.GetModel();
|
const models::TexturedModel model = entity.GetModel();
|
||||||
const models::RawModel rawModel = model.raw_model;
|
const models::RawModel raw_model = model.raw_model;
|
||||||
|
const models::ModelTexture texture = model.texture;
|
||||||
|
|
||||||
// Enable the model
|
// Enable the model
|
||||||
glBindVertexArray(rawModel.vao_id);
|
glBindVertexArray(raw_model.vao_id);
|
||||||
|
|
||||||
// Enable the inputs for the vertexShader
|
// Enable the VBO's from the model (VAO)
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
// Load the transformation of the model into the shader
|
// Load the transformation of the model into the shader
|
||||||
const glm::mat4 modelMatrix = toolbox::CreateModelMatrix(entity.GetPosition(), entity.GetRotation(), entity.GetScale());
|
const glm::mat4 modelMatrix = toolbox::CreateModelMatrix(entity.GetPosition(), entity.GetRotation(), entity.GetScale());
|
||||||
shader.LoadModelMatrix(modelMatrix);
|
shader.LoadModelMatrix(modelMatrix);
|
||||||
|
shader.LoadShineVariables(texture.shine_damper, texture.reflectivity);
|
||||||
|
|
||||||
// Draw the model
|
// Draw the model
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, model.texture.texture_id);
|
glBindTexture(GL_TEXTURE_2D, model.texture.texture_id);
|
||||||
glDrawElements(GL_TRIANGLES, rawModel.vertex_count, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLES, raw_model.vertex_count, GL_UNSIGNED_INT, 0);
|
||||||
|
|
||||||
|
// Disable the VBO's and model
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
glDisableVertexAttribArray(1);
|
glDisableVertexAttribArray(1);
|
||||||
|
glDisableVertexAttribArray(2);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,5 +125,5 @@ models::RawModel LoadObjModel(std::string file_name)
|
|||||||
vertex_array[p++] = vertex.z;
|
vertex_array[p++] = vertex.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
return render_engine::loader::LoadToVAO( vertex_array, texture_array, indices);
|
return render_engine::loader::LoadToVAO( vertex_array, texture_array, normal_array, indices);
|
||||||
}
|
}
|
||||||
@@ -12,21 +12,34 @@ namespace shaders
|
|||||||
in vec3 position;
|
in vec3 position;
|
||||||
// Coordinates of the texture
|
// Coordinates of the texture
|
||||||
in vec2 texture_coords;
|
in vec2 texture_coords;
|
||||||
|
// The normal of the vertex
|
||||||
|
in vec3 normal;
|
||||||
|
|
||||||
// Equal to the texture_coords
|
// Equal to the texture_coords
|
||||||
out vec2 pass_texture_coords;
|
out vec2 pass_texture_coords;
|
||||||
|
out vec3 surface_normal;
|
||||||
|
out vec3 to_light_vector;
|
||||||
|
out vec3 to_camera_vector;
|
||||||
|
|
||||||
uniform mat4 model_matrix;
|
uniform mat4 model_matrix;
|
||||||
uniform mat4 projection_matrix;
|
uniform mat4 projection_matrix;
|
||||||
uniform mat4 view_matrix;
|
uniform mat4 view_matrix;
|
||||||
|
uniform vec3 light_position;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
|
// Calculate the real position of the vertex (after rotation and scaling)
|
||||||
|
vec4 world_position = model_matrix * vec4(position, 1.0);
|
||||||
|
|
||||||
// Tell OpenGL where to render the vertex
|
// Tell OpenGL where to render the vertex
|
||||||
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(position, 1.0);
|
gl_Position = projection_matrix * view_matrix * world_position;
|
||||||
|
|
||||||
// Pass the texture_coords directly to the fragment shader
|
// Pass the textureCoords directly to the fragment shader
|
||||||
pass_texture_coords = texture_coords;
|
pass_texture_coords = texture_coords;
|
||||||
|
|
||||||
|
surface_normal = (model_matrix * vec4(normal, 0.0)).xyz;
|
||||||
|
to_light_vector = light_position - world_position.xyz;
|
||||||
|
to_camera_vector = (inverse(view_matrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - world_position.xyz;
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -39,15 +52,40 @@ namespace shaders
|
|||||||
// Interpolated textureCoordinates of the vertex (relative to the distance to each vertex)
|
// Interpolated textureCoordinates of the vertex (relative to the distance to each vertex)
|
||||||
in vec2 pass_texture_coords;
|
in vec2 pass_texture_coords;
|
||||||
|
|
||||||
|
in vec3 surface_normal;
|
||||||
|
in vec3 to_light_vector;
|
||||||
|
in vec3 to_camera_vector;
|
||||||
|
|
||||||
// Final color of the pixel
|
// Final color of the pixel
|
||||||
out vec4 out_color;
|
out vec4 out_color;
|
||||||
|
|
||||||
// The texture of the model
|
// The texture of the model
|
||||||
uniform sampler2D texture_sampler;
|
uniform sampler2D texture_sampler;
|
||||||
|
|
||||||
|
uniform vec3 light_color;
|
||||||
|
uniform float shine_damper;
|
||||||
|
uniform float reflectivity;
|
||||||
|
|
||||||
void main(void)
|
void main(void)
|
||||||
{
|
{
|
||||||
out_color = texture(texture_sampler, pass_texture_coords);
|
vec3 unit_normal = normalize(surface_normal);
|
||||||
|
vec3 unit_light_vector = normalize(to_light_vector);
|
||||||
|
vec3 unit_camera_vector = normalize(to_camera_vector);
|
||||||
|
|
||||||
|
// Calculate the diffuse lighting
|
||||||
|
float dot_diffuse = dot(unit_normal, unit_light_vector);
|
||||||
|
float brightness = max(dot_diffuse, 0.1);
|
||||||
|
vec3 diffuse = brightness * light_color;
|
||||||
|
|
||||||
|
// Calculate the specular lighting
|
||||||
|
vec3 light_direction = -unit_light_vector;
|
||||||
|
vec3 reflected_light_direction = reflect(light_direction, unit_normal);
|
||||||
|
float dot_specular = dot(reflected_light_direction, unit_camera_vector);
|
||||||
|
dot_specular = max(dot_specular, 0.0);
|
||||||
|
float damped_specular = pow(dot_specular, shine_damper);
|
||||||
|
vec3 specular = damped_specular * reflectivity * light_color;
|
||||||
|
|
||||||
|
out_color = vec4(diffuse, 1.0) * texture(texture_sampler, pass_texture_coords) + vec4(specular, 1.0);
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -72,16 +110,35 @@ namespace shaders
|
|||||||
LoadMatrix(location_view_matrix, view_matrix);
|
LoadMatrix(location_view_matrix, view_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StaticShader::LoadLight(entities::Light& light) const
|
||||||
|
{
|
||||||
|
LoadVector(location_light_position, light.GetPosition());
|
||||||
|
LoadVector(location_light_color, light.GetColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StaticShader::LoadShineVariables(float shine_damper, float reflectivity) const
|
||||||
|
{
|
||||||
|
LoadFloat(location_shine_damper, shine_damper);
|
||||||
|
LoadFloat(location_reflectivity, reflectivity);
|
||||||
|
}
|
||||||
|
|
||||||
void StaticShader::SetAttributes() const
|
void StaticShader::SetAttributes() const
|
||||||
{
|
{
|
||||||
|
// Load the position VBO and textureCoords VBO from the VAO into the shader "in" variables
|
||||||
SetAttribute(0, "position");
|
SetAttribute(0, "position");
|
||||||
SetAttribute(1, "texture_coords");
|
SetAttribute(1, "texture_coords");
|
||||||
|
SetAttribute(2, "normal");
|
||||||
}
|
}
|
||||||
|
|
||||||
void StaticShader::GetAllUniformLocations()
|
void StaticShader::GetAllUniformLocations()
|
||||||
{
|
{
|
||||||
|
// Get the locations from the uniform variables from the shaders
|
||||||
location_model_matrix = GetUniformLocation("model_matrix");
|
location_model_matrix = GetUniformLocation("model_matrix");
|
||||||
location_projection_matrix = GetUniformLocation("projection_matrix");
|
location_projection_matrix = GetUniformLocation("projection_matrix");
|
||||||
location_view_matrix = GetUniformLocation("view_matrix");
|
location_view_matrix = GetUniformLocation("view_matrix");
|
||||||
|
location_light_position = GetUniformLocation("light_position");
|
||||||
|
location_light_color = GetUniformLocation("light_color");
|
||||||
|
location_shine_damper = GetUniformLocation("shine_damper");
|
||||||
|
location_reflectivity = GetUniformLocation("reflectivity");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include "shader_program.h"
|
#include "shader_program.h"
|
||||||
#include "../entities/camera.h"
|
#include "../entities/camera.h"
|
||||||
|
#include "../entities/light.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This class does represents the shaders for the models.
|
This class does represents the shaders for the models.
|
||||||
@@ -16,6 +17,10 @@ namespace shaders
|
|||||||
GLuint location_model_matrix;
|
GLuint location_model_matrix;
|
||||||
GLuint location_projection_matrix;
|
GLuint location_projection_matrix;
|
||||||
GLuint location_view_matrix;
|
GLuint location_view_matrix;
|
||||||
|
GLuint location_light_position;
|
||||||
|
GLuint location_light_color;
|
||||||
|
GLuint location_shine_damper;
|
||||||
|
GLuint location_reflectivity;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StaticShader();
|
StaticShader();
|
||||||
@@ -23,6 +28,9 @@ namespace shaders
|
|||||||
void LoadModelMatrix(const glm::mat4& matrix) const;
|
void LoadModelMatrix(const glm::mat4& matrix) const;
|
||||||
void LoadProjectionMatrix(const glm::mat4& projection) const;
|
void LoadProjectionMatrix(const glm::mat4& projection) const;
|
||||||
void LoadViewMatrix(entities::Camera& camera) const;
|
void LoadViewMatrix(entities::Camera& camera) const;
|
||||||
|
|
||||||
|
void LoadLight(entities::Light& light) const;
|
||||||
|
void LoadShineVariables(float shine_damper, float reflectivity) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetAttributes() const override;
|
void SetAttributes() const override;
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\entities\camera.h" />
|
<ClInclude Include="src\entities\camera.h" />
|
||||||
<ClInclude Include="src\entities\entity.h" />
|
<ClInclude Include="src\entities\entity.h" />
|
||||||
|
<ClInclude Include="src\entities\light.h" />
|
||||||
<ClInclude Include="src\models\model.h" />
|
<ClInclude Include="src\models\model.h" />
|
||||||
<ClInclude Include="src\renderEngine\loader.h" />
|
<ClInclude Include="src\renderEngine\loader.h" />
|
||||||
<ClInclude Include="src\renderEngine\obj_loader.h" />
|
<ClInclude Include="src\renderEngine\obj_loader.h" />
|
||||||
|
|||||||
@@ -74,5 +74,8 @@
|
|||||||
<ClInclude Include="src\toolbox\toolbox.h">
|
<ClInclude Include="src\toolbox\toolbox.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\entities\light.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user