From 34c722e8be363231f04271911e53109221fa35b1 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Sun, 3 Mar 2024 01:17:15 +1100 Subject: [PATCH] more models --- assets/scene.blend | 4 +- assets/scene.glb | 4 +- assets/shader/light.gsh | 5 +- assets/shader/light.vsh | 7 +- assets/shader/main.fsh | 10 +- assets/shader/main.vsh | 13 ++- .../texture/safety_signs/radiation_area.png | 3 + .../safety_signs/radiation_area_auth_only.png | 3 + src/graphics/equipment/reactor.cpp | 35 ++++--- src/graphics/equipment/reactor.hpp | 8 +- src/graphics/mesh/arrays.cpp | 3 + src/graphics/mesh/arrays.hpp | 1 + src/graphics/mesh/mesh.cpp | 67 ++++++++------ src/graphics/mesh/mesh.hpp | 2 + src/graphics/mesh/meshgen.hpp | 8 +- src/graphics/monitor/core.cpp | 69 +++++--------- src/graphics/monitor/core.hpp | 6 +- src/graphics/monitor/primary_loop.cpp | 45 +++++---- src/graphics/monitor/primary_loop.hpp | 6 +- src/graphics/monitor/secondary_loop.cpp | 47 +++++----- src/graphics/monitor/secondary_loop.hpp | 6 +- src/graphics/monitor/turbine.cpp | 91 +++++++++---------- src/graphics/monitor/turbine.hpp | 8 +- src/graphics/monitor/vessel.cpp | 17 +--- src/graphics/monitor/vessel.hpp | 6 +- src/graphics/shader.cpp | 17 ++++ src/graphics/shader.hpp | 3 + src/graphics/widget/clock.cpp | 2 +- src/graphics/window.cpp | 87 ++++++++++-------- src/graphics/window.hpp | 1 + 30 files changed, 309 insertions(+), 275 deletions(-) create mode 100644 assets/texture/safety_signs/radiation_area.png create mode 100644 assets/texture/safety_signs/radiation_area_auth_only.png diff --git a/assets/scene.blend b/assets/scene.blend index a14daa5..d940ef6 100644 --- a/assets/scene.blend +++ b/assets/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:307d5523ea353ee6edbe0aa0a5bf26b88dcb1ece8eeac922f8963128842ccfff -size 10701717 +oid sha256:7ccf320301ad1147b66f3277a19ec22ae0185505edd30a7abb6191015bc06465 +size 11098565 diff --git a/assets/scene.glb b/assets/scene.glb index 2580e89..48a4b5c 100644 --- a/assets/scene.glb +++ b/assets/scene.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:338d18e7c3b6eda70612d390018c0c01bddf0c926c1c6cc38128a397977f7c8b -size 3265988 +oid sha256:1e48376251379c8a4c5468202fe4798c06778a37df80fe6e2f000c8110709f15 +size 3457104 diff --git a/assets/shader/light.gsh b/assets/shader/light.gsh index 2e66648..c234248 100644 --- a/assets/shader/light.gsh +++ b/assets/shader/light.gsh @@ -6,13 +6,12 @@ layout (triangle_strip, max_vertices=18) out; uniform mat4 shadow_mats[6]; -in float emissive[]; -in float base_transparency[]; +in flat int should_ignore[]; out vec3 frag_pos; void main() { - if(emissive[0] > 0 || base_transparency[0] > 0) return; + if(should_ignore[0] != 0) return; for(int i = 0; i < 6; i++) { diff --git a/assets/shader/light.vsh b/assets/shader/light.vsh index f2f3d45..e2ad551 100644 --- a/assets/shader/light.vsh +++ b/assets/shader/light.vsh @@ -4,17 +4,16 @@ layout (location = 2) in vec4 aPos; layout (location = 4) in vec4 aColour; layout (location = 5) in vec3 aMaterial; +layout (location = 6) in float aTransformIndex; uniform mat4 model; uniform mat4 camera; -out float emissive; -out float base_transparency; +out flat int should_ignore; void main() { gl_Position = camera * model * aPos; - base_transparency = 1.f - aColour.a; - emissive = aMaterial[2]; + should_ignore = int(aTransformIndex >= 0.f || aMaterial[2] > 0.f || aColour.a < 1.f); } diff --git a/assets/shader/main.fsh b/assets/shader/main.fsh index f4c3056..234da8d 100644 --- a/assets/shader/main.fsh +++ b/assets/shader/main.fsh @@ -18,12 +18,12 @@ struct Light vec4 colour; }; -layout(std140, binding = 1) buffer ssbo_lights +layout(std140, binding = 1) readonly buffer LightBuffer { Light lights[]; }; -layout(std430, binding = 2) buffer ssbo_shadow_maps +layout(std430, binding = 2) readonly buffer ShadowMapBuffer { samplerCube shadow_maps[]; }; @@ -97,10 +97,11 @@ vec3 sRGB_To_LinRGB(vec3 c) void main() { - vec4 albedo = texture2D(frag_tex, vin.tex_pos) * vin.colour; + vec4 albedo = texture2D(frag_tex, vin.tex_pos); if(albedo.a == 0.f) discard; - vec3 albedo_lin = sRGB_To_LinRGB(albedo.rgb); + vec3 albedo_lin = sRGB_To_LinRGB(albedo.rgb) * vin.colour.rgb; + albedo *= vin.colour; float roughness = vin.material[0]; float metalness = vin.material[1]; @@ -163,6 +164,5 @@ void main() light = mix(light, albedo.rgb, luminance); frag_colour = vec4(light, albedo.a); - } diff --git a/assets/shader/main.vsh b/assets/shader/main.vsh index 9131902..36ca57a 100644 --- a/assets/shader/main.vsh +++ b/assets/shader/main.vsh @@ -8,11 +8,17 @@ layout (location = 2) in vec4 aPos; layout (location = 3) in vec3 aNormal; layout (location = 4) in vec4 aColour; layout (location = 5) in vec3 aMaterial; +layout (location = 6) in float aTransformIndex; uniform mat4 model; uniform mat4 camera; uniform mat4 projection; +layout (binding = 3) readonly buffer TransformBuffer +{ + mat4 transforms[]; +}; + out VS_OUT { vec3 normal; vec4 colour; @@ -25,11 +31,12 @@ out flat sampler2D frag_tex; void main() { - mat4 mvp = camera * model; + mat4 m = (aTransformIndex >= 0.f ? transforms[int(aTransformIndex)] : mat4(1.f)) * model; + mat4 mvp = camera * m; vec4 pos = mvp * aPos; - vout.normal = mat3(model) * aNormal; - vout.pos = (model * aPos).xyz; + vout.normal = mat3(m) * aNormal; + vout.pos = (m * aPos).xyz; vout.colour = aColour; vout.tex_pos = aTexPos; vout.material = aMaterial; diff --git a/assets/texture/safety_signs/radiation_area.png b/assets/texture/safety_signs/radiation_area.png new file mode 100644 index 0000000..5e4a2f7 --- /dev/null +++ b/assets/texture/safety_signs/radiation_area.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7eba9d9b9d0e036ac2dfa97ac5d072f33e59b0f5bdaf82c05ece19d6f3e5e6b6 +size 140641 diff --git a/assets/texture/safety_signs/radiation_area_auth_only.png b/assets/texture/safety_signs/radiation_area_auth_only.png new file mode 100644 index 0000000..19e88f0 --- /dev/null +++ b/assets/texture/safety_signs/radiation_area_auth_only.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:196698c04cbf687bc905410da74e1392132d91b11ea2f2c4cc6a90dea7d00c17 +size 185309 diff --git a/src/graphics/equipment/reactor.cpp b/src/graphics/equipment/reactor.cpp index 3d26b72..d23fe68 100644 --- a/src/graphics/equipment/reactor.cpp +++ b/src/graphics/equipment/reactor.cpp @@ -9,16 +9,34 @@ using namespace Sim::Graphics::Equipment; -Reactor::Reactor(const Model& model, Mesh& rmesh) +Reactor::Reactor(const Model& model) { g_control_rod = model.load("visual_control_rod"); } -void Reactor::update(double dt) +void Reactor::remesh_static(Mesh& rmesh) { + Sim::System& sys = *Sim::System::active; + + for(int i = 0; i < sys.reactor.size; i++) + { + Sim::Reactor::Rod* r = sys.reactor.rods[i].get(); + + if(!r->should_display()) + { + continue; + } + + if(r->get_colour()[3] != 0) + { + Mesh m = g_control_rod; + m.set_transform_id(); + rmesh.add(m); + } + } } -void Reactor::remesh_slow(Mesh& rmesh) +void Reactor::get_static_transforms(std::vector& transforms) { Sim::System& sys = *Sim::System::active; @@ -42,17 +60,8 @@ void Reactor::remesh_slow(Mesh& rmesh) if(r->get_colour()[3] != 0) { - rmesh.add(g_control_rod, glm::translate(glm::mat4(1), glm::vec3(ox, oy, (1 - r->get_colour().r) * sys.reactor.cell_height))); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(ox, oy, (1 - r->get_colour().r) * sys.reactor.cell_height))); } } } -void Reactor::remesh_fast(Mesh& rmesh) -{ -} - -void Reactor::render() -{ -} - - diff --git a/src/graphics/equipment/reactor.hpp b/src/graphics/equipment/reactor.hpp index 72afb47..77863c8 100644 --- a/src/graphics/equipment/reactor.hpp +++ b/src/graphics/equipment/reactor.hpp @@ -12,11 +12,9 @@ class Reactor : public MeshGen public: - Reactor(const Model& model, Mesh& rmesh); - virtual void update(double dt); - virtual void remesh_slow(Mesh& rmesh); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); + Reactor(const Model& model); + virtual void get_static_transforms(std::vector& transforms); + virtual void remesh_static(Mesh& rmesh); }; }; diff --git a/src/graphics/mesh/arrays.cpp b/src/graphics/mesh/arrays.cpp index 8e5ab9c..5e6375b 100644 --- a/src/graphics/mesh/arrays.cpp +++ b/src/graphics/mesh/arrays.cpp @@ -36,5 +36,8 @@ void Arrays::vertex_attrib_pointers() glVertexAttribPointer(5, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.material, &v)); glEnableVertexAttribArray(5); + + glVertexAttribPointer(6, 1, GL_FLOAT, false, sizeof(v), ptr_diff(&v.transform_id, &v)); + glEnableVertexAttribArray(6); } diff --git a/src/graphics/mesh/arrays.hpp b/src/graphics/mesh/arrays.hpp index cf8d8a5..6f86b06 100644 --- a/src/graphics/mesh/arrays.hpp +++ b/src/graphics/mesh/arrays.hpp @@ -14,6 +14,7 @@ struct Vertex glm::vec3 normal = {0, 0, 0}; glm::vec4 colour = {1, 1, 1, 1}; glm::vec3 material = {0, 0, 0}; + float transform_id = -1; constexpr bool operator==(const Vertex&) const = default; diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index 2c4bc89..fbe3936 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -15,11 +15,22 @@ Mesh::Mesh() } +void Mesh::set_transform_id() +{ + for(unsigned int i = 0; i < vertices.size(); i++) + { + vertices[i].transform_id = 0; + } + + max_transform_id = 0; +} + void Mesh::add(const Mesh& o, glm::mat4 mat) { unsigned int off = vertices.size(); - glm::mat3 mat3(mat); + float t_off = max_transform_id + 1; + glm::mat3 mat3(mat); vertices.reserve(vertices.size() + o.vertices.size()); indices.reserve(indices.size() + o.indices.size()); @@ -28,6 +39,13 @@ void Mesh::add(const Mesh& o, glm::mat4 mat) Arrays::Vertex v = o.vertices[i]; v.normal = mat3 * v.normal; v.pos = mat * v.pos; + + if(v.transform_id >= 0) + { + v.transform_id += t_off; + max_transform_id = std::max(max_transform_id, v.transform_id); + } + vertices.push_back(v); } @@ -192,40 +210,29 @@ vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const } vec3 path_n = path / l; - unsigned int i_found = 0; + bool changing = true; - for(unsigned int i = 0; i < indices.size(); i += 3) + while(changing) { - vec3 v[3] = { - vec3(this->vertices[indices[i]].pos), - vec3(this->vertices[indices[i + 1]].pos), - vec3(this->vertices[indices[i + 2]].pos) - }; - - if(calc_intercept_vert(v, pos, path, path_n, l)) - { - i_found = i; - } + changing = false; - if(l == 0) + for(unsigned int i = 0; i < indices.size(); i += 3) { - return path; - } - } + vec3 v[3] = { + vec3(this->vertices[indices[i]].pos), + vec3(this->vertices[indices[i + 1]].pos), + vec3(this->vertices[indices[i + 2]].pos) + }; + + if(calc_intercept_vert(v, pos, path, path_n, l)) + { + changing = true; + } - for(unsigned int i = 0; i < i_found; i += 3) - { - vec3 v[3] = { - vec3(this->vertices[indices[i]].pos), - vec3(this->vertices[indices[i + 1]].pos), - vec3(this->vertices[indices[i + 2]].pos) - }; - - calc_intercept_vert(v, pos, path, path_n, l); - - if(l == 0) - { - return path; + if(l == 0) + { + return path; + } } } diff --git a/src/graphics/mesh/mesh.hpp b/src/graphics/mesh/mesh.hpp index ed1fa55..0159e6b 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/mesh/mesh.hpp @@ -19,9 +19,11 @@ struct Mesh { std::vector vertices; std::vector indices; + float max_transform_id = -1; Mesh(); + void set_transform_id(); void set_vertices(const Arrays::Vertex* data, size_t size); void set_indices(const unsigned int* data, size_t size); void load_text(const char* text, double size); diff --git a/src/graphics/mesh/meshgen.hpp b/src/graphics/mesh/meshgen.hpp index b1f7b1f..bdf9ac5 100644 --- a/src/graphics/mesh/meshgen.hpp +++ b/src/graphics/mesh/meshgen.hpp @@ -10,10 +10,10 @@ class MeshGen { public: virtual ~MeshGen() {} - virtual void update(double dt) = 0; - virtual void remesh_slow(Mesh& rmesh) = 0; - virtual void remesh_fast(Mesh& rmesh) = 0; - virtual void render() = 0; + 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) {}; }; }; diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index 3e44a6b..658b705 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -116,14 +116,9 @@ struct CoreJoystick : public Focus::FocusType } }; -Core::Core(const Model& model, Mesh& rmesh) +Core::Core(const Model& model) { - Mesh mesh = model.load("translation_monitor_3"); mat = Locations::monitors[2]; - - mesh.load_text("Reactor Core", 0.04); - rmesh.add(mesh, mat); - m_buttons[0] = model.load("click_numpad_1"); m_buttons[1] = model.load("click_numpad_2"); m_buttons[2] = model.load("click_numpad_3"); @@ -138,6 +133,13 @@ Core::Core(const Model& model, Mesh& rmesh) m_scram = model.load("click_scram"); } +void Core::remesh_static(Mesh& rmesh) +{ + Mesh mesh; + mesh.load_text("Reactor Core", 0.04); + rmesh.add(mesh, mat); +} + static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour) { unsigned int indices[] = {0, 1, 3, 0, 3, 2}; @@ -183,16 +185,6 @@ void Core::update(double dt) } void Core::remesh_slow(Mesh& rmesh) -{ - remesh(rmesh, false); -} - -void Core::remesh_fast(Mesh& rmesh) -{ - remesh(rmesh, true); -} - -void Core::remesh(Mesh& rmesh, bool fast) { Sim::System& sys = *System::active; Sim::Graphics::Mesh mesh; @@ -221,43 +213,32 @@ void Core::remesh(Mesh& rmesh, bool fast) } glm::mat4 mat = glm::translate(glm::mat4(1), glm::vec3(ox, oy, 0)) * mat_scale; + glm::vec4 colour_heat = r->get_heat_colour() * glm::vec4(glm::vec3(1), 1); + glm::vec4 colour_spec = r->get_colour(); - if(!fast) + if(colour_heat[3] == 0) { - glm::vec4 colour_heat = r->get_heat_colour() * glm::vec4(glm::vec3(1), 1); - glm::vec4 colour_spec = r->get_colour(); - - if(colour_heat[3] == 0) - { - continue; - } - - mesh.add(add_dot(mat, colour_heat)); - - if(colour_spec[3] != 0) - { - mesh.add(add_dot(mat * mat_spec, colour_spec)); - } + continue; } - else + mesh.add(add_dot(mat, colour_heat)); + + if(colour_spec[3] != 0) { - if(sys.reactor.cursor == i) - { - mesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1})); - } + mesh.add(add_dot(mat * mat_spec, colour_spec)); + } - if(r->selected) - { - mesh.add(add_dot(mat * mat_select, {1, 1, 0, 1})); - } + if(sys.reactor.cursor == i) + { + mesh.add(add_dot(mat * mat_cursor, {1, 0, 0, 1})); + } + + if(r->selected) + { + mesh.add(add_dot(mat * mat_select, {1, 1, 0, 1})); } } rmesh.add(mesh, mat); } -void Core::render() -{ -} - diff --git a/src/graphics/monitor/core.hpp b/src/graphics/monitor/core.hpp index 9479aac..308e7b6 100644 --- a/src/graphics/monitor/core.hpp +++ b/src/graphics/monitor/core.hpp @@ -18,12 +18,10 @@ class Core : public MeshGen public: - Core(const Model& model, Mesh& rmesh); - void remesh(Mesh& rmesh, bool fast); + Core(const Model& model); virtual void update(double dt); + virtual void remesh_static(Mesh& rmesh); virtual void remesh_slow(Mesh& rmesh); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); }; }; diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index 418cc70..076f811 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -49,12 +49,29 @@ struct ValveJoystick : public Focus::FocusType } }; -PrimaryLoop::PrimaryLoop(const Model& model, Mesh& rmesh) +PrimaryLoop::PrimaryLoop(const Model& model) { mat = Locations::monitors[3]; + g_switch_pump = model.load("visual_pump_switch_1"); + g_switch_bypass = model.load("visual_bypass_switch"); + g_switch_inlet = model.load("visual_inlet_switch"); + + m_joystick_turbine_bypass = model.load("click_bypass_joystick"); + m_joystick_turbine_inlet = model.load("click_inlet_joystick"); + m_switch_pump = model.load("click_pump_switch_1"); + m_switch_bypass = model.load("click_bypass_switch"); + m_switch_inlet = model.load("click_inlet_switch"); + + g_switch_pump.set_transform_id(); + g_switch_bypass.set_transform_id(); + g_switch_inlet.set_transform_id(); +} + +void PrimaryLoop::remesh_static(Mesh& rmesh) +{ std::stringstream ss; - Sim::Graphics::Mesh mesh; + Mesh mesh; ss << "Turbine Bypass Valve\n\n"; ss << "Opened\nFlow\nSetpoint\n\n"; @@ -71,15 +88,9 @@ PrimaryLoop::PrimaryLoop(const Model& model, Mesh& rmesh) mesh.load_text(ss.str().c_str(), 0.04); rmesh.add(mesh, mat); - g_switch_pump = model.load("visual_pump_switch_1"); - g_switch_bypass = model.load("visual_bypass_switch"); - g_switch_inlet = model.load("visual_inlet_switch"); - - m_joystick_turbine_bypass = model.load("click_bypass_joystick"); - m_joystick_turbine_inlet = model.load("click_inlet_joystick"); - m_switch_pump = model.load("click_pump_switch_1"); - m_switch_bypass = model.load("click_bypass_switch"); - m_switch_inlet = model.load("click_inlet_switch"); + rmesh.add(g_switch_pump); + rmesh.add(g_switch_bypass); + rmesh.add(g_switch_inlet); } void PrimaryLoop::update(double dt) @@ -146,7 +157,7 @@ void PrimaryLoop::remesh_slow(Mesh& rmesh) rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0))); } -void PrimaryLoop::remesh_fast(Mesh& rmesh) +void PrimaryLoop::get_static_transforms(std::vector& transforms) { System& sys = *System::active; @@ -154,12 +165,8 @@ void PrimaryLoop::remesh_fast(Mesh& rmesh) float off2 = sys.loop.turbine_bypass_valve.get_auto() ? 0.07 : 0; float off3 = sys.loop.turbine_inlet_valve.get_auto() ? 0.07 : 0; - rmesh.add(g_switch_pump, glm::translate(glm::mat4(1), glm::vec3(0, off1, 0))); - rmesh.add(g_switch_bypass, glm::translate(glm::mat4(1), glm::vec3(0, off2, 0))); - rmesh.add(g_switch_inlet, glm::translate(glm::mat4(1), glm::vec3(0, off3, 0))); -} - -void PrimaryLoop::render() -{ + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off1, 0))); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off2, 0))); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off3, 0))); } diff --git a/src/graphics/monitor/primary_loop.hpp b/src/graphics/monitor/primary_loop.hpp index f981f84..382b9e2 100644 --- a/src/graphics/monitor/primary_loop.hpp +++ b/src/graphics/monitor/primary_loop.hpp @@ -24,11 +24,11 @@ class PrimaryLoop : public MeshGen public: - PrimaryLoop(const Model& model, Mesh& rmesh); + 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); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); }; }; diff --git a/src/graphics/monitor/secondary_loop.cpp b/src/graphics/monitor/secondary_loop.cpp index c9d6fc9..608e85e 100644 --- a/src/graphics/monitor/secondary_loop.cpp +++ b/src/graphics/monitor/secondary_loop.cpp @@ -17,23 +17,10 @@ using namespace Sim::Graphics::Monitor; using namespace Sim::Util::Streams; -SecondaryLoop::SecondaryLoop(const Model& model, Mesh& rmesh) +SecondaryLoop::SecondaryLoop(const Model& model) { mat = Locations::monitors[5]; - std::stringstream ss; - Sim::Graphics::Mesh mesh; - - ss << "Cooling Tower\n\n"; - ss << "Heat\nSteam\nPressure\nLevel\n\n"; - ss << "Secondary Pump\n\n"; - ss << "Power\nSpeed\nFlow\n\n"; - ss << "Freight Pump\n\n"; - ss << "Power\nSpeed\nFlow\n\n"; - - mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, mat); - g_switch_2 = model.load("visual_pump_switch_2"); g_switch_3 = model.load("visual_pump_switch_3"); @@ -41,6 +28,9 @@ SecondaryLoop::SecondaryLoop(const Model& model, Mesh& rmesh) m_joystick_turbine_inlet = model.load("click_inlet_joystick"); m_switch_2 = model.load("click_pump_switch_2"); m_switch_3 = model.load("click_pump_switch_3"); + + g_switch_2.set_transform_id(); + g_switch_3.set_transform_id(); } void SecondaryLoop::update(double dt) @@ -53,6 +43,24 @@ void SecondaryLoop::update(double dt) sys.freight_pump.powered = !sys.freight_pump.powered; } +void SecondaryLoop::remesh_static(Mesh& rmesh) +{ + std::stringstream ss; + Mesh mesh; + + ss << "Cooling Tower\n\n"; + ss << "Heat\nSteam\nPressure\nLevel\n\n"; + ss << "Secondary Pump\n\n"; + ss << "Power\nSpeed\nFlow\n\n"; + ss << "Freight Pump\n\n"; + ss << "Power\nSpeed\nFlow\n\n"; + + mesh.load_text(ss.str().c_str(), 0.04); + rmesh.add(mesh, mat); + rmesh.add(g_switch_2); + rmesh.add(g_switch_3); +} + void SecondaryLoop::remesh_slow(Mesh& rmesh) { std::stringstream ss; @@ -77,19 +85,14 @@ void SecondaryLoop::remesh_slow(Mesh& rmesh) rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0))); } -void SecondaryLoop::remesh_fast(Mesh& rmesh) +void SecondaryLoop::get_static_transforms(std::vector& transforms) { System& sys = *System::active; float off2 = sys.loop.secondary_pump.powered ? 0.07 : 0; float off3 = sys.freight_pump.powered ? 0.07 : 0; - rmesh.add(g_switch_2, glm::translate(glm::mat4(1), glm::vec3(0, off2, 0))); - rmesh.add(g_switch_3, glm::translate(glm::mat4(1), glm::vec3(0, off3, 0))); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off2, 0))); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off3, 0))); } -void SecondaryLoop::render() -{ -} - - diff --git a/src/graphics/monitor/secondary_loop.hpp b/src/graphics/monitor/secondary_loop.hpp index cf20f84..9048036 100644 --- a/src/graphics/monitor/secondary_loop.hpp +++ b/src/graphics/monitor/secondary_loop.hpp @@ -21,11 +21,11 @@ class SecondaryLoop : public MeshGen public: - SecondaryLoop(const Model& model, Mesh& rmesh); + 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); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); }; }; diff --git a/src/graphics/monitor/turbine.cpp b/src/graphics/monitor/turbine.cpp index 39e2ec5..fb85f78 100644 --- a/src/graphics/monitor/turbine.cpp +++ b/src/graphics/monitor/turbine.cpp @@ -16,10 +16,47 @@ using namespace Sim::Graphics; using namespace Sim::Graphics::Monitor; using namespace Sim::Util::Streams; -Turbine::Turbine(const Model& model, Mesh& rmesh) +Turbine::Turbine(const Model& model) { mat = Locations::monitors[4]; + + g_synchroscope_dial = model.load("visual_synchroscope_dial"); + g_switch_breaker = model.load("visual_breaker_switch"); + m_switch_breaker = model.load("click_breaker_switch"); + g_synchroscope_dial.set_transform_id(); + g_switch_breaker.set_transform_id(); +} + +void Turbine::update(double dt) +{ + System& sys = *System::active; + + if(m_switch_breaker.check_focus()) + sys.loop.generator.breaker_closed = !sys.loop.generator.breaker_closed; +} + +void Turbine::get_static_transforms(std::vector& transforms) +{ + System& sys = *System::active; + double rpm = sys.loop.generator.get_rpm(); + glm::mat4 mat(1); + + if(rpm > 3570 && rpm < 3630) + { + mat = glm::translate(mat, glm::vec3(6.35, 3.949, 1.35)); + mat = glm::rotate(mat, float(sys.loop.generator.get_phase_diff()), glm::vec3(0, 1, 0)); + mat = glm::translate(mat, glm::vec3(-6.35, -3.949, -1.35)); + } + + float off1 = sys.loop.generator.breaker_closed ? 0.07 : 0; + + transforms.push_back(mat); + transforms.push_back(glm::translate(glm::mat4(1), glm::vec3(0, off1, 0))); +} + +void Turbine::remesh_static(Mesh& rmesh) +{ std::stringstream ss; Sim::Graphics::Mesh mesh; @@ -28,34 +65,9 @@ Turbine::Turbine(const Model& model, Mesh& rmesh) mesh.load_text(ss.str().c_str(), 0.04); rmesh.add(mesh, mat); - - mesh.load_text("Synchroscope", 0.04); - rmesh.add(mesh, glm::translate(mat, glm::vec3(0, 0.6, 0))); - mesh = model.load("visual_synchroscope_dial"); - gm_synchroscope_dial.bind(); - gm_synchroscope_dial.set(mesh, GL_STATIC_DRAW); - - g_switch_breaker = model.load("visual_breaker_switch"); - m_switch_breaker = model.load("click_breaker_switch"); -} - -void Turbine::update(double dt) -{ - System& sys = *System::active; - double rpm = sys.loop.generator.get_rpm(); - - if(rpm > 3570 && rpm < 3630) - { - glm::mat4 mat = glm::mat4(1); - mat = glm::translate(mat, glm::vec3(6.35, 3.949, 1.35)); - mat = glm::rotate(mat, float(sys.loop.generator.get_phase_diff()), glm::vec3(0, 1, 0)); - mat = glm::translate(mat, glm::vec3(-6.35, -3.949, -1.35)); - gm_synchroscope_dial.model_matrix = mat; - } - - if(m_switch_breaker.check_focus()) - sys.loop.generator.breaker_closed = !sys.loop.generator.breaker_closed; + rmesh.add(g_synchroscope_dial); + rmesh.add(g_switch_breaker); } void Turbine::remesh_slow(Mesh& rmesh) @@ -79,7 +91,7 @@ void Turbine::remesh_slow(Mesh& rmesh) Util::Streams::show_units( ss, sys.loop.generator.get_energy_generated() ) << "W\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, glm::translate(mat, glm::vec3(0.4, 0.7, 0))); + rmesh.add(mesh, glm::translate(mat, glm::vec3(0.4, 0.75, 0))); ss = std::stringstream(); @@ -87,25 +99,6 @@ void Turbine::remesh_slow(Mesh& rmesh) ss << show( sys.grid.frequency ) << " Hz\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, glm::translate(mat, glm::vec3(0.7, 0.7, 0))); -} - -void Turbine::remesh_fast(Mesh& rmesh) -{ - System& sys = *System::active; - float off1 = sys.loop.generator.breaker_closed ? 0.07 : 0; - rmesh.add(g_switch_breaker, glm::translate(glm::mat4(1), glm::vec3(0, off1, 0))); -} - -void Turbine::render() -{ - double rpm = System::active->loop.generator.get_rpm(); - - if(rpm > 3570 && rpm < 3630) - { - gm_synchroscope_dial.bind(); - gm_synchroscope_dial.uniform(); - gm_synchroscope_dial.render(); - } + rmesh.add(mesh, glm::translate(mat, glm::vec3(0.7, 0.75, 0))); } diff --git a/src/graphics/monitor/turbine.hpp b/src/graphics/monitor/turbine.hpp index 48dade3..fc64fcf 100644 --- a/src/graphics/monitor/turbine.hpp +++ b/src/graphics/monitor/turbine.hpp @@ -12,17 +12,17 @@ class Turbine : public MeshGen { glm::mat4 mat; - GLMesh gm_synchroscope_dial; + Mesh g_synchroscope_dial; Mesh g_switch_breaker; Mesh m_switch_breaker; public: - Turbine(const Model& model, Mesh& rmesh); + 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); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); }; }; diff --git a/src/graphics/monitor/vessel.cpp b/src/graphics/monitor/vessel.cpp index 9549e95..8e696f0 100644 --- a/src/graphics/monitor/vessel.cpp +++ b/src/graphics/monitor/vessel.cpp @@ -15,10 +15,13 @@ using namespace Sim::Graphics::Monitor; using namespace Sim::Util::Streams; -Vessel::Vessel(const Model& model, Mesh& rmesh) +Vessel::Vessel(const Model& model) { mat = Locations::monitors[1]; +} +void Vessel::remesh_static(Mesh& rmesh) +{ std::stringstream ss; Sim::Graphics::Mesh mesh; @@ -38,10 +41,6 @@ Vessel::Vessel(const Model& model, Mesh& rmesh) rmesh.add(mesh, mat); } -void Vessel::update(double dt) -{ -} - void Vessel::remesh_slow(Mesh& rmesh) { std::stringstream ss; @@ -97,11 +96,3 @@ void Vessel::remesh_slow(Mesh& rmesh) rmesh.add(mesh, glm::translate(mat, glm::vec3(0.5, 0, 0))); } -void Vessel::remesh_fast(Mesh& rmesh) -{ -} - -void Vessel::render() -{ -} - diff --git a/src/graphics/monitor/vessel.hpp b/src/graphics/monitor/vessel.hpp index ef814e1..b986a32 100644 --- a/src/graphics/monitor/vessel.hpp +++ b/src/graphics/monitor/vessel.hpp @@ -13,11 +13,9 @@ class Vessel : public MeshGen public: - Vessel(const Model& model, Mesh& rmesh); - virtual void update(double dt); + Vessel(const Model& model); + virtual void remesh_static(Mesh& rmesh); virtual void remesh_slow(Mesh& rmesh); - virtual void remesh_fast(Mesh& rmesh); - virtual void render(); }; }; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index 3fc6df1..c79a7b8 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -121,6 +121,11 @@ void Shader::use() ACTIVE = this; } +void Shader::block_binding(const char* name, unsigned int binding) +{ + glUniformBlockBinding(prog_id, get_block_index(name), binding); +} + unsigned int Shader::operator [](const char* pos) { auto it = uniform_locations.find(pos); @@ -133,6 +138,18 @@ unsigned int Shader::operator [](const char* pos) return uniform_locations[pos] = glGetUniformLocation(prog_id, pos); } +unsigned int Shader::get_block_index(const char* pos) +{ + auto it = uniform_block_indices.find(pos); + + if(it != uniform_block_indices.end()) + { + return it->second; + } + + return uniform_block_indices[pos] = glGetUniformBlockIndex(prog_id, pos); +} + unsigned int Shader::get(const char* pos) { return operator[](pos); diff --git a/src/graphics/shader.hpp b/src/graphics/shader.hpp index 4901f16..06bd72b 100644 --- a/src/graphics/shader.hpp +++ b/src/graphics/shader.hpp @@ -11,6 +11,7 @@ class Shader unsigned int prog_id = 0; std::unordered_map uniform_locations; + std::unordered_map uniform_block_indices; public: @@ -27,9 +28,11 @@ public: 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 block_binding(const char* name, unsigned int index); void use(); unsigned int operator[](const char* pos); + unsigned int get_block_index(const char* pos); unsigned int get(const char* pos); }; diff --git a/src/graphics/widget/clock.cpp b/src/graphics/widget/clock.cpp index 3a512fc..15f8dd9 100644 --- a/src/graphics/widget/clock.cpp +++ b/src/graphics/widget/clock.cpp @@ -34,7 +34,7 @@ void Clock::remesh_slow(Mesh& rmesh) int t_m = std::fmod(at / 60, 60); int t_h = std::fmod(at / 3600, 24); -// ss << "FPS: " << (1.0 / dt) << "\n"; + ss << "FPS: " << (1.0 / dt) << "\n"; ss << "Time: " << std::setfill('0') << std::setw(2) << t_h << ":"; ss << std::setfill('0') << std::setw(2) << t_m << ":"; ss << std::setfill('0') << std::setw(2) << t_s << "\n"; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index 483b3bd..c16fc2d 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -37,20 +37,22 @@ using namespace Sim::Graphics; +constexpr int SSBO_TRANSFORMS_LEN = 2; + static GLFWwindow* win; static bool win_should_close = false; static unsigned int ssbo_lights; static unsigned int ssbo_shadow_maps; +static unsigned int ssbo_transforms[SSBO_TRANSFORMS_LEN]; static double secs_wait_at = 0; static double secs_wait_now = 0; static int gm_dynamic_slow_at = 0; +static int ssbo_transforms_at = 0; static GLMesh gm_scene; static GLMesh gm_transparent; static GLMesh gm_dynamic_slow[2]; -static GLMesh gm_dynamic_fast; -static Mesh m_dynamic_fast; static std::vector lights; static std::vector> monitors; @@ -149,13 +151,22 @@ void Window::create() glUniform1i(Shader::MAIN["lights_count"], model.lights.size()); - monitors.push_back(std::make_unique(model, m_scene)); - monitors.push_back(std::make_unique(model, m_scene)); - monitors.push_back(std::make_unique(model, m_scene)); - monitors.push_back(std::make_unique(model, m_scene)); - monitors.push_back(std::make_unique(model, m_scene)); + 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, m_scene)); + for(auto& monitor : monitors) + { + monitor->remesh_static(m_scene); + } + + for(auto& equipment : equipment) + { + equipment->remesh_static(m_scene); + } gm_scene.bind(); gm_scene.set(m_scene, GL_STATIC_DRAW); @@ -190,6 +201,28 @@ void Window::create() glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_shadow_maps); glBufferData(GL_SHADER_STORAGE_BUFFER, light_handles.size() * sizeof(light_handles[0]), &light_handles[0], GL_STATIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo_shadow_maps); + + // setup the transforms ssbos and their initial values + + std::vector transforms; + + for(auto& monitor : monitors) + { + monitor->get_static_transforms(transforms); + } + + for(auto& equipment : equipment) + { + equipment->get_static_transforms(transforms); + } + + glGenBuffers(SSBO_TRANSFORMS_LEN, ssbo_transforms); + + for(int i = 0; i < SSBO_TRANSFORMS_LEN; i++) + { + glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_transforms[i]); + glBufferData(GL_SHADER_STORAGE_BUFFER, transforms.size() * sizeof(transforms[0]), &transforms[0], GL_DYNAMIC_DRAW); + } } void update_slow() @@ -216,37 +249,28 @@ void update_slow() void Window::update(double dt) { Mesh mesh; + std::vector transforms; glfwPollEvents(); for(auto& monitor : monitors) { monitor->update(dt); + monitor->get_static_transforms(transforms); } for(auto& equipment : equipment) { equipment->update(dt); + equipment->get_static_transforms(transforms); } UI::update(dt); - for(auto& monitor : monitors) - { - monitor->remesh_fast(mesh); - } - - for(auto& equipment : equipment) - { - equipment->remesh_fast(mesh); - } - - if(mesh != m_dynamic_fast) - { - gm_dynamic_fast.bind(); - gm_dynamic_fast.set(mesh, GL_DYNAMIC_DRAW); - m_dynamic_fast = std::move(mesh); - } + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]); + ssbo_transforms_at = (ssbo_transforms_at + 1) % SSBO_TRANSFORMS_LEN; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo_transforms[ssbo_transforms_at]); + glBufferData(GL_SHADER_STORAGE_BUFFER, transforms.size() * sizeof(transforms[0]), &transforms[0], GL_DYNAMIC_DRAW); secs_wait_now += dt; if(secs_wait_now > secs_wait_at + 1.0/30.0) @@ -265,20 +289,6 @@ void Window::render_scene() gm_dynamic_slow[gm_dynamic_slow_at].bind(); gm_dynamic_slow[gm_dynamic_slow_at].uniform(); gm_dynamic_slow[gm_dynamic_slow_at].render(); - - gm_dynamic_fast.bind(); - gm_dynamic_fast.uniform(); - gm_dynamic_fast.render(); - - for(auto& monitor : monitors) - { - monitor->render(); - } - - for(auto& equipment : equipment) - { - equipment->render(); - } gm_transparent.bind(); gm_transparent.uniform(); @@ -303,6 +313,7 @@ void Window::render() 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]); + projection_matrix = mat_projection; glFrontFace(GL_CCW); glClearColor(0, 0, 0, 1.0f); diff --git a/src/graphics/window.hpp b/src/graphics/window.hpp index 3f0f155..66bf7cf 100644 --- a/src/graphics/window.hpp +++ b/src/graphics/window.hpp @@ -13,6 +13,7 @@ extern glm::mat4 projection_matrix; bool should_close(); void create(); +void remesh(); void update(double dt); void render(); void render_scene();