761 lines
29 KiB
C++
761 lines
29 KiB
C++
#include "../gen/Def.h"
|
|
#include "Gen.h"
|
|
#include "Global.h"
|
|
#include "Instance.h"
|
|
#include "Log.h"
|
|
#include "Mesh.h"
|
|
#include "Puzzle.h"
|
|
#include "Tools.h"
|
|
|
|
#include "bgfx/bgfx.h"
|
|
#include "bx/filepath.h"
|
|
#include "bx/string.h"
|
|
#include "bx/timer.h"
|
|
#include "rendering/Rendering.h"
|
|
#include <imgui.h>
|
|
#include <tracy/Tracy.hpp>
|
|
|
|
using namespace Gen;
|
|
|
|
namespace
|
|
{
|
|
constexpr int32_t FrameTimeBufSize = 512;
|
|
int64_t FrameTimes[FrameTimeBufSize]{0};
|
|
int32_t FrameTimeIdx = 0;
|
|
} // namespace
|
|
|
|
namespace Tools
|
|
{
|
|
const char* GetAssetPath(Gen::AssetHandle assetHandle)
|
|
{
|
|
const auto& inst = Game::GetInstance();
|
|
for (int32_t j = 0; j < inst.DebugData.AssetCount; ++j)
|
|
{
|
|
if (inst.DebugData.AssetHandles[j] == assetHandle)
|
|
{
|
|
return inst.DebugData.AssetHandlePaths[j];
|
|
}
|
|
}
|
|
return "---";
|
|
}
|
|
|
|
bool EntityDataSettings(Gen::SavedEntityRenderData& data)
|
|
{
|
|
ImGui::PushID(&data);
|
|
bool changed = false;
|
|
changed |= ModelDropdown(data.Model);
|
|
changed |= MaterialDropdown(data.Material);
|
|
changed |= TextureDropdown(data.Texture);
|
|
changed |= TransformUI(data.TF);
|
|
changed |= ImGui::Checkbox("Visible", &data.Visible);
|
|
changed |= ImGui::ColorEdit4("Color 1", &data.BaseColor.x);
|
|
changed |= ImGui::ColorEdit4("Color 2", &data.HighlightColor.x);
|
|
ImGui::PopID();
|
|
return changed;
|
|
}
|
|
|
|
bool ModelDropdown(Gen::ModelHandle& modelHandle, const char* title)
|
|
{
|
|
bool changed = false;
|
|
auto& R = Game::GameRendering::Get();
|
|
const char* assetName = GetAssetPath(modelHandle.Asset);
|
|
if (ImGui::BeginCombo(title, assetName))
|
|
{
|
|
for (int32_t i = 0; i < R.ModelCount; ++i)
|
|
{
|
|
if (ImGui::Selectable(GetAssetPath(R.Models[i].Handle.Asset), i == modelHandle.ModelIdx))
|
|
{
|
|
modelHandle = R.Models[i].Handle;
|
|
changed = true;
|
|
}
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
return changed;
|
|
}
|
|
|
|
bool TextureDropdown(Gen::TextureHandle& texHandle, const char* title)
|
|
{
|
|
bool changed = false;
|
|
auto& R = Game::GameRendering::Get();
|
|
const char* name = GetAssetPath(texHandle.Asset);
|
|
if (ImGui::BeginCombo(title, name))
|
|
{
|
|
for (int32_t i = 0; i < R.MaxTextures; ++i)
|
|
{
|
|
if (!IsValid(R.Textures[i].TexHandle)) continue;
|
|
ImGui::PushID(i);
|
|
ImVec2 pos = ImGui::GetCursorScreenPos();
|
|
if (ImGui::Selectable("", i == texHandle.TextureIdx, ImGuiSelectableFlags_AllowOverlap, {0, 64}))
|
|
{
|
|
texHandle = R.Textures[i].TexHandle;
|
|
changed = true;
|
|
}
|
|
ImGui::SetCursorScreenPos(pos);
|
|
ImGui::Image(R.Textures[i].RenderHandle.idx, {64, 64});
|
|
ImGui::SameLine();
|
|
ImGui::Text("%s", GetAssetPath(R.Textures[i].TexHandle.Asset));
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
return changed;
|
|
}
|
|
|
|
bool MaterialDropdown(Gen::EMaterial::Enum& material)
|
|
{
|
|
bool changed = false;
|
|
const char* selectedText = "---";
|
|
if (material < Gen::EMaterial::EntryCount)
|
|
{
|
|
selectedText = Gen::EMaterial::EntryNames[material];
|
|
}
|
|
|
|
if (ImGui::BeginCombo("Material", selectedText))
|
|
{
|
|
for (int32_t i = 0; i < Gen::EMaterial::EntryCount; ++i)
|
|
{
|
|
if (ImGui::Selectable(Gen::EMaterial::EntryNames[i], i == material))
|
|
{
|
|
material = (Gen::EMaterial::Enum)i;
|
|
changed = true;
|
|
}
|
|
}
|
|
ImGui::EndCombo();
|
|
}
|
|
return changed;
|
|
}
|
|
|
|
constexpr const char* UnitStrings[]{
|
|
"b",
|
|
"kb",
|
|
"mb",
|
|
"gb",
|
|
};
|
|
const char* GetUnitString(uint64_t byteCount, uint64_t& outCount)
|
|
{
|
|
outCount = byteCount;
|
|
int32_t strIdx = 0;
|
|
for (int32_t i = 0; i < BX_COUNTOF(UnitStrings); ++i)
|
|
{
|
|
if (outCount < 1024) break;
|
|
++strIdx;
|
|
outCount /= 1024;
|
|
}
|
|
return UnitStrings[strIdx];
|
|
}
|
|
|
|
void ProgressBar(const char* title, uint64_t current, uint64_t max)
|
|
{
|
|
ImGui::PushID(title);
|
|
float percent = static_cast<double>(current) / static_cast<double>(max);
|
|
ImVec2 startPos = ImGui::GetCursorScreenPos();
|
|
char content[128]{0};
|
|
|
|
uint64_t currentUnit = 0;
|
|
const char* currentUnitStr = GetUnitString(current, currentUnit);
|
|
uint64_t maxUnit = 0;
|
|
const char* maxUnitStr = GetUnitString(max, maxUnit);
|
|
|
|
bx::snprintf(content,
|
|
sizeof(content),
|
|
"%s: %u %s/%u %s (%.2f%%)",
|
|
title,
|
|
currentUnit,
|
|
currentUnitStr,
|
|
maxUnit,
|
|
maxUnitStr,
|
|
percent);
|
|
ImGui::Text("%s", content);
|
|
ImGui::PopID();
|
|
}
|
|
|
|
bool TransformUI(Gen::Transform& transform)
|
|
{
|
|
bool changed = false;
|
|
changed |= ImGui::DragFloat3("Pos", &transform.Position.x, 0.1f);
|
|
Vec3 euler = EulerFromRotation(transform.Rotation);
|
|
if (ImGui::DragFloat3("Rot", &euler.x, 0.1f))
|
|
{
|
|
transform.Rotation = RotationFromEuler(euler);
|
|
changed = true;
|
|
}
|
|
changed |= ImGui::DragFloat3("Scale", &transform.Scale.x, 0.01f);
|
|
return changed;
|
|
}
|
|
|
|
void RenderLogUI()
|
|
{
|
|
auto& time = Game::GetInstance().Time;
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
|
|
if (ImGui::Begin("Log"))
|
|
{
|
|
ImGui::Checkbox("Shorten File Names", &debug.ShortenLogFileNames);
|
|
ImGui::BeginTable("tbl",
|
|
4,
|
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit |
|
|
ImGuiTableFlags_RowBg);
|
|
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_NoResize);
|
|
ImGui::TableSetupColumn("Log");
|
|
ImGui::TableSetupColumn("Line", ImGuiTableColumnFlags_NoResize);
|
|
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_NoResize);
|
|
ImGui::TableHeadersRow();
|
|
|
|
auto& logs = GetLogHistory();
|
|
|
|
int32_t lineCount = bx::min(100, LogInternal::LogHistorySize);
|
|
for (int32_t i = 0; i < lineCount; ++i)
|
|
{
|
|
int32_t idx = logs.WriteIdx - i - 1;
|
|
if (idx < 0) idx += LogInternal::LogHistorySize;
|
|
const char* line = &logs.LogBuffer[idx * LogInternal::MaxLineSize];
|
|
if (line[0] != 0)
|
|
{
|
|
int64_t timeOffset = logs.WriteTime[idx] - time.StartTime;
|
|
double writeTime = (double)timeOffset / bx::getHPFrequency();
|
|
uint32_t fileLine = logs.LineBuffer[idx];
|
|
const char* filePath = &logs.FileBuffer[idx * LogInternal::MaxLineSize];
|
|
const char* filePathRes =
|
|
debug.ShortenLogFileNames ? bx::FilePath{filePath}.getFileName().getPtr() : filePath;
|
|
|
|
ImGui::TableNextRow();
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%.01f", writeTime);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%s", line);
|
|
ImGui::SetItemTooltip("%f\n%s%s:%u", writeTime, line, filePath, fileLine);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%u", fileLine);
|
|
|
|
ImGui::TableNextColumn();
|
|
ImGui::Text("%s", filePathRes);
|
|
|
|
if (i > 0) ImGui::PopStyleColor(2);
|
|
ImVec4 bgCol = {0.0f, 0.0f, 0.0f, 1.0f};
|
|
if (logs.WriteType[idx] == ELogType::Warn)
|
|
bgCol = {0.2f, 0.2f, 0.0f, 1.0f};
|
|
else if (logs.WriteType[idx] == ELogType::Error)
|
|
bgCol = {0.2f, 0.0f, 0.0f, 1.0f};
|
|
ImGui::PushStyleColor(ImGuiCol_TableRowBg, bgCol);
|
|
ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, bgCol);
|
|
}
|
|
}
|
|
|
|
ImGui::EndTable();
|
|
|
|
if (lineCount > 0) ImGui::PopStyleColor(2);
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderRenderSettingsUI(Game::GameRendering& rendering)
|
|
{
|
|
auto& time = Game::GetInstance().Time;
|
|
auto& shared = Game::GetShared();
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
auto& level = Game::GetInstance().GameLevel;
|
|
auto& player = Game::GetInstance().Player;
|
|
|
|
if (ImGui::Begin("Rendering"))
|
|
{
|
|
if (rendering.LastShaderLoadTime >= 0.0f)
|
|
{
|
|
ImGui::TextColored({0.2f, 0.9f, 0.2f, 1.0f},
|
|
"Shader loaded %.0f seconds ago",
|
|
time.Now - rendering.LastShaderLoadTime);
|
|
}
|
|
else
|
|
{
|
|
ImGui::TextColored({0.9f, 0.2f, 0.2f, 1.0f}, "Shader load Failiure!");
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Reload Level"))
|
|
{
|
|
level = {};
|
|
level.Setup(shared.Game);
|
|
}
|
|
|
|
ImGui::DragFloat3("Player Pos", &player.PlayerCamTransform.Position.x);
|
|
ImGui::DragFloat3("Puz0 Pos", &level.Puzzles[0].WorldPosition.x);
|
|
ImGui::SliderFloat("Mouse Sensitivity", &player.MouseSensitivity, 0.1f, 5.0f);
|
|
ImGui::SliderFloat("Player Speed", &player.MovementSpeed, 1.0f, 30.0f);
|
|
|
|
ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo);
|
|
ImGui::Checkbox("Show Stats", &debug.ShowStats);
|
|
if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo);
|
|
|
|
ImGui::Separator();
|
|
|
|
if (ImGui::TreeNodeEx("Entity Groups"))
|
|
{
|
|
ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled);
|
|
ImGui::Checkbox("Tests", &level.Tests.IsEnabled);
|
|
ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled);
|
|
ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled);
|
|
ImGui::Checkbox("Level", &level.LevelEntities.IsEnabled);
|
|
ImGui::TreePop();
|
|
}
|
|
|
|
bool uiconfigChanged = false;
|
|
if (ImGui::TreeNodeEx("Game Tablet"))
|
|
{
|
|
uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletBackgroundRenderData);
|
|
ImGui::Separator();
|
|
ImGui::Text("Status");
|
|
uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData);
|
|
uiconfigChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture, "Solved Texture");
|
|
uiconfigChanged |=
|
|
Tools::TextureDropdown(player.Config.TabletStatusNotSolvedTexture, "Not Solved Texture");
|
|
ImGui::Separator();
|
|
ImGui::Text("Reset");
|
|
uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletResetRenderData);
|
|
ImGui::TreePop();
|
|
}
|
|
|
|
if (ImGui::TreeNodeEx("Background Level"))
|
|
{
|
|
for (int32_t i = 0; i < BX_COUNTOF(player.Config.BackgroundLevelRenderData); ++i)
|
|
{
|
|
if (i > 0) ImGui::Separator();
|
|
uiconfigChanged |= Tools::EntityDataSettings(player.Config.BackgroundLevelRenderData[i]);
|
|
}
|
|
ImGui::TreePop();
|
|
}
|
|
|
|
if (uiconfigChanged)
|
|
{
|
|
Serializer s;
|
|
s.Init("game/data/static/uiconfig.dat", "UICO");
|
|
s.WriteT(player.Config);
|
|
s.Finish();
|
|
level.PuzzleUI.Reset();
|
|
level.ReloadLevelEntities();
|
|
}
|
|
|
|
if (ImGui::TreeNodeEx("Dithering"))
|
|
{
|
|
if (ImGui::Button("Dithergen"))
|
|
{
|
|
DitherGen(rendering.DitherTextures, rendering.DitherRecursion);
|
|
}
|
|
ImGui::SameLine();
|
|
ImGui::SliderInt("Recursion", &rendering.DitherRecursion, 1, 4);
|
|
ImGui::Text("%ux%ux%u",
|
|
rendering.DitherTextures.DitherTexWH,
|
|
rendering.DitherTextures.DitherTexWH,
|
|
rendering.DitherTextures.DitherTexDepth);
|
|
if (!isValid(rendering.DitherTextures.PreviewTex))
|
|
{
|
|
ImGui::Text("Invalid Texture");
|
|
}
|
|
else
|
|
{
|
|
ImGui::Image(
|
|
rendering.DitherTextures.PreviewTex.idx,
|
|
{(float)rendering.DitherTextures.DitherTexWH,
|
|
(float)rendering.DitherTextures.DitherTexWH * rendering.DitherTextures.DitherTexDepth});
|
|
}
|
|
if (isValid(rendering.DitherTextures.RampTex))
|
|
{
|
|
ImGui::Image(rendering.DitherTextures.RampTex.idx,
|
|
{BX_COUNTOF(rendering.DitherTextures.BrightnessRamp), 8});
|
|
}
|
|
ImGui::TreePop();
|
|
}
|
|
|
|
if (ImGui::TreeNodeEx("Shader log"))
|
|
{
|
|
ImGui::TextWrapped("%s", Game::GetShared().Dev.ShaderLog);
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderTexturesUI(Game::GameRendering& rendering)
|
|
{
|
|
if (ImGui::Begin("Textures"))
|
|
{
|
|
if (ImGui::Button("Reload"))
|
|
{
|
|
rendering.LoadTextures();
|
|
}
|
|
for (int32_t i = 0; i < rendering.MaxTextures; ++i)
|
|
{
|
|
if (!isValid(rendering.Textures[i].RenderHandle)) continue;
|
|
ImGui::Text("%i", i);
|
|
float width = bx::min<float>(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.width);
|
|
float height = bx::min<float>(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.height);
|
|
ImGui::Image(rendering.Textures[i].RenderHandle.idx, {width, height});
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderModelsUI(Game::GameRendering& rendering)
|
|
{
|
|
if (ImGui::Begin("Models"))
|
|
{
|
|
if (ImGui::Button("Reload"))
|
|
{
|
|
LoadModels(rendering.Models, rendering.ModelCount);
|
|
}
|
|
for (int32_t i = 0; i < rendering.ModelCount; ++i)
|
|
{
|
|
auto& mdl = rendering.Models[i];
|
|
if (bgfx::isValid(mdl.HeightMapTexture))
|
|
{
|
|
ImGui::Text("%s", mdl.Name);
|
|
ImGui::Image(mdl.HeightMapTexture.idx,
|
|
ImVec2{(float)Game::HeightMap::Height, (float)Game::HeightMap::Width});
|
|
}
|
|
else
|
|
{
|
|
ImGui::Text("Invalid Handle!");
|
|
}
|
|
ImGui::Spacing();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderPuzzlesUI()
|
|
{
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
auto& level = Game::GetInstance().GameLevel;
|
|
|
|
if (ImGui::Begin("Puzzles"))
|
|
{
|
|
char nameBuf[64]{0};
|
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
|
{
|
|
ImGui::PushID(i);
|
|
auto& puzzleData = level.Puzzles[i].Data;
|
|
|
|
bool isSelected = debug.SelectedDebugLevel == i;
|
|
ImGui::PushID("selectable");
|
|
bx::snprintf(nameBuf, sizeof(nameBuf), "%u: %s", i, puzzleData.PuzzleName);
|
|
if (ImGui::Selectable(nameBuf, isSelected))
|
|
{
|
|
debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i;
|
|
}
|
|
ImGui::DragFloat3("Pos", &level.Puzzles[i].WorldPosition.x);
|
|
ImGui::PopID();
|
|
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
|
|
if (debug.SelectedDebugLevel < BX_COUNTOF(level.Puzzles))
|
|
{
|
|
if (!Puzzle::RenderDebugUI(level.Puzzles[debug.SelectedDebugLevel].Data))
|
|
{
|
|
debug.SelectedDebugLevel = UINT16_MAX;
|
|
}
|
|
}
|
|
}
|
|
|
|
void RenderCardsUI(Game::GameRendering& rendering)
|
|
{
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
|
|
if (ImGui::Begin("Cards"))
|
|
{
|
|
Gen::StaticPuzzleData& staticData = Puzzle::GetStaticPuzzleData();
|
|
|
|
if (ImGui::Button("Save"))
|
|
{
|
|
Puzzle::SaveStaticPuzzleData();
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Reload"))
|
|
{
|
|
Puzzle::LoadStaticPuzzleData();
|
|
}
|
|
|
|
ImGui::Separator();
|
|
|
|
ImGui::ColorEdit3("Disabled Tint", &staticData.Visuals.DisabledCardTint.x);
|
|
ImGui::ColorEdit3("Tile Base Color", &staticData.Visuals.TileBaseColor.x);
|
|
ImGui::ColorEdit3("Tile Dot Color", &staticData.Visuals.TileDotColor.x);
|
|
|
|
for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i)
|
|
{
|
|
ImGui::Separator();
|
|
|
|
Gen::StaticPuzzleCard& card = staticData.Cards[i];
|
|
ImGui::PushID(i);
|
|
char cardName[64]{0};
|
|
bx::snprintf(cardName, sizeof(cardName), "%i", i);
|
|
ImGui::Selectable(cardName);
|
|
if (ImGui::BeginDragDropSource())
|
|
{
|
|
Puzzle::DrawCard(card, debug.DebugCardRotation, ImGui::GetCursorScreenPos());
|
|
ImGui::SetDragDropPayload("cardtype", &i, sizeof(i));
|
|
ImGui::EndDragDropSource();
|
|
}
|
|
|
|
Tools::ModelDropdown(card.BaseModelHandle);
|
|
Tools::TextureDropdown(card.ModelTextureHandle, "World Texture");
|
|
Tools::TextureDropdown(card.BoardTextureHandle, "UI Texture");
|
|
if (IsValid(card.BaseModelHandle))
|
|
{
|
|
auto& mdl = rendering.Models[card.BaseModelHandle.ModelIdx];
|
|
if (mdl.SocketCount > 0 && ImGui::TreeNodeEx("Slots"))
|
|
{
|
|
for (int32_t sIdx = 0; sIdx < mdl.SocketCount; ++sIdx)
|
|
{
|
|
Tools::ModelDropdown(card.Sockets[sIdx].Model, mdl.Sockets[sIdx].Name);
|
|
int val = card.Sockets[sIdx].ConnectionDirection;
|
|
ImGui::PushID(sIdx);
|
|
if (ImGui::Combo("Connection Direction", &val, "North\0East\0South\0West\0"))
|
|
{
|
|
card.Sockets[sIdx].ConnectionDirection = val;
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
|
|
ImGui::Text("Card");
|
|
for (int8_t y = 0; y < Puzzle::Config::CardSize; ++y)
|
|
{
|
|
ImGui::PushID(y);
|
|
for (int8_t x = 0; x < Puzzle::Config::CardSize; ++x)
|
|
{
|
|
if (x > 0) ImGui::SameLine();
|
|
ImGui::PushID(x);
|
|
auto& node = Puzzle::EditCardNodeAt(card, 0, x, y);
|
|
if (ImGui::Button(Gen::PuzzleElementType::ShortName[node], {26, 24}))
|
|
{
|
|
int32_t newVal = int32_t(node) + 1;
|
|
if (newVal >= Gen::PuzzleElementType::EntryCount)
|
|
{
|
|
newVal = 0;
|
|
}
|
|
node = Gen::PuzzleElementType::Enum(newVal);
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::PopID();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderEntitiesUI()
|
|
{
|
|
auto& level = Game::GetInstance().GameLevel;
|
|
|
|
if (ImGui::Begin("Entities"))
|
|
{
|
|
if (ImGui::TreeNodeEx("UIQuads"))
|
|
{
|
|
ImGui::Text("Count: %u", level.UIQuads.Count);
|
|
for (uint16_t i = 0; i < level.UIQuads.Count; ++i)
|
|
{
|
|
ImGui::Separator();
|
|
ImGui::PushID(i);
|
|
ImGui::Text("%u", i);
|
|
ImGui::SameLine();
|
|
auto& quad = level.UIQuads.Get({i});
|
|
ImGui::Checkbox("Visible", &quad.EData.Visible);
|
|
TextureDropdown(quad.EData.TextureHandle);
|
|
MaterialDropdown(quad.EData.MaterialHandle);
|
|
ImGui::DragFloat3("Pos", &quad.EData.Transform.Position.x);
|
|
ImGui::DragFloat3("UI Pos", &quad.UIPos.x);
|
|
ImGui::Text("RenderID: %i", quad.EData.RenderID);
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::TreePop();
|
|
}
|
|
if (ImGui::TreeNodeEx("Level"))
|
|
{
|
|
ImGui::Text("Count: %u", level.LevelEntities.Count);
|
|
for (uint16_t i = 0; i < level.LevelEntities.Count; ++i)
|
|
{
|
|
ImGui::Separator();
|
|
ImGui::PushID(i);
|
|
ImGui::Text("%u", i);
|
|
ImGui::SameLine();
|
|
auto& levelEnt = level.LevelEntities.Get({i});
|
|
ImGui::Checkbox("Visible", &levelEnt.EData.Visible);
|
|
TextureDropdown(levelEnt.EData.TextureHandle);
|
|
MaterialDropdown(levelEnt.EData.MaterialHandle);
|
|
ImGui::DragFloat3("Pos", &levelEnt.EData.Transform.Position.x);
|
|
ImGui::Text("RenderID: %i", levelEnt.EData.RenderID);
|
|
ImGui::PopID();
|
|
}
|
|
ImGui::TreePop();
|
|
}
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void RenderStatsUI()
|
|
{
|
|
auto& time = Game::GetInstance().Time;
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
|
|
if (debug.ShowStats)
|
|
{
|
|
ImGui::SetNextWindowPos({0, 0});
|
|
if (ImGui::Begin("Stats",
|
|
nullptr,
|
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoInputs |
|
|
ImGuiWindowFlags_AlwaysAutoResize))
|
|
{
|
|
if (Game::GetInstance().Player.CameraM == Game::CameraMode::Freefly)
|
|
{
|
|
ImGui::PushStyleColor(ImGuiCol_Text, {0.8f, 0.1f, 0.1f, 1.0f});
|
|
ImGui::Text("NOCLIP");
|
|
ImGui::PopStyleColor();
|
|
}
|
|
ImGui::Text("Delta: %.01fms", time.Delta * 1000);
|
|
ImGui::Text("FPS: %.0f", 1.0 / time.Delta);
|
|
|
|
constexpr ImVec2 FpsPlotSize{200, 60};
|
|
if (ImGui::BeginChild("FpsPlot", FpsPlotSize, 0, ImGuiWindowFlags_NoInputs))
|
|
{
|
|
auto& drawList = *ImGui::GetWindowDrawList();
|
|
ImVec2 pos = ImGui::GetWindowPos();
|
|
drawList.AddRectFilled(pos, {pos.x + FpsPlotSize.x, pos.y + FpsPlotSize.y}, 0x22222233);
|
|
|
|
float scale = 1000.0f;
|
|
|
|
for (int32_t i = 0; i < FrameTimeBufSize; ++i)
|
|
{
|
|
int32_t idx = FrameTimeIdx - i - 1;
|
|
int32_t prevIdx = idx - 1;
|
|
if (idx < 0) idx += FrameTimeBufSize;
|
|
if (prevIdx < 0) prevIdx += FrameTimeBufSize;
|
|
|
|
if (FrameTimes[idx] == 0 || FrameTimes[prevIdx] == 0) continue;
|
|
|
|
int64_t frameTime = FrameTimes[idx] - FrameTimes[prevIdx];
|
|
double frameTimeSec = (double)frameTime / bx::getHPFrequency();
|
|
drawList.AddLine(
|
|
{pos.x + (FpsPlotSize.x - i - 1), pos.y + FpsPlotSize.y},
|
|
{pos.x + (FpsPlotSize.x - i - 1), pos.y + FpsPlotSize.y - (float)frameTimeSec * scale},
|
|
0xFFFFFFFF);
|
|
}
|
|
}
|
|
ImGui::EndChild();
|
|
}
|
|
ImGui::End();
|
|
}
|
|
}
|
|
|
|
void RenderDebugUI(Game::GameRendering& rendering)
|
|
{
|
|
if (!rendering.SetupData.UseImgui) return;
|
|
ZoneScopedN("DebugUI");
|
|
|
|
auto& time = Game::GetInstance().Time;
|
|
auto& shared = Game::GetShared();
|
|
auto& debug = Game::GetInstance().DebugData;
|
|
auto& level = Game::GetInstance().GameLevel;
|
|
auto& player = Game::GetInstance().Player;
|
|
|
|
if (ImGui::Begin("Hilfe"))
|
|
{
|
|
if (ImGui::Button("Spiel Neustarten"))
|
|
{
|
|
player.PlayerCamTransform.Position = {0.0f, 3.0f, 0.0f};
|
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
|
{
|
|
Puzzle::ResetPuzzle(level.Puzzles[i].Data);
|
|
}
|
|
}
|
|
ImGui::SameLine();
|
|
if (ImGui::Button("Zurück zum Anfang"))
|
|
{
|
|
player.PlayerCamTransform.Position = {0.0f, 3.0f, 0.0f};
|
|
}
|
|
ImGui::Separator();
|
|
ImGui::Text("Anleitung:");
|
|
ImGui::Text("Bewege dich mit");
|
|
ImGui::SameLine();
|
|
ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "W, A, S, D");
|
|
ImGui::SameLine();
|
|
ImGui::Text("und schau dich um mit der");
|
|
ImGui::SameLine();
|
|
ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Maus.");
|
|
ImGui::Text("Drücke");
|
|
ImGui::SameLine();
|
|
ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Leertaste");
|
|
ImGui::SameLine();
|
|
ImGui::Text("um den Spielplan zu öffnen.");
|
|
ImGui::Text("Auf dem Spielplan kannst du Karten verschieben.");
|
|
ImGui::Text("Mit");
|
|
ImGui::SameLine();
|
|
ImGui::TextColored({1.0f, 0.6f, 0.6f, 1.0f}, "Rechter Maustaste");
|
|
ImGui::SameLine();
|
|
ImGui::Text("kannst du Karten drehen.");
|
|
ImGui::Text("");
|
|
ImGui::Text("Dein Ziel: Verbinde die Pumpe mit dem Abfluss, um das");
|
|
ImGui::Text("Tor zum nächsten Level zu öffnen!");
|
|
ImGui::Text("");
|
|
auto& inflowTexture = rendering.Textures[10];
|
|
auto& outflowTexture = rendering.Textures[9];
|
|
auto& connectionTexture = rendering.Textures[8];
|
|
ImGui::Text("Pumpe (Wasserquelle):");
|
|
ImGui::Image(inflowTexture.RenderHandle.idx, {64.0f, 64.0f});
|
|
ImGui::Text("Abfluss (Ziel):");
|
|
ImGui::Image(outflowTexture.RenderHandle.idx, {64.0f, 64.0f});
|
|
ImGui::Text("Verbindung:");
|
|
ImGui::Image(connectionTexture.RenderHandle.idx, {64.0f, 64.0f});
|
|
}
|
|
ImGui::End();
|
|
|
|
if (rendering.UIVisible == Game::UIVisibilityState::Debug)
|
|
{
|
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
|
{
|
|
debug.DebugCardRotation++;
|
|
if (debug.DebugCardRotation >= 4) debug.DebugCardRotation = 0;
|
|
}
|
|
|
|
if (ImGui::Begin("Debug"))
|
|
{
|
|
ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo);
|
|
ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f);
|
|
ImGui::Checkbox("Break on ID", &debug.DebugBreakIDEnabled);
|
|
ImGui::SameLine();
|
|
ImGui::PushID("@#$");
|
|
ImGui::InputInt("", &debug.DebugBreakID);
|
|
ImGui::PopID();
|
|
|
|
ImGui::Separator();
|
|
ImGui::Text("Arenas");
|
|
ProgressBar("Permanent", shared.Game.PermanentArena.Used, shared.Game.PermanentArena.MaxSize);
|
|
ProgressBar("Entity", shared.Game.EntityArena.Used, shared.Game.EntityArena.MaxSize);
|
|
ProgressBar("Transient", shared.Game.TransientArena.Used, shared.Game.TransientArena.MaxSize);
|
|
}
|
|
ImGui::End();
|
|
|
|
RenderLogUI();
|
|
RenderRenderSettingsUI(rendering);
|
|
RenderTexturesUI(rendering);
|
|
RenderModelsUI(rendering);
|
|
RenderPuzzlesUI();
|
|
RenderCardsUI(rendering);
|
|
RenderEntitiesUI();
|
|
}
|
|
RenderStatsUI();
|
|
}
|
|
void MeasureFrameEnd()
|
|
{
|
|
FrameTimes[FrameTimeIdx] = bx::getHPCounter();
|
|
++FrameTimeIdx;
|
|
if (FrameTimeIdx >= FrameTimeBufSize) FrameTimeIdx = 0;
|
|
}
|
|
} // namespace Tools
|