From e2f8eefe5b291d8c4daa01866b5182eb45c4b324 Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Wed, 6 Mar 2024 22:32:54 +1100 Subject: [PATCH] improved how model matrices are done --- assets/scene.blend | 4 +- assets/scene.glb | 4 +- assets/shader/light.vsh | 23 +++- assets/shader/main.vsh | 23 ++-- src/graphics/equipment/reactor.cpp | 15 ++- src/graphics/equipment/reactor.hpp | 2 +- src/graphics/mesh/arrays.cpp | 2 +- src/graphics/mesh/arrays.hpp | 2 +- src/graphics/mesh/font.cpp | 19 ++- src/graphics/mesh/glmesh.cpp | 37 ++++-- src/graphics/mesh/glmesh.hpp | 11 +- src/graphics/mesh/mesh.cpp | 162 ++++++++++++++++-------- src/graphics/mesh/mesh.hpp | 16 +-- src/graphics/mesh/model.cpp | 17 ++- src/graphics/monitor/core.cpp | 19 ++- src/graphics/monitor/primary_loop.cpp | 6 +- src/graphics/monitor/secondary_loop.cpp | 5 +- src/graphics/monitor/turbine.cpp | 18 +-- src/graphics/monitor/vessel.cpp | 2 +- src/graphics/ui.cpp | 19 +-- src/graphics/widget/clock.cpp | 5 +- src/graphics/widget/clock.hpp | 1 - src/graphics/window.cpp | 40 ++++-- src/util/streams.hpp | 14 ++ 24 files changed, 287 insertions(+), 179 deletions(-) diff --git a/assets/scene.blend b/assets/scene.blend index 4e5db57..26aa843 100644 --- a/assets/scene.blend +++ b/assets/scene.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d831a119d62b22c8466a48edaadccb6cc97e93bced215eac1f9187223f9f5be -size 12277593 +oid sha256:8f3bfe3273bc69e19caf98fb967b5f57e2f01fd7650c33b3f65aba0edb9e1a35 +size 12259665 diff --git a/assets/scene.glb b/assets/scene.glb index a492152..479b32d 100644 --- a/assets/scene.glb +++ b/assets/scene.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:52689766e1bbddae89c5f1501e06fe82cf614bbb0773445660010c85ee1e9357 -size 4091100 +oid sha256:b01a5e8079b95c2f32d653a2622a6204ffebb36ec58950c410bf3492a6901831 +size 1603960 diff --git a/assets/shader/light.vsh b/assets/shader/light.vsh index e2ad551..a351367 100644 --- a/assets/shader/light.vsh +++ b/assets/shader/light.vsh @@ -1,19 +1,32 @@ #version 460 core -layout (location = 2) in vec4 aPos; +layout (location = 2) in vec3 aPos; layout (location = 4) in vec4 aColour; layout (location = 5) in vec3 aMaterial; layout (location = 6) in float aTransformIndex; -uniform mat4 model; +layout (binding = 3) readonly buffer TransformBuffer +{ + mat4 transforms[]; +}; + uniform mat4 camera; out flat int should_ignore; -void main() +mat4 load_model_mat(int index) { - gl_Position = camera * model * aPos; - should_ignore = int(aTransformIndex >= 0.f || aMaterial[2] > 0.f || aColour.a < 1.f); + return index < 0 ? mat4(1.f) : transforms[index]; +} + +void main() +{ + vec4 pos = vec4(aPos, 1.f); + mat4 model = load_model_mat(int(aTransformIndex)); + mat4 mv = camera * model; + + gl_Position = mv * pos; + should_ignore = int(aMaterial[2] > 0.f || aColour.a < 1.f); } diff --git a/assets/shader/main.vsh b/assets/shader/main.vsh index 36ca57a..441434f 100644 --- a/assets/shader/main.vsh +++ b/assets/shader/main.vsh @@ -4,17 +4,16 @@ layout (location = 0) in sampler2D aTex; layout (location = 1) in vec2 aTexPos; -layout (location = 2) in vec4 aPos; +layout (location = 2) in vec3 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 +layout (binding = 3) readonly buffer TransformBuffer1 { mat4 transforms[]; }; @@ -29,19 +28,25 @@ out VS_OUT { out flat sampler2D frag_tex; +mat4 load_model_mat(int index) +{ + return index < 0 ? mat4(1.f) : transforms[index]; +} + void main() { - mat4 m = (aTransformIndex >= 0.f ? transforms[int(aTransformIndex)] : mat4(1.f)) * model; - mat4 mvp = camera * m; - vec4 pos = mvp * aPos; + vec4 pos = vec4(aPos, 1.f); + mat4 model = load_model_mat(int(aTransformIndex)); + mat4 mv = camera * model; + mat4 mvp = projection * mv; - vout.normal = mat3(m) * aNormal; - vout.pos = (m * aPos).xyz; + vout.normal = mat3(model) * aNormal; + vout.pos = (model * pos).xyz; vout.colour = aColour; vout.tex_pos = aTexPos; vout.material = aMaterial; frag_tex = aTex; - gl_Position = projection * pos; + gl_Position = mvp * pos; } diff --git a/src/graphics/equipment/reactor.cpp b/src/graphics/equipment/reactor.cpp index 96537c1..8db143d 100644 --- a/src/graphics/equipment/reactor.cpp +++ b/src/graphics/equipment/reactor.cpp @@ -11,9 +11,8 @@ using namespace Sim::Graphics::Equipment; Reactor::Reactor(const Model& model) { - g_control_rod = model.load("visual_control_rod_lift"); - g_control_rod.set_transform_id(); - g_control_rod.add(model.load("visual_control_rod_base")); + g_control_rod_lift = model.load("visual_control_rod_lift"); + g_control_rod_base = model.load("visual_control_rod_base"); } void Reactor::remesh_static(Mesh& rmesh) @@ -39,7 +38,15 @@ void Reactor::remesh_static(Mesh& rmesh) if(r->get_colour()[3] != 0) { - rmesh.add(g_control_rod, glm::translate(glm::mat4(1), glm::vec3(ox, oy, 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))); + m1.bake_transforms(); + m2.bake_transforms(); + m2.set_blank_transform(); + + rmesh.add(m1); + rmesh.add(m2); } } } diff --git a/src/graphics/equipment/reactor.hpp b/src/graphics/equipment/reactor.hpp index 77863c8..c76ddad 100644 --- a/src/graphics/equipment/reactor.hpp +++ b/src/graphics/equipment/reactor.hpp @@ -8,7 +8,7 @@ namespace Sim::Graphics::Equipment class Reactor : public MeshGen { - Mesh g_control_rod; + Mesh g_control_rod_lift, g_control_rod_base; public: diff --git a/src/graphics/mesh/arrays.cpp b/src/graphics/mesh/arrays.cpp index 5e6375b..f937645 100644 --- a/src/graphics/mesh/arrays.cpp +++ b/src/graphics/mesh/arrays.cpp @@ -25,7 +25,7 @@ void Arrays::vertex_attrib_pointers() glVertexAttribPointer(1, 2, GL_FLOAT, false, sizeof(v), ptr_diff(&v.texpos, &v)); glEnableVertexAttribArray(1); - glVertexAttribPointer(2, 4, GL_FLOAT, false, sizeof(v), ptr_diff(&v.pos, &v)); + glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.pos, &v)); glEnableVertexAttribArray(2); glVertexAttribPointer(3, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.normal, &v)); diff --git a/src/graphics/mesh/arrays.hpp b/src/graphics/mesh/arrays.hpp index 6f86b06..a0ca692 100644 --- a/src/graphics/mesh/arrays.hpp +++ b/src/graphics/mesh/arrays.hpp @@ -10,7 +10,7 @@ struct Vertex { unsigned long texid = 0; glm::vec2 texpos = {0, 0}; - glm::vec4 pos = {0, 0, 0, 1}; + glm::vec3 pos = {0, 0, 0}; glm::vec3 normal = {0, 0, 0}; glm::vec4 colour = {1, 1, 1, 1}; glm::vec3 material = {0, 0, 0}; diff --git a/src/graphics/mesh/font.cpp b/src/graphics/mesh/font.cpp index de3cc62..5ad81e3 100644 --- a/src/graphics/mesh/font.cpp +++ b/src/graphics/mesh/font.cpp @@ -101,7 +101,7 @@ void Font::init() FT_Done_FreeType(ft); } -void Mesh::load_text(const char* text, double size) +Mesh& Mesh::load_text(const char* text, double size) { std::vector vertices; std::vector indices; @@ -113,7 +113,7 @@ void Mesh::load_text(const char* text, double size) { this->vertices.clear(); this->indices.clear(); - return; + return *this; } for(unsigned int i = 0; text[i] != '\0'; i++) @@ -144,10 +144,10 @@ void Mesh::load_text(const char* text, double size) float ex = sx + ch.size.x * size; float ey = sy + ch.size.y * size; - vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 0}, .pos={sx, sy, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}}); - vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 1}, .pos={sx, ey, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}}); - vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 0}, .pos={ex, sy, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}}); - vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 1}, .pos={ex, ey, 0, 1}, .normal={0, 0, -1}, .material={0, 0, 1}}); + vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 0}, .pos={sx, sy, 0}, .normal={0, 0, -1}, .material={0, 0, 1}}); + vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={0, 1}, .pos={sx, ey, 0}, .normal={0, 0, -1}, .material={0, 0, 1}}); + vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 0}, .pos={ex, sy, 0}, .normal={0, 0, -1}, .material={0, 0, 1}}); + vertices.push_back(Arrays::Vertex{.texid=ch.handle, .texpos={1, 1}, .pos={ex, ey, 0}, .normal={0, 0, -1}, .material={0, 0, 1}}); indices.insert(indices.end(), &index[0], &index[6]); at += 4; @@ -156,9 +156,12 @@ void Mesh::load_text(const char* text, double size) this->vertices = std::move(vertices); this->indices = std::move(indices); + this->transforms.clear(); + + return *this; } -void Mesh::load_text(const char* text, double size, glm::vec2 align) +Mesh& Mesh::load_text(const char* text, double size, glm::vec2 align) { glm::vec2 max; @@ -184,5 +187,7 @@ void Mesh::load_text(const char* text, double size, glm::vec2 align) v.pos.x -= align.x; v.pos.y -= align.y; } + + return *this; } diff --git a/src/graphics/mesh/glmesh.cpp b/src/graphics/mesh/glmesh.cpp index 6a260a2..e313219 100644 --- a/src/graphics/mesh/glmesh.cpp +++ b/src/graphics/mesh/glmesh.cpp @@ -6,6 +6,7 @@ #include "arrays.hpp" #include "../shader.hpp" #include "../camera.hpp" +#include "../../util/streams.hpp" using namespace Sim::Graphics; @@ -32,40 +33,58 @@ GLMesh::GLMesh(GLMesh&& o) vbo = o.vbo; ebo = o.ebo; vao = o.vao; - size = o.size; - model_matrix = o.model_matrix; + ssbo = o.ssbo; o.vbo = 0; o.ebo = 0; o.vao = 0; + o.ssbo = 0; + + size = o.size; + ssbo_size = o.ssbo_size; } GLMesh::~GLMesh() { if(vbo) glDeleteBuffers(1, &vbo); if(ebo) glDeleteBuffers(1, &ebo); + if(ssbo) glDeleteBuffers(1, &ssbo); if(vao) glDeleteVertexArrays(1, &vao); } -void GLMesh::bind() +void GLMesh::bind(bool bind_ssbo) { 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::uniform() -{ - glUniformMatrix4fv(Shader::ACTIVE->get("model"), 1, false, &model_matrix[0][0]); -} - -void GLMesh::set(const Mesh& m, int mode) +void GLMesh::set(const Mesh& m, int mode, bool send_ssbo) { glBindBuffer(GL_ARRAY_BUFFER, vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ARRAY_BUFFER, m.vertices.size() * sizeof(m.vertices[0]), &m.vertices[0], mode); glBufferData(GL_ELEMENT_ARRAY_BUFFER, m.indices.size() * sizeof(m.indices[0]), &m.indices[0], mode); + 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/mesh/glmesh.hpp index fcec883..5769819 100644 --- a/src/graphics/mesh/glmesh.hpp +++ b/src/graphics/mesh/glmesh.hpp @@ -13,9 +13,9 @@ namespace Sim::Graphics struct GLMesh { - unsigned int vao = 0, vbo = 0, ebo = 0, size = 0; - - glm::mat4 model_matrix {1.0f}; + unsigned int vao = 0, vbo = 0, ebo = 0, ssbo = 0; + int ssbo_size = 0; + int size = 0; constexpr GLMesh() { } @@ -23,9 +23,8 @@ struct GLMesh GLMesh(const GLMesh& o) = delete; ~GLMesh(); - void bind(); - void uniform(); - void set(const Mesh& m, int mode); + void bind(bool bind_ssbo = true); + void set(const Mesh& m, int mode, bool send_ssbo = true); void render(int type); void render(); }; diff --git a/src/graphics/mesh/mesh.cpp b/src/graphics/mesh/mesh.cpp index c74343d..1e74d49 100644 --- a/src/graphics/mesh/mesh.cpp +++ b/src/graphics/mesh/mesh.cpp @@ -15,79 +15,122 @@ 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::set_texture_id(unsigned int id) +Mesh& Mesh::set_texture_id(unsigned int id) { for(unsigned int i = 0; i < vertices.size(); i++) { vertices[i].texid = id; } + + return *this; } -void Mesh::add(const Mesh& o, glm::mat4 mat) +Mesh& Mesh::set_blank_transform() { - unsigned int off = vertices.size(); - float t_off = max_transform_id + 1; + transforms = {glm::mat4(1)}; + + for(unsigned int i = 0; i < vertices.size(); i++) + { + vertices[i].transform_id = 0; + } + + return *this; +} + +Mesh& Mesh::add(const Mesh& o, glm::mat4 mat, bool bake) +{ + int off = vertices.size(); + + indices.reserve(indices.size() + o.indices.size()); + vertices.reserve(vertices.size() + o.vertices.size()); + + if(bake) + { + for(int i = 0; i < o.vertices.size(); i++) + { + Arrays::Vertex v = o.vertices[i]; + int t_id = (int)v.transform_id; + glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1); + t_mat = mat * t_mat; + + v.pos = t_mat * glm::vec4(v.pos, 1); + v.normal = glm::normalize(glm::mat3(t_mat) * v.normal); + v.transform_id = -1; + vertices.push_back(v); + } + + for(int i = 0; i < o.indices.size(); i++) + { + indices.push_back(o.indices[i] + off); + } + + return *this; + } glm::mat3 mat3(mat); - vertices.reserve(vertices.size() + o.vertices.size()); - indices.reserve(indices.size() + o.indices.size()); + float t_off = transforms.size(); + float t_new = -1; - for(unsigned int i = 0; i < o.vertices.size(); i++) + if(mat != glm::mat4(1)) + { + t_new = transforms.size() + o.transforms.size(); + } + + transforms.reserve(transforms.size() + o.transforms.size() + (t_new >= 0 ? 1 : 0)); + + for(int i = 0; i < o.vertices.size(); i++) { 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); } + else + { + v.transform_id = t_new; + } + vertices.push_back(v); } - for(unsigned int i = 0; i < o.indices.size(); i++) + for(int i = 0; i < o.transforms.size(); i++) + { + transforms.push_back(o.transforms[i] * mat); + } + + for(int i = 0; i < o.indices.size(); i++) { indices.push_back(o.indices[i] + off); } -} -void Mesh::add(const Mesh& o) -{ - add(o, glm::mat4(1)); -} - -void Mesh::set_vertices(const Arrays::Vertex* data, size_t size) -{ - vertices.clear(); - vertices.reserve(size); - - for(unsigned int i = 0; i < size; i++) + if(t_new >= 0) { - vertices.push_back(data[i]); + transforms.push_back(mat); } + + return *this; } -void Mesh::set_indices(const unsigned int* data, size_t size) +Mesh& Mesh::bake_transforms() { - indices.clear(); - indices.reserve(size); - - for(unsigned int i = 0; i < size; i++) + for(unsigned int i = 0; i < vertices.size(); i++) { - indices.push_back(data[i]); + int id = (int)vertices[i].transform_id; + + if(id >= 0) + { + glm::mat4 transform = transforms[id]; + vertices[i].pos = glm::vec3(transform * glm::vec4(vertices[i].pos, 1)); + vertices[i].normal = glm::normalize(glm::mat3(transform) * vertices[i].normal); + vertices[i].transform_id = -1; + } } + + transforms.clear(); + + return *this; } typedef glm::vec<3, double> vec3; @@ -158,11 +201,21 @@ bool Mesh::check_intersect(vec3 pos, vec3 path) const for(unsigned int i = 0; i < indices.size(); 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) + Arrays::Vertex verts[3] = { + vertices[indices[i]], + vertices[indices[i + 1]], + vertices[indices[i + 2]] }; + + vec3 v[3]; + + for(int j = 0; j < 3; j++) + { + int t_id = (int)verts[j].transform_id; + glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1); + + v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1)); + } vec3 ipoint; vec3 normal = glm::normalize(glm::cross(v[1] - v[0], v[2] - v[0])); @@ -226,11 +279,21 @@ vec3 Mesh::calc_intersect(vec3 pos, vec3 path) const for(unsigned int i = 0; i < indices.size(); 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) + Arrays::Vertex verts[3] = { + vertices[indices[i]], + vertices[indices[i + 1]], + vertices[indices[i + 2]] }; + + vec3 v[3]; + + for(int j = 0; j < 3; j++) + { + int t_id = (int)verts[j].transform_id; + glm::mat4 t_mat = t_id >= 0 ? transforms[t_id] : glm::mat4(1); + + v[j] = vec3(t_mat * glm::vec4(verts[j].pos, 1)); + } if(calc_intercept_vert(v, pos, path, path_n, l)) { @@ -265,4 +328,3 @@ Mesh Mesh::to_lines() const return m; } - diff --git a/src/graphics/mesh/mesh.hpp b/src/graphics/mesh/mesh.hpp index 2aba0b8..c8ba105 100644 --- a/src/graphics/mesh/mesh.hpp +++ b/src/graphics/mesh/mesh.hpp @@ -19,18 +19,16 @@ struct Mesh { std::vector vertices; std::vector indices; - float max_transform_id = -1; + std::vector transforms; Mesh(); - void set_transform_id(); - void set_texture_id(unsigned int 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); - void load_text(const char* text, double size, glm::vec2 align); - void add(const Mesh& o, glm::mat4 mat); - void add(const Mesh& o); + Mesh& bake_transforms(); + Mesh& set_blank_transform(); + Mesh& set_texture_id(unsigned int id); + Mesh& load_text(const char* text, double size); + Mesh& load_text(const char* text, double size, glm::vec2 align); + Mesh& add(const Mesh& o, glm::mat4 mat = glm::mat4(1), bool bake = false); Mesh to_lines() const; bool check_focus() const; diff --git a/src/graphics/mesh/model.cpp b/src/graphics/mesh/model.cpp index 838b428..aa4f237 100644 --- a/src/graphics/mesh/model.cpp +++ b/src/graphics/mesh/model.cpp @@ -23,6 +23,7 @@ struct ProcState std::string base; std::vector vertices; std::vector indices; + std::vector transforms; std::unordered_map handles; }; @@ -51,7 +52,7 @@ static unsigned int proc_texture(const ProcState& state, aiMaterial* mat, const return Texture::load(state.base + "/" + filename); } -static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiScene* scene) +static void proc_mesh(ProcState& state, aiMesh* mesh, const aiScene* scene) { aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; aiString name; @@ -114,7 +115,6 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce unsigned int handle = proc_texture(state, material, scene, aiTextureType_BASE_COLOR, 0); unsigned int offset = state.offset; - glm::mat3 mat3(mat); if(!handle) { @@ -131,7 +131,8 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce Arrays::Vertex vertex; auto [x, y, z] = mesh->mVertices[i]; - vertex.pos = glm::vec4(x, y, z, 1) * mat; + vertex.pos = glm::vec3(x, y, z); + vertex.transform_id = state.transforms.size(); vertex.material = matv; vertex.texid = handle; vertex.colour = cb; @@ -139,7 +140,7 @@ static void proc_mesh(ProcState& state, glm::mat4 mat, aiMesh* mesh, const aiSce if(mesh->HasNormals()) { auto [x, y, z] = mesh->mNormals[i]; - vertex.normal = glm::vec3(x, y, z) * mat3; + vertex.normal = glm::vec3(x, y, z); } /*if(mesh->HasTangentsAndBitangents()) @@ -207,7 +208,12 @@ static void proc_node(ProcState& state, glm::mat4 mat, aiNode* node, const aiSce for(size_t i = 0; i < node->mNumMeshes; i++) { aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; - proc_mesh(state, mat, mesh, scene); + proc_mesh(state, mesh, scene); + } + + if(node->mNumMeshes > 0) + { + state.transforms.push_back(glm::transpose(mat)); } } @@ -296,6 +302,7 @@ Mesh Model::load(const char* name, glm::mat4 mat) const mesh.vertices = std::move(state.vertices); mesh.indices = std::move(state.indices); + mesh.transforms = std::move(state.transforms); return mesh; } diff --git a/src/graphics/monitor/core.cpp b/src/graphics/monitor/core.cpp index dd8d396..9431f4e 100644 --- a/src/graphics/monitor/core.cpp +++ b/src/graphics/monitor/core.cpp @@ -137,22 +137,21 @@ void Core::remesh_static(Mesh& rmesh) { Mesh mesh; mesh.load_text("Reactor Core", 0.04); - rmesh.add(mesh, mat); + rmesh.add(mesh, mat, true); } static Mesh add_dot(glm::mat4 model_mat, glm::vec4 colour) { - unsigned int indices[] = {0, 1, 3, 0, 3, 2}; - Arrays::Vertex vertices[] = { - {.texid=Texture::handle_white, .texpos={0, 0}, .pos=model_mat * glm::vec4(-0.75, -0.75, 0, 1), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, - {.texid=Texture::handle_white, .texpos={0, 1}, .pos=model_mat * glm::vec4(-0.75, 0.75, 0, 1), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, - {.texid=Texture::handle_white, .texpos={1, 0}, .pos=model_mat * glm::vec4( 0.75, -0.75, 0, 1), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, - {.texid=Texture::handle_white, .texpos={1, 1}, .pos=model_mat * glm::vec4( 0.75, 0.75, 0, 1), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, + Mesh mesh; + + mesh.indices = {0, 1, 3, 0, 3, 2}; + mesh.vertices = { + {.texid=Texture::handle_white, .texpos={0, 0}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, -0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, + {.texid=Texture::handle_white, .texpos={0, 1}, .pos=glm::vec3(model_mat * glm::vec4(-0.75, 0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, + {.texid=Texture::handle_white, .texpos={1, 0}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, -0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, + {.texid=Texture::handle_white, .texpos={1, 1}, .pos=glm::vec3(model_mat * glm::vec4( 0.75, 0.75, 0, 1)), .normal={0, 0, -1}, .colour=colour, .material={0, 0, 1}}, }; - Mesh mesh; - mesh.set_indices(indices, 6); - mesh.set_vertices(vertices, 4); return mesh; } diff --git a/src/graphics/monitor/primary_loop.cpp b/src/graphics/monitor/primary_loop.cpp index 076f811..82c9d27 100644 --- a/src/graphics/monitor/primary_loop.cpp +++ b/src/graphics/monitor/primary_loop.cpp @@ -62,10 +62,6 @@ PrimaryLoop::PrimaryLoop(const Model& model) 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) @@ -86,7 +82,7 @@ void PrimaryLoop::remesh_static(Mesh& rmesh) ss << "Level\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, mat); + rmesh.add(mesh, mat, true); rmesh.add(g_switch_pump); rmesh.add(g_switch_bypass); diff --git a/src/graphics/monitor/secondary_loop.cpp b/src/graphics/monitor/secondary_loop.cpp index 608e85e..1fda1db 100644 --- a/src/graphics/monitor/secondary_loop.cpp +++ b/src/graphics/monitor/secondary_loop.cpp @@ -28,9 +28,6 @@ SecondaryLoop::SecondaryLoop(const Model& model) 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) @@ -56,7 +53,7 @@ void SecondaryLoop::remesh_static(Mesh& rmesh) ss << "Power\nSpeed\nFlow\n\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, mat); + rmesh.add(mesh, mat, true); rmesh.add(g_switch_2); rmesh.add(g_switch_3); } diff --git a/src/graphics/monitor/turbine.cpp b/src/graphics/monitor/turbine.cpp index 2cea05d..dd307b0 100644 --- a/src/graphics/monitor/turbine.cpp +++ b/src/graphics/monitor/turbine.cpp @@ -28,12 +28,6 @@ Turbine::Turbine(const Model& model) g_switch_breaker = model.load("visual_breaker_switch"); m_switch_breaker = model.load("click_breaker_switch"); - - g_dial_phase.set_transform_id(); - g_dial_voltage.set_transform_id(); - g_dial_power.set_transform_id(); - g_dial_frequency.set_transform_id(); - g_switch_breaker.set_transform_id(); } void Turbine::update(double dt) @@ -55,22 +49,12 @@ void Turbine::get_static_transforms(std::vector& transforms) if(rpm > 3570 && rpm < 3630) { - mat_phase = glm::translate(mat_phase, glm::vec3(6.35, 3.949, 1.35)); mat_phase = glm::rotate(mat_phase, float(sys.loop.generator.get_phase_diff()), glm::vec3(0, 1, 0)); - mat_phase = glm::translate(mat_phase, glm::vec3(-6.35, -3.949, -1.35)); } - mat_voltage = glm::translate(mat_voltage, glm::vec3(6.95, 3.949, 1.95)); mat_voltage = glm::rotate(mat_voltage, float(Util::Math::map(sys.loop.generator.get_voltage(), 0, 24e3, 0, M_PI)), glm::vec3(0, 1, 0)); - mat_voltage = glm::translate(mat_voltage, glm::vec3(-6.95, -3.949, -1.95)); - - mat_power = glm::translate(mat_power, glm::vec3(6.35, 3.949, 1.95)); mat_power = glm::rotate(mat_power, float(Util::Math::map(sys.loop.generator.get_power(), 0, 600e6, 0, M_PI)), glm::vec3(0, 1, 0)); - mat_power = glm::translate(mat_power, glm::vec3(-6.35, -3.949, -1.95)); - - mat_frequency = glm::translate(mat_frequency, glm::vec3(6.95, 3.949, 1.35)); mat_frequency = glm::rotate(mat_frequency, float(Util::Math::map(sys.loop.generator.get_frequency(), 0, 120, 0, M_PI)), glm::vec3(0, 1, 0)); - mat_frequency = glm::translate(mat_frequency, glm::vec3(-6.95, -3.949, -1.35)); transforms.push_back(mat_phase); transforms.push_back(mat_voltage); @@ -91,7 +75,7 @@ void Turbine::remesh_static(Mesh& rmesh) ss << "Heat\nPressure\nSpeed\n\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, mat); + rmesh.add(mesh, mat, true); rmesh.add(g_dial_phase); rmesh.add(g_dial_voltage); diff --git a/src/graphics/monitor/vessel.cpp b/src/graphics/monitor/vessel.cpp index 8e696f0..fa5ce9c 100644 --- a/src/graphics/monitor/vessel.cpp +++ b/src/graphics/monitor/vessel.cpp @@ -38,7 +38,7 @@ void Vessel::remesh_static(Mesh& rmesh) ss << "Control Rods\nMin\nMax\nSpeed\n"; mesh.load_text(ss.str().c_str(), 0.04); - rmesh.add(mesh, mat); + rmesh.add(mesh, mat, true); } void Vessel::remesh_slow(Mesh& rmesh) diff --git a/src/graphics/ui.cpp b/src/graphics/ui.cpp index 57fce98..06959ca 100644 --- a/src/graphics/ui.cpp +++ b/src/graphics/ui.cpp @@ -30,16 +30,15 @@ void UI::init() Mesh m; unsigned int handle = Texture::handle_white; - const unsigned int indices[] = {0, 1, 3, 0, 3, 2}; - const Arrays::Vertex vertices[] = { - {.texid=handle, .texpos={0, 0}, .pos={-1, -1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, - {.texid=handle, .texpos={0, 1}, .pos={-1, 1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, - {.texid=handle, .texpos={1, 0}, .pos={ 1, -1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, - {.texid=handle, .texpos={1, 1}, .pos={ 1, 1, 0, 1}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, + 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}}, + {.texid=handle, .texpos={0, 1}, .pos={-1, 1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, + {.texid=handle, .texpos={1, 0}, .pos={ 1, -1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, + {.texid=handle, .texpos={1, 1}, .pos={ 1, 1, 0}, .normal={0, 0, -1}, .colour={1, 1, 1, 1}, .material={0, 0, 1}}, }; - m.set_indices(indices, 6); - m.set_vertices(vertices, 4); + m.bake_transforms(); gm_ui.bind(); gm_ui.set(m, GL_STATIC_DRAW); @@ -73,13 +72,9 @@ void UI::render() glUniformMatrix4fv(Shader::MAIN["camera"], 1, false, &mat_camera[0][0]); gm_ui.bind(); - gm_ui.uniform(); gm_ui.render(); gm_dynamic_slow[gm_dynamic_slow_at].bind(); - gm_dynamic_slow[gm_dynamic_slow_at].uniform(); gm_dynamic_slow[gm_dynamic_slow_at].render(); - - w_clock.render(); } diff --git a/src/graphics/widget/clock.cpp b/src/graphics/widget/clock.cpp index 15f8dd9..142c964 100644 --- a/src/graphics/widget/clock.cpp +++ b/src/graphics/widget/clock.cpp @@ -15,6 +15,7 @@ #include "../mesh/arrays.hpp" #include "../resize.hpp" #include "../../system.hpp" +#include "../../util/streams.hpp" using namespace Sim::Graphics::Widget; @@ -44,7 +45,3 @@ void Clock::remesh_slow(Mesh& rmesh) rmesh.add(m, glm::translate(glm::mat4(1), glm::vec3(-wsize + glm::vec2(2, 2), 0))); } -void Clock::render() -{ -} - diff --git a/src/graphics/widget/clock.hpp b/src/graphics/widget/clock.hpp index 8e4f57a..3ee3bd7 100644 --- a/src/graphics/widget/clock.hpp +++ b/src/graphics/widget/clock.hpp @@ -12,7 +12,6 @@ struct Clock void update(double dt); void remesh_slow(Mesh& rmesh); - void render(); }; }; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index a59b581..5985e6d 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -44,13 +44,13 @@ 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 unsigned int wait_at = 0; static int gm_dynamic_slow_at = 0; static int ssbo_transforms_at = 0; static Mesh g_scene; +static std::vector g_scene_transforms; static GLMesh gm_scene; static GLMesh gm_transparent; @@ -89,8 +89,9 @@ void remesh_static() equipment->remesh_static(mesh); } - gm_scene.bind(); - gm_scene.set(mesh, GL_STATIC_DRAW); + gm_scene.bind(false); + gm_scene.set(mesh, GL_STATIC_DRAW, false); + g_scene_transforms = std::move(mesh.transforms); std::cout << "Remeshed static\n"; } @@ -171,10 +172,12 @@ void Window::create() Model model("../assets", "scene.glb"); m_transparent = model.load("visual_water"); + m_transparent.bake_transforms(); g_scene.add(model.load("cr")); g_scene.add(model.load("cb")); g_scene.add(model.load("hw")); + g_scene.bake_transforms(); Camera::init(model); @@ -263,6 +266,8 @@ void update_slow() equipment->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; @@ -273,7 +278,6 @@ void update_slow() void Window::reload() { remesh_static(); - render_shadow_map(); } void Window::update(double dt) @@ -294,34 +298,40 @@ void Window::update(double dt) equipment->update(dt); equipment->get_static_transforms(transforms); } + + for(int i = 0; i < transforms.size(); i++) + { + transforms[i] = g_scene_transforms[i] * transforms[i]; + } + + if(transforms.size() != g_scene_transforms.size()) + { + std::cerr << "Transforms size mismatch! " << transforms.size() << " != " << g_scene_transforms.size() << "\n"; + close(); + } UI::update(dt); - 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); + ssbo_transforms_at = (ssbo_transforms_at + 1) % SSBO_TRANSFORMS_LEN; - secs_wait_now += dt; - if(secs_wait_now > secs_wait_at + 1.0/30.0) + if(wait_at++ % 4 == 0) { - secs_wait_at += 1.0/30.0; update_slow(); } } void Window::render_scene() { - gm_scene.bind(); - gm_scene.uniform(); + gm_scene.bind(false); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, ssbo_transforms[ssbo_transforms_at]); gm_scene.render(); 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_transparent.bind(); - gm_transparent.uniform(); gm_transparent.render(); Focus::render(); @@ -329,6 +339,8 @@ void Window::render_scene() void Window::render() { + render_shadow_map(); + glm::vec<2, int> size = Resize::get_size(); glm::vec3 camera_pos = Camera::get_pos(); glm::mat4 mat_camera = Camera::get_matrix(); diff --git a/src/util/streams.hpp b/src/util/streams.hpp index 559cd48..9b51e71 100644 --- a/src/util/streams.hpp +++ b/src/util/streams.hpp @@ -37,3 +37,17 @@ std::ostream& operator<<(std::ostream& o, const glm::vec& v) return o; } +template +std::ostream& operator<<(std::ostream& o, const glm::mat& m) +{ + o << "{\n"; + + for(int i = 0; i < N - 1; i++) + { + o << " " << m[i] << ",\n"; + } + + o << " " << m[N - 1] << "}"; + return o; +} +