Compare commits
3 Commits
d7ed08eb08
...
60f1e72144
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60f1e72144 | ||
|
|
d3dcec1458 | ||
|
|
369b994755 |
1
src/.gitattributes
vendored
Normal file
1
src/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.glb filter=lfs diff=lfs merge=lfs -text
|
||||||
@@ -46,5 +46,7 @@ namespace Game
|
|||||||
Time Time;
|
Time Time;
|
||||||
PlayerData Player;
|
PlayerData Player;
|
||||||
Level GameLevel;
|
Level GameLevel;
|
||||||
|
uint64_t ImguiIniSize = 0;
|
||||||
|
char ImguiIni[4096]{0};
|
||||||
};
|
};
|
||||||
} // namespace Game
|
} // namespace Game
|
||||||
|
|||||||
@@ -3,9 +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 "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>
|
||||||
@@ -15,7 +18,9 @@ namespace Game
|
|||||||
void EntityRenderData::Render(const Model* models, const Material* materials)
|
void EntityRenderData::Render(const Model* models, const Material* materials)
|
||||||
{
|
{
|
||||||
if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return;
|
if (ModelHandle == UINT16_MAX || MaterialHandle == UINT16_MAX) return;
|
||||||
|
if (!Visible) return;
|
||||||
|
|
||||||
|
// Log("%u", ModelHandle);
|
||||||
Transform.UpdateMatrix();
|
Transform.UpdateMatrix();
|
||||||
bgfx::setTransform(Transform.M.M);
|
bgfx::setTransform(Transform.M.M);
|
||||||
|
|
||||||
@@ -42,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
|
||||||
|
|
||||||
@@ -52,26 +58,37 @@ namespace Game
|
|||||||
bool needReset = false;
|
bool needReset = false;
|
||||||
needReset |= Cubes.Setup(storagePtr, needReset);
|
needReset |= Cubes.Setup(storagePtr, needReset);
|
||||||
needReset |= Tests.Setup(storagePtr, needReset);
|
needReset |= Tests.Setup(storagePtr, needReset);
|
||||||
|
needReset |= PuzzleTiles.Setup(storagePtr, needReset);
|
||||||
|
|
||||||
|
PuzzleData.Setup();
|
||||||
|
|
||||||
if (Cubes.Count == 0)
|
if (Cubes.Count == 0)
|
||||||
{
|
{
|
||||||
for (uint32_t yy = 0; yy < 11; ++yy)
|
for (uint32_t yy = 0; yy < 11; ++yy)
|
||||||
{
|
{
|
||||||
for (uint32_t xx = 0; xx < 11; ++xx)
|
for (uint32_t xx = 0; xx < 11; ++xx)
|
||||||
{
|
{
|
||||||
Cube* c = Cubes.New();
|
Cube* c = Cubes.Get(Cubes.New());
|
||||||
if (c)
|
if (c)
|
||||||
{
|
{
|
||||||
c->TestX = xx;
|
c->TestX = xx;
|
||||||
c->TestY = yy;
|
c->TestY = yy;
|
||||||
|
c->Setup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Cubes.New(); // Floor
|
||||||
Cube* floor = Cubes.New();
|
|
||||||
}
|
}
|
||||||
if (Tests.Count == 0)
|
if (Tests.Count == 0)
|
||||||
{
|
{
|
||||||
Tests.New();
|
Tests.Get(Tests.New())->Setup();
|
||||||
|
}
|
||||||
|
if (PuzzleTiles.Count == 0)
|
||||||
|
{
|
||||||
|
for (uint32_t puzI = 0; puzI < BX_COUNTOF(Puzzles); ++puzI)
|
||||||
|
{
|
||||||
|
Puzzles[puzI].Setup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdatePlayerInputMode();
|
UpdatePlayerInputMode();
|
||||||
@@ -82,6 +99,7 @@ namespace Game
|
|||||||
START_PERF();
|
START_PERF();
|
||||||
PlayerData& player = GetInstance().Player;
|
PlayerData& player = GetInstance().Player;
|
||||||
|
|
||||||
|
// Input
|
||||||
float delta = GetInstance().Time.Delta;
|
float delta = GetInstance().Time.Delta;
|
||||||
delta = 1.0f / 144.0f;
|
delta = 1.0f / 144.0f;
|
||||||
constexpr float moveSpeed = 10.0f;
|
constexpr float moveSpeed = 10.0f;
|
||||||
@@ -138,8 +156,18 @@ namespace Game
|
|||||||
player.PlayerCamTransform.RotateLocal({player.WalkXRot, 0.0f, 0.0f});
|
player.PlayerCamTransform.RotateLocal({player.WalkXRot, 0.0f, 0.0f});
|
||||||
}
|
}
|
||||||
|
|
||||||
Cubes.Update();
|
// Cubes
|
||||||
Tests.Update();
|
for (uint16_t i = 0; i < Cubes.Count; ++i)
|
||||||
|
{
|
||||||
|
Cubes.Get({i})->Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Puzzle tiles
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(Puzzles); ++i)
|
||||||
|
{
|
||||||
|
Puzzles[i].Update();
|
||||||
|
}
|
||||||
|
|
||||||
END_PERF(GetShared().Window.PerfCounters, PerfCounterType::GameLevelUpdate, GetShared().Window.FrameCounter);
|
END_PERF(GetShared().Window.PerfCounters, PerfCounterType::GameLevelUpdate, GetShared().Window.FrameCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,21 +188,24 @@ namespace Game
|
|||||||
{
|
{
|
||||||
player.FreeflyCamTransform.UpdateMatrix();
|
player.FreeflyCamTransform.UpdateMatrix();
|
||||||
bgfx::setViewTransform(viewId, player.FreeflyCamTransform.M.M, proj);
|
bgfx::setViewTransform(viewId, player.FreeflyCamTransform.M.M, proj);
|
||||||
|
bgfx::dbgTextPrintf(1, 0, 0b1100, "NOCLIP");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
player.PlayerCamTransform.UpdateMatrix();
|
player.PlayerCamTransform.UpdateMatrix();
|
||||||
bgfx::setViewTransform(viewId, player.PlayerCamTransform.M.M, proj);
|
bgfx::setViewTransform(viewId, player.PlayerCamTransform.M.M, proj);
|
||||||
|
bgfx::dbgTextPrintf(1, 0, 0b1100, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Cubes.Render(models, materials);
|
// Cubes.Render(models, materials);
|
||||||
Tests.Render(models, materials);
|
Tests.Render(models, materials);
|
||||||
|
PuzzleTiles.Render(models, materials);
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
@@ -200,13 +231,45 @@ 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};
|
||||||
}
|
|
||||||
|
|
||||||
void TestEntity::Update()
|
|
||||||
{
|
|
||||||
EData.TestColor[0] = 0.0f;
|
EData.TestColor[0] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldPuzzle::Setup()
|
||||||
|
{
|
||||||
|
Data.PlacedCardCount = 16;
|
||||||
|
for (int32_t i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
Data.PlacedCards[i].RefCard = {0};
|
||||||
|
Data.PlacedCards[i].Position = {int8_t(i % 4), int8_t(i / 4)};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
||||||
|
{
|
||||||
|
const Puzzle::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
||||||
|
auto& tiles = GetInstance().GameLevel.PuzzleTiles;
|
||||||
|
TileHandles[cardI] = tiles.New();
|
||||||
|
bx::Vec3 Pos = {
|
||||||
|
WorldPosition.x + card.Position.X * WorldCardSize.x,
|
||||||
|
WorldPosition.y,
|
||||||
|
WorldPosition.z + card.Position.Y * WorldCardSize.y,
|
||||||
|
};
|
||||||
|
auto& tile = *tiles.Get(TileHandles[cardI]);
|
||||||
|
tile.EData.Transform.Position = Pos;
|
||||||
|
tile.EData.MaterialHandle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WorldPuzzle::Update()
|
||||||
|
{
|
||||||
|
for (int32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
||||||
|
{
|
||||||
|
Puzzle::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
||||||
|
if (!card.RefCard.IsValid()) continue;
|
||||||
|
const Puzzle::StaticPuzzleCard& cData = Puzzle::StaticPuzzleData::Get().GetCard(card.RefCard);
|
||||||
|
GetInstance().GameLevel.PuzzleTiles.Get(TileHandles[cardI])->EData.ModelHandle = cData.ModelHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace Game
|
} // namespace Game
|
||||||
|
|||||||
@@ -2,10 +2,17 @@
|
|||||||
#include "../engine/Shared.h"
|
#include "../engine/Shared.h"
|
||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Puzzle.h"
|
||||||
#include "rendering/Rendering.h"
|
#include "rendering/Rendering.h"
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define ENTITY_HANDLE(X) \
|
||||||
|
struct X \
|
||||||
|
{ \
|
||||||
|
uint16_t Idx = UINT16_MAX; \
|
||||||
|
};
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
struct EntityRenderData
|
struct EntityRenderData
|
||||||
@@ -14,10 +21,12 @@ namespace Game
|
|||||||
Transform Transform;
|
Transform Transform;
|
||||||
uint16_t MaterialHandle = UINT16_MAX;
|
uint16_t MaterialHandle = UINT16_MAX;
|
||||||
uint16_t ModelHandle = UINT16_MAX;
|
uint16_t ModelHandle = UINT16_MAX;
|
||||||
|
bool Visible = true;
|
||||||
|
|
||||||
void Render(const Model* models, const Material* materials);
|
void Render(const Model* models, const Material* materials);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(CubeHandle);
|
||||||
struct Cube
|
struct Cube
|
||||||
{
|
{
|
||||||
int32_t TestX = -1;
|
int32_t TestX = -1;
|
||||||
@@ -28,15 +37,21 @@ namespace Game
|
|||||||
void Update();
|
void Update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ENTITY_HANDLE(TestEntityHandle);
|
||||||
struct TestEntity
|
struct TestEntity
|
||||||
{
|
{
|
||||||
EntityRenderData EData;
|
EntityRenderData EData;
|
||||||
|
|
||||||
void Setup();
|
void Setup();
|
||||||
void Update();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, uint32_t C> class EntityManager
|
ENTITY_HANDLE(PuzzleTileEntityHandle);
|
||||||
|
struct PuzzleTileEntity
|
||||||
|
{
|
||||||
|
EntityRenderData EData;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, typename HandleT, uint32_t C> class EntityManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
uint16_t Count = 0;
|
uint16_t Count = 0;
|
||||||
@@ -59,58 +74,66 @@ namespace Game
|
|||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* New()
|
HandleT New()
|
||||||
{
|
{
|
||||||
if (Data == nullptr)
|
if (Data == nullptr)
|
||||||
{
|
{
|
||||||
Log("Accessed EntityManager before setup!");
|
Log("Accessed EntityManager before setup!");
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
if (Count >= C)
|
if (Count >= C)
|
||||||
{
|
{
|
||||||
Log("Too many entities!");
|
Log("Too many entities!");
|
||||||
return nullptr;
|
return {};
|
||||||
}
|
}
|
||||||
Data[Count] = {};
|
Data[Count] = {};
|
||||||
Data[Count].Setup();
|
HandleT H;
|
||||||
T* result = &Data[Count];
|
H.Idx = Count;
|
||||||
++Count;
|
++Count;
|
||||||
return result;
|
return H;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* Get(uint16_t idx)
|
T* Get(HandleT handle)
|
||||||
{
|
{
|
||||||
if (idx > Count)
|
if (handle.Idx > Count)
|
||||||
{
|
{
|
||||||
Log("OOB Access!");
|
Log("OOB Access!");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return &Data[idx];
|
return &Data[handle.Idx];
|
||||||
}
|
|
||||||
|
|
||||||
void Update()
|
|
||||||
{
|
|
||||||
for (uint32_t i = 0; i < Count; ++i)
|
|
||||||
{
|
|
||||||
Data[i].Update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render(const Model* models, const Material* materials)
|
void Render(const Model* models, const Material* materials)
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < Count; ++i)
|
for (uint16_t i = 0; i < Count; ++i)
|
||||||
{
|
{
|
||||||
T* c = Get(i);
|
T* c = Get({i});
|
||||||
if (c) c->EData.Render(models, materials);
|
if (c) c->EData.Render(models, materials);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WorldPuzzle
|
||||||
|
{
|
||||||
|
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
|
||||||
|
Puzzle::PuzzleData Data;
|
||||||
|
Vec3 WorldPosition;
|
||||||
|
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
|
|
||||||
|
void Setup();
|
||||||
|
void Update();
|
||||||
|
};
|
||||||
|
|
||||||
class Level
|
class Level
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EntityManager<Cube, 1024> Cubes;
|
EntityManager<Cube, CubeHandle, 1024> Cubes;
|
||||||
EntityManager<TestEntity, 32> Tests;
|
EntityManager<TestEntity, TestEntityHandle, 32> Tests;
|
||||||
|
EntityManager<PuzzleTileEntity, PuzzleTileEntityHandle, 1024> PuzzleTiles;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Puzzle::StaticPuzzleData PuzzleData;
|
||||||
|
WorldPuzzle Puzzles[1];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void Setup(GameData& data);
|
void Setup(GameData& data);
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
|
#include "Log.h"
|
||||||
#include "Puzzle.h"
|
#include "Puzzle.h"
|
||||||
|
#include "rendering/Rendering.h"
|
||||||
|
|
||||||
|
#include "bx/bx.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -9,10 +13,33 @@ namespace
|
|||||||
{0, 1},
|
{0, 1},
|
||||||
{1, 0},
|
{1, 0},
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
Puzzle::StaticPuzzleData* StaticDataInstance = nullptr;
|
||||||
|
} // namespace
|
||||||
|
|
||||||
namespace Puzzle
|
namespace Puzzle
|
||||||
{
|
{
|
||||||
|
void StaticPuzzleData::Setup()
|
||||||
|
{
|
||||||
|
StaticDataInstance = this;
|
||||||
|
Log("Setting up static puzzle data");
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(Cards); ++i)
|
||||||
|
{
|
||||||
|
Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticPuzzleData& StaticPuzzleData::Get()
|
||||||
|
{
|
||||||
|
assert(StaticDataInstance != nullptr);
|
||||||
|
return *StaticDataInstance;
|
||||||
|
}
|
||||||
|
const StaticPuzzleCard& StaticPuzzleData::GetCard(StaticPuzzleCardHandle H) const
|
||||||
|
{
|
||||||
|
assert(H.IsValid());
|
||||||
|
return Cards[H.Idx];
|
||||||
|
}
|
||||||
|
|
||||||
bool PuzzleNode::HasElement(PuzzleElementType search) const
|
bool PuzzleNode::HasElement(PuzzleElementType search) const
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
||||||
@@ -37,11 +64,29 @@ namespace Puzzle
|
|||||||
return MaxAvailableCount - UsedCount;
|
return MaxAvailableCount - UsedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PuzzleNode& PuzzleData::GetNodeAt(PuzPos pos) const
|
||||||
|
{
|
||||||
|
assert(pos.X < Config::MaxPuzzleSizeCards && pos.Y < Config::MaxPuzzleSizeCards && pos.X >= 0 && pos.Y >= 0);
|
||||||
|
return PlacedNodes[pos.Y * Config::MaxPuzzleSizeCards + pos.X];
|
||||||
|
}
|
||||||
|
|
||||||
|
PuzzleElementType PuzzleData::GetElementAt(ElemPos pos) const
|
||||||
|
{
|
||||||
|
assert(pos.ElemIdx < Config::MaxElementsPerTile);
|
||||||
|
const PuzzleNode& node = GetNodeAt(pos.Position);
|
||||||
|
return node.PlacedTypes[pos.ElemIdx];
|
||||||
|
}
|
||||||
|
|
||||||
bool PuzzleSolver::IsPuzzleSolved(const PuzzleData& puzzle)
|
bool PuzzleSolver::IsPuzzleSolved(const PuzzleData& puzzle)
|
||||||
{
|
{
|
||||||
bool IsSolved = true;
|
bool IsSolved = true;
|
||||||
for (uint32_t i = 0; i < puzzle.GoalPositionCount; ++i)
|
for (uint32_t i = 0; i < puzzle.GoalPositionCount; ++i)
|
||||||
{
|
{
|
||||||
|
if (!IsExitSatisfied(puzzle, puzzle.GoalPositions[i]))
|
||||||
|
{
|
||||||
|
IsSolved = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return IsSolved;
|
return IsSolved;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,25 @@ namespace Puzzle
|
|||||||
struct StaticPuzzleCard
|
struct StaticPuzzleCard
|
||||||
{
|
{
|
||||||
PuzzleNode Nodes[Config::NodesPerCard];
|
PuzzleNode Nodes[Config::NodesPerCard];
|
||||||
|
uint16_t ModelHandle = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StaticPuzzleCardHandle
|
struct StaticPuzzleCardHandle
|
||||||
{
|
{
|
||||||
uint16_t Idx = UINT16_MAX;
|
uint16_t Idx = UINT16_MAX;
|
||||||
|
bool IsValid()
|
||||||
|
{
|
||||||
|
return Idx != UINT16_MAX;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StaticPuzzleData
|
||||||
|
{
|
||||||
|
StaticPuzzleCard Cards[64];
|
||||||
|
|
||||||
|
void Setup();
|
||||||
|
static StaticPuzzleData& Get();
|
||||||
|
const StaticPuzzleCard& GetCard(StaticPuzzleCardHandle H) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlacedPuzzleCard
|
struct PlacedPuzzleCard
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
#include "SDL3/SDL_events.h"
|
#include "SDL3/SDL_events.h"
|
||||||
#include "backends/imgui_impl_sdl3.h"
|
#include "backends/imgui_impl_sdl3.h"
|
||||||
#include "bgfx/defines.h"
|
#include "bgfx/defines.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>
|
||||||
@@ -190,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;
|
||||||
@@ -228,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);
|
||||||
@@ -250,9 +259,15 @@ namespace Game
|
|||||||
// platIO.Platform_SetWindowSize = TODO;
|
// platIO.Platform_SetWindowSize = TODO;
|
||||||
// platIO.Platform_RenderWindow = TODO;
|
// platIO.Platform_RenderWindow = TODO;
|
||||||
|
|
||||||
if (!GetInstance().IsInitialized)
|
GameInstance& inst = GetInstance();
|
||||||
|
if (!inst.IsInitialized)
|
||||||
{
|
{
|
||||||
GetInstance().Time.StartTime = bx::getHPCounter();
|
inst.Time.StartTime = bx::getHPCounter();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inst.ImguiIniSize > 0)
|
||||||
|
{
|
||||||
|
ImGui::LoadIniSettingsFromMemory(inst.ImguiIni, inst.ImguiIniSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,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);
|
||||||
@@ -333,9 +365,15 @@ namespace Game
|
|||||||
|
|
||||||
void GameRendering::Shutdown()
|
void GameRendering::Shutdown()
|
||||||
{
|
{
|
||||||
|
Log("--- RENDERING_SHUTDOWN ---");
|
||||||
|
const char* iniData = ImGui::SaveIniSettingsToMemory(reinterpret_cast<uint64_t*>(&GetInstance().ImguiIniSize));
|
||||||
|
assert(GetInstance().ImguiIniSize <= BX_COUNTOF(GameInstance::ImguiIni));
|
||||||
|
bx::memCopy(
|
||||||
|
GetInstance().ImguiIni, iniData, bx::min(GetInstance().ImguiIniSize, BX_COUNTOF(GameInstance::ImguiIni)));
|
||||||
ImGui_ImplSDL3_Shutdown();
|
ImGui_ImplSDL3_Shutdown();
|
||||||
imguiDestroy();
|
imguiDestroy();
|
||||||
bgfx::shutdown();
|
bgfx::shutdown();
|
||||||
|
Instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Material Material::LoadFromShader(
|
Material Material::LoadFromShader(
|
||||||
@@ -356,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
BIN
src/models/ConcretePlane.glb
LFS
Normal file
BIN
src/models/ConcretePlane.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/blocked.glb
LFS
Normal file
BIN
src/models/blocked.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/e!.glb
LFS
Normal file
BIN
src/models/e!.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/e+.glb
LFS
Normal file
BIN
src/models/e+.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w corner long.glb
LFS
Normal file
BIN
src/models/w corner long.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w corner short.glb
LFS
Normal file
BIN
src/models/w corner short.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w straight.glb
LFS
Normal file
BIN
src/models/w straight.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w! corner short.glb
LFS
Normal file
BIN
src/models/w! corner short.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w! straight.glb
LFS
Normal file
BIN
src/models/w! straight.glb
LFS
Normal file
Binary file not shown.
BIN
src/models/w+ straight.glb
LFS
Normal file
BIN
src/models/w+ straight.glb
LFS
Normal file
Binary file not shown.
Reference in New Issue
Block a user