This commit is contained in:
Asuro
2025-02-25 04:03:48 +01:00
parent d3dcec1458
commit 60f1e72144
17 changed files with 194 additions and 19 deletions
+1
View File
@@ -0,0 +1 @@
*.glb filter=lfs diff=lfs merge=lfs -text
+6 -2
View File
@@ -3,10 +3,12 @@
#include "Instance.h" #include "Instance.h"
#include "Level.h" #include "Level.h"
#include "Log.h" #include "Log.h"
#include "Mesh.h"
#include "Puzzle.h" #include "Puzzle.h"
#include "SDL3/SDL_mouse.h" #include "SDL3/SDL_mouse.h"
#include "bgfx/bgfx.h" #include "bgfx/bgfx.h"
#include "imgui.h" #include "imgui.h"
#include "rendering/Rendering.h"
#include <SDL3/SDL.h> #include <SDL3/SDL.h>
#include <bx/math.h> #include <bx/math.h>
#include <cstdint> #include <cstdint>
@@ -18,6 +20,7 @@ namespace Game
if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return; if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return;
if (!Visible) return; if (!Visible) return;
// Log("%u", ModelHandle);
Transform.UpdateMatrix(); Transform.UpdateMatrix();
bgfx::setTransform(Transform.M.M); bgfx::setTransform(Transform.M.M);
@@ -44,6 +47,7 @@ namespace Game
SDL_SetWindowRelativeMouseMode(GetShared().Window.SDLWindow, IsGaming); SDL_SetWindowRelativeMouseMode(GetShared().Window.SDLWindow, IsGaming);
auto& IO = ImGui::GetIO(); auto& IO = ImGui::GetIO();
IO.ConfigFlags = FlagBool(IO.ConfigFlags, ImGuiConfigFlags_NoMouse | ImGuiConfigFlags_NoKeyboard, IsGaming); IO.ConfigFlags = FlagBool(IO.ConfigFlags, ImGuiConfigFlags_NoMouse | ImGuiConfigFlags_NoKeyboard, IsGaming);
GameRendering::Get().UIVisible = IsGaming ? UIVisibilityState::Game : UIVisibilityState::Debug;
} }
} // namespace } // namespace
@@ -201,7 +205,7 @@ namespace Game
void Cube::Setup() void Cube::Setup()
{ {
EData.MaterialHandle = 0; EData.MaterialHandle = 0;
EData.ModelHandle = 0; EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/cube.gltf");
} }
void Cube::Update() void Cube::Update()
@@ -227,7 +231,7 @@ namespace Game
void TestEntity::Setup() void TestEntity::Setup()
{ {
EData.MaterialHandle = 0; EData.MaterialHandle = 0;
EData.ModelHandle = 1; EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/zurg.gltf");
EData.Transform.Position = {0.0f, 0.0f, 10.0f}; EData.Transform.Position = {0.0f, 0.0f, 10.0f};
EData.TestColor[0] = 0.0f; EData.TestColor[0] = 0.0f;
+84 -3
View File
@@ -1,6 +1,12 @@
#include "Log.h" #include "Log.h"
#include "Mesh.h" #include "Mesh.h"
#include "bx/bx.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 TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
@@ -9,7 +15,7 @@
namespace Game namespace Game
{ {
void LoadMesh(Model& mesh, const char* path) bool LoadMesh(Model& mesh, const char* path, bool isBinary)
{ {
mesh.VertLayout.begin() mesh.VertLayout.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float) .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
@@ -22,14 +28,23 @@ namespace Game
tinygltf::TinyGLTF loader; tinygltf::TinyGLTF loader;
std::string warn; std::string warn;
std::string err; 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 (!warn.empty()) Log("WARN: %s", warn.c_str());
if (!err.empty()) Log("ERR: %s", err.c_str()); if (!err.empty()) Log("ERR: %s", err.c_str());
if (!loadSuccess) if (!loadSuccess)
{ {
Log("Model load failed!"); Log("Model load failed!");
return; return false;
} }
tinygltf::Primitive primitive = model.meshes[0].primitives[0]; tinygltf::Primitive primitive = model.meshes[0].primitives[0];
@@ -69,5 +84,71 @@ namespace Game
} }
mesh.VertexBuffer = bgfx::createVertexBuffer(vbMem, mesh.VertLayout); 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 } // namespace Game
+4 -2
View File
@@ -4,5 +4,7 @@
namespace Game 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
+5 -5
View File
@@ -1,5 +1,8 @@
#include "Log.h" #include "Log.h"
#include "Puzzle.h" #include "Puzzle.h"
#include "rendering/Rendering.h"
#include "bx/bx.h"
#include <cassert> #include <cassert>
namespace namespace
@@ -17,15 +20,12 @@ namespace
namespace Puzzle namespace Puzzle
{ {
void StaticPuzzleData::Setup() void StaticPuzzleData::Setup()
{
if (StaticDataInstance == nullptr)
{ {
StaticDataInstance = this; StaticDataInstance = this;
Log("Setting up static puzzle data"); Log("Setting up static puzzle data");
} for (int32_t i = 0; i < BX_COUNTOF(Cards); ++i)
else
{ {
Log("Static puzzle data already set up"); Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
} }
} }
+44 -4
View File
@@ -10,7 +10,6 @@
#include "bgfx/defines.h" #include "bgfx/defines.h"
#include "bx/bx.h" #include "bx/bx.h"
#include "bx/filepath.h" #include "bx/filepath.h"
#include "bx/math.h"
#include "bx/timer.h" #include "bx/timer.h"
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
#include <bimg/bimg.h> #include <bimg/bimg.h>
@@ -191,11 +190,21 @@ namespace Game
return handle; return handle;
} }
GameRendering* Instance = nullptr;
} // namespace } // namespace
GameRendering& GameRendering::Get()
{
assert(Instance != nullptr);
return *Instance;
}
void GameRendering::Setup() void GameRendering::Setup()
{ {
Log("--- RENDERING STARTUP ---"); Log("--- RENDERING STARTUP ---");
if (Instance != nullptr) Log("Warning, old rendering wasn't destroyed!");
Instance = this;
SharedData& shared = GetShared(); SharedData& shared = GetShared();
bgfx::Init init; bgfx::Init init;
@@ -229,8 +238,7 @@ namespace Game
Textures[0].Handle = Textures[0].Handle =
loadTexture(bx::FilePath{"models/body.dds"}, BGFX_TEXTURE_NONE | BGFX_SAMPLER_NONE, 0, nullptr, nullptr); loadTexture(bx::FilePath{"models/body.dds"}, BGFX_TEXTURE_NONE | BGFX_SAMPLER_NONE, 0, nullptr, nullptr);
Textures[0].SamplerHandle = DefaultSampler; Textures[0].SamplerHandle = DefaultSampler;
LoadMesh(Models[0], "models/cube.gltf"); LoadModels(Models, ModelCount);
LoadMesh(Models[1], "models/zurg.gltf");
Materials[0] = Materials[0] =
Material::LoadFromShader("vert", "frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle); Material::LoadFromShader("vert", "frag", MainViewID, Textures[0].Handle, Textures[0].SamplerHandle);
@@ -312,7 +320,24 @@ namespace Game
imguiBeginFrame(20); imguiBeginFrame(20);
ImGui_ImplSDL3_NewFrame(); ImGui_ImplSDL3_NewFrame();
ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode); 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.Update();
GetInstance().GameLevel.Render(MainViewID, Models, Materials); GetInstance().GameLevel.Render(MainViewID, Models, Materials);
@@ -348,6 +373,7 @@ namespace Game
ImGui_ImplSDL3_Shutdown(); ImGui_ImplSDL3_Shutdown();
imguiDestroy(); imguiDestroy();
bgfx::shutdown(); bgfx::shutdown();
Instance = nullptr;
} }
Material Material::LoadFromShader( Material Material::LoadFromShader(
@@ -368,4 +394,18 @@ namespace Game
mat.ViewID = view; mat.ViewID = view;
return mat; 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 } // namespace Game
+18 -1
View File
@@ -32,6 +32,7 @@ namespace Game
bgfx::VertexBufferHandle VertexBuffer; bgfx::VertexBufferHandle VertexBuffer;
bgfx::IndexBufferHandle IndexBuffer; bgfx::IndexBufferHandle IndexBuffer;
bgfx::VertexLayout VertLayout; bgfx::VertexLayout VertLayout;
uint32_t AssetHandle = UINT16_MAX;
}; };
struct Material struct Material
@@ -54,13 +55,28 @@ namespace Game
bgfx::UniformHandle sampler = BGFX_INVALID_HANDLE); bgfx::UniformHandle sampler = BGFX_INVALID_HANDLE);
}; };
enum class UIVisibilityState
{
None,
Game,
Debug,
};
class GameRendering class GameRendering
{ {
public:
static constexpr uint32_t MaxModels = 64;
static GameRendering& Get();
public:
UIVisibilityState UIVisible = UIVisibilityState::Game;
private: private:
bgfx::UniformHandle DefaultSampler; bgfx::UniformHandle DefaultSampler;
Texture Textures[8]; Texture Textures[8];
Material Materials[8]; Material Materials[8];
Model Models[8]; uint32_t ModelCount = 0;
Model Models[MaxModels];
int32_t LastWidth = 0; int32_t LastWidth = 0;
int32_t LastHeight = 0; int32_t LastHeight = 0;
uint32_t ResetFlags = BGFX_RESET_VSYNC; uint32_t ResetFlags = BGFX_RESET_VSYNC;
@@ -70,5 +86,6 @@ namespace Game
void Setup(); void Setup();
void Update(); void Update();
void Shutdown(); void Shutdown();
uint16_t GetModelHandleFromPath(const char* path);
}; };
} // namespace Game } // namespace Game
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.