diff --git a/assets/scene.blend b/assets/scene.blend index 1364395..e7c4615 100644 --- a/assets/scene.blend +++ b/assets/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb00bcd432a1380d925bec21896b8fc5d03f5cf828c7081e56e7813383b7bb70 -size 15915245 +oid sha256:b85c7237e37ff2b9ba6b0d3407f27989c1173b3e4c0eee5776fe52effd26ad69 +size 16317033 diff --git a/assets/scene.glb b/assets/scene.glb index 0e3e0c9..e41dd76 100644 --- a/assets/scene.glb +++ b/assets/scene.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c75a3989a2bc1edcead17eb35e26d800b66f43d53f21a9cccde5ae7830c040ef -size 1876068 +oid sha256:588b2c0d24f195a86b22f5d45aec1008a8b8c35164797c4d74f1631de926d8d7 +size 1932828 diff --git a/assets/shader/blur.fsh b/assets/shader/blur.fsh index 14d3baf..b44da61 100644 --- a/assets/shader/blur.fsh +++ b/assets/shader/blur.fsh @@ -1,26 +1,26 @@ #version 460 core -uniform int samples; uniform sampler2D tex; +uniform vec2 direction; +uniform int samples; -in vec2 texPos; - +in vec2 FragPos; out vec4 FragColour; void main() { - vec2 texel_size = 1.f / vec2(textureSize(tex, 0)); - float samples_n = pow(samples * 2 + 1, 2); - vec4 colour; - - for(int x = -samples; x <= samples; x++) - for(int y = -samples; y <= samples; y++) + int radius = (samples - 1) / 2; + ivec2 size = textureSize(tex, 0); + vec2 step = direction / size; + vec4 sum = vec4(0.f); + + for(int i = -radius; i <= radius; i++) { - vec2 off = texel_size * vec2(x, y); - colour += texture2D(tex, texPos + off); + vec2 offset = vec2(i) * step; + sum += texture(tex, FragPos + offset); } - FragColour = vec4((colour / samples_n).rgb, 1); + FragColour = sum / float(samples); } diff --git a/assets/shader/blur.vsh b/assets/shader/blur.vsh deleted file mode 100644 index eea7bfb..0000000 --- a/assets/shader/blur.vsh +++ /dev/null @@ -1,14 +0,0 @@ - -#version 460 core - -layout (location = 1) in vec2 aTexPos; -layout (location = 2) in vec4 aPos; - -out vec2 texPos; - -void main() -{ - texPos = aTexPos; - gl_Position = aPos; -} - diff --git a/assets/shader/main.fsh b/assets/shader/main.fsh index 272e354..086b51d 100644 --- a/assets/shader/main.fsh +++ b/assets/shader/main.fsh @@ -122,23 +122,26 @@ void main() vec3 N = normalize(vin.normal); vec3 V = normalize(camera_pos - vin.pos.xyz); - vec3 F0 = vec3(0.04f); - F0 = mix(F0, albedo_lin, metalness); - + vec3 F0 = mix(vec3(0.04f), albedo_lin, metalness); + vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness; vec3 Lo = vec3(0.f); + for(int i = 0; i < lights_count; i++) { Light l = lights[i]; - - float light_m; - vec3 L = normalize(l.pos.xyz - vin.pos); float d = length(vin.pos - l.pos.xyz); + vec3 L = (l.pos.xyz - vin.pos) / d; + float light_m; if(shadows_enabled) { float max_d = texture(shadow_maps[i], -L).r * far_plane; light_m = Ramp(d - max_d, 0.f, 2.5e-2f, 1.f, 0.f); - if(light_m <= 0.f) continue; + + if(light_m <= 0.f) + { + continue; + } } else @@ -162,14 +165,12 @@ void main() vec3 numerator = NDF * G * F; float denominator = 4.f * max(dot(N, V), 0.f) * max(dot(N, L), 0.f) + 1e-4f; vec3 specular = numerator / denominator; - // add to outgoing radiance Lo float NdotL = max(dot(N, L), 0.f); Lo += (kD * albedo_lin / PI + specular) * radiance * NdotL * light_m; } - vec3 ambient = vec3(vin.ambient) * albedo_lin * brightness; vec3 light = LinRGB_To_sRGB(ambient + Lo); light = mix(light, albedo.rgb, luminance); diff --git a/assets/shader/post_base.vsh b/assets/shader/post_base.vsh new file mode 100644 index 0000000..6891ada --- /dev/null +++ b/assets/shader/post_base.vsh @@ -0,0 +1,21 @@ + +#version 460 core + +const vec2 QuadVertices[6] = vec2[6]( + vec2(-1.0, 1.0), + vec2(-1.0, -1.0), + vec2( 1.0, -1.0), + vec2(-1.0, 1.0), + vec2( 1.0, -1.0), + vec2( 1.0, 1.0) +); + +out vec2 FragPos; + +void main() +{ + vec2 vertex = QuadVertices[gl_VertexID]; + FragPos = vertex * 0.5f + 0.5f; + gl_Position = vec4(vertex, 0.f, 1.f); +} + diff --git a/assets/texture/scene/Keys.001.png b/assets/texture/scene/Keys.001.png index 4fc0f99..70b1f86 100644 Binary files a/assets/texture/scene/Keys.001.png and b/assets/texture/scene/Keys.001.png differ diff --git a/assets/texture/scene/Player.png b/assets/texture/scene/Player.png new file mode 100644 index 0000000..7b0ee6c Binary files /dev/null and b/assets/texture/scene/Player.png differ diff --git a/src/electric/generator.cpp b/src/electric/generator.cpp index bd93b2d..59d76c7 100644 --- a/src/electric/generator.cpp +++ b/src/electric/generator.cpp @@ -33,7 +33,7 @@ void Generator::update(double dt) double energy_input = turbine->extract_energy(); double energy_friction = get_rpm() / 60 * dt * friction; double work = Util::Math::j_to_ms2(energy_input - energy_friction, mass); - phase = std::fmod(phase + Util::Math::map( get_rpm(), 0, 3600, 0, 120 * M_PI ) * dt, 2 * M_PI); + phase = std::fmod(phase + Util::Math::map( get_rpm(), 0, 3600, 0, 120 * M_PI ) * dt, 4 * M_PI); // do energy transfer stuff here if(breaker_closed) diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 4e9a168..22d2bef 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -3,7 +3,7 @@ #include #include "camera.hpp" -#include "mesh/mesh.hpp" +#include "data/mesh.hpp" #include "input/keyboard.hpp" #include "../util/math.hpp" @@ -19,7 +19,7 @@ static bool on_ground = false; static double yaw = 0, pitch = 0; static glm::vec<3, double> pos(0, 0, 2); static glm::vec<3, double> velocity(0); -static Mesh collision_scene; +static Data::Mesh collision_scene; static glm::mat4 camera_mat; Json::Value Camera::serialize() @@ -79,7 +79,12 @@ glm::vec<3, double> Camera::get_pos() return pos; } -void Camera::init(const Model& model) +glm::vec<3, double> Camera::get_pos_base() +{ + return pos - glm::vec<3, double>(0, 0, 1.5); +} + +void Camera::init(const Data::Model& model) { collision_scene = model.load("collision"); } diff --git a/src/graphics/camera.hpp b/src/graphics/camera.hpp index 8da9d6f..bfeec35 100644 --- a/src/graphics/camera.hpp +++ b/src/graphics/camera.hpp @@ -5,13 +5,14 @@ #include #include "../system.hpp" -#include "mesh/model.hpp" +#include "data/model.hpp" namespace Sim::Graphics::Camera { glm::vec<3, double> get_normal(); glm::vec<3, double> get_pos(); +glm::vec<3, double> get_pos_base(); glm::mat4 get_matrix(); double get_pitch(); double get_yaw(); @@ -19,7 +20,7 @@ double get_yaw(); Json::Value serialize(); void load(const Json::Value& node); -void init(const Model& model); +void init(const Data::Model& model); void rotate(double pitch, double yaw); void move(double x, double y, double z); void update(double dt); diff --git a/src/graphics/mesh/arrays.cpp b/src/graphics/data/arrays.cpp similarity index 97% rename from src/graphics/mesh/arrays.cpp rename to src/graphics/data/arrays.cpp index 87a6d87..aaaba0c 100644 --- a/src/graphics/mesh/arrays.cpp +++ b/src/graphics/data/arrays.cpp @@ -9,7 +9,7 @@ #include "arrays.hpp" #include "font.hpp" -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; static void* ptr_diff(void* a, void* b) { diff --git a/src/graphics/mesh/arrays.hpp b/src/graphics/data/arrays.hpp similarity index 92% rename from src/graphics/mesh/arrays.hpp rename to src/graphics/data/arrays.hpp index 8377346..734ad33 100644 --- a/src/graphics/mesh/arrays.hpp +++ b/src/graphics/data/arrays.hpp @@ -4,7 +4,7 @@ #include #include -namespace Sim::Graphics::Arrays +namespace Sim::Graphics::Data::Arrays { struct Vertex diff --git a/src/graphics/data/camera.hpp b/src/graphics/data/camera.hpp new file mode 100644 index 0000000..c1e4fce --- /dev/null +++ b/src/graphics/data/camera.hpp @@ -0,0 +1,22 @@ + +#pragma once + +#include + +namespace Sim::Graphics::Data +{ + +struct Camera +{ + glm::vec3 pos; + glm::vec3 look; + glm::vec3 up; + float fov; + + float pitch = 0; + float yaw = 0; + float zoom = 1; +}; + +}; + diff --git a/src/graphics/mesh/font.cpp b/src/graphics/data/font.cpp similarity index 99% rename from src/graphics/mesh/font.cpp rename to src/graphics/data/font.cpp index 5ad81e3..d3f9a68 100644 --- a/src/graphics/mesh/font.cpp +++ b/src/graphics/data/font.cpp @@ -13,7 +13,7 @@ #include "arrays.hpp" #include "font.hpp" -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; struct Character { diff --git a/src/graphics/mesh/font.hpp b/src/graphics/data/font.hpp similarity index 72% rename from src/graphics/mesh/font.hpp rename to src/graphics/data/font.hpp index 40df8ab..552e9a1 100644 --- a/src/graphics/mesh/font.hpp +++ b/src/graphics/data/font.hpp @@ -6,7 +6,7 @@ #include #include -namespace Sim::Graphics::Font +namespace Sim::Graphics::Data::Font { void init(); diff --git a/src/graphics/mesh/gllight.cpp b/src/graphics/data/gllight.cpp similarity index 88% rename from src/graphics/mesh/gllight.cpp rename to src/graphics/data/gllight.cpp index 38eeae3..5def4a8 100644 --- a/src/graphics/mesh/gllight.cpp +++ b/src/graphics/data/gllight.cpp @@ -10,7 +10,7 @@ #include #include -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; static glm::mat4 shadow_mats[6]; @@ -64,12 +64,20 @@ void GLLight::render() glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos); glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]); glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glViewport(0, 0, size, size); Window::render_scene(); } +void GLLight::render_player() +{ + glm::mat4 camera_mat = glm::translate(glm::mat4(1), -light.pos); + glUniformMatrix4fv(Shader::LIGHT["camera"], 1, false, &camera_mat[0][0]); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glViewport(0, 0, size, size); + Window::render_player(); +} + void GLLight::init() { glm::mat4 shadow_proj = glm::perspective(M_PI * 0.5f, 1.0f, 0.01f, 100.f); diff --git a/src/graphics/mesh/gllight.hpp b/src/graphics/data/gllight.hpp similarity index 84% rename from src/graphics/mesh/gllight.hpp rename to src/graphics/data/gllight.hpp index e14e202..44c4c25 100644 --- a/src/graphics/mesh/gllight.hpp +++ b/src/graphics/data/gllight.hpp @@ -3,7 +3,7 @@ #include "light.hpp" -namespace Sim::Graphics +namespace Sim::Graphics::Data { struct GLLight @@ -22,6 +22,7 @@ struct GLLight static void init(); void render(); + void render_player(); }; }; diff --git a/src/graphics/mesh/glmesh.cpp b/src/graphics/data/glmesh.cpp similarity index 73% rename from src/graphics/mesh/glmesh.cpp rename to src/graphics/data/glmesh.cpp index e313219..1725b14 100644 --- a/src/graphics/mesh/glmesh.cpp +++ b/src/graphics/data/glmesh.cpp @@ -8,7 +8,7 @@ #include "../camera.hpp" #include "../../util/streams.hpp" -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; constexpr static void init(GLMesh* m) { @@ -52,20 +52,25 @@ GLMesh::~GLMesh() if(vao) glDeleteVertexArrays(1, &vao); } -void GLMesh::bind(bool bind_ssbo) +void GLMesh::bind() { init(this); glBindVertexArray(vao); - - if(ssbo_size > 0 && bind_ssbo) - { - glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo); - } } -void GLMesh::set(const Mesh& m, int mode, bool send_ssbo) +void GLMesh::bind_ssbo() +{ + if(!ssbo) + { + glGenBuffers(1, &ssbo); + } + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo); +} + +void GLMesh::set(const Mesh& m, int mode) { glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); @@ -74,17 +79,6 @@ void GLMesh::set(const Mesh& m, int mode, bool send_ssbo) this->size = m.indices.size(); this->ssbo_size = m.transforms.size(); - - if(ssbo_size > 0 && send_ssbo) - { - if(ssbo == 0) - { - glGenBuffers(1, &ssbo); - } - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); - glBufferData(GL_SHADER_STORAGE_BUFFER, m.transforms.size() * sizeof(m.transforms[0]), &m.transforms[0], mode); - } } void GLMesh::render() diff --git a/src/graphics/mesh/glmesh.hpp b/src/graphics/data/glmesh.hpp similarity index 74% rename from src/graphics/mesh/glmesh.hpp rename to src/graphics/data/glmesh.hpp index 5769819..2f5f08d 100644 --- a/src/graphics/mesh/glmesh.hpp +++ b/src/graphics/data/glmesh.hpp @@ -8,7 +8,7 @@ #include -namespace Sim::Graphics +namespace Sim::Graphics::Data { struct GLMesh @@ -23,8 +23,9 @@ struct GLMesh GLMesh(const GLMesh& o) = delete; ~GLMesh(); - void bind(bool bind_ssbo = true); - void set(const Mesh& m, int mode, bool send_ssbo = true); + void bind(); + void bind_ssbo(); + void set(const Mesh& m, int mode); void render(int type); void render(); }; diff --git a/src/graphics/mesh/light.hpp b/src/graphics/data/light.hpp similarity index 91% rename from src/graphics/mesh/light.hpp rename to src/graphics/data/light.hpp index e61c0db..b6852f5 100644 --- a/src/graphics/mesh/light.hpp +++ b/src/graphics/data/light.hpp @@ -3,7 +3,7 @@ #include -namespace Sim::Graphics +namespace Sim::Graphics::Data { struct Light diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/data/mesh.cpp similarity index 92% rename from src/graphics/mesh/mesh.cpp rename to src/graphics/data/mesh.cpp index f532171..e503629 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/data/mesh.cpp @@ -9,7 +9,7 @@ #include -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; Mesh::Mesh() { @@ -178,15 +178,28 @@ bool ray_intersects_triangle(vec3 ray_origin, bool Mesh::check_focus(double len) const { + if(!Focus::is_triggered()) + { + return false; + } + auto near = Focus::get_trigger_near(); auto far = Focus::get_trigger_far(); - return Focus::is_triggered() && check_intersect(near, glm::normalize(far - near) * len); + return check_intersect(near, glm::normalize(far - near) * len); } -bool Mesh::check_focus() const +bool Mesh::check_focus_hold(double len) { - return check_focus(2.5); + if(!Focus::is_triggered() && (!focus || Focus::is_triggered_release())) + { + return focus = false; + } + + auto near = Focus::get_trigger_near(); + auto far = Focus::get_trigger_far(); + + return focus = check_intersect(near, glm::normalize(far - near) * len); } bool Mesh::check_intersect(vec3 pos, vec3 path) const @@ -329,7 +342,7 @@ Mesh Mesh::to_lines() const return m; } -std::ostream& Sim::Graphics::operator<<(std::ostream& os, const Mesh& m) +std::ostream& Sim::Graphics::Data::operator<<(std::ostream& os, const Mesh& m) { os << "Mesh(\n"; os << " Vertices(\n"; diff --git a/src/graphics/mesh/mesh.hpp b/src/graphics/data/mesh.hpp similarity index 89% rename from src/graphics/mesh/mesh.hpp rename to src/graphics/data/mesh.hpp index 1cd7081..69ba390 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/data/mesh.hpp @@ -12,7 +12,7 @@ #include "arrays.hpp" #include "light.hpp" -namespace Sim::Graphics +namespace Sim::Graphics::Data { struct Mesh @@ -20,6 +20,7 @@ struct Mesh std::vector vertices; std::vector indices; std::vector transforms; + bool focus = false; Mesh(); @@ -31,8 +32,8 @@ struct Mesh Mesh& add(const Mesh& o, glm::mat4 mat = glm::mat4(1), bool bake = false); Mesh to_lines() const; - bool check_focus() const; - bool check_focus(double len) const; + bool check_focus(double len = 2.5) const; + bool check_focus_hold(double len = 2.5); bool check_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; glm::vec<3, double> calc_intersect(glm::vec<3, double> pos, glm::vec<3, double> path) const; diff --git a/src/graphics/mesh/meshgen.hpp b/src/graphics/data/meshgen.hpp similarity index 83% rename from src/graphics/mesh/meshgen.hpp rename to src/graphics/data/meshgen.hpp index bdf9ac5..9a3d018 100644 --- a/src/graphics/mesh/meshgen.hpp +++ b/src/graphics/data/meshgen.hpp @@ -1,9 +1,9 @@ #pragma once -#include "../mesh/model.hpp" +#include "model.hpp" -namespace Sim::Graphics +namespace Sim::Graphics::Data { class MeshGen diff --git a/src/graphics/mesh/model.cpp b/src/graphics/data/model.cpp similarity index 88% rename from src/graphics/mesh/model.cpp rename to src/graphics/data/model.cpp index aa4f237..ec00973 100644 --- a/src/graphics/mesh/model.cpp +++ b/src/graphics/data/model.cpp @@ -14,7 +14,7 @@ #include "model.hpp" #include "../../util/streams.hpp" -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; struct ProcState { @@ -176,10 +176,10 @@ static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene) glm::mat4 convert_mat(aiMatrix4x4 m) { return { - m.a1, m.a2, m.a3, m.a4, - m.b1, m.b2, m.b3, m.b4, - m.c1, m.c2, m.c3, m.c4, - m.d1, m.d2, m.d3, m.d4 + m.a1, m.b1, m.c1, m.d1, + m.a2, m.b2, m.c2, m.d2, + m.a3, m.b3, m.c3, m.d3, + m.a4, m.b4, m.c4, m.d4 }; } @@ -213,7 +213,7 @@ static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiSce if(node->mNumMeshes > 0) { - state.transforms.push_back(glm::transpose(mat)); + state.transforms.push_back(mat); } } @@ -258,7 +258,7 @@ glm::mat4 get_transforms(const aiNode* node) return mat; } -glm::mat4 Model::get_matrix(const char* name) const +glm::mat4 Model::load_matrix(const char* name) const { return get_transforms(scene->mRootNode->FindNode(name)); } @@ -280,18 +280,34 @@ Model::Model(std::string base, std::string filename) : base(base) for(int i = 0; i < scene->mNumLights; i++) { aiLight* light = scene->mLights[i]; - glm::mat4 mat = get_matrix(light->mName.C_Str()); + glm::mat4 mat = load_matrix(light->mName.C_Str()); auto [x, y, z] = light->mPosition; auto [r, g, b] = light->mColorDiffuse; - glm::vec4 pos = glm::vec4(x, y, z, 1) * mat; + glm::vec4 pos = mat * glm::vec4(x, y, z, 1); lights.push_back({ glm::vec3(pos), {r, g, b}, }); } + + for(int i = 0; i < scene->mNumCameras; i++) + { + aiCamera* camera = scene->mCameras[i]; + glm::mat4 mat = load_matrix(camera->mName.C_Str()); + + auto [x, y, z] = camera->mPosition; + auto [dx, dy, dz] = camera->mLookAt; + auto [ux, uy, uz] = camera->mUp; + + glm::vec4 pos = mat * glm::vec4(x, y, z, 1); + glm::vec3 look = glm::normalize(glm::mat3(mat) * glm::vec3(dx, dy, dz)); + glm::vec3 up = glm::normalize(glm::mat3(mat) * glm::vec3(ux, uy, uz)); + + cameras.push_back({.pos=glm::vec3(pos), .look=look, .up=up, .fov=camera->mHorizontalFOV}); + } } Mesh Model::load(const char* name, glm::mat4 mat) const diff --git a/src/graphics/mesh/model.hpp b/src/graphics/data/model.hpp similarity index 83% rename from src/graphics/mesh/model.hpp rename to src/graphics/data/model.hpp index 7c8323d..e849f75 100644 --- a/src/graphics/mesh/model.hpp +++ b/src/graphics/data/model.hpp @@ -3,6 +3,7 @@ #include "mesh.hpp" #include "light.hpp" +#include "camera.hpp" #include #include @@ -14,7 +15,7 @@ #include #include -namespace Sim::Graphics +namespace Sim::Graphics::Data { class Model @@ -26,6 +27,7 @@ class Model public: std::vector textures; + std::vector cameras; std::vector lights; Model(std::string base, std::string filename); @@ -35,7 +37,7 @@ public: Mesh load_root(glm::mat4 mat) const; Mesh load(const char* name) const; Mesh load(const char* name, glm::mat4 mat) const; - glm::mat4 get_matrix(const char* name) const; + glm::mat4 load_matrix(const char* name) const; }; }; diff --git a/src/graphics/mesh/texture.cpp b/src/graphics/data/texture.cpp similarity index 98% rename from src/graphics/mesh/texture.cpp rename to src/graphics/data/texture.cpp index 7871b68..0e6266c 100644 --- a/src/graphics/mesh/texture.cpp +++ b/src/graphics/data/texture.cpp @@ -8,7 +8,7 @@ #include "texture.hpp" -using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; static std::unordered_map loaded; unsigned int Texture::handle_white; diff --git a/src/graphics/mesh/texture.hpp b/src/graphics/data/texture.hpp similarity index 87% rename from src/graphics/mesh/texture.hpp rename to src/graphics/data/texture.hpp index 686a917..223a135 100644 --- a/src/graphics/mesh/texture.hpp +++ b/src/graphics/data/texture.hpp @@ -3,7 +3,7 @@ #include -namespace Sim::Graphics::Texture +namespace Sim::Graphics::Data::Texture { extern unsigned int handle_white; diff --git a/src/graphics/equipment/generator.cpp b/src/graphics/equipment/generator.cpp index c847cac..b6dfdf6 100644 --- a/src/graphics/equipment/generator.cpp +++ b/src/graphics/equipment/generator.cpp @@ -5,6 +5,7 @@ #include using namespace Sim::Graphics::Equipment; +using namespace Sim::Graphics::Data; Generator::Generator(const Model& model) { @@ -19,7 +20,7 @@ void Generator::remesh_static(Mesh& rmesh) void Generator::get_static_transforms(std::vector& transforms) { Sim::System& sys = *Sim::System::active; - glm::mat4 rot = glm::rotate(glm::mat4(1), (float)sys.loop.generator.get_phase(), glm::vec3(0, 0, 1)); + glm::mat4 rot = glm::rotate(glm::mat4(1), (float)sys.loop.generator.get_phase() * 0.5f, glm::vec3(0, 0, 1)); transforms.push_back(rot); } diff --git a/src/graphics/equipment/generator.hpp b/src/graphics/equipment/generator.hpp index 28a8b8f..3dc735e 100644 --- a/src/graphics/equipment/generator.hpp +++ b/src/graphics/equipment/generator.hpp @@ -1,20 +1,20 @@ #pragma once -#include "../mesh/meshgen.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Equipment { -class Generator : public MeshGen +class Generator : public Data::MeshGen { - Mesh g_rotor; + Data::Mesh g_rotor; public: - Generator(const Model& model); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); + Generator(const Data::Model& model); + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/equipment/pool.cpp b/src/graphics/equipment/pool.cpp index d97c255..d522cd1 100644 --- a/src/graphics/equipment/pool.cpp +++ b/src/graphics/equipment/pool.cpp @@ -5,6 +5,7 @@ #include using namespace Sim::Graphics::Equipment; +using namespace Sim::Graphics::Data; Pool::Pool(const Model& model) { diff --git a/src/graphics/equipment/pool.hpp b/src/graphics/equipment/pool.hpp index c918dd8..0f534ed 100644 --- a/src/graphics/equipment/pool.hpp +++ b/src/graphics/equipment/pool.hpp @@ -1,20 +1,20 @@ #pragma once -#include "../mesh/meshgen.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Equipment { -class Pool : public MeshGen +class Pool : public Data::MeshGen { - Mesh g_pool; + Data::Mesh g_pool; public: - Pool(const Model& model); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); + Pool(const Data::Model& model); + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/equipment/reactor.cpp b/src/graphics/equipment/reactor.cpp index 8db143d..c040180 100644 --- a/src/graphics/equipment/reactor.cpp +++ b/src/graphics/equipment/reactor.cpp @@ -8,6 +8,7 @@ #include using namespace Sim::Graphics::Equipment; +using namespace Sim::Graphics::Data; Reactor::Reactor(const Model& model) { @@ -22,6 +23,8 @@ void Reactor::remesh_static(Mesh& rmesh) double t_sx = -(sys.reactor.width - 1) * t_step / 2.0; double t_sy = -(sys.reactor.height - 1) * t_step / 2.0; + glm::mat4 mat_scale = glm::scale(glm::mat4(1), glm::vec3(t_step / 0.4)); + for(int i = 0; i < sys.reactor.size; i++) { int x = i % sys.reactor.width; @@ -39,12 +42,21 @@ void Reactor::remesh_static(Mesh& rmesh) if(r->get_colour()[3] != 0) { Mesh m1, m2; - m1.add(g_control_rod_base, glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0))); - m2.add(g_control_rod_lift, glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0))); + glm::mat4 m = glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale; + m1.add(g_control_rod_base, m); + m2.add(g_control_rod_lift, m); m1.bake_transforms(); m2.bake_transforms(); m2.set_blank_transform(); + for(int i = 0; i < m2.vertices.size(); i++) + { + if(g_control_rod_lift.vertices[i].pos.z == 0) + { + m2.vertices[i].transform_id = -1; + } + } + rmesh.add(m1); rmesh.add(m2); } diff --git a/src/graphics/equipment/reactor.hpp b/src/graphics/equipment/reactor.hpp index c76ddad..d6420b0 100644 --- a/src/graphics/equipment/reactor.hpp +++ b/src/graphics/equipment/reactor.hpp @@ -1,20 +1,20 @@ #pragma once -#include "../mesh/meshgen.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Equipment { -class Reactor : public MeshGen +class Reactor : public Data::MeshGen { - Mesh g_control_rod_lift, g_control_rod_base; + Data::Mesh g_control_rod_lift, g_control_rod_base; public: - Reactor(const Model& model); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); + Reactor(const Data::Model& model); + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/input/focus.cpp b/src/graphics/input/focus.cpp index 627452d..31cc256 100644 --- a/src/graphics/input/focus.cpp +++ b/src/graphics/input/focus.cpp @@ -24,6 +24,7 @@ static std::unique_ptr state = nullptr; static bool mouse_visible = false; static bool mouse_locked = false; static bool triggered = false; +static bool triggered_release = false; void Focus::on_keypress(int key, int sc, int action, int mods) { @@ -53,8 +54,10 @@ void Focus::on_mouse_button(int button, int action, int mods) state->on_mouse_button(button, action, mods); } - if(button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) + if(button == GLFW_MOUSE_BUTTON_LEFT && (action == GLFW_RELEASE || action == GLFW_PRESS)) { + bool t = false; + if(is_mouse_locked() && mouse_visible) { double mx, my; @@ -66,14 +69,21 @@ void Focus::on_mouse_button(int button, int action, int mods) trigger_near = glm::unProject(glm::vec3(mouse, -1), Camera::get_matrix(), Window::projection_matrix, viewport); trigger_far = glm::unProject(glm::vec3(mouse, 1), Camera::get_matrix(), Window::projection_matrix, viewport); - triggered = true; + t = true; } else if(!mouse_visible) { trigger_near = Camera::get_pos(); trigger_far = trigger_near + Camera::get_normal(); - triggered = true; + t = true; + } + + if(t) + { + t = (action == GLFW_PRESS); + triggered_release = !t; + triggered = t; } } } @@ -107,6 +117,7 @@ glm::vec<3, double> Focus::get_trigger_far() void Focus::update(double dt) { triggered = false; + triggered_release = false; bool c = is_mouse_locked(); @@ -194,3 +205,8 @@ bool Focus::is_triggered() return triggered; } +bool Focus::is_triggered_release() +{ + return triggered_release; +} + diff --git a/src/graphics/input/focus.hpp b/src/graphics/input/focus.hpp index a78f9aa..d016ab5 100644 --- a/src/graphics/input/focus.hpp +++ b/src/graphics/input/focus.hpp @@ -24,6 +24,7 @@ struct FocusType bool is_focused(); void clear_focus(); bool is_triggered(); +bool is_triggered_release(); bool is_mouse_locked(); void clear_mouse_locked(); glm::vec<3, double> get_trigger_near(); diff --git a/src/graphics/locations.cpp b/src/graphics/locations.cpp deleted file mode 100644 index ad9ebe6..0000000 --- a/src/graphics/locations.cpp +++ /dev/null @@ -1,47 +0,0 @@ - -#include "locations.hpp" -#include - -using namespace Sim::Graphics; - -const glm::mat4 Locations::monitors[7] = { - ( - glm::translate(glm::mat4(1), glm::vec3(-2.9475, -1.7778 + 0.05, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(0, 1, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(-1.5 + 0.05, 3.9475, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(1 + 0.05, 3.9475, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(3.5 + 0.05, 3.9475, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(6 + 0.05, 3.9475, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(8.9475, 7.0/3.0 - 0.05, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::rotate(glm::mat4(1), glm::radians(90), glm::vec3(0, 1, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ), - ( - glm::translate(glm::mat4(1), glm::vec3(8.9475, -1.0/3.0 - 0.05, 3 - 0.05)) * - glm::rotate(glm::mat4(1), glm::radians(-90), glm::vec3(1, 0, 0)) * - glm::rotate(glm::mat4(1), glm::radians(90), glm::vec3(0, 1, 0)) * - glm::scale(glm::mat4(1), glm::vec3(1.9, 1.9, 1.9)) - ) -}; - diff --git a/src/graphics/locations.hpp b/src/graphics/locations.hpp deleted file mode 100644 index 471a29f..0000000 --- a/src/graphics/locations.hpp +++ /dev/null @@ -1,12 +0,0 @@ - -#pragma once - -#include - -namespace Sim::Graphics::Locations -{ - -extern const glm::mat4 monitors[7]; - -}; - diff --git a/src/graphics/monitor/cctv.cpp b/src/graphics/monitor/cctv.cpp new file mode 100644 index 0000000..0884820 --- /dev/null +++ b/src/graphics/monitor/cctv.cpp @@ -0,0 +1,270 @@ + +#include +#include + +#include +#include + +#include + +#include "cctv.hpp" +#include "../shader.hpp" +#include "../window.hpp" +#include "../camera.hpp" +#include "../input/focus.hpp" +#include "../../system.hpp" +#include "../../util/math.hpp" +#include "../../util/streams.hpp" + +#define HEIGHT 512 + +using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; +using namespace Sim::Graphics; +using namespace Sim; + +class FocusCCTV : public Focus::FocusType +{ + CCTV* parent; + + int zoom = 0; + int rot_pitch = 0; + int rot_yaw = 0; + +public: + + FocusCCTV(CCTV* parent) + { + this->parent = parent; + } + + virtual void update(double dt) + { + if(rot_pitch || rot_yaw) + { + parent->rotate(dt, rot_pitch, -rot_yaw); + } + + if(zoom) + { + Data::Camera& active = parent->cameras[parent->camera_at]; + active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom - zoom * dt * 0.5f), 1.f, 4.f); + } + } + + virtual void on_keypress(int key, int sc, int action, int mods) + { + if(action == GLFW_PRESS) + { + switch(key) + { + case GLFW_KEY_KP_1: + parent->camera_at = (parent->camera_at + parent->cameras.size() - 1) % parent->cameras.size(); + break; + case GLFW_KEY_KP_2: + rot_pitch -= 1; + break; + case GLFW_KEY_KP_3: + parent->camera_at = (parent->camera_at + 1) % parent->cameras.size(); + break; + case GLFW_KEY_KP_4: + rot_yaw += 1; + break; + case GLFW_KEY_KP_5: + parent->powered = !parent->powered; + break; + case GLFW_KEY_KP_6: + rot_yaw -= 1; + break; + case GLFW_KEY_KP_7: + zoom += 1; + break; + case GLFW_KEY_KP_8: + rot_pitch += 1; + break; + case GLFW_KEY_KP_9: + zoom -= 1; + break; + } + } + + else if(action == GLFW_RELEASE) + { + switch(key) + { + case GLFW_KEY_KP_2: + rot_pitch += 1; + break; + case GLFW_KEY_KP_4: + rot_yaw -= 1; + break; + case GLFW_KEY_KP_6: + rot_yaw += 1; + break; + case GLFW_KEY_KP_7: + zoom -= 1; + break; + case GLFW_KEY_KP_8: + rot_pitch -= 1; + break; + case GLFW_KEY_KP_9: + zoom += 1; + break; + } + } + } +}; + +CCTV::CCTV(Model& model) + : height(HEIGHT) + , width(HEIGHT * 16 / 9) + , cameras(model.cameras) +{ + m_buttons[0] = model.load("click_cctv_numpad_1"); + m_buttons[1] = model.load("click_cctv_numpad_2"); + m_buttons[2] = model.load("click_cctv_numpad_3"); + m_buttons[3] = model.load("click_cctv_numpad_4"); + m_buttons[4] = model.load("click_cctv_numpad_5"); + m_buttons[5] = model.load("click_cctv_numpad_6"); + m_buttons[6] = model.load("click_cctv_numpad_7"); + m_buttons[7] = model.load("click_cctv_numpad_8"); + m_buttons[8] = model.load("click_cctv_numpad_9"); + + glGenFramebuffers(1, &fbo); + glGenTextures(1, &texture); + glGenRenderbuffers(1, &rbo_depth); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + + handle = glGetTextureHandleARB(texture); + glMakeTextureHandleResidentARB(handle); + + m_screen.vertices = { + {.texid=handle, .texpos={0, 1}, .pos={0, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, + {.texid=handle, .texpos={0, 0}, .pos={0, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, + {.texid=handle, .texpos={1, 1}, .pos={1, 0, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, + {.texid=handle, .texpos={1, 0}, .pos={1, 1, 0}, .normal={0, 0, 1}, .material={0, 0, 1}, .transform_id=0}, + }; + m_screen.indices = {0, 1, 3, 0, 3, 2}; + m_screen.transforms = {model.load_matrix("translation_monitor_1")}; + m_screen.bake_transforms(); + + gm_screen.bind(); + gm_screen.set(m_screen, GL_STATIC_DRAW); +} + +CCTV::~CCTV() +{ + if(fbo) glDeleteFramebuffers(1, &fbo); + if(texture) glDeleteTextures(1, &texture); + if(rbo_depth) glDeleteRenderbuffers(1, &rbo_depth); +} + +CCTV::CCTV(CCTV&& o) + : width(o.width) + , height(o.height) + , cameras(std::move(o.cameras)) + , gm_screen(std::move(o.gm_screen)) + , m_screen(std::move(o.m_screen)) + , m_buttons(std::move(o.m_buttons)) + , powered(o.powered) +{ + fbo = o.fbo; + texture = o.texture; + rbo_depth = o.rbo_depth; + handle = o.handle; + + o.fbo = 0; + o.texture = 0; + o.rbo_depth = 0; + o.handle = 0; +} + +void CCTV::rotate(double dt, float pitch, float yaw) +{ + Data::Camera& active = cameras[camera_at]; + float m = float(M_PI) * dt * 0.5f / active.zoom; + + active.pitch = Util::Math::clamp(active.pitch + pitch * m, -M_PI / 4, M_PI / 4); + active.yaw = Util::Math::clamp(active.yaw + yaw * m, -M_PI / 4, M_PI / 4); +} + +void CCTV::update(double dt) +{ + Data::Camera& active = cameras[camera_at]; + + if(m_screen.check_focus()) + Focus::set(std::make_unique(this)); + if(m_buttons[0].check_focus_hold()) + active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom - dt * 0.5f), 1.f, 4.f); + if(m_buttons[1].check_focus_hold()) + rotate(dt, 1, 0); + if(m_buttons[2].check_focus_hold()) + active.zoom = Util::Math::clamp(1.f / (1.f / active.zoom + dt * 0.5f), 1.f, 4.f); + if(m_buttons[3].check_focus_hold()) + rotate(dt, 0, -1); + if(m_buttons[4].check_focus()) + powered = !powered; + if(m_buttons[5].check_focus_hold()) + rotate(dt, 0, 1); + if(m_buttons[6].check_focus()) + camera_at = (camera_at + cameras.size() - 1) % cameras.size(); + if(m_buttons[7].check_focus_hold()) + rotate(dt, -1, 0); + if(m_buttons[8].check_focus()) + camera_at = (camera_at + 1) % cameras.size(); +} + +void CCTV::render_view() +{ + if(!powered) + return; + + Data::Camera& active = cameras[camera_at]; + + glm::mat4 rot = glm::mat4(1); + glm::vec3 right = glm::normalize(glm::cross(active.look, active.up)); + rot = glm::rotate(rot, -active.yaw, active.up); + rot = glm::rotate(rot, active.pitch, right); + + glm::mat4 view = glm::lookAt(active.pos, active.pos + glm::mat3(rot) * active.look, active.up); + glm::mat4 proj = glm::perspective(active.fov / active.zoom, (float)width / height, 0.1f, 100.0f); + glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity()); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glViewport(0, 0, width, height); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glFrontFace(GL_CCW); + + glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &proj[0][0]); + glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &view[0][0]); + glUniform3fv(Shader::MAIN["camera_pos"], 1, &active.pos[0]); + + Window::render_scene(); + Window::render_player(); +} + +void CCTV::render_screen() +{ + if(!powered) + return; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBlendFunc(GL_SRC_COLOR, GL_ONE); + + gm_screen.bind(); + gm_screen.render(); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + diff --git a/src/graphics/monitor/cctv.hpp b/src/graphics/monitor/cctv.hpp new file mode 100644 index 0000000..c39bde4 --- /dev/null +++ b/src/graphics/monitor/cctv.hpp @@ -0,0 +1,47 @@ + +#pragma once + +#include +#include + +#include "../data/meshgen.hpp" +#include "../data/camera.hpp" +#include "../data/glmesh.hpp" + +namespace Sim::Graphics::Monitor +{ + +class CCTV : public Data::MeshGen +{ + Data::GLMesh gm_screen; + Data::Mesh m_screen; + std::array m_buttons; + + unsigned int fbo; + unsigned int texture; + unsigned int rbo_depth; + unsigned int handle; + + const int width; + const int height; + + +public: + + std::vector cameras; + int camera_at = 0; + bool powered = false; + + CCTV(Data::Model& model); + CCTV(const CCTV&) = delete; + CCTV(CCTV&&); + ~CCTV(); + + void update(double dt) override; + void rotate(double dt, float pitch, float yaw); + void render_view(); + void render_screen(); +}; + +}; + diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 9431f4e..e4de59f 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -3,10 +3,9 @@ #include #include "core.hpp" -#include "../locations.hpp" #include "../input/focus.hpp" -#include "../mesh/arrays.hpp" -#include "../mesh/texture.hpp" +#include "../data/arrays.hpp" +#include "../data/texture.hpp" #include "../../system.hpp" #include "../../util/streams.hpp" @@ -18,6 +17,7 @@ using namespace Sim; using namespace Sim::Graphics; using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; using namespace Sim::Util::Streams; static void set_all(bool state) @@ -118,16 +118,16 @@ struct CoreJoystick : public Focus::FocusType Core::Core(const Model& model) { - mat = Locations::monitors[2]; - m_buttons[0] = model.load("click_numpad_1"); - m_buttons[1] = model.load("click_numpad_2"); - m_buttons[2] = model.load("click_numpad_3"); - m_buttons[3] = model.load("click_numpad_4"); - m_buttons[4] = model.load("click_numpad_5"); - m_buttons[5] = model.load("click_numpad_6"); - m_buttons[6] = model.load("click_numpad_7"); - m_buttons[7] = model.load("click_numpad_8"); - m_buttons[8] = model.load("click_numpad_9"); + mat = model.load_matrix("translation_monitor_3"); + m_buttons[0] = model.load("click_reactor_numpad_1"); + m_buttons[1] = model.load("click_reactor_numpad_2"); + m_buttons[2] = model.load("click_reactor_numpad_3"); + m_buttons[3] = model.load("click_reactor_numpad_4"); + m_buttons[4] = model.load("click_reactor_numpad_5"); + m_buttons[5] = model.load("click_reactor_numpad_6"); + m_buttons[6] = model.load("click_reactor_numpad_7"); + m_buttons[7] = model.load("click_reactor_numpad_8"); + m_buttons[8] = model.load("click_reactor_numpad_9"); m_joystick = model.load("click_reactor_joystick"); m_monitor = model.load("translation_monitor_3"); m_scram = model.load("click_scram"); @@ -135,14 +135,14 @@ Core::Core(const Model& model) void Core::remesh_static(Mesh& rmesh) { - Mesh mesh; + Data::Mesh mesh; mesh.load_text("Reactor Core", 0.04); rmesh.add(mesh, mat, true); } -static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour) +static Data::Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour) { - Mesh mesh; + Data::Mesh mesh; mesh.indices = {0, 1, 3, 0, 3, 2}; mesh.vertices = { @@ -186,7 +186,7 @@ void Core::update(double dt) void Core::remesh_slow(Mesh& rmesh) { Sim::System& sys = *System::active; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; double step = sys.reactor.cell_width / sys.vessel.diameter * 0.8; double sx = 0.5 - (sys.reactor.width - 1) * step / 2.0; diff --git a/src/graphics/monitor/core.hpp b/src/graphics/monitor/core.hpp index 308e7b6..18b6d57 100644 --- a/src/graphics/monitor/core.hpp +++ b/src/graphics/monitor/core.hpp @@ -1,27 +1,27 @@ #pragma once -#include "../mesh/model.hpp" -#include "../mesh/meshgen.hpp" +#include "../data/model.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Monitor { -class Core : public MeshGen +class Core : public Data::MeshGen { glm::mat4 mat; - Mesh m_monitor; - Mesh m_buttons[9]; - Mesh m_joystick; - Mesh m_scram; + Data::Mesh m_monitor; + Data::Mesh m_buttons[9]; + Data::Mesh m_joystick; + Data::Mesh m_scram; public: - Core(const Model& model); - virtual void update(double dt); - virtual void remesh_static(Mesh& rmesh); - virtual void remesh_slow(Mesh& rmesh); + Core(const Data::Model& model); + void update(double dt) override; + void remesh_static(Data::Mesh& rmesh) override; + void remesh_slow(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index 82c9d27..a3f820c 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -3,7 +3,6 @@ #include #include "primary_loop.hpp" -#include "../locations.hpp" #include "../../system.hpp" #include "../../coolant/valve.hpp" #include "../input/focus.hpp" @@ -14,6 +13,7 @@ using namespace Sim::Graphics; using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; using namespace Sim::Util::Streams; struct ValveJoystick : public Focus::FocusType @@ -51,7 +51,7 @@ struct ValveJoystick : public Focus::FocusType PrimaryLoop::PrimaryLoop(const Model& model) { - mat = Locations::monitors[3]; + mat = model.load_matrix("translation_monitor_4"); g_switch_pump = model.load("visual_pump_switch_1"); g_switch_bypass = model.load("visual_bypass_switch"); @@ -67,7 +67,7 @@ PrimaryLoop::PrimaryLoop(const Model& model) void PrimaryLoop::remesh_static(Mesh& rmesh) { std::stringstream ss; - Mesh mesh; + Data::Mesh mesh; ss << "Turbine Bypass Valve\n\n"; ss << "Opened\nFlow\nSetpoint\n\n"; @@ -108,7 +108,7 @@ void PrimaryLoop::update(double dt) void PrimaryLoop::remesh_slow(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; System& sys = *System::active; ss << "\n\n"; diff --git a/src/graphics/monitor/primary_loop.hpp b/src/graphics/monitor/primary_loop.hpp index 382b9e2..493acd6 100644 --- a/src/graphics/monitor/primary_loop.hpp +++ b/src/graphics/monitor/primary_loop.hpp @@ -1,34 +1,34 @@ #pragma once -#include "../mesh/model.hpp" -#include "../mesh/meshgen.hpp" +#include "../data/model.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Monitor { -class PrimaryLoop : public MeshGen +class PrimaryLoop : public Data::MeshGen { glm::mat4 mat; - Mesh m_joystick_turbine_bypass; - Mesh m_joystick_turbine_inlet; + Data::Mesh m_joystick_turbine_bypass; + Data::Mesh m_joystick_turbine_inlet; - Mesh g_switch_pump; - Mesh g_switch_bypass; - Mesh g_switch_inlet; + Data::Mesh g_switch_pump; + Data::Mesh g_switch_bypass; + Data::Mesh g_switch_inlet; - Mesh m_switch_pump; - Mesh m_switch_bypass; - Mesh m_switch_inlet; + Data::Mesh m_switch_pump; + Data::Mesh m_switch_bypass; + Data::Mesh m_switch_inlet; public: - PrimaryLoop(const Model& model); - virtual void update(double dt); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); - virtual void remesh_slow(Mesh& rmesh); + PrimaryLoop(const Data::Model& model); + void update(double dt) override; + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; + void remesh_slow(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/monitor/secondary_loop.cpp b/src/graphics/monitor/secondary_loop.cpp index 1fda1db..230f916 100644 --- a/src/graphics/monitor/secondary_loop.cpp +++ b/src/graphics/monitor/secondary_loop.cpp @@ -3,7 +3,6 @@ #include #include "secondary_loop.hpp" -#include "../locations.hpp" #include "../../system.hpp" #include "../../coolant/valve.hpp" #include "../input/focus.hpp" @@ -14,12 +13,12 @@ using namespace Sim::Graphics; using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; using namespace Sim::Util::Streams; - SecondaryLoop::SecondaryLoop(const Model& model) { - mat = Locations::monitors[5]; + mat = model.load_matrix("translation_monitor_6"); g_switch_2 = model.load("visual_pump_switch_2"); g_switch_3 = model.load("visual_pump_switch_3"); @@ -43,7 +42,7 @@ void SecondaryLoop::update(double dt) void SecondaryLoop::remesh_static(Mesh& rmesh) { std::stringstream ss; - Mesh mesh; + Data::Mesh mesh; ss << "Cooling Tower\n\n"; ss << "Heat\nSteam\nPressure\nLevel\n\n"; @@ -61,7 +60,7 @@ void SecondaryLoop::remesh_static(Mesh& rmesh) void SecondaryLoop::remesh_slow(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; System& sys = *System::active; ss << "\n\n"; diff --git a/src/graphics/monitor/secondary_loop.hpp b/src/graphics/monitor/secondary_loop.hpp index 9048036..28c035d 100644 --- a/src/graphics/monitor/secondary_loop.hpp +++ b/src/graphics/monitor/secondary_loop.hpp @@ -1,31 +1,31 @@ #pragma once -#include "../mesh/model.hpp" -#include "../mesh/meshgen.hpp" +#include "../data/model.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Monitor { -class SecondaryLoop : public MeshGen +class SecondaryLoop : public Data::MeshGen { glm::mat4 mat; - Mesh g_switch_2; - Mesh g_switch_3; - - Mesh m_joystick_turbine_bypass; - Mesh m_joystick_turbine_inlet; - Mesh m_switch_2; - Mesh m_switch_3; + Data::Mesh g_switch_2; + Data::Mesh g_switch_3; + + Data::Mesh m_joystick_turbine_bypass; + Data::Mesh m_joystick_turbine_inlet; + Data::Mesh m_switch_2; + Data::Mesh m_switch_3; public: - SecondaryLoop(const Model& model); - virtual void update(double dt); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); - virtual void remesh_slow(Mesh& rmesh); + SecondaryLoop(const Data::Model& model); + void update(double dt) override; + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; + void remesh_slow(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/monitor/turbine.cpp b/src/graphics/monitor/turbine.cpp index dd307b0..e87f465 100644 --- a/src/graphics/monitor/turbine.cpp +++ b/src/graphics/monitor/turbine.cpp @@ -3,7 +3,6 @@ #include #include "turbine.hpp" -#include "../locations.hpp" #include "../../system.hpp" #include "../../coolant/valve.hpp" #include "../input/focus.hpp" @@ -15,11 +14,12 @@ using namespace Sim::Graphics; using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; using namespace Sim::Util::Streams; Turbine::Turbine(const Model& model) { - mat = Locations::monitors[4]; + mat = model.load_matrix("translation_monitor_5"); g_dial_phase = model.load("visual_dial_phase"); g_dial_voltage = model.load("visual_dial_voltage"); @@ -69,7 +69,7 @@ void Turbine::get_static_transforms(std::vector& transforms) void Turbine::remesh_static(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; ss << "Turbine\n\n"; ss << "Heat\nPressure\nSpeed\n\n"; @@ -87,7 +87,7 @@ void Turbine::remesh_static(Mesh& rmesh) void Turbine::remesh_slow(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; System& sys = *System::active; ss << "\n\n"; diff --git a/src/graphics/monitor/turbine.hpp b/src/graphics/monitor/turbine.hpp index 5a7a21a..73ab166 100644 --- a/src/graphics/monitor/turbine.hpp +++ b/src/graphics/monitor/turbine.hpp @@ -1,31 +1,31 @@ #pragma once -#include "../mesh/model.hpp" -#include "../mesh/glmesh.hpp" -#include "../mesh/meshgen.hpp" +#include "../data/model.hpp" +#include "../data/glmesh.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Monitor { -class Turbine : public MeshGen +class Turbine : public Data::MeshGen { glm::mat4 mat; - Mesh g_dial_phase; - Mesh g_dial_voltage; - Mesh g_dial_power; - Mesh g_dial_frequency; - Mesh g_switch_breaker; - Mesh m_switch_breaker; + Data::Mesh g_dial_phase; + Data::Mesh g_dial_voltage; + Data::Mesh g_dial_power; + Data::Mesh g_dial_frequency; + Data::Mesh g_switch_breaker; + Data::Mesh m_switch_breaker; public: - Turbine(const Model& model); - virtual void update(double dt); - virtual void get_static_transforms(std::vector& transforms); - virtual void remesh_static(Mesh& rmesh); - virtual void remesh_slow(Mesh& rmesh); + Turbine(const Data::Model& model); + void update(double dt) override; + void get_static_transforms(std::vector& transforms) override; + void remesh_static(Data::Mesh& rmesh) override; + void remesh_slow(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/monitor/vessel.cpp b/src/graphics/monitor/vessel.cpp index fa5ce9c..f288d70 100644 --- a/src/graphics/monitor/vessel.cpp +++ b/src/graphics/monitor/vessel.cpp @@ -5,7 +5,6 @@ #include "vessel.hpp" #include "../../reactor/rod.hpp" #include "../../reactor/control/boron_rod.hpp" -#include "../locations.hpp" #include "../../system.hpp" #include "../../util/streams.hpp" @@ -13,17 +12,18 @@ #include using namespace Sim::Graphics::Monitor; +using namespace Sim::Graphics::Data; using namespace Sim::Util::Streams; Vessel::Vessel(const Model& model) { - mat = Locations::monitors[1]; + mat = model.load_matrix("translation_monitor_2"); } void Vessel::remesh_static(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; ss << "Reactor Vessel\n\n"; ss << "Heat\n"; @@ -44,7 +44,7 @@ void Vessel::remesh_static(Mesh& rmesh) void Vessel::remesh_slow(Mesh& rmesh) { std::stringstream ss; - Sim::Graphics::Mesh mesh; + Sim::Graphics::Data::Mesh mesh; Sim::System& sys = *System::active; double temp_min, temp_max; diff --git a/src/graphics/monitor/vessel.hpp b/src/graphics/monitor/vessel.hpp index b986a32..4991a1b 100644 --- a/src/graphics/monitor/vessel.hpp +++ b/src/graphics/monitor/vessel.hpp @@ -1,21 +1,21 @@ #pragma once -#include "../mesh/model.hpp" -#include "../mesh/meshgen.hpp" +#include "../data/model.hpp" +#include "../data/meshgen.hpp" namespace Sim::Graphics::Monitor { -class Vessel : public MeshGen +class Vessel : public Data::MeshGen { glm::mat4 mat; public: - Vessel(const Model& model); - virtual void remesh_static(Mesh& rmesh); - virtual void remesh_slow(Mesh& rmesh); + Vessel(const Data::Model& model); + void remesh_static(Data::Mesh& rmesh) override; + void remesh_slow(Data::Mesh& rmesh) override; }; }; diff --git a/src/graphics/resize.cpp b/src/graphics/resize.cpp index 888a794..db2ade3 100644 --- a/src/graphics/resize.cpp +++ b/src/graphics/resize.cpp @@ -7,6 +7,7 @@ using namespace Sim::Graphics; using namespace Sim::Graphics::Resize; +using namespace Sim::Graphics::Window; static bool is_fullscreen = false; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index c79a7b8..cd29c22 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "shader.hpp" #include "window.hpp" @@ -12,26 +13,20 @@ using namespace Sim::Graphics; Shader Shader::MAIN; -Shader Shader::BLUR; Shader Shader::LIGHT; Shader* Shader::ACTIVE; -static int load_shader(const char* src, int type) -{ - int id = glCreateShader(type); - - glShaderSource(id, 1, &src, nullptr); - glCompileShader(id); - - return id; -} - static std::string read_shader(const char* path) { std::stringstream ss; std::ifstream file(path, std::ios::binary); char buff[1024]; + if(!file.is_open()) + { + throw std::runtime_error(std::format("Shader Read Error: {0}", path)); + } + while(!file.eof()) { file.read(buff, 1024); @@ -47,6 +42,37 @@ static std::string read_shader(const char* base, const char* file) return read_shader(path.c_str()); } +Shader::Source::Source(const char* path, GLenum type) +{ + int success; + std::string src = read_shader(path); + const char* c_src = src.c_str(); + + id = glCreateShader(type); + glShaderSource(id, 1, &c_src, nullptr); + glCompileShader(id); + glGetShaderiv(id, GL_COMPILE_STATUS, &success); + + if(!success) + { + char infoLog[512]; + glGetShaderInfoLog(id, 512, NULL, infoLog); + std::string entry = std::format("Shader Compile Error ({0}): {1}", path, infoLog); + throw std::runtime_error(entry); + } +} + +Shader::Source::Source(Source&& o) +{ + id = o.id; + o.id = 0; +} + +Shader::Source::~Source() +{ + if(id) glDeleteShader(id); +} + Shader::Shader() { @@ -66,30 +92,15 @@ Shader::~Shader() } } -void Shader::load(const char* path, const char* file_vsh, const char* file_fsh) +void Shader::load(const Source* sources, int count) { - load(path, file_vsh, nullptr, file_fsh); -} - -void Shader::load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh) -{ - std::string shader_vsh = file_vsh ? read_shader(path, file_vsh) : ""; - std::string shader_gsh = file_gsh ? read_shader(path, file_gsh) : ""; - std::string shader_fsh = file_fsh ? read_shader(path, file_fsh) : ""; - int success; - int vsh_id = file_vsh ? load_shader(shader_vsh.c_str(), GL_VERTEX_SHADER) : 0; - int gsh_id = file_gsh ? load_shader(shader_gsh.c_str(), GL_GEOMETRY_SHADER) : 0; - int fsh_id = file_fsh ? load_shader(shader_fsh.c_str(), GL_FRAGMENT_SHADER) : 0; - prog_id = glCreateProgram(); - if(file_vsh) - glAttachShader(prog_id, vsh_id); - if(file_gsh) - glAttachShader(prog_id, gsh_id); - if(file_fsh) - glAttachShader(prog_id, fsh_id); + for(int i = 0; i < count; i++) + { + glAttachShader(prog_id, sources[i].id); + } glLinkProgram(prog_id); glGetProgramiv(prog_id, GL_LINK_STATUS, &success); @@ -98,21 +109,9 @@ void Shader::load(const char* path, const char* file_vsh, const char* file_gsh, { char infoLog[512]; glGetProgramInfoLog(prog_id, 512, NULL, infoLog); - std::cout << "Shader Link Error (" << path << "," << file_vsh << "," << file_fsh << "): " << infoLog << std::endl; - Window::close(); - return; + std::string entry = std::format("Shader Link Error: {0}", infoLog); + throw std::runtime_error(entry); } - - glUseProgram(prog_id); - - if(file_vsh) - glDeleteShader(vsh_id); - if(file_gsh) - glDeleteShader(gsh_id); - if(file_fsh) - glDeleteShader(fsh_id); - - ACTIVE = this; } void Shader::use() diff --git a/src/graphics/shader.hpp b/src/graphics/shader.hpp index 06bd72b..2846a92 100644 --- a/src/graphics/shader.hpp +++ b/src/graphics/shader.hpp @@ -1,11 +1,14 @@ #pragma once +#include + #include namespace Sim::Graphics { + class Shader { unsigned int prog_id = 0; @@ -14,9 +17,18 @@ class Shader std::unordered_map uniform_block_indices; public: + + struct Source + { + unsigned int id; + + Source(const char* path, GLenum type); + Source(const Source& o) = delete; + Source(Source&& o); + ~Source(); + }; static Shader MAIN; - static Shader BLUR; static Shader LIGHT; static Shader* ACTIVE; @@ -26,8 +38,7 @@ public: Shader(Shader&& o); ~Shader(); - void load(const char* path, const char* file_vsh, const char* file_gsh, const char* file_fsh); - void load(const char* path, const char* file_vsh, const char* file_fsh); + void load(const Source* sources, int count); void block_binding(const char* name, unsigned int index); void use(); diff --git a/src/graphics/ui.cpp b/src/graphics/ui.cpp index 06959ca..66f80d2 100644 --- a/src/graphics/ui.cpp +++ b/src/graphics/ui.cpp @@ -6,11 +6,11 @@ #include -#include "mesh/mesh.hpp" -#include "mesh/glmesh.hpp" -#include "mesh/arrays.hpp" -#include "mesh/font.hpp" -#include "mesh/texture.hpp" +#include "data/mesh.hpp" +#include "data/glmesh.hpp" +#include "data/arrays.hpp" +#include "data/font.hpp" +#include "data/texture.hpp" #include "resize.hpp" #include "shader.hpp" @@ -18,18 +18,17 @@ using namespace Sim::Graphics; -static GLMesh gm_ui; -static GLMesh gm_dynamic_slow[2]; - +static Data::GLMesh gm_ui; +static Data::GLMesh gm_dynamic_slow[2]; static Widget::Clock w_clock; static int gm_dynamic_slow_at = 0; void UI::init() { - Mesh m; + Data::Mesh m; - unsigned int handle = Texture::handle_white; + unsigned int handle = Data::Texture::handle_white; m.indices = {0, 1, 3, 0, 3, 2}; m.vertices = { {.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, @@ -51,10 +50,12 @@ void UI::update(double dt) void UI::update_slow() { - Mesh mesh; + Data::Mesh mesh; w_clock.remesh_slow(mesh); + mesh.bake_transforms(); + gm_dynamic_slow[gm_dynamic_slow_at].bind(); gm_dynamic_slow[gm_dynamic_slow_at].set(mesh, GL_DYNAMIC_DRAW); gm_dynamic_slow_at = (gm_dynamic_slow_at + 1) % 2; diff --git a/src/graphics/widget/clock.cpp b/src/graphics/widget/clock.cpp index 142c964..a7273ce 100644 --- a/src/graphics/widget/clock.cpp +++ b/src/graphics/widget/clock.cpp @@ -10,14 +10,15 @@ #include #include -#include "../mesh/arrays.hpp" -#include "../mesh/font.hpp" -#include "../mesh/arrays.hpp" +#include "../data/arrays.hpp" +#include "../data/font.hpp" +#include "../data/arrays.hpp" #include "../resize.hpp" #include "../../system.hpp" #include "../../util/streams.hpp" using namespace Sim::Graphics::Widget; +using namespace Sim::Graphics::Data; void Clock::update(double dt) { diff --git a/src/graphics/widget/clock.hpp b/src/graphics/widget/clock.hpp index 3ee3bd7..d0b6dd4 100644 --- a/src/graphics/widget/clock.hpp +++ b/src/graphics/widget/clock.hpp @@ -1,7 +1,7 @@ #pragma once -#include "../mesh/glmesh.hpp" +#include "../data/glmesh.hpp" namespace Sim::Graphics::Widget { @@ -11,7 +11,7 @@ struct Clock double dt; void update(double dt); - void remesh_slow(Mesh& rmesh); + void remesh_slow(Data::Mesh& rmesh); }; }; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index d4ee3f8..daec62e 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -10,8 +10,8 @@ #include #include -#include "mesh/mesh.hpp" -#include "mesh/arrays.hpp" +#include "data/mesh.hpp" +#include "data/arrays.hpp" #include "input/keyboard.hpp" #include "input/mouse.hpp" #include "input/focus.hpp" @@ -19,17 +19,17 @@ #include "resize.hpp" #include "window.hpp" #include "shader.hpp" -#include "mesh/font.hpp" -#include "locations.hpp" +#include "data/font.hpp" #include "monitor/vessel.hpp" #include "monitor/core.hpp" #include "monitor/primary_loop.hpp" #include "monitor/secondary_loop.hpp" #include "monitor/turbine.hpp" -#include "mesh/texture.hpp" -#include "mesh/model.hpp" -#include "mesh/gllight.hpp" -#include "mesh/meshgen.hpp" +#include "monitor/cctv.hpp" +#include "data/texture.hpp" +#include "data/model.hpp" +#include "data/gllight.hpp" +#include "data/meshgen.hpp" #include "equipment/reactor.hpp" #include "equipment/generator.hpp" #include "equipment/pool.hpp" @@ -38,6 +38,7 @@ #include "ui.hpp" using namespace Sim::Graphics; +using namespace Sim::Graphics::Data; constexpr int SSBO_TRANSFORMS_LEN = 2; @@ -55,11 +56,14 @@ static Mesh g_scene; static std::vector g_scene_transforms; static GLMesh gm_scene; +static GLMesh gm_player; static GLMesh gm_dynamic_slow[2]; static std::vector lights; -static std::vector> monitors; -static std::vector> equipment; +static std::vector monitors; +static std::vector equipment; + +static Monitor::CCTV* monitor_cctv; glm::mat4 Window::projection_matrix; @@ -90,21 +94,15 @@ void remesh_static() equipment->remesh_static(mesh); } - gm_scene.bind(false); - gm_scene.set(mesh, GL_STATIC_DRAW, false); + gm_scene.bind(); + gm_scene.set(mesh, GL_STATIC_DRAW); g_scene_transforms = std::move(mesh.transforms); - std::cout << "Total triangles: " << mesh.indices.size() / 3 << "\n"; + std::cout << "Total triangle count: " << mesh.indices.size() / 3 << "\n"; } void render_shadow_map() { - Shader::LIGHT.use(); - - for(auto& light : lights) - { - light.render(); - } } void Window::create() @@ -165,21 +163,36 @@ void Window::create() Font::init(); UI::init(); - Shader::MAIN.load("../assets/shader", "main.vsh", "main.fsh"); + // load all the shaders + Shader::Source sources_main[] = { + {"../assets/shader/main.vsh", GL_VERTEX_SHADER}, + {"../assets/shader/main.fsh", GL_FRAGMENT_SHADER}, + }; + Shader::Source sources_light[] = { + {"../assets/shader/light.vsh", GL_VERTEX_SHADER}, + {"../assets/shader/light.gsh", GL_GEOMETRY_SHADER}, + {"../assets/shader/light.fsh", GL_FRAGMENT_SHADER}, + }; + Shader::MAIN.load(sources_main, 2); + Shader::LIGHT.load(sources_light, 3); + + Shader::MAIN.use(); glBindFramebuffer(GL_FRAMEBUFFER, 0); Sim::System& sys = *System::active; - Mesh m_transparent; Model model("../assets", "scene.glb"); + Mesh m_player = model.load("visual_player"); + + gm_player.bind(); + gm_player.bind_ssbo(); + gm_player.set(m_player, GL_STATIC_DRAW); g_scene.add(model.load("cr")); g_scene.add(model.load("cb")); g_scene.add(model.load("hw")); g_scene.bake_transforms(); - std::cout << "Static scene triangles: " << g_scene.indices.size() / 3 << "\n"; - Camera::init(model); // send all the light data @@ -190,21 +203,23 @@ void Window::create() glUniform1i(Shader::MAIN["lights_count"], model.lights.size()); - monitors.push_back(std::make_unique(model)); - monitors.push_back(std::make_unique(model)); - monitors.push_back(std::make_unique(model)); - monitors.push_back(std::make_unique(model)); - monitors.push_back(std::make_unique(model)); - equipment.push_back(std::make_unique(model)); - equipment.push_back(std::make_unique(model)); - equipment.push_back(std::make_unique(model)); + monitors.push_back(new Monitor::Core(model)); + monitors.push_back(new Monitor::Vessel(model)); + monitors.push_back(new Monitor::PrimaryLoop(model)); + monitors.push_back(new Monitor::SecondaryLoop(model)); + monitors.push_back(new Monitor::Turbine(model)); + monitors.push_back(monitor_cctv = new Monitor::CCTV(model)); + + equipment.push_back(new Equipment::Reactor(model)); + equipment.push_back(new Equipment::Generator(model)); + equipment.push_back(new Equipment::Pool(model)); remesh_static(); glfwShowWindow(win); // setup lighting and prerender shadows - Shader::LIGHT.load("../assets/shader", "light.vsh", "light.gsh", "light.fsh"); + Shader::LIGHT.use(); glUniform1f(Shader::LIGHT["far_plane"], 100.0f); GLLight::init(); @@ -322,9 +337,16 @@ void Window::update(double dt) } } +void Window::render_player() +{ + gm_player.bind(); + gm_player.bind_ssbo(); + gm_player.render(); +} + void Window::render_scene() { - gm_scene.bind(false); + gm_scene.bind(); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]); gm_scene.render(); @@ -336,32 +358,49 @@ void Window::render_scene() void Window::render() { - render_shadow_map(); + Shader::LIGHT.use(); + for(auto& light : lights) + { + light.render(); + } glm::vec<2, int> size = Resize::get_size(); glm::vec3 camera_pos = Camera::get_pos(); glm::mat4 mat_camera = Camera::get_matrix(); Shader::MAIN.use(); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glViewport(0, 0, size.x, size.y); - + glm::vec3 brightness = glm::vec3(System::active->grid.get_light_intensity()); glm::mat4 mat_projection = glm::perspective(glm::radians(90.0f), Resize::get_aspect(), 0.01f, 100.f); - glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]); + glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); + + glm::mat4 mat_player = glm::mat4(1); + mat_player = glm::translate(mat_player, glm::vec3(Camera::get_pos_base())); + mat_player = glm::rotate(mat_player, (float)glm::radians(90 - Camera::get_yaw()), glm::vec3(0, 0, 1)); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, gm_player.ssbo); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(glm::mat4), &mat_player, GL_STREAM_DRAW); + + monitor_cctv->render_view(); + glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]); glUniform3fv(Shader::MAIN["camera_pos"], 1, &camera_pos[0]); - glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); + glUniformMatrix4fv(Shader::MAIN["projection"], 1, false, &mat_projection[0][0]); projection_matrix = mat_projection; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glViewport(0, 0, size.x, size.y); glFrontFace(GL_CCW); - glClearColor(0, 0, 0, 1.0f); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); render_scene(); + monitor_cctv->render_screen(); brightness = glm::vec3(1); + glBindFramebuffer(GL_FRAMEBUFFER, 0); glUniform3fv(Shader::MAIN["brightness"], 1, &brightness[0]); + glClear(GL_DEPTH_BUFFER_BIT); UI::render(); Focus::render_ui(); diff --git a/src/graphics/window.hpp b/src/graphics/window.hpp index 16b3eb5..0baf471 100644 --- a/src/graphics/window.hpp +++ b/src/graphics/window.hpp @@ -17,6 +17,7 @@ void reload(); void update(double dt); void render(); void render_scene(); +void render_player(); void destroy(); void close(); diff --git a/src/main.cpp b/src/main.cpp index 6298681..af2e703 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,7 +10,6 @@ #include "coolant/valve.hpp" #include "coolant/pump.hpp" -#include "graphics/mesh/mesh.hpp" #include "graphics/input/focus.hpp" #include "graphics/window.hpp" diff --git a/src/util/math.hpp b/src/util/math.hpp index 527d4f3..0b30f01 100644 --- a/src/util/math.hpp +++ b/src/util/math.hpp @@ -19,13 +19,24 @@ constexpr double j_to_ms2(double j, double mass) return m*std::sqrt(m * j / (mass * 0.001)); } -constexpr float map(float v, float imin, float imax, float omin, float omax) +template +constexpr A map(A v, auto imin, auto imax, auto omin, auto omax) { return (v - imin) * (omax - omin) / (imax - imin) + omin; } -template -constexpr A mod(A a, B b) +template +constexpr A clamp(A v, auto min, auto max) +{ + if(v < min) + return min; + if(v > max) + return max; + return v; +} + +template +constexpr A mod(A a, auto b) { A v = std::fmod(a, b);