Files
LearningOpenGL/LevelMap.cpp
2025-08-15 20:35:29 -04:00

281 lines
7.6 KiB
C++

#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 };
}
std::vector<Sector>& LevelMap::GetSectors()
{
return sectors;
}
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]);
}
}