#include "LevelMap.h" #include 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 floor_vertices; std::vector 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 LevelMap::GetMeshes() { return { &wall_renderer, &floor_renderer, &ceiling_renderer }; } std::vector& 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 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 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 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 vertices, std::vector& 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 normals, std::vector& 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 colors, std::vector& 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 indices, std::vector& target_indices) { for (unsigned int i = 0; i < indices.size(); i += 1) { target_indices.push_back(indices[i]); } }