From 60f1e72144312ffb97756b1024a30694b31acf2c Mon Sep 17 00:00:00 2001 From: Asuro Date: Tue, 25 Feb 2025 04:03:48 +0100 Subject: [PATCH] meshes! --- src/.gitattributes | 1 + src/game/Level.cpp | 8 ++- src/game/Mesh.cpp | 87 ++++++++++++++++++++++++++++++-- src/game/Mesh.h | 6 ++- src/game/Puzzle.cpp | 14 ++--- src/game/rendering/Rendering.cpp | 48 ++++++++++++++++-- src/game/rendering/Rendering.h | 19 ++++++- src/models/ConcretePlane.glb | 3 ++ src/models/blocked.glb | 3 ++ src/models/e!.glb | 3 ++ src/models/e+.glb | 3 ++ src/models/w corner long.glb | 3 ++ src/models/w corner short.glb | 3 ++ src/models/w straight.glb | 3 ++ src/models/w! corner short.glb | 3 ++ src/models/w! straight.glb | 3 ++ src/models/w+ straight.glb | 3 ++ 17 files changed, 194 insertions(+), 19 deletions(-) create mode 100644 src/.gitattributes create mode 100644 src/models/ConcretePlane.glb create mode 100644 src/models/blocked.glb create mode 100644 src/models/e!.glb create mode 100644 src/models/e+.glb create mode 100644 src/models/w corner long.glb create mode 100644 src/models/w corner short.glb create mode 100644 src/models/w straight.glb create mode 100644 src/models/w! corner short.glb create mode 100644 src/models/w! straight.glb create mode 100644 src/models/w+ straight.glb diff --git a/src/.gitattributes b/src/.gitattributes new file mode 100644 index 0000000..28cf0c3 --- /dev/null +++ b/src/.gitattributes @@ -0,0 +1 @@ +*.glb filter=lfs diff=lfs merge=lfs -text diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 8a47c88..812f1b5 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -3,10 +3,12 @@ #include "Instance.h" #include "Level.h" #include "Log.h" +#include "Mesh.h" #include "Puzzle.h" #include "SDL3/SDL_mouse.h" #include "bgfx/bgfx.h" #include "imgui.h" +#include "rendering/Rendering.h" #include #include #include @@ -18,6 +20,7 @@ namespace Game if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return; if (!Visible) return; + // Log("%u", ModelHandle); Transform.UpdateMatrix(); bgfx::setTransform(Transform.M.M); @@ -44,6 +47,7 @@ namespace Game SDL_SetWindowRelativeMouseMode(GetShared().Window.SDLWindow, IsGaming); auto& IO = ImGui::GetIO(); IO.ConfigFlags = FlagBool(IO.ConfigFlags, ImGuiConfigFlags_NoMouse | ImGuiConfigFlags_NoKeyboard, IsGaming); + GameRendering::Get().UIVisible = IsGaming ? UIVisibilityState::Game : UIVisibilityState::Debug; } } // namespace @@ -201,7 +205,7 @@ namespace Game void Cube::Setup() { EData.MaterialHandle = 0; - EData.ModelHandle = 0; + EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/cube.gltf"); } void Cube::Update() @@ -227,7 +231,7 @@ namespace Game void TestEntity::Setup() { EData.MaterialHandle = 0; - EData.ModelHandle = 1; + EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/zurg.gltf"); EData.Transform.Position = {0.0f, 0.0f, 10.0f}; EData.TestColor[0] = 0.0f; diff --git a/src/game/Mesh.cpp b/src/game/Mesh.cpp index 56357ff..40fd445 100644 --- a/src/game/Mesh.cpp +++ b/src/game/Mesh.cpp @@ -1,6 +1,12 @@ #include "Log.h" #include "Mesh.h" #include "bx/bx.h" +#include "bx/error.h" +#include "bx/file.h" +#include "bx/filepath.h" +#include "bx/hash.h" +#include "bx/string.h" +#include "rendering/Rendering.h" #define TINYGLTF_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION @@ -9,7 +15,7 @@ namespace Game { - void LoadMesh(Model& mesh, const char* path) + bool LoadMesh(Model& mesh, const char* path, bool isBinary) { mesh.VertLayout.begin() .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) @@ -22,14 +28,23 @@ namespace Game tinygltf::TinyGLTF loader; std::string warn; std::string err; - bool loadSuccess = loader.LoadASCIIFromFile(&model, &err, &warn, path); + + bool loadSuccess; + if (isBinary) + { + loadSuccess = loader.LoadBinaryFromFile(&model, &err, &warn, path); + } + else + { + loadSuccess = loader.LoadASCIIFromFile(&model, &err, &warn, path); + } if (!warn.empty()) Log("WARN: %s", warn.c_str()); if (!err.empty()) Log("ERR: %s", err.c_str()); if (!loadSuccess) { Log("Model load failed!"); - return; + return false; } tinygltf::Primitive primitive = model.meshes[0].primitives[0]; @@ -69,5 +84,71 @@ namespace Game } mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout); } + return true; + } + + void LoadModels(Model* models, uint32_t& outCount) + { + bx::Error err; + bx::DirectoryReader reader{}; + if (!reader.open("models", &err) || !err.isOk()) + { + Log("Failed to read models dir: %s", err.getMessage()); + } + bx::FileInfo info; + int32_t modelFilePathCount = 0; + bx::FilePath modelFilePaths[GameRendering::MaxModels]; + bool modelFileIsBinary[GameRendering::MaxModels]{false}; + while (err.isOk()) + { + int32_t res = reader.read(&info, sizeof(info), &err); + if (res == 0) break; // EOF + if (res != sizeof(info)) + { + Log("Dir iter error: %s", err.getMessage()); + break; + } + const bx::StringView ext = info.filePath.getExt(); + bool isBinary = bx::strCmp(ext, ".glb") == 0; + bool isText = bx::strCmp(ext, ".gltf") == 0; + if ((isBinary || isText) && !ext.isEmpty() && info.type == bx::FileType::File) + { + if (modelFilePathCount >= GameRendering::MaxModels) + { + Log("Model limit reached!"); + break; + } + modelFilePaths[modelFilePathCount] = info.filePath; + modelFileIsBinary[modelFilePathCount] = isBinary; + modelFilePathCount++; + } + } + Log("Found %u models!", modelFilePathCount); + + int32_t writeI = 0; + for (int32_t i = 0; i < modelFilePathCount; ++i) + { + bx::FilePath fullPath = bx::FilePath{"models"}; + fullPath.join(modelFilePaths[i].getCPtr()); + Model& mod = models[writeI]; + if (LoadMesh(mod, fullPath.getCPtr(), modelFileIsBinary[i])) + { + mod.AssetHandle = CrcPath(fullPath.getCPtr()); + ++writeI; + } + else + { + Log("Failed to load model: %s", fullPath.getCPtr()); + } + } + outCount = writeI; + } + + uint32_t CrcPath(const char* path) + { + bx::HashCrc32 hash; + hash.begin(); + hash.add(path); + return hash.end(); } } // namespace Game diff --git a/src/game/Mesh.h b/src/game/Mesh.h index a7272e8..cef56c0 100644 --- a/src/game/Mesh.h +++ b/src/game/Mesh.h @@ -4,5 +4,7 @@ namespace Game { - void LoadMesh(Model& mesh, const char* path); -} + bool LoadMesh(Model& mesh, const char* path, bool isBinary); + void LoadModels(Model* models, uint32_t& outCount); + uint32_t CrcPath(const char* path); +} // namespace Game diff --git a/src/game/Puzzle.cpp b/src/game/Puzzle.cpp index d4c9069..5370dc3 100644 --- a/src/game/Puzzle.cpp +++ b/src/game/Puzzle.cpp @@ -1,5 +1,8 @@ #include "Log.h" #include "Puzzle.h" +#include "rendering/Rendering.h" + +#include "bx/bx.h" #include namespace @@ -18,14 +21,11 @@ namespace Puzzle { void StaticPuzzleData::Setup() { - if (StaticDataInstance == nullptr) + StaticDataInstance = this; + Log("Setting up static puzzle data"); + for (int32_t i = 0; i < BX_COUNTOF(Cards); ++i) { - StaticDataInstance = this; - Log("Setting up static puzzle data"); - } - else - { - Log("Static puzzle data already set up"); + Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb"); } } diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index 8617f52..e1f9be2 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -10,7 +10,6 @@ #include "bgfx/defines.h" #include "bx/bx.h" #include "bx/filepath.h" -#include "bx/math.h" #include "bx/timer.h" #include #include @@ -191,11 +190,21 @@ namespace Game return handle; } + + GameRendering* Instance = nullptr; } // namespace + GameRendering& GameRendering::Get() + { + assert(Instance != nullptr); + return *Instance; + } + void GameRendering::Setup() { Log("--- RENDERING STARTUP ---"); + if (Instance != nullptr) Log("Warning, old rendering wasn't destroyed!"); + Instance = this; SharedData& shared = GetShared(); bgfx::Init init; @@ -229,8 +238,7 @@ namespace Game Textures[0].Handle = loadTexture(bx::FilePath{"models/body.dds"}, BGFX_TEXTURE_NONE | BGFX_SAMPLER_NONE, 0, nullptr, nullptr); Textures[0].SamplerHandle = DefaultSampler; - LoadMesh(Models[0], "models/cube.gltf"); - LoadMesh(Models[1], "models/zurg.gltf"); + LoadModels(Models, ModelCount); Materials[0] = Material::LoadFromShader("vert", "frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle); @@ -312,7 +320,24 @@ namespace Game imguiBeginFrame(20); ImGui_ImplSDL3_NewFrame(); ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode); - ImGui::ShowDemoWindow(); + + if (UIVisible == UIVisibilityState::Debug) + { + if (ImGui::Begin("Rendering")) + { + if (ImGui::Button("Reload Meshes")) + { + LoadModels(Models, ModelCount); + } + if (ImGui::Button("Reload Level")) + { + auto& lvl = GetInstance().GameLevel; + lvl = {}; + lvl.Setup(shared.Game); + } + } + ImGui::End(); + } GetInstance().GameLevel.Update(); GetInstance().GameLevel.Render(MainViewID, Models, Materials); @@ -348,6 +373,7 @@ namespace Game ImGui_ImplSDL3_Shutdown(); imguiDestroy(); bgfx::shutdown(); + Instance = nullptr; } Material Material::LoadFromShader( @@ -368,4 +394,18 @@ namespace Game mat.ViewID = view; return mat; } + + uint16_t GameRendering::GetModelHandleFromPath(const char* path) + { + uint32_t AssetHandle = CrcPath(path); + for (int32_t i = 0; i < ModelCount; ++i) + { + if (Models[i].AssetHandle == AssetHandle) + { + return i; + } + } + return 0; + } + } // namespace Game diff --git a/src/game/rendering/Rendering.h b/src/game/rendering/Rendering.h index 34bfc3e..621fcd7 100644 --- a/src/game/rendering/Rendering.h +++ b/src/game/rendering/Rendering.h @@ -32,6 +32,7 @@ namespace Game bgfx::VertexBufferHandle VertexBuffer; bgfx::IndexBufferHandle IndexBuffer; bgfx::VertexLayout VertLayout; + uint32_t AssetHandle = UINT16_MAX; }; struct Material @@ -54,13 +55,28 @@ namespace Game bgfx::UniformHandle sampler = BGFX_INVALID_HANDLE); }; + enum class UIVisibilityState + { + None, + Game, + Debug, + }; + class GameRendering { + public: + static constexpr uint32_t MaxModels = 64; + static GameRendering& Get(); + + public: + UIVisibilityState UIVisible = UIVisibilityState::Game; + private: bgfx::UniformHandle DefaultSampler; Texture Textures[8]; Material Materials[8]; - Model Models[8]; + uint32_t ModelCount = 0; + Model Models[MaxModels]; int32_t LastWidth = 0; int32_t LastHeight = 0; uint32_t ResetFlags = BGFX_RESET_VSYNC; @@ -70,5 +86,6 @@ namespace Game void Setup(); void Update(); void Shutdown(); + uint16_t GetModelHandleFromPath(const char* path); }; } // namespace Game diff --git a/src/models/ConcretePlane.glb b/src/models/ConcretePlane.glb new file mode 100644 index 0000000..621714b --- /dev/null +++ b/src/models/ConcretePlane.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c3187769a45718de02c01904e832c38143faa7ddbffd88ce86d336257403ddb +size 1480 diff --git a/src/models/blocked.glb b/src/models/blocked.glb new file mode 100644 index 0000000..5853071 --- /dev/null +++ b/src/models/blocked.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42f8fcf705a60de377cdd9dbcde99311f468844eef197295ffa50f0f531ad783 +size 2752 diff --git a/src/models/e!.glb b/src/models/e!.glb new file mode 100644 index 0000000..afdad0d --- /dev/null +++ b/src/models/e!.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3e54d580068b4b3f48806851298f18e13645c03e1042c44adbdb8075ba0fba4c +size 18988 diff --git a/src/models/e+.glb b/src/models/e+.glb new file mode 100644 index 0000000..c70939a --- /dev/null +++ b/src/models/e+.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f79bbff9c2f9107b9787c3fd82d3cc9bcef66032cc682838f285b5f41ca8e2ea +size 3664 diff --git a/src/models/w corner long.glb b/src/models/w corner long.glb new file mode 100644 index 0000000..45d56fd --- /dev/null +++ b/src/models/w corner long.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7e0c3968772ea80a7de6cfecd5b083c25e874bc87960356ec5a987ac0ef4db62 +size 2896 diff --git a/src/models/w corner short.glb b/src/models/w corner short.glb new file mode 100644 index 0000000..91b27bd --- /dev/null +++ b/src/models/w corner short.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eb5b475840163cd44c996a27477e1cf3a26f8e73217c7d37de97e1a3f27b207 +size 2896 diff --git a/src/models/w straight.glb b/src/models/w straight.glb new file mode 100644 index 0000000..a0ded79 --- /dev/null +++ b/src/models/w straight.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bca71fef2436990460135dc4a57af9ed189d144cc611db4478b19d3c6707782d +size 2260 diff --git a/src/models/w! corner short.glb b/src/models/w! corner short.glb new file mode 100644 index 0000000..d156c81 --- /dev/null +++ b/src/models/w! corner short.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e5d9ee20215dba3d0f79035352a6a9d84a8f73c6cea629129038dd1afcfee4a +size 7108 diff --git a/src/models/w! straight.glb b/src/models/w! straight.glb new file mode 100644 index 0000000..dca2a4d --- /dev/null +++ b/src/models/w! straight.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1780c353abc03d03bb4e3668c6d4d2584da56875ee5867602e3da5ead34fb907 +size 13252 diff --git a/src/models/w+ straight.glb b/src/models/w+ straight.glb new file mode 100644 index 0000000..7ce8cff --- /dev/null +++ b/src/models/w+ straight.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d30dc7e4cf4029f3d65870ecd390b883130b82400e6499032ebb7e342c1349a0 +size 15308