GameObjects

Began to add GameObjects, starting with the player.
This commit is contained in:
onTheZero
2025-08-13 00:59:03 -04:00
parent 237272c17b
commit 4bf6b02255
37 changed files with 2640 additions and 222 deletions

61
GameObject.h Normal file
View File

@@ -0,0 +1,61 @@
#pragma once
#include <glm/glm.hpp>
#include <InputComponent.h>
#include <GraphicsComponent.h>
#include <PhysicsComponent.h>
class GameObject
{
public:
glm::vec3 Position;
glm::vec3 Rotation;
glm::vec3 Scale;
GameObject(glm::vec3 Position, glm::vec3 Rotation, glm::vec3 Scale)
: Input(nullptr),
Graphics(nullptr),
Physics(nullptr),
Position(Position),
Rotation(Rotation),
Scale(Scale),
Front(0.0f, 0.0f, 1.0f),
Up(0.0f, 1.0f, 0.0f),
Right(1.0f, 0.0f, 0.0f),
WorldUp(0.0f, 1.0f, 0.0f)
{
}
GameObject(InputComponent* Input, GraphicsComponent* Graphics, PhysicsComponent* Physics)
: Input(Input),
Graphics(Graphics),
Physics(Physics),
Position(0.0f, 0.0f, 0.0f),
Rotation(0.0f, 0.0f, 0.0f),
Scale(1.0f, 1.0f, 1.0f),
Front(0.0f, 0.0f, 1.0f),
Up(0.0f, 1.0f, 0.0f),
Right(1.0f, 0.0f, 0.0f),
WorldUp(0.0f, 1.0f, 0.0f)
{}
void Update()
{
Input->Update();
Graphics->Update();
Physics->Update();
}
protected:
InputComponent* Input;
GraphicsComponent* Graphics;
PhysicsComponent* Physics;
glm::vec3 Front;
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
};

8
GraphicsComponent.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
class GraphicsComponent
{
public:
virtual ~GraphicsComponent() {};
virtual void Update() = 0;
};

8
InputComponent.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
class InputComponent
{
public:
virtual ~InputComponent() {};
virtual void Update() = 0;
};

View File

@@ -134,7 +134,20 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\..\Development Tools\glad\src\glad.c" />
<ClCompile Include="imgui\backends\imgui_impl_glfw.cpp" />
<ClCompile Include="imgui\backends\imgui_impl_opengl3.cpp" />
<ClCompile Include="imgui\imgui.cpp" />
<ClCompile Include="imgui\imgui_draw.cpp" />
<ClCompile Include="imgui\imgui_tables.cpp" />
<ClCompile Include="imgui\imgui_widgets.cpp" />
<ClCompile Include="LevelMap.cpp" />
<ClCompile Include="Light.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="MeshRenderer.cpp" />
<ClCompile Include="Player.cpp" />
<ClCompile Include="PointLight.cpp" />
<ClCompile Include="ResourceManager.cpp" />
<ClCompile Include="Shader.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="cube.frag" />
@@ -142,13 +155,36 @@
<None Include="fragment.frag" />
<None Include="light.frag" />
<None Include="light.vert" />
<None Include="point_shadow_depth.frag" />
<None Include="point_shadow_depth.geom" />
<None Include="point_shadow_depth.vert" />
<None Include="vertex.vert" />
<None Include="wall.frag" />
<None Include="wall.vert" />
<None Include="wall_test.frag" />
<None Include="wall_test.vert" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="camera.h" />
<ClInclude Include="Camera.h" />
<ClInclude Include="cube.h" />
<ClInclude Include="cubeFactory.h" />
<ClInclude Include="shader.h" />
<ClInclude Include="GameObject.h" />
<ClInclude Include="GraphicsComponent.h" />
<ClInclude Include="InputComponent.h" />
<ClInclude Include="LevelMap.h" />
<ClInclude Include="Light.h" />
<ClInclude Include="map_reader.h" />
<ClInclude Include="MeshRenderer.h" />
<ClInclude Include="PhysicsComponent.h" />
<ClInclude Include="Player.h" />
<ClInclude Include="PlayerInputComponent.h" />
<ClInclude Include="PointLight.h" />
<ClInclude Include="ResourceManager.h" />
<ClInclude Include="Shader.h" />
</ItemGroup>
<ItemGroup>
<Text Include="map_test.txt" />
<Text Include="map_test_2.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -21,6 +21,45 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_draw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_tables.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\imgui_widgets.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_glfw.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imgui\backends\imgui_impl_opengl3.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Player.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MeshRenderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Shader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ResourceManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LevelMap.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Light.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PointLight.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="fragment.frag" />
@@ -29,19 +68,66 @@
<None Include="cube.frag" />
<None Include="light.vert" />
<None Include="light.frag" />
<None Include="wall.vert" />
<None Include="wall.frag" />
<None Include="wall_test.vert" />
<None Include="wall_test.frag" />
<None Include="point_shadow_depth.vert" />
<None Include="point_shadow_depth.frag" />
<None Include="point_shadow_depth.geom" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cube.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="camera.h">
<ClInclude Include="Camera.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="cubeFactory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="map_reader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameObject.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Player.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PlayerInputComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PhysicsComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GraphicsComponent.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MeshRenderer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Shader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ResourceManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LevelMap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Light.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PointLight.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="map_test.txt" />
<Text Include="map_test_2.txt" />
</ItemGroup>
</Project>

275
LevelMap.cpp Normal file
View File

@@ -0,0 +1,275 @@
#include "LevelMap.h"
#include <iostream>
LevelMap::LevelMap()
{
}
LevelMap::~LevelMap()
{
}
void LevelMap::Compile(std::string level_map_code)
{
std::stringstream level_map_stream(level_map_code);
std::string line;
bool in_sector = false, in_wall = false;
unsigned int sector_index = 0;
unsigned int wall_index = 0;
while (std::getline(level_map_stream, line))
{
if (line.empty() || line[0] == '#') continue;
if (line.find("[SECTOR]") != std::string::npos)
{
in_sector = true;
in_wall = false;
continue;
}
if (line.find("[WALL]") != std::string::npos)
{
in_sector = false;
in_wall = true;
continue;
}
if (in_sector)
{
Sector sector = ParseSector(line);
sectors.push_back(sector);
}
if (in_wall && !sectors.empty())
{
Wall wall = ParseWall(line);
if (wall_index >= sectors[sector_index].number_of_walls)
{
sector_index++;
wall_index = 0;
}
sectors[sector_index].walls.push_back(wall);
wall_index++;
}
}
wall_index = 0;
unsigned int floor_index = 0;
unsigned int ceiling_index = 0;
for (Sector& sector : sectors)
{
std::vector<glm::vec3> floor_vertices;
std::vector<glm::vec3> ceiling_vertices;
for (Wall& wall : sector.walls)
{
glm::vec3 floor_vertex(wall.a.x, sector.floor_height, wall.a.y);
glm::vec3 ceiling_vertex(wall.a.x, sector.ceiling_height, wall.a.y);
floor_vertices.push_back(floor_vertex);
ceiling_vertices.push_back(ceiling_vertex);
AddWall(sector, wall, wall_index);
}
AddFloor(sector, floor_vertices);
AddCeiling(sector, ceiling_vertices);
//AddFloorOrCeiling(sector, floor_vertices, true);
//AddFloorOrCeiling(sector, ceiling_vertices, false);
}
}
void LevelMap::RenderSetup
(
Shader *wall_shader,
Shader *floor_shader,
Shader *ceiling_shader
)
{
wall_renderer.Setup(wall_vertices, wall_normals, wall_colors, wall_indices, wall_shader);
floor_renderer.Setup(floor_vertices, floor_normals, floor_colors, floor_indices, floor_shader);
ceiling_renderer.Setup(ceiling_vertices, ceiling_normals, ceiling_colors, ceiling_indices, ceiling_shader);
}
void LevelMap::Update(glm::mat4 projection, glm::mat4 view, glm::vec3 light_position, glm::vec3 light_color, glm::vec3 view_position)
{
wall_renderer.Render(projection, view, light_position, light_color, view_position);
floor_renderer.Render(projection, view, light_position, light_color, view_position);
ceiling_renderer.Render(projection, view, light_position, light_color, view_position);
}
std::vector<MeshRenderer*> LevelMap::GetMeshes()
{
return { &wall_renderer, &floor_renderer, &ceiling_renderer };
}
Sector LevelMap::ParseSector(std::string& line)
{
Sector sector;
std::stringstream ss(line);
ss >> sector.index >> sector.number_of_walls >> sector.floor_height >> sector.ceiling_height >> sector.outward_facing >> sector.color.x >> sector.color.y >> sector.color.z;
/*static std::random_device rd; // Obtain a random number from hardware
static std::mt19937 eng(rd()); // Seed the generator
std::uniform_real_distribution<float> distr(0.0f, 1.0f); // Define the range
glm::vec3 randomColor(distr(eng), distr(eng), distr(eng));*/
//sector.color = glm::vec3(sector.index+1 / 5.0f, 0.0f, sector.index+1 / 7.0f);
return sector;
}
Wall LevelMap::ParseWall(std::string& line)
{
Wall wall;
std::stringstream ss(line);
ss >> wall.a.x >> wall.a.y >> wall.b.x >> wall.b.y >> wall.portal;
return wall;
}
void LevelMap::AddWall(Sector& sector, Wall& wall, unsigned int& wall_index)
{
glm::vec3 v0(wall.a.x, sector.floor_height, wall.a.y);
glm::vec3 v1(wall.a.x, sector.ceiling_height, wall.a.y);
glm::vec3 v2(wall.b.x, sector.ceiling_height, wall.b.y);
glm::vec3 v3(wall.b.x, sector.floor_height, wall.b.y);
glm::vec3 normal = glm::normalize(glm::cross(v1 - v0, v3 - v1));
normal = sector.outward_facing ? -normal : normal;
if (sector.outward_facing)
{
std::swap(v0, v3);
std::swap(v1, v2);
}
if (wall.portal == 0)
{
AddVertices({ v0, v1, v2, v3 }, wall_vertices);
AddNormals({ normal, normal, normal, normal }, wall_normals);
AddColors({ sector.color, sector.color, sector.color, sector.color }, wall_colors);
AddIndices({ wall_index, wall_index + 1, wall_index + 2, wall_index, wall_index + 2, wall_index + 3 }, wall_indices);
wall_index += 4;
}
else
{
Sector& portal_sector = sectors[wall.portal - 1];
if (portal_sector.floor_height > sector.floor_height)
{
v1.y = portal_sector.floor_height;
v2.y = portal_sector.floor_height;
AddVertices({ v0, v1, v2, v3 }, wall_vertices);
AddNormals({ normal, normal, normal, normal }, wall_normals);
AddColors({ sector.color, sector.color, sector.color, sector.color }, wall_colors);
AddIndices({ wall_index, wall_index + 1, wall_index + 2, wall_index, wall_index + 2, wall_index + 3 }, wall_indices);
wall_index += 4;
}
if (portal_sector.ceiling_height < sector.ceiling_height)
{
v0.y = portal_sector.ceiling_height;
v1.y = sector.ceiling_height;
v2.y = sector.ceiling_height;
v3.y = portal_sector.ceiling_height;;
AddVertices({ v0, v1, v2, v3 }, wall_vertices);
AddNormals({ normal, normal, normal, normal }, wall_normals);
AddColors({ sector.color, sector.color, sector.color, sector.color }, wall_colors);
AddIndices({ wall_index, wall_index + 1, wall_index + 2, wall_index, wall_index + 2, wall_index + 3 }, wall_indices);
wall_index += 4;
}
}
}
void LevelMap::AddFloor(Sector& sector, std::vector<glm::vec3> vertices)
{
unsigned int starting_index = sector.index;
unsigned int _index = starting_index + 1;
glm::vec3 normal = glm::vec3(0.0f, 1.0f, 0.0f);
for (int i = vertices.size() - 1; i >= 0; i--)
{
AddVertices({ vertices[i] }, floor_vertices);
AddNormals({ normal }, floor_normals);
AddColors({ glm::vec3(1.0f) - sector.color }, floor_colors);
if (_index + 1 < sector.index + sector.number_of_walls)
{
unsigned int next_index = _index + 1;
AddIndices({ starting_index, _index, next_index }, floor_indices);
_index++;
}
}
}
void LevelMap::AddCeiling(Sector& sector, std::vector<glm::vec3> vertices)
{
unsigned int starting_index = sector.index;
unsigned int _index = starting_index + 1;
glm::vec3 normal = glm::vec3(0.0f, 1.0f, 0.0f);
normal = -normal;
for (int i = 0; i < vertices.size(); i++)
{
AddVertices({ vertices[i] }, ceiling_vertices);
AddNormals({ normal }, ceiling_normals);
AddColors({ glm::vec3(1.0f) - sector.color }, ceiling_colors);
if ( _index + 1 < sector.index + sector.number_of_walls)
{
unsigned int next_index = _index + 1;
AddIndices({ starting_index, _index, next_index }, ceiling_indices);
_index++;
}
}
}
void LevelMap::AddVertices(std::vector<glm::vec3> vertices, std::vector<float>& target_vertices)
{
for (unsigned int i = 0; i < vertices.size(); i += 1)
{
target_vertices.push_back(vertices[i].x);
target_vertices.push_back(vertices[i].y);
target_vertices.push_back(vertices[i].z);
}
}
void LevelMap::AddNormals(std::vector<glm::vec3> normals, std::vector<float>& target_normals)
{
for (unsigned int i = 0; i < normals.size(); i += 1)
{
target_normals.push_back(normals[i].x);
target_normals.push_back(normals[i].y);
target_normals.push_back(normals[i].z);
}
}
void LevelMap::AddColors(std::vector<glm::vec3> colors, std::vector<float>& target_colors)
{
for (unsigned int i = 0; i < colors.size(); i += 1)
{
target_colors.push_back(colors[i].x);
target_colors.push_back(colors[i].y);
target_colors.push_back(colors[i].z);
}
}
void LevelMap::AddIndices(std::vector<unsigned int> indices, std::vector<unsigned int>& target_indices)
{
for (unsigned int i = 0; i < indices.size(); i += 1)
{
target_indices.push_back(indices[i]);
}
}

94
LevelMap.h Normal file
View File

@@ -0,0 +1,94 @@
#pragma once
#include <vector>
#include <sstream>
#include <random>
#include <glm/glm.hpp>
#include "MeshRenderer.h"
struct Wall
{
glm::vec2 a, b;
int portal;
};
struct Sector
{
unsigned int index;
unsigned int number_of_walls;
float floor_height;
float ceiling_height;
bool outward_facing;
glm::vec3 color;
std::vector<Wall> walls;
};
class LevelMap
{
public:
LevelMap();
~LevelMap();
void Compile(std::string level_map_code);
void RenderSetup
(
Shader *wall_shader,
Shader *floor_shader,
Shader *ceiling_shader
);
void Update
(
glm::mat4 projection,
glm::mat4 view,
glm::vec3 light_position,
glm::vec3 light_color,
glm::vec3 view_position
);
std::vector<MeshRenderer*> GetMeshes();
private:
std::vector<Sector> sectors;
std::vector<float> wall_vertices;
std::vector<float> wall_normals;
std::vector<float> wall_colors;
std::vector<unsigned int> wall_indices;
MeshRenderer wall_renderer;
Shader wall_shader;
std::vector<float> floor_vertices;
std::vector<float> floor_normals;
std::vector<float> floor_colors;
std::vector<unsigned int> floor_indices;
MeshRenderer floor_renderer;
Shader floor_shader;
std::vector<float> ceiling_vertices;
std::vector<float> ceiling_normals;
std::vector<float> ceiling_colors;
std::vector<unsigned int> ceiling_indices;
MeshRenderer ceiling_renderer;
Shader ceiling_shader;
Sector ParseSector(std::string& line);
Wall ParseWall(std::string& line);
void AddWall(Sector& sector, Wall& wall, unsigned int& wall_index);
void AddFloor(Sector& sector, std::vector<glm::vec3> vertices);
void AddCeiling(Sector& sector, std::vector<glm::vec3> vertices);
void AddVertices(std::vector<glm::vec3> vertices, std::vector<float>& target_vertices);
void AddNormals(std::vector<glm::vec3> normals, std::vector<float>& target_normals);
void AddColors(std::vector<glm::vec3> colors, std::vector<float>& target_colors);
void AddIndices(std::vector<unsigned int> indices, std::vector<unsigned int>& target_indices);
};

1
Light.cpp Normal file
View File

@@ -0,0 +1 @@
#include "Light.h"

0
Light.h Normal file
View File

240
MeshRenderer.cpp Normal file
View File

@@ -0,0 +1,240 @@
#include <MeshRenderer.h>
#include <iostream>
// when creating a meshrenderer the important question is "do all these vertices share the same shader?"
MeshRenderer::MeshRenderer()
{
}
MeshRenderer::~MeshRenderer()
{
glDeleteVertexArrays(1, &this->VAO);
}
void MeshRenderer::Setup
(
std::vector<float> vertices,
std::vector<float> normals,
std::vector<float> colors,
std::vector<unsigned int> indices,
Shader* lit_shader
)
{
this->vertices = vertices;
this->normals = normals;
this->colors = colors;
this->indices = indices;
this->lit_shader = lit_shader;
this->shadow_shader = shadow_shader;
this->SetupBuffers();
//if (shadow_shader != nullptr)
//{
// //std::cout << "Setup lighting" << std::endl;
// this->SetupLighting();
//}
}
void MeshRenderer::Render(Shader &shader)
{
//std::cout << "Rendering with Shader: " << shader.ID << std::endl;
shader.Use();
glm::mat4 model = glm::mat4(1.0f);
shader.SetMatrix4("model", model);
glBindVertexArray(this->VAO);
//std::cout << this->indices.size() << std::endl;
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void MeshRenderer::Render
(
glm::mat4 projection,
glm::mat4 view,
glm::vec3 light_position,
glm::vec3 light_color,
glm::vec3 view_position
)
{
glm::mat4 model = glm::mat4(1.0f);
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
//if (shadow_shader != nullptr)
//{
// this->shader = shadow_shader;
// RenderShadows(projection, view, model, light_position);
//}
this->shader = lit_shader;
RenderObject(projection, view, model, light_position, light_color, view_position);
}
void MeshRenderer::Render
(
glm::mat4 projection,
glm::mat4 view,
glm::vec3 light_position,
glm::vec3 light_color,
glm::vec3 view_position,
glm::vec3 position,
glm::vec3 scale,
glm::vec3 rotation
)
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, position);
model = glm::rotate(model, glm::radians(rotation.x), glm::vec3(1, 0, 0));
model = glm::rotate(model, glm::radians(rotation.y), glm::vec3(0, 1, 0));
model = glm::rotate(model, glm::radians(rotation.z), glm::vec3(0, 0, 1));
model = glm::scale(model, scale);
if (shadow_shader != nullptr)
{
this->lit_shader = shadow_shader;
RenderShadows(projection, view, model, light_position);
}
this->shader = lit_shader;
RenderObject(projection, view, model, light_position, light_color, view_position);
}
void MeshRenderer::SetupBuffers()
{
/*for (int i = 0; i < this->normals.size(); i += 3)
{
std::cout << this->normals[i] << " " << this->normals[i + 1] << " " << this->normals[i + 2] << std::endl;
}*/
glGenVertexArrays(1, &this->VAO);
unsigned int VBO, NBO, CBO, EBO;
glGenBuffers(1, &VBO);
glGenBuffers(1, &NBO);
glGenBuffers(1, &CBO);
glGenBuffers(1, &EBO);
glBindVertexArray(this->VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(float), this->vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, NBO);
glBufferData(GL_ARRAY_BUFFER, this->normals.size() * sizeof(float), this->normals.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, CBO);
glBufferData(GL_ARRAY_BUFFER, this->colors.size() * sizeof(float), this->colors.data(), GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(unsigned int), this->indices.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
}
void MeshRenderer::SetupLighting()
{
/*glGenFramebuffers(1, &depth_map_FBO);
glGenTextures(1, &depth_map);
for (unsigned int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_map, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);*/
}
void MeshRenderer::RenderObject
(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 model,
glm::vec3 light_position,
glm::vec3 light_color,
glm::vec3 view_position
)
{
this->shader->Use();
this->shader->SetMatrix4("projection", projection);
this->shader->SetMatrix4("view", view);
this->shader->SetMatrix4("model", model);
this->shader->SetVector3f("lightPos", light_position);
this->shader->SetVector3f("lightColor", light_color);
this->shader->SetVector3f("viewPos", view_position);
this->shader->SetFloat("far_plane", 25.0f);
glBindVertexArray(this->VAO);
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void MeshRenderer::RenderShadows(glm::mat4 projection, glm::mat4 view, glm::mat4 model, glm::vec3 light_position)
{
this->shader->Use();
this->shader->SetMatrix4("projection", projection);
this->shader->SetMatrix4("view", view);
this->shader->SetMatrix4("model", model);
float near_plane = 1.0f;
float far_plane = 50.0f;
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane);
std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(light_position, light_position + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO);
//glClear(GL_DEPTH_BUFFER_BIT);
for (unsigned int i = 0; i < 6; ++i)
{
std::string matrix_name = "shadowMatrices[" + std::to_string(i) + "]";
this->shader->SetMatrix4(matrix_name.c_str(), shadowTransforms[i]);
}
this->shader->SetFloat("far_plane", far_plane);
this->shader->SetVector3f("lightPos", light_position);
glBindVertexArray(this->VAO);
glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_CUBE_MAP, depth_map);
}

56
MeshRenderer.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
#include <vector>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Shader.h"
class MeshRenderer
{
public:
MeshRenderer();
~MeshRenderer();
void Setup
(
std::vector<float> vertices,
std::vector<float> normals,
std::vector<float> colors,
std::vector<unsigned int> indices,
Shader* lit_shader
);
void Render(Shader &shader);
void Render(glm::mat4 projection, glm::mat4 view, glm::vec3 light_position, glm::vec3 light_color, glm::vec3 view_position);
void Render(glm::mat4 projection, glm::mat4 view, glm::vec3 light_position, glm::vec3 light_color, glm::vec3 view_position, glm::vec3 position, glm::vec3 scale, glm::vec3 rotation);
private:
std::vector<float> vertices;
std::vector<float> normals;
std::vector<float> colors;
std::vector<unsigned int> indices;
unsigned int VAO;
unsigned int depth_map;
unsigned int depth_map_FBO;
unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
int SCR_WIDTH = 1600;
int SCR_HEIGHT = 900;
Shader *shader;
Shader *lit_shader;
Shader *shadow_shader;
void SetupBuffers();
void SetupLighting();
void RenderObject(glm::mat4 projection, glm::mat4 view, glm::mat4 model, glm::vec3 light_position, glm::vec3 light_color, glm::vec3 view_position);
void RenderShadows(glm::mat4 projection, glm::mat4 view, glm::mat4 model, glm::vec3 light_position);
};

8
PhysicsComponent.h Normal file
View File

@@ -0,0 +1,8 @@
#pragma once
class PhysicsComponent
{
public:
virtual ~PhysicsComponent() {};
virtual void Update() = 0;
};

64
Player.cpp Normal file
View File

@@ -0,0 +1,64 @@
#include "Player.h"
#include "Camera.h"
#include <iostream>
Player::Player(glm::vec3 Position, glm::vec3 Rotation)
: GameObject(Position, Rotation, glm::vec3(1.0f, 1.0f, 1.0f)),
PlayerCamera(new Camera(glm::vec3(0.0f, 1.0f, 0.0f)))
{
PlayerCamera->Position = Position + PlayerCamera->CameraOffset;
PlayerCamera->WorldUp = this->WorldUp;
std::cout << "{" << Position.x << ", " << Position.y << ", " << Position.z << "}" << std::endl;
std::cout << "{" << PlayerCamera->Position.x << ", " << PlayerCamera->Position.y << ", " << PlayerCamera->Position.z << "}" << std::endl;
}
void Player::Update()
{
}
void Player::ProcessKeyboard(EInputDirection Direction, float Delta)
{
float Velocity = bIsRunning ? RunSpeed : WalkSpeed;
Velocity = Velocity * Delta;
if (Direction == FORWARD)
Position += Front * Velocity;
if (Direction == BACKWARD)
Position -= Front * Velocity;
if (Direction == LEFT)
Position -= Right * Velocity;
if (Direction == RIGHT)
Position += Right * Velocity;
PlayerCamera->Position = Position + PlayerCamera->CameraOffset;
PlayerCamera->WorldUp = this->WorldUp;
}
void Player::ProcessMouseMovement(float XOffset, float YOffset, GLboolean bConstrainPitch)
{
XOffset *= MOUSE_SENSITIVITY;
YOffset *= MOUSE_SENSITIVITY;
Yaw += XOffset;
PlayerCamera->Yaw = Yaw;
PlayerCamera->ProcessMouseMovement(XOffset, YOffset);
UpdatePlayerVectors();
}
glm::mat4 Player::GetViewMatrix() const
{
return PlayerCamera->GetViewMatrix();
}
void Player::UpdatePlayerVectors()
{
glm::vec3 UpdatedFront;
UpdatedFront.x = cos(glm::radians(Yaw)) * cos(0);
UpdatedFront.y = sin(0);
UpdatedFront.z = sin(glm::radians(Yaw)) * cos(0);
Front = glm::normalize(UpdatedFront);
Right = glm::normalize(glm::cross(Front, WorldUp));
Up = glm::normalize(glm::cross(Right, Front));
}

43
Player.h Normal file
View File

@@ -0,0 +1,43 @@
#pragma once
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <GameObject.h>
#include <Camera.h>
enum EInputDirection
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
class Player : public GameObject
{
public:
Player(glm::vec3 Position, glm::vec3 Rotation);
~Player() = default;
void Update();
void ProcessKeyboard(EInputDirection Direction, float Delta);
void ProcessMouseMovement(float XOffset, float YOffset, GLboolean ConstrainPitch = true);
glm::mat4 GetViewMatrix() const;
private:
Camera* PlayerCamera;
float Yaw;
float MouseSensitivity;
float WalkSpeed = 5.0f;
float RunSpeed = 15.0f;
bool bIsRunning = false;
void UpdatePlayerVectors();
};

22
PlayerInputComponent.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <InputComponent.h>
enum EInputDirection
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
};
class PlayerInputComponent : public InputComponent
{
private:
public:
virtual void Update(float deltaTime)
{
}
};

1
PointLight.cpp Normal file
View File

@@ -0,0 +1 @@
#include "PointLight.h"

115
PointLight.h Normal file
View File

@@ -0,0 +1,115 @@
#pragma once
#include <vector>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include "Shader.h"
#include "MeshRenderer.h"
#define SHADOW_WIDTH 1024
#define SHADOW_HEIGHT 1024
class PointLight
{
public:
unsigned int depth_map, depth_map_FBO;
float near_plane = 1.0f,
far_plane = 100.0f,
ambient_intensity = 0.5f,
diffuse_intensity = 1.0f,
attenuation_constant = 1.0f,
attenuation_linear = 0.09f,
attenuation_exponential = 0.032f;
glm::vec3 Position;
glm::vec3 color;
Shader shader;
PointLight(glm::vec3 position, glm::vec3 color, Shader shader)
{
this->Position = position;
this->color = color;
this->shader = shader;
SetupLighting();
}
void RenderSceneShadows(std::vector<MeshRenderer*> meshes)
{
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane);
std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Right
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Left
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f))); // Up
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f))); // Down
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Forward
shadowTransforms.push_back(shadowProj * glm::lookAt(Position, Position + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))); // Backward
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO);
glClear(GL_DEPTH_BUFFER_BIT);
shader.Use();
for (unsigned int i = 0; i < 6; ++i)
{
std::string matrix_name = "shadowMatrices[" + std::to_string(i) + "]";
shader.SetMatrix4(matrix_name.c_str(), shadowTransforms[i]);
}
shader.SetFloat("farPlane", far_plane);
shader.SetVector3f("lightPosition", Position);
for (MeshRenderer* mesh : meshes)
{
mesh->Render(shader);
}
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "Framebuffer not complete!" << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glCullFace(GL_BACK);
}
private:
void SetupLighting()
{
//std::cout << "SetupLighting" << std::endl;
glGenFramebuffers(1, &depth_map_FBO);
glGenTextures(1, &depth_map);
glBindTexture(GL_TEXTURE_CUBE_MAP, depth_map);
for (unsigned int i = 0; i < 6; i++)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, depth_map_FBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_map, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "Framebuffer not complete!" << std::endl;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
};

102
ResourceManager.cpp Normal file
View File

@@ -0,0 +1,102 @@
#include "ResourceManager.h"
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
// Instantiate static variables
std::map<std::string, Shader> ResourceManager::shaders;
std::map<std::string, LevelMap> ResourceManager::levelMaps;
Shader ResourceManager::LoadShader(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile, std::string name)
{
shaders[name] = LoadShaderFromFile(vShaderFile, fShaderFile, gShaderFile);
return shaders[name];
}
Shader ResourceManager::GetShader(std::string name)
{
return shaders[name];
}
void ResourceManager::Clear()
{
// (properly) delete all shaders
for (auto iter : shaders)
glDeleteProgram(iter.second.ID);
}
Shader ResourceManager::LoadShaderFromFile(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::string geometryCode;
try
{
// open files
std::ifstream vertexShaderFile(vShaderFile);
std::ifstream fragmentShaderFile(fShaderFile);
std::stringstream vShaderStream, fShaderStream;
// read file's buffer contents into streams
vShaderStream << vertexShaderFile.rdbuf();
fShaderStream << fragmentShaderFile.rdbuf();
// close file handlers
vertexShaderFile.close();
fragmentShaderFile.close();
// convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
// if geometry shader path is present, also load a geometry shader
if (gShaderFile != nullptr)
{
std::ifstream geometryShaderFile(gShaderFile);
std::stringstream gShaderStream;
gShaderStream << geometryShaderFile.rdbuf();
geometryShaderFile.close();
geometryCode = gShaderStream.str();
}
}
catch (std::exception e)
{
std::cout << "ERROR::SHADER: Failed to read shader files" << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
const char* gShaderCode = geometryCode.c_str();
// 2. now create shader object from source code
Shader shader;
shader.Compile(vShaderCode, fShaderCode, gShaderFile != nullptr ? gShaderCode : nullptr);
return shader;
}
LevelMap ResourceManager::LoadLevelMap(const char* filePath, std::string name)
{
levelMaps[name] = LoadLevelMapFromFile(filePath);
return levelMaps[name];
}
LevelMap ResourceManager::LoadLevelMapFromFile(const char* filePath)
{
std::string level_map_code;
try
{
std::ifstream level_map_file(filePath);
std::stringstream level_map_stream;
level_map_stream << level_map_file.rdbuf();
level_map_file.close();
level_map_code = level_map_stream.str();
}
catch (std::exception e)
{
std::cout << "ERROR::LEVELMAP: Failed to read level map file: " << filePath << std::endl;
}
LevelMap level_map;
level_map.Compile(level_map_code);
return level_map;
}

33
ResourceManager.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <map>
#include <string>
#include <glad/glad.h>
#include "Shader.h"
#include "LevelMap.h"
class ResourceManager
{
public:
// resource storage
static std::map<std::string, Shader> shaders;
static std::map<std::string, LevelMap> levelMaps;
// loads (and generates) a shader program from file loading vertex, fragment (and geometry) shader's source code. If gShaderFile is not nullptr, it also loads a geometry shader
static Shader LoadShader(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile, std::string name);
// retrieves a stored sader
static Shader GetShader(std::string name);
// properly de-allocates all loaded resources
static void Clear();
static LevelMap LoadLevelMap(const char* filePath, std::string name);
private:
// private constructor, that is we do not want any actual resource manager objects. Its members and functions should be publicly available (static).
ResourceManager() { }
// loads and generates a shader from file
static Shader LoadShaderFromFile(const char* vShaderFile, const char* fShaderFile, const char* gShaderFile = nullptr);
static LevelMap LoadLevelMapFromFile(const char* filePath);
};

129
Shader.cpp Normal file
View File

@@ -0,0 +1,129 @@
#include "Shader.h"
#include <iostream>
Shader& Shader::Use()
{
glUseProgram(this->ID);
return *this;
}
void Shader::Compile(const char* vertexSource, const char* fragmentSource, const char* geometrySource)
{
unsigned int sVertex, sFragment, gShader;
// vertex Shader
sVertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(sVertex, 1, &vertexSource, NULL);
glCompileShader(sVertex);
checkCompileErrors(sVertex, "VERTEX");
// fragment Shader
sFragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(sFragment, 1, &fragmentSource, NULL);
glCompileShader(sFragment);
checkCompileErrors(sFragment, "FRAGMENT");
// if geometry shader source code is given, also compile geometry shader
if (geometrySource != nullptr)
{
gShader = glCreateShader(GL_GEOMETRY_SHADER);
glShaderSource(gShader, 1, &geometrySource, NULL);
glCompileShader(gShader);
checkCompileErrors(gShader, "GEOMETRY");
}
// shader program
this->ID = glCreateProgram();
glAttachShader(this->ID, sVertex);
glAttachShader(this->ID, sFragment);
if (geometrySource != nullptr)
glAttachShader(this->ID, gShader);
glLinkProgram(this->ID);
checkCompileErrors(this->ID, "PROGRAM");
// delete the shaders as they're linked into our program now and no longer necessary
glDeleteShader(sVertex);
glDeleteShader(sFragment);
if (geometrySource != nullptr)
glDeleteShader(gShader);
}
void Shader::SetFloat(const char* name, float value, bool useShader)
{
if (useShader)
this->Use();
glUniform1f(glGetUniformLocation(this->ID, name), value);
}
void Shader::SetInteger(const char* name, int value, bool useShader)
{
if (useShader)
this->Use();
glUniform1i(glGetUniformLocation(this->ID, name), value);
}
void Shader::SetVector2f(const char* name, float x, float y, bool useShader)
{
if (useShader)
this->Use();
glUniform2f(glGetUniformLocation(this->ID, name), x, y);
}
void Shader::SetVector2f(const char* name, const glm::vec2& value, bool useShader)
{
if (useShader)
this->Use();
glUniform2f(glGetUniformLocation(this->ID, name), value.x, value.y);
}
void Shader::SetVector3f(const char* name, float x, float y, float z, bool useShader)
{
if (useShader)
this->Use();
glUniform3f(glGetUniformLocation(this->ID, name), x, y, z);
}
void Shader::SetVector3f(const char* name, const glm::vec3& value, bool useShader)
{
if (useShader)
this->Use();
glUniform3f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z);
}
void Shader::SetVector4f(const char* name, float x, float y, float z, float w, bool useShader)
{
if (useShader)
this->Use();
glUniform4f(glGetUniformLocation(this->ID, name), x, y, z, w);
}
void Shader::SetVector4f(const char* name, const glm::vec4& value, bool useShader)
{
if (useShader)
this->Use();
glUniform4f(glGetUniformLocation(this->ID, name), value.x, value.y, value.z, value.w);
}
void Shader::SetMatrix4(const char* name, const glm::mat4& matrix, bool useShader)
{
if (useShader)
this->Use();
glUniformMatrix4fv(glGetUniformLocation(this->ID, name), 1, false, glm::value_ptr(matrix));
}
void Shader::checkCompileErrors(unsigned int object, std::string type)
{
int success;
char infoLog[1024];
if (type != "PROGRAM")
{
glGetShaderiv(object, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(object, 1024, NULL, infoLog);
std::cout << "| ERROR::SHADER: Compile-time error: Type: " << type << "\n"
<< infoLog << "\n -- --------------------------------------------------- -- "
<< std::endl;
}
}
else
{
glGetProgramiv(object, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(object, 1024, NULL, infoLog);
std::cout << "| ERROR::Shader: Link-time error: Type: " << type << "\n"
<< infoLog << "\n -- --------------------------------------------------- -- "
<< std::endl;
}
}
}

View File

@@ -8,16 +8,16 @@
enum Camera_Movement
{
FORWARD,
BACKWARD,
LEFT,
RIGHT
_FORWARD,
_BACKWARD,
_LEFT,
_RIGHT
};
const float YAW = -90.0f;
const float PITCH = 0.0f;
const float SPEED = 2.5f;
const float SENSITIVITY = 0.1f;
const float SPEED = 5.0f;
const float MOUSE_SENSITIVITY = 0.1f;
const float ZOOM = 45.0f;
class Camera
@@ -28,6 +28,7 @@ public:
glm::vec3 Up;
glm::vec3 Right;
glm::vec3 WorldUp;
glm::vec3 CameraOffset;
float Yaw;
float Pitch;
@@ -39,15 +40,17 @@ public:
Camera(
glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3 offset = glm::vec3(0.0f, 1.0f, 0.0f),
float yaw = YAW,
float pitch = PITCH)
:
Front(glm::vec3(0.0f, 0.0f, -1.0f)),
MovementSpeed(SPEED),
MouseSensitivity(SENSITIVITY),
MouseSensitivity(MOUSE_SENSITIVITY),
Zoom(ZOOM)
{
Position = position;
CameraOffset = offset;
WorldUp = up;
Yaw = yaw;
Pitch = pitch;
@@ -62,25 +65,22 @@ public:
void ProcessKeyboard(Camera_Movement direction, float deltaTime)
{
float velocity = MovementSpeed * deltaTime;
if (direction == FORWARD)
if (direction == _FORWARD)
Position += Front * velocity;
if (direction == BACKWARD)
if (direction == _BACKWARD)
Position -= Front * velocity;
if (direction == LEFT)
if (direction == _LEFT)
Position -= Right * velocity;
if (direction == RIGHT)
if (direction == _RIGHT)
Position += Right * velocity;
}
void ProcessMouseMovement(float xoffset, float yoffset, GLboolean constrainPitch = true)
void ProcessMouseMovement(float XOffset, float YOffset, GLboolean bConstrainPitch = true)
{
xoffset *= MouseSensitivity;
yoffset *= MouseSensitivity;
//Yaw += XOffset;
Pitch += YOffset;
Yaw += xoffset;
Pitch += yoffset;
if (constrainPitch)
if (bConstrainPitch)
{
if (Pitch > 89.0f)
Pitch = 89.0f;
@@ -100,6 +100,7 @@ public:
Zoom = 45.0f;
}
private:
void updateCameraVectors()
{
glm::vec3 front;

10
cube.h
View File

@@ -10,7 +10,7 @@
class Cube
{
private:
glm::vec3 position;
glm::vec3 Position;
glm::vec3 scale;
glm::vec3 rotation;
glm::vec3 color;
@@ -30,7 +30,7 @@ public:
Cube(glm::vec3 position, glm::vec3 scale, glm::vec3 rotation, glm::vec3 color)
{
this->position = position;
this->Position = position;
this->scale = scale;
this->rotation = rotation;
this->color = color;
@@ -48,7 +48,7 @@ public:
glm::mat4 getModelMatrix() const
{
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, position);
model = glm::translate(model, Position);
model = glm::rotate(model, glm::radians(rotation.x), glm::vec3(1, 0, 0));
model = glm::rotate(model, glm::radians(rotation.y), glm::vec3(0, 1, 0));
model = glm::rotate(model, glm::radians(rotation.z), glm::vec3(0, 0, 1));
@@ -59,7 +59,7 @@ public:
void setPosition(glm::vec3 position)
{
this->position = position;
this->Position = position;
}
void setScale(glm::vec3 scale)
@@ -79,7 +79,7 @@ public:
glm::vec3 getPosition() const
{
return position;
return Position;
}
glm::vec3 getScale() const

View File

@@ -153,6 +153,43 @@ public:
}
}
void render(glm::mat4 view, glm::mat4 projection, glm::vec3 lightPos, float deltaTime, int amountOfCubes)
{
shader.use();
shader.setMat4("projection", projection);
shader.setMat4("view", view);
int i = 0;
for (Cube& cube : cubes)
{
if (i >= amountOfCubes)
{
break;
}
//std::cout << "Cube position: (" << cube.getColor().x << "," << cube.getColor().y << "," << cube.getColor().z << ")" << std::endl;
cube.setRotation(cube.getRotation() + (glm::vec3(5.0f, 10.0f, 20.0f)) * deltaTime);
glm::mat4 model = cube.getModelMatrix();
glm::vec3 color = cube.getColor();
shader.setMat4("model", model);
shader.setVec3("objectColor", color);
shader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
shader.setVec3("lightPos", lightPos);
glBindVertexArray(VAO);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawArrays(GL_TRIANGLES, 0, 36);
//glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
//shader.setVec3("objectColor", 0.0f, 0.0f, 0.0f);
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
//glDrawArrays(GL_TRIANGLES, 0, 36);
//glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
i++;
}
}
std::list<Cube> getCubes()
{
return cubes;

12
imgui.ini Normal file
View File

@@ -0,0 +1,12 @@
[Window][Debug##Default]
Pos=60,60
Size=400,400
Collapsed=0
[Window][Settings]
Pos=69,71
Size=445,126
Collapsed=0
[Docking][Data]

1
input_processor.h Normal file
View File

@@ -0,0 +1 @@
#pragma once

262
main.cpp
View File

@@ -7,23 +7,29 @@
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <Camera.h>
#include <Player.h>
#include <imgui.h>
#include <imgui_impl_glfw.h>
#include <imgui_impl_opengl3.h>
#include <camera.h>
#include <cubeFactory.h>
#include "ResourceManager.h"
#include "PointLight.h"
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
int SCR_WIDTH = 800;
int SCR_HEIGHT = 800;
int SCR_WIDTH = 1600;
int SCR_HEIGHT = 900;
//Camera camera(glm::vec3(20.0f, 1.0f, 20.0f));
glm::vec3 StartingPosition = glm::vec3(20.0f, 0.0f, 20.0f);
glm::vec3 StartingRotation = glm::vec3(0.0f, 0.0f, 0.0f);
Player PlayerCharacter(StartingPosition, StartingRotation);
Camera camera(glm::vec3(0.0f, 0.0f, 20.0f));
float lastX = SCR_WIDTH / 2.0f;
float lastY = SCR_HEIGHT / 2.0f;
bool firstMouse = true;
@@ -32,17 +38,13 @@ float deltaTime = 0.0f;
float lastFrame = 0.0f;
float elapsedTime = 0.0f;
int amountOfCubes = 1000;
//glm::vec3 lightPos(1.2f, 1.0f, 2.0f);
int main()
{
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
const char* glsl_version = "#version 330";
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
@@ -61,7 +63,7 @@ int main()
glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback);
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
@@ -69,41 +71,76 @@ int main()
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
std::cout << "Loaded GLFW context, OpenGL 3.3" << std::endl;
CubeFactory cubeFactory;
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
float offset = 2.0f;
int xAmount = 10;
int yAmount = 10;
int zAmount = 10;
//ImGui_ImplGlfw_InitForOpenGL(window, true);
//ImGui_ImplOpenGL3_Init(glsl_version);
for (int x = 0; x < xAmount; x++)
{
for (int y = 0; y < yAmount; y++)
{
for (int z = 0; z < zAmount; z++)
{
glm::vec3 position = glm::vec3( (x * offset) - (xAmount * offset / 2.0f),
(y * offset) - (yAmount * offset / 2.0f),
(z * offset) - (zAmount * offset / 2.0f));
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
glm::vec3 rotation = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 color = glm::vec3(x/10.0f, y/10.0f, z/10.0f);
cubeFactory.addCube(position, scale, rotation, color);
}
}
if (!ImGui_ImplGlfw_InitForOpenGL(window, true)) {
std::cout << "Failed to initialize ImGui GLFW backend" << std::endl;
}
if (!ImGui_ImplOpenGL3_Init(glsl_version)) {
std::cout << "Failed to initialize ImGui OpenGL backend" << std::endl;
}
//std::cout << "Amount of cubes: " << cubeFactory.getCubes().size() << std::endl;
Shader simple_depth_shader = ResourceManager::LoadShader("point_shadow_depth.vert", "point_shadow_depth.frag", "point_shadow_depth.geom", "simple_depth_shader");
Shader wall_shader = ResourceManager::LoadShader("wall_test.vert", "wall_test.frag", nullptr, "wall");
LevelMap level_map = ResourceManager::LoadLevelMap("map_test.txt", "test_level");
level_map.RenderSetup(&wall_shader, &wall_shader, &wall_shader);
int number_of_point_lights = 0;
std::vector<PointLight> point_lights_vector;
//PointLight point_light3(glm::vec3(30.0f, 3.0f, 30.0f), glm::vec3(1.0f, 1.0f, 1.0f), simple_depth_shader);
//PointLight point_light2(glm::vec3(70.0f, 2.0f, 55.0f), glm::vec3(1.0f, 1.0f, 1.0f), simple_depth_shader);
//PointLight point_light(glm::vec3(20.0f, 3.0f, 35.0f), glm::vec3(1.0f, 1.0f, 1.0f), simple_depth_shader);
//PointLight point_lights[3] = { point_light, point_light2, point_light3 };
/*unsigned int depthCubemap, depthMapFBO;
glGenFramebuffers(1, &depthMapFBO);
glGenTextures(1, &depthCubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);
for (unsigned int i = 0; i < 6; ++i)
{
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubemap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);*/
float r = 0.05f, g = 0.05f, b = 0.05f;
while (!glfwWindowShouldClose(window)) {
//timing
float currentFrame = glfwGetTime();
float currentFrame = (float)glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
elapsedTime += deltaTime;
@@ -111,25 +148,142 @@ int main()
//input
processInput(window);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Settings");
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
if (ImGui::Button("Create Light") && number_of_point_lights < 10) {
point_lights_vector.push_back(PointLight(PlayerCharacter.Position, glm::vec3(1.0f, 1.0f, 1.0f), simple_depth_shader));
number_of_point_lights = point_lights_vector.size();
}
//ImGui::SliderInt("Amount of cubes: ", &amountOfCubes, 0, 1000);
ImGui::End();
ImGui::Render();
// view/projection transformations
glClearColor(r, g, b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// view/projection transformations
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = camera.GetViewMatrix();
//glDisable(GL_CULL_FACE);
glm::vec3 lightPos = glm::vec3(100.2f, 100.0f, 200.0f);
//level_map.GetMeshes();
cubeFactory.render(view, projection, lightPos, deltaTime);
for (PointLight& point_light : point_lights_vector)
{
point_light.RenderSceneShadows(level_map.GetMeshes());
}
//for (int i = 0; i < numOfPointLights; i++)
//{
// point_lights[i].RenderSceneShadows(level_map.GetMeshes());
//}
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
wall_shader.Use();
// CHANGED PROJECTION TO USE FLAT 45 TO GET PLAYER CHARACTER TO WORK
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glm::mat4 view = PlayerCharacter.GetViewMatrix();
wall_shader.SetMatrix4("projection", projection);
wall_shader.SetMatrix4("view", view);
wall_shader.SetVector3f("viewPosition", PlayerCharacter.Position);
wall_shader.SetVector3f("material.ambientColor", glm::vec3(1.0f, 0.0f, 0.0f));
wall_shader.SetVector3f("material.diffuseColor", glm::vec3(0.5f, 0.5f, 0.5f));
wall_shader.SetVector3f("material.specularColor", glm::vec3(0.0f, 0.0f, 1.0f));
wall_shader.SetFloat("material.shininess", 1.0f);
// set lighting uniforms
wall_shader.SetInteger("numOfPointLights", number_of_point_lights);
int light_index = 0;
for (PointLight& point_light : point_lights_vector)
{
std::string name = "pointLights[" + std::to_string(light_index) + "].";
wall_shader.SetVector3f((name + "base.color").c_str(), point_light.color);
wall_shader.SetFloat((name + "base.ambientIntensity").c_str(), point_light.ambient_intensity);
wall_shader.SetFloat((name + "base.diffuseIntensity").c_str(), point_light.diffuse_intensity);
wall_shader.SetFloat((name + "atten.constant").c_str(), point_light.attenuation_constant);
wall_shader.SetFloat((name + "atten.linear").c_str(), point_light.attenuation_linear);
wall_shader.SetFloat((name + "atten.exponential").c_str(), point_light.attenuation_exponential);
wall_shader.SetVector3f((name + "position").c_str(), point_light.Position);
wall_shader.SetFloat((name + "farPlane").c_str(), point_light.far_plane);
wall_shader.SetInteger((name + "depthMap").c_str(), light_index);
glActiveTexture(GL_TEXTURE0 + light_index);
glBindTexture(GL_TEXTURE_CUBE_MAP, point_light.depth_map);
light_index++;
}
/*wall_shader.SetVector3f("pointLights[0].base.color", point_light.color);
wall_shader.SetVector3f("pointLights[0].base.ambientIntensity", point_light.ambient);
wall_shader.SetVector3f("pointLights[0].position", point_light.position);
wall_shader.SetVector3f("lightPosition2", point_light2.position);
wall_shader.SetVector3f("lightColor", point_light.color);*/
//wall_shader.SetInteger("shadows", 1); // enable/disable shadows by pressing 'SPACE'
//wall_shader.SetInteger("depthMap", 0);
GLenum err;
while(err = glGetError())
{
std::cout << "Error: " << err << std::endl;
}
for (auto* mesh : level_map.GetMeshes())
{
// //std::cout << "Rendering mesh" << std::endl;
mesh->Render(wall_shader);
}
/*float near_plane = 1.0f;
float far_plane = 50.0f;
glm::mat4 shadowProj = glm::perspective(glm::radians(90.0f), (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, near_plane, far_plane);*/
/*std::vector<glm::mat4> shadowTransforms;
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));
shadowTransforms.push_back(shadowProj * glm::lookAt(lightPos, lightPos + glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f)));*/
/*glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
glCullFace(GL_FRONT);
simpleDepthShader.Use();
for (unsigned int i = 0; i < 6; ++i)
simpleDepthShader.SetMatrix4("shadowMatrices[" + std::to_string(i) + "]", shadowTransforms[i]);
simpleDepthShader.SetFloat("far_plane", far_plane);
simpleDepthShader.SetVector3f("lightPos", lightPos);
levelMap.Update(projection, view);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glCullFace(GL_BACK);
glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubemap);*/
//map.render(projection, view, lightPos, deltaTime, glm::vec3(SCR_WIDTH, SCR_HEIGHT, 0.0f), far_plane);
//level_map.Update(projection, view, point_light.position, point_light.color, camera.Position);
//cubeFactory.render(view, projection, lightPos, deltaTime, amountOfCubes);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
//check and call
glfwSwapBuffers(window);
glfwPollEvents();
}
//cubeFactory.clear();
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
@@ -145,18 +299,26 @@ void processInput(GLFWwindow* window)
const float cameraSpeed = 5.0f * deltaTime;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
PlayerCharacter.ProcessKeyboard(FORWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
camera.ProcessKeyboard(BACKWARD, deltaTime);
PlayerCharacter.ProcessKeyboard(BACKWARD, deltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
camera.ProcessKeyboard(LEFT, deltaTime);
PlayerCharacter.ProcessKeyboard(LEFT, deltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime);
PlayerCharacter.ProcessKeyboard(RIGHT, deltaTime);
}
void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
{
//std::cout << "Mouse callback" << std::endl;
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != GLFW_PRESS)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
firstMouse = true;
return;
}
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
//std::cout << "Mouse callback" << std::endl;
float xpos = static_cast<float>(xposIn);
float ypos = static_cast<float>(yposIn);
@@ -173,10 +335,10 @@ void mouse_callback(GLFWwindow* window, double xposIn, double yposIn)
lastX = xpos;
lastY = ypos;
camera.ProcessMouseMovement(xoffset, yoffset);
PlayerCharacter.ProcessMouseMovement(xoffset, yoffset);
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{
camera.ProcessMouseScroll(static_cast<float>(yoffset));
//PlayerCharacter.ProcessMouseScroll(static_cast<float>(yoffset));
}

489
map_reader.h Normal file
View File

@@ -0,0 +1,489 @@
#pragma once
#ifndef MAP_READER_H
#define MAP_READER_H
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <random>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "Shader.h"
struct Wall
{
glm::vec2 a, b;
int portal;
};
struct Sector
{
int id;
int index;
int numberOfWalls;
float floorHeight;
float ceilingHeight;
bool outwardFacing;
glm::vec3 color;
std::vector<Wall> walls;
};
class Map
{
public:
Map(std::string filename) : wallShader(Shader("wall_test.vert", "wall_test.frag")), floorShader(Shader("wall_test.vert", "wall_test.frag"))
{
parseMapFile(filename);
setupBuffers();
}
void render(glm::mat4 projection, glm::mat4 view, glm::vec3 lightPos)
{
wallShader.use();
wallShader.setMat4("projection", projection);
wallShader.setMat4("view", view);
glm::mat4 model = glm::mat4(1.0f);
wallShader.setMat4("model", model);
//shader.setVec3("objectColor", 1.0f, 0.0f, 0.0f);
wallShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
wallShader.setVec3("lightPos", lightPos);
glBindVertexArray(wallVAO);
// Use glDrawElements since we are using indices
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, wallIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
floorShader.use();
floorShader.setMat4("projection", projection);
floorShader.setMat4("view", view);
model = glm::mat4(1.0f);
floorShader.setMat4("model", model);
floorShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
floorShader.setVec3("lightPos", lightPos);
glBindVertexArray(floorVAO);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, floorIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void render(glm::mat4 projection, glm::mat4 view, glm::vec3 lightPos, float deltaTime, glm::vec3 resolution, float far_plane)
{
time += deltaTime;
wallShader.use();
wallShader.setMat4("projection", projection);
wallShader.setMat4("view", view);
wallShader.setVec3("iResolution", resolution);
wallShader.setFloat("iTime", time);
wallShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
wallShader.setVec3("lightPos", lightPos);
wallShader.setInt("shadows", 1);
wallShader.setFloat("far_plane", far_plane);
wallShader.setInt("diffuseTexture", 0);
wallShader.setInt("shadowMap", 1);
glm::mat4 model = glm::mat4(1.0f);
wallShader.setMat4("model", model);
//shader.setVec3("objectColor", 1.0f, 0.0f, 0.0f);
glBindVertexArray(wallVAO);
// Use glDrawElements since we are using indices
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, wallIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
floorShader.use();
floorShader.setMat4("projection", projection);
floorShader.setMat4("view", view);
floorShader.setVec3("iResolution", resolution);
floorShader.setFloat("iTime", time);
floorShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
floorShader.setVec3("lightPos", lightPos);
floorShader.setInt("shadows", 1);
floorShader.setFloat("far_plane", far_plane);
floorShader.setInt("diffuseTexture", 0);
floorShader.setInt("shadowMap", 1);
model = glm::mat4(1.0f);
floorShader.setMat4("model", model);
glBindVertexArray(floorVAO);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, floorIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
void render(glm::mat4 projection, glm::mat4 view, glm::vec3 lightPos, Shader _shader)
{
glm::mat4 model = glm::mat4(1.0f);
_shader.setMat4("model", model);
glBindVertexArray(wallVAO);
// Use glDrawElements since we are using indices
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, wallIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glBindVertexArray(floorVAO);
//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, floorIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
/*floorShader.use();
floorShader.setMat4("projection", projection);
floorShader.setMat4("view", view);
model = glm::mat4(1.0f);
floorShader.setMat4("model", model);
floorShader.setVec3("lightColor", 1.0f, 1.0f, 1.0f);
floorShader.setVec3("lightPos", lightPos);
glBindVertexArray(floorVAO);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glDrawElements(GL_TRIANGLES, floorIndices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);*/
}
private:
std::vector<Sector> sectors;
unsigned int wallVAO;
unsigned int wallVBO, wallEBO, wallNBO, wallCBO;
unsigned int floorVAO;
unsigned int floorVBO, floorEBO, floorNBO, floorCBO;
std::vector<float> wallVertices, wallNormals, wallColors;
std::vector<unsigned int> wallIndices;
std::vector<float> floorVertices, floorNormals, floorColors;
std::vector<unsigned int> floorIndices;
Shader wallShader;
Shader floorShader;
float time;
Sector parseSector(std::string& line)
{
Sector sector;
std::stringstream ss(line);
ss >> sector.id >> sector.index >> sector.numberOfWalls >> sector.floorHeight >> sector.ceilingHeight >> sector.outwardFacing;
static std::random_device rd; // Obtain a random number from hardware
static std::mt19937 eng(rd()); // Seed the generator
std::uniform_real_distribution<float> distr(0.0f, 1.0f); // Define the range
glm::vec3 randomColor(distr(eng), distr(eng), distr(eng));
sector.color = randomColor;
return sector;
}
Wall parseWall(std::string& line)
{
Wall wall;
std::stringstream ss(line);
ss >> wall.a.x >> wall.a.y >> wall.b.x >> wall.b.y >> wall.portal;
return wall;
}
void parseMapFile(std::string filename)
{
//std::cout << "Parsing map file: " << filename << std::endl;
std::ifstream file(filename);
std::string line;
bool inSector = false, inWall = false;
while (std::getline(file, line))
{
//std::cout << "Line: " << line << std::endl;
if (line.empty() || line[0] == '#') continue;
if (line.find("[SECTOR]") != std::string::npos)
{
inSector = true;
inWall = false;
continue;
}
else if (line.find("[WALL]") != std::string::npos)
{
inSector = false;
inWall = true;
continue;
}
if (inSector)
{
sectors.push_back(parseSector(line));
}
if (inWall && !sectors.empty())
{
Wall wall = parseWall(line);
sectors.back().walls.push_back(wall);
}
}
}
void setupBuffers()
{
std::cout << "Setting up buffers" << std::endl;
int wallBaseIndex = 0;
int floorBaseIndex = 0;
for (Sector sector : sectors)
{
std::vector<glm::vec3> _floorVertices;
std::vector<glm::vec3> _ceilingVertices;
for (Wall wall : sector.walls)
{
glm::vec3 v0(wall.a.x, sector.floorHeight, wall.a.y);
glm::vec3 v1(wall.b.x, sector.floorHeight, wall.b.y);
glm::vec3 v2(wall.b.x, sector.ceilingHeight, wall.b.y);
glm::vec3 v3(wall.a.x, sector.ceilingHeight, wall.a.y);
_floorVertices.push_back(v0);
_ceilingVertices.push_back(v3);
if (wall.portal != 0)
{
Sector& portalSector = sectors[wall.portal - 1];
if (portalSector.floorHeight > sector.floorHeight)
{
v2.y = portalSector.floorHeight;
v3.y = portalSector.floorHeight;
addWallVectors(v0, v1, v2, v3, sector.color, wallBaseIndex, sector.outwardFacing);
}
if (portalSector.ceilingHeight < sector.ceilingHeight)
{
v0.y = portalSector.ceilingHeight;
v1.y = portalSector.ceilingHeight;
v2.y = sector.ceilingHeight;
v3.y = sector.ceilingHeight;
addWallVectors(v0, v1, v2, v3, sector.color, wallBaseIndex, sector.outwardFacing);
}
continue;
}
addWallVectors(v0, v1, v2, v3, sector.color, wallBaseIndex, sector.outwardFacing);
continue;
}
addFloorVectors(_floorVertices, floorBaseIndex, true);
addFloorVectors(_ceilingVertices, floorBaseIndex, false);
}
glGenVertexArrays(1, &wallVAO);
glGenBuffers(1, &wallVBO);
glGenBuffers(1, &wallEBO);
glGenBuffers(1, &wallNBO);
glGenBuffers(1, &wallCBO);
glBindVertexArray(wallVAO);
glBindBuffer(GL_ARRAY_BUFFER, wallVBO);
glBufferData(GL_ARRAY_BUFFER, wallVertices.size() * sizeof(float), wallVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, wallNBO);
glBufferData(GL_ARRAY_BUFFER, wallNormals.size() * sizeof(float), wallNormals.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, wallCBO);
glBufferData(GL_ARRAY_BUFFER, wallColors.size() * sizeof(float), wallColors.data(), GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wallEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, wallIndices.size() * sizeof(unsigned int), wallIndices.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
glGenVertexArrays(1, &floorVAO);
glGenBuffers(1, &floorVBO);
glGenBuffers(1, &floorEBO);
glGenBuffers(1, &floorNBO);
glGenBuffers(1, &floorCBO);
glBindVertexArray(floorVAO);
glBindBuffer(GL_ARRAY_BUFFER, floorVBO);
glBufferData(GL_ARRAY_BUFFER, floorVertices.size() * sizeof(float), floorVertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, floorNBO);
glBufferData(GL_ARRAY_BUFFER, floorNormals.size() * sizeof(float), floorNormals.data(), GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, floorCBO);
glBufferData(GL_ARRAY_BUFFER, floorColors.size() * sizeof(float), floorColors.data(), GL_STATIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, floorEBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, floorIndices.size() * sizeof(unsigned int), floorIndices.data(), GL_STATIC_DRAW);
glBindVertexArray(0);
}
void addWallVectors(glm::vec3 v0, glm::vec3 v1, glm::vec3 v2, glm::vec3 v3, glm::vec3 color, int& baseIndex, bool outward)
{
wallVertices.push_back(v0.x);
wallVertices.push_back(v0.y);
wallVertices.push_back(v0.z);
wallVertices.push_back(v1.x);
wallVertices.push_back(v1.y);
wallVertices.push_back(v1.z);
wallVertices.push_back(v2.x);
wallVertices.push_back(v2.y);
wallVertices.push_back(v2.z);
wallVertices.push_back(v3.x);
wallVertices.push_back(v3.y);
wallVertices.push_back(v3.z);
glm::vec3 normal = glm::normalize(glm::cross(v1 - v0, v3 - v0));
normal = outward ? normal : -normal;
wallNormals.push_back(normal.x);
wallNormals.push_back(normal.y);
wallNormals.push_back(normal.z);
wallNormals.push_back(normal.x);
wallNormals.push_back(normal.y);
wallNormals.push_back(normal.z);
wallNormals.push_back(normal.x);
wallNormals.push_back(normal.y);
wallNormals.push_back(normal.z);
wallNormals.push_back(normal.x);
wallNormals.push_back(normal.y);
wallNormals.push_back(normal.z);
wallColors.push_back(color.x);
wallColors.push_back(color.y);
wallColors.push_back(color.z);
wallColors.push_back(color.x);
wallColors.push_back(color.y);
wallColors.push_back(color.z);
wallColors.push_back(color.x);
wallColors.push_back(color.y);
wallColors.push_back(color.z);
wallColors.push_back(color.x);
wallColors.push_back(color.y);
wallColors.push_back(color.z);
// First triangle
wallIndices.push_back(baseIndex);
wallIndices.push_back(baseIndex + 1);
wallIndices.push_back(baseIndex + 2);
// Second triangle
wallIndices.push_back(baseIndex);
wallIndices.push_back(baseIndex + 2);
wallIndices.push_back(baseIndex + 3);
baseIndex += 4;
}
void addFloorVectors(std::vector<glm::vec3> _vertices, int& baseIndex, bool floor)
{
for (int i = 0; i + 2 < _vertices.size() ; i+=1)
{
this->floorVertices.push_back(_vertices[0].x);
this->floorVertices.push_back(_vertices[0].y);
this->floorVertices.push_back(_vertices[0].z);
this->floorVertices.push_back(_vertices[i + 1].x);
this->floorVertices.push_back(_vertices[i + 1].y);
this->floorVertices.push_back(_vertices[i + 1].z);
this->floorVertices.push_back(_vertices[i + 2].x);
this->floorVertices.push_back(_vertices[i + 2].y);
this->floorVertices.push_back(_vertices[i + 2].z);
glm::vec3 normal = glm::normalize(glm::cross(_vertices[i + 1] - _vertices[0], _vertices[i + 2] - _vertices[0]));
normal = floor ? -normal : normal;
floorNormals.push_back(normal.x);
floorNormals.push_back(normal.y);
floorNormals.push_back(normal.z);
floorNormals.push_back(normal.x);
floorNormals.push_back(normal.y);
floorNormals.push_back(normal.z);
floorNormals.push_back(normal.x);
floorNormals.push_back(normal.y);
floorNormals.push_back(normal.z);
glm::vec3 color;
color = floor ? glm::vec3(0.75f, 0.5f, 0.25f) : glm::vec3(0.25f, 0.5f, 0.75f);
this->floorColors.push_back(color.x);
this->floorColors.push_back(color.y);
this->floorColors.push_back(color.z);
this->floorColors.push_back(color.x);
this->floorColors.push_back(color.y);
this->floorColors.push_back(color.z);
this->floorColors.push_back(color.x);
this->floorColors.push_back(color.y);
this->floorColors.push_back(color.z);
floorIndices.push_back(baseIndex);
floorIndices.push_back(baseIndex + 1);
floorIndices.push_back(baseIndex + 2);
baseIndex += 3;
}
}
};
#endif

36
map_test.txt Normal file
View File

@@ -0,0 +1,36 @@
[SECTOR]
0 8 0.0 5.0 0 0.65 0.1 0.2
8 3 1.0 4.0 0 0.65 0.65 0.2
11 4 0.2 6.0 0 0.65 0.1 0.65
15 5 0.0 3.0 0 0.1 0.1 0.65
20 4 0.0 5.0 1 0.1 0.65 0.2
[WALL]
40 10 20 10 0
50 20 40 10 0
50 30 50 20 0
40 40 50 30 3
20 40 40 40 0
10 30 20 40 2
10 20 10 30 0
20 10 10 20 0
20 40 10 30 1
10 50 20 40 0
10 30 10 50 0
50 30 40 40 1
60 50 50 30 0
60 70 60 50 4
40 40 60 70 0
70 40 60 50 0
80 50 70 40 0
80 70 80 50 0
60 70 80 70 0
60 50 60 70 3
25 25 25 26 0
26 25 25 25 0
26 26 26 25 0
25 26 26 26 0

9
map_test_2.txt Normal file
View File

@@ -0,0 +1,9 @@
[SECTOR]
1 0 4 -1.0 5.0
[WALL]
# SECTOR 1: 0..7
-10 -10 10 -10 0
10 -10 10 10 0
10 10 -10 10 0
-10 10 -10 -10 0

15
point_shadow_depth.frag Normal file
View File

@@ -0,0 +1,15 @@
#version 330
in vec4 FragPosition;
uniform vec3 lightPosition;
uniform float farPlane;
void main()
{
float lightDistance = length(FragPosition.xyz - lightPosition);
lightDistance = lightDistance / farPlane;
gl_FragDepth = lightDistance;
}

25
point_shadow_depth.geom Normal file
View File

@@ -0,0 +1,25 @@
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;
uniform mat4 shadowMatrices[6];
out vec4 FragPosition; // FragPos from GS (output per emitvertex)
void main()
{
for(int face = 0; face < 6; ++face)
{
gl_Layer = face; // built-in variable that specifies to which face we render.
for(int i = 0; i < 3; ++i) // for each triangle's vertices
{
FragPosition = gl_in[i].gl_Position;
gl_Position = shadowMatrices[face] * FragPosition;
EmitVertex();
}
EndPrimitive();
}
}

10
point_shadow_depth.vert Normal file
View File

@@ -0,0 +1,10 @@
#version 330 core
layout (location = 0) in vec3 aPosition;
uniform mat4 model;
void main()
{
gl_Position = model * vec4(aPosition, 1.0);
}

172
shader.h
View File

@@ -2,154 +2,40 @@
#ifndef SHADER_H
#define SHADER_H
#include <glad/glad.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
// General purpose shader object. Compiles from file, generates
// compile/link-time error messages and hosts several utility
// functions for easy management.
class Shader
{
public:
unsigned int ID;
Shader(const char* vertexPath, const char* fragmentPath)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
unsigned int vertex, fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
checkCompileErrors(fragment, "FRAGMENT");
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
checkCompileErrors(ID, "PROGRAM");
glDeleteShader(vertex);
glDeleteShader(fragment);
}
void use()
{
glUseProgram(ID);
}
// utility uniform functions
// ------------------------------------------------------------------------
void setBool(const std::string& name, bool value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
}
// ------------------------------------------------------------------------
void setInt(const std::string& name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setFloat(const std::string& name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
// ------------------------------------------------------------------------
void setVec2(const std::string& name, const glm::vec2& value) const
{
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec2(const std::string& name, float x, float y) const
{
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
}
// ------------------------------------------------------------------------
void setVec3(const std::string& name, const glm::vec3& value) const
{
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec3(const std::string& name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
}
// ------------------------------------------------------------------------
void setVec4(const std::string& name, const glm::vec4& value) const
{
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void setVec4(const std::string& name, float x, float y, float z, float w) const
{
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
}
// ------------------------------------------------------------------------
void setMat2(const std::string& name, const glm::mat2& mat) const
{
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string& name, const glm::mat3& mat) const
{
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string& name, const glm::mat4& mat) const
{
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// state
unsigned int ID;
// constructor
Shader() { }
// sets the current shader as active
Shader& Use();
// compiles the shader from given source code
void Compile(const char* vertexSource, const char* fragmentSource, const char* geometrySource = nullptr); // note: geometry source code is optional
// utility functions
void SetFloat(const char* name, float value, bool useShader = false);
void SetInteger(const char* name, int value, bool useShader = false);
void SetVector2f(const char* name, float x, float y, bool useShader = false);
void SetVector2f(const char* name, const glm::vec2& value, bool useShader = false);
void SetVector3f(const char* name, float x, float y, float z, bool useShader = false);
void SetVector3f(const char* name, const glm::vec3& value, bool useShader = false);
void SetVector4f(const char* name, float x, float y, float z, float w, bool useShader = false);
void SetVector4f(const char* name, const glm::vec4& value, bool useShader = false);
void SetMatrix4(const char* name, const glm::mat4& matrix, bool useShader = false);
private:
void checkCompileErrors(unsigned int shader, std::string type)
{
int success;
char infoLog[1024];
if (type != "PROGRAM")
{
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- ---------------------------------------------------- -- " << std::endl;
}
}
else
{
glGetProgramiv(shader, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- ---------------------------------------------------- -- " << std::endl;
}
}
}
// checks if compilation or linking failed and if so, print the error logs
void checkCompileErrors(unsigned int object, std::string type);
};
#endif
#endif

71
wall.frag Normal file
View File

@@ -0,0 +1,71 @@
#version 330 core
out vec4 FragColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform sampler2D diffuseTexture;
uniform samplerCube depthMap;
uniform float far_plane;
uniform bool shadows;
uniform vec3 iResolution; // viewport resolution (in pixels)
uniform float iTime; // shader playback time (in seconds)
uniform float iTimeDelta; // render time (in seconds)
uniform float iFrameRate; // shader frame rate
uniform int iFrame; // shader playback frame
uniform float iChannelTime[4]; // channel playback time (in seconds)
uniform vec3 iChannelResolution[4]; // channel resolution (in pixels)
uniform vec4 iMouse; // mouse pixel coords. xy: current (if MLB down), zw: click
uniform sampler2D iChannel0; // input channel. XX = 2D/Cube
uniform vec4 iDate; // (year, month, day, time in seconds)
in vec3 FragPos;
in vec3 Normal;
in vec3 Color;
float ShadowCalculation(vec3 fragPos)
{
// get vector between fragment position and light position
vec3 fragToLight = fragPos - lightPos;
// ise the fragment to light vector to sample from the depth map
float closestDepth = texture(depthMap, fragToLight).r;
// it is currently in linear range between [0,1], let's re-transform it back to original depth value
closestDepth *= far_plane;
// now get current linear depth as the length between the fragment and light position
float currentDepth = length(fragToLight);
// test for shadows
float bias = 0.05; // we use a much larger bias since depth is now in [near_plane, far_plane] range
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
// display closestDepth as debug (to visualize depth cubemap)
//FragColor = vec4(vec3(closestDepth / far_plane), 1.0);
return shadow;
}
void main()
{
//vec3 color = texture(diffuseTexture, FragPos.xy).rgb;
vec3 normal = normalize(Normal);
vec3 lightColor = vec3(0.3);
// ambient
vec3 ambient = 0.3 * lightColor;
// diffuse
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(lightDir, normal), 0.0);
vec3 diffuse = diff * lightColor;
// specular
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, normal);
float spec = 0.0;
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(normal, halfwayDir), 0.0), 64.0);
vec3 specular = spec * lightColor;
// calculate shadow
float shadow = ShadowCalculation(FragPos);
vec3 lighting = (ambient + (1.0 - shadow) * (diffuse + specular)) * Color;
FragColor = vec4(lighting, 1.0);
}

22
wall.vert Normal file
View File

@@ -0,0 +1,22 @@
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec3 aColor;
out vec3 FragPos;
out vec3 Normal;
out vec3 Color;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
Color = aColor;
gl_Position = projection * view * vec4(FragPos, 1.0);
}

238
wall_test.frag Normal file
View File

@@ -0,0 +1,238 @@
#version 330 core
out vec4 FragColor;
const int MAX_POINT_LIGHTS = 10;
in vec3 FragPosition;
in vec3 Normal;
in vec3 Color;
struct BaseLight
{
vec3 color;
float ambientIntensity;
float diffuseIntensity;
};
struct Attenuation
{
float constant;
float linear;
float exponential;
};
struct PointLight
{
BaseLight base;
Attenuation atten;
vec3 position;
float farPlane;
samplerCube depthMap;
};
struct Material
{
vec3 ambientColor;
vec3 diffuseColor;
vec3 specularColor;
float shininess;
};
uniform int numOfPointLights;
uniform PointLight pointLights[MAX_POINT_LIGHTS];
uniform Material material;
//uniform sampler2D diffuseTexture;
uniform vec3 viewPosition;
//uniform float farPlane;
//uniform bool shadows;
vec3 gridSamplingDisk[20] = vec3[]
(
vec3(1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
vec3(1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
vec3(1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
vec3(1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
vec3(0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
);
int bayer[64] = int[64](
0, 32, 8, 40, 2, 34, 10, 42,
48, 16, 56, 24, 50, 18, 58, 26,
12, 44, 4, 36, 14, 46, 6, 38,
60, 28, 52, 20, 62, 30, 54, 22,
3, 35, 11, 43, 1, 33, 9, 41,
51, 19, 59, 27, 49, 17, 57, 25,
15, 47, 7, 39, 13, 45, 5, 37,
63, 31, 55, 23, 61, 29, 53, 21
);
float ShadowCalculation(PointLight light, vec3 normal)
{
// get vector between fragment position and light position
vec3 fragToLight = FragPosition - light.position;
float currentDepth = length(fragToLight);
vec3 lightDir = normalize(light.position - FragPosition);
float shadow = 0.0;
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
//float bias = 0.15;
int samples = 20;
float viewDistance = length(viewPosition - FragPosition);
float diskRadius = (1.0 + (viewDistance / light.farPlane)) / 25.0;
for(int i = 0; i < samples; ++i)
{
float closestDepth = texture(light.depthMap, fragToLight + gridSamplingDisk[i] * diskRadius).r;
//FragColor = vec4(vec3(closestDepth / farPlane), 1.0);
closestDepth *= light.farPlane; // undo mapping [0;1]
if(currentDepth - bias > closestDepth)
shadow += 1.0;
}
shadow /= float(samples);
//shadow = dither(shadow);
// display closestDepth as debug (to visualize depth cubemap)
// FragColor = vec4(vec3(closestDepth / farPlane), 1.0);
return shadow;
}
vec4 dither(vec4 color)
{
float downsampleFactor = 2;
float ditherSize = 0.05;
float colorSize = 8.0;
float _x = (gl_FragCoord.x/downsampleFactor);
float _y = (gl_FragCoord.y/downsampleFactor);
_x = mod(_x, 8);
_y = mod(_y, 8);
int _M = bayer[8*int(_y) + int(_x)];
float _z = float(_M) * (1.0 / pow(8, 2.0));
_z -= 0.5;
color.x += _z * ditherSize;
color.y += _z * ditherSize;
color.z += _z * ditherSize;
//color = greyscale;
color = floor(color * (colorSize - 1) + 0.5) / (colorSize - 1);
vec3 greyscale = vec3(0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b);
return color;
}
/*vec3 diffuse(vec3 _lightColor, vec3 _lightPosition)
{
// diffuse
vec3 lightDir = normalize(_lightPosition - FragPosition);
vec3 lightDist = _lightPosition - FragPosition;
float diff = max(dot(lightDir, Normal), 0.0);
float linear = 0.2;
float exponential = 0.2;
// Apply attenuation: light fades over distance
float attenuation = 1.0 / (1.0 + (linear * length(lightDist)) + (exponential * pow(length(lightDist), 2.0)));
vec3 diffuse = diff * lightColor;
return diffuse;
}*/
/*vec3 specular(vec3 _lightPosition)
{
// specular
vec3 lightDir = normalize(_lightPosition - FragPosition);
vec3 viewDir = normalize(viewPosition - FragPosition);
vec3 reflectDir = reflect(-lightDir, Normal);
float spec = 0.0;
vec3 halfwayDir = normalize(lightDir + viewDir);
spec = pow(max(dot(Normal, halfwayDir), 0.0), 64.0);
vec3 specular = spec * lightColor;
return specular;
}*/
vec4 calculateAmbient(BaseLight light)
{
vec4 ambientColor = vec4(light.color, 1.0) *
light.ambientIntensity *
vec4(material.ambientColor, 1.0);
return ambientColor;
}
vec4 calculateDiffuse(BaseLight light, vec3 lightDirection, vec3 normal)
{
vec4 diffuseColor = vec4(0.0);
float diffuseFactor = dot(normal, -lightDirection);
if (diffuseFactor > 0.0)
{
diffuseColor = vec4(light.color, 1.0) *
light.diffuseIntensity *
vec4(material.diffuseColor, 1.0) *
diffuseFactor;
}
return diffuseColor;
}
vec4 calculateSpecular(BaseLight light, vec3 lightDirection, vec3 normal)
{
vec4 specularColor = vec4(0.0);
vec3 pixelToCamera = normalize(viewPosition - FragPosition);
vec3 lightReflect = normalize(reflect(lightDirection, normal));
float specularFactor = dot(pixelToCamera, lightReflect);
if (specularFactor > 0.0)
{
specularColor = vec4(light.color, 1.0) *
light.diffuseIntensity *
vec4(material.specularColor, 1.0) *
specularFactor;
}
return specularColor * material.shininess;
}
vec4 caclulatePointLight(int index, vec3 normal)
{
vec3 lightDirection = FragPosition - pointLights[index].position;
float lightDistance = length(lightDirection);
lightDirection = normalize(lightDirection);
float shadow = 1.0 - ShadowCalculation(pointLights[index], normal);
vec4 color = calculateAmbient(pointLights[index].base) +
shadow *
(calculateDiffuse(pointLights[index].base, lightDirection, normal) +
calculateSpecular(pointLights[index].base, lightDirection, normal));
// color = vec4(Color, 1.0);
float attenuation = pointLights[index].atten.constant +
pointLights[index].atten.linear * lightDistance +
pointLights[index].atten.exponential * (lightDistance * lightDistance);
return color / attenuation;
}
void main()
{
vec3 normal = normalize(Normal);
vec4 totalLight = vec4(0.0, 0.0, 0.0, 0.0);
for (int i = 0; i < numOfPointLights; i++)
{
totalLight += caclulatePointLight(i, normal);
}
//totalLight = dither(totalLight);
FragColor = totalLight;
}

22
wall_test.vert Normal file
View File

@@ -0,0 +1,22 @@
#version 330 core
layout (location = 0) in vec3 aPosition;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec3 aColor;
out vec3 FragPosition;
out vec3 Normal;
out vec3 Color;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPosition = vec3(model * vec4(aPosition, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
Color = aColor;
gl_Position = projection * view * vec4(FragPosition, 1.0);
}