cleanup
This commit is contained in:
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.10)
|
|||||||
project(PuzGameProj)
|
project(PuzGameProj)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||||
else()
|
else()
|
||||||
add_compile_options(-g -gcodeview)
|
add_compile_options(-g -gcodeview)
|
||||||
add_link_options(-fuse-ld=lld -g -Wl,--pdb=)
|
add_link_options(-fuse-ld=lld -g -Wl,--pdb=)
|
||||||
|
|||||||
@@ -279,7 +279,12 @@ int main()
|
|||||||
DevData.FileWatcher.ShaderWatcher.ChangeType = FileChangeType::Shader;
|
DevData.FileWatcher.ShaderWatcher.ChangeType = FileChangeType::Shader;
|
||||||
DevData.FileWatcher.CompiledShaderWatcher.ChangeType = FileChangeType::CompiledShader;
|
DevData.FileWatcher.CompiledShaderWatcher.ChangeType = FileChangeType::CompiledShader;
|
||||||
|
|
||||||
bx::strCopy(DevData.FileWatcher.DLLWatcher.DirPath, sizeof(DevData.FileWatcher.DLLWatcher.DirPath), "cmake-build");
|
char exePath[1024];
|
||||||
|
GetModuleFileName(nullptr, exePath, BX_COUNTOF(exePath));
|
||||||
|
bx::FilePath exeFilePath{exePath};
|
||||||
|
bx::FilePath exeDir{exeFilePath.getPath()};
|
||||||
|
bx::strCopy(
|
||||||
|
DevData.FileWatcher.DLLWatcher.DirPath, sizeof(DevData.FileWatcher.DLLWatcher.DirPath), exeDir.getCPtr());
|
||||||
bx::strCopy(
|
bx::strCopy(
|
||||||
DevData.FileWatcher.ShaderWatcher.DirPath, sizeof(DevData.FileWatcher.ShaderWatcher.DirPath), "game/shaders");
|
DevData.FileWatcher.ShaderWatcher.DirPath, sizeof(DevData.FileWatcher.ShaderWatcher.DirPath), "game/shaders");
|
||||||
bx::strCopy(DevData.FileWatcher.CompiledShaderWatcher.DirPath,
|
bx::strCopy(DevData.FileWatcher.CompiledShaderWatcher.DirPath,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "Global.h"
|
|
||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
|
#include "Mesh.h"
|
||||||
#include "Tools.h"
|
#include "Tools.h"
|
||||||
#include "rendering/Rendering.h"
|
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
#include <tracy/Tracy.hpp>
|
||||||
|
|
||||||
namespace Tools
|
namespace Tools
|
||||||
{
|
{
|
||||||
@@ -61,4 +61,286 @@ namespace Tools
|
|||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void RenderDebugUI(Game::GameRendering& rendering)
|
||||||
|
{
|
||||||
|
auto& time = Game::GetInstance().Time;
|
||||||
|
if (rendering.UIVisible == Game::UIVisibilityState::Debug)
|
||||||
|
{
|
||||||
|
ZoneScopedN("DebugUI");
|
||||||
|
|
||||||
|
auto& shared = Game::GetShared();
|
||||||
|
auto& debug = Game::GetInstance().DebugData;
|
||||||
|
auto& level = Game::GetInstance().GameLevel;
|
||||||
|
|
||||||
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
||||||
|
{
|
||||||
|
debug.DebugCardRotation++;
|
||||||
|
if (debug.DebugCardRotation >= 4) debug.DebugCardRotation = 0;
|
||||||
|
}
|
||||||
|
if (ImGui::Begin("Log"))
|
||||||
|
{
|
||||||
|
ImGui::Checkbox("Shorten File Names", &debug.ShortenLogFileNames);
|
||||||
|
ImGui::BeginTable(
|
||||||
|
"tbl", 4, ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit);
|
||||||
|
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_NoResize);
|
||||||
|
ImGui::TableSetupColumn("Log");
|
||||||
|
ImGui::TableSetupColumn("Line", ImGuiTableColumnFlags_NoResize);
|
||||||
|
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_NoResize);
|
||||||
|
ImGui::TableHeadersRow();
|
||||||
|
for (int32_t i = 0; i < bx::min(100, LogInternal::LogHistorySize); ++i)
|
||||||
|
{
|
||||||
|
int32_t idx = GetLogHistory().WriteIdx - i - 1;
|
||||||
|
if (idx < 0) idx += LogInternal::LogHistorySize;
|
||||||
|
const char* line = &GetLogHistory().LogBuffer[idx * LogInternal::MaxLineSize];
|
||||||
|
if (line[0] != 0)
|
||||||
|
{
|
||||||
|
int64_t timeOffset = GetLogHistory().WriteTime[idx] - time.StartTime;
|
||||||
|
double writeTime = (double)timeOffset / bx::getHPFrequency();
|
||||||
|
uint32_t fileLine = GetLogHistory().LineBuffer[idx];
|
||||||
|
const char* filePath = &GetLogHistory().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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndTable();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Reload Meshes"))
|
||||||
|
{
|
||||||
|
LoadModels(rendering.Models, rendering.ModelCount);
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Reload Level"))
|
||||||
|
{
|
||||||
|
level = {};
|
||||||
|
level.Setup(shared.Game);
|
||||||
|
}
|
||||||
|
ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo);
|
||||||
|
if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled);
|
||||||
|
ImGui::Checkbox("Tests", &level.Tests.IsEnabled);
|
||||||
|
ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled);
|
||||||
|
ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled);
|
||||||
|
|
||||||
|
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});
|
||||||
|
}
|
||||||
|
Vec3 quadPos = level.UIQuads.Get({0}).EData.Transform.GetPosition();
|
||||||
|
ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z);
|
||||||
|
|
||||||
|
if (ImGui::ColorEdit3("Base Color", &rendering.DefaultBaseColor.x))
|
||||||
|
{
|
||||||
|
auto& tiles = level.PuzzleTiles;
|
||||||
|
for (int32_t i = 0; i < tiles.Count; ++i)
|
||||||
|
{
|
||||||
|
tiles.Data[i].EData.BaseColor = rendering.DefaultBaseColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ImGui::ColorEdit3("Dot Color", &rendering.DefaultTileColor.x))
|
||||||
|
{
|
||||||
|
auto& tiles = level.PuzzleTiles;
|
||||||
|
for (int32_t i = 0; i < tiles.Count; ++i)
|
||||||
|
{
|
||||||
|
tiles.Data[i].EData.TestColor = rendering.DefaultTileColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Shader log:");
|
||||||
|
ImGui::TextWrapped("%s", Game::GetShared().Dev.ShaderLog);
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
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();
|
||||||
|
if (ImGui::Begin("Puzzles"))
|
||||||
|
{
|
||||||
|
if (ImGui::Button("Add"))
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
||||||
|
{
|
||||||
|
auto& puz = level.Puzzles[i].Data;
|
||||||
|
if (puz.ID == UINT16_MAX)
|
||||||
|
{
|
||||||
|
bx::strCopy(puz.PuzzleName, sizeof(puz.PuzzleName), "Unnamed Puzzle");
|
||||||
|
puz.ID = i;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Too many puzzles!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
||||||
|
{
|
||||||
|
auto& puzzleData = level.Puzzles[i].Data;
|
||||||
|
if (puzzleData.ID == UINT16_MAX) continue;
|
||||||
|
|
||||||
|
bool isSelected = debug.SelectedDebugLevel == i;
|
||||||
|
ImGui::PushID("selectable");
|
||||||
|
if (ImGui::Selectable(puzzleData.PuzzleName, isSelected))
|
||||||
|
{
|
||||||
|
debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
if (debug.SelectedDebugLevel < BX_COUNTOF(level.Puzzles))
|
||||||
|
{
|
||||||
|
if (!Puzzle::RenderDebugUI(level.Puzzles[debug.SelectedDebugLevel].Data))
|
||||||
|
{
|
||||||
|
debug.SelectedDebugLevel = UINT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ImGui::Begin("Cards"))
|
||||||
|
{
|
||||||
|
Generated::StaticPuzzleData& staticData = Puzzle::GetStaticPuzzleData();
|
||||||
|
if (ImGui::Button("Save"))
|
||||||
|
{
|
||||||
|
Puzzle::SaveStaticPuzzleData();
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Reload"))
|
||||||
|
{
|
||||||
|
Puzzle::LoadStaticPuzzleData();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i)
|
||||||
|
{
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
Generated::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.ModelHandle);
|
||||||
|
Tools::TextureDropdown(card.BoardTextureHandle);
|
||||||
|
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(Generated::PuzzleElementType::ShortName[node], {26, 24}))
|
||||||
|
{
|
||||||
|
int32_t newVal = int32_t(node) + 1;
|
||||||
|
if (newVal >= Generated::PuzzleElementType::EntryCount)
|
||||||
|
{
|
||||||
|
newVal = 0;
|
||||||
|
}
|
||||||
|
node = Generated::PuzzleElementType::Enum(newVal);
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
auto& drawList = *ImGui::GetWindowDrawList();
|
||||||
|
ImVec2 pos = ImGui::GetWindowPos();
|
||||||
|
drawList.AddRectFilled(pos, {pos.x + FpsPlotSize.x, pos.y + FpsPlotSize.y}, 0xFFFFFF33);
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
} // namespace Tools
|
} // namespace Tools
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Gen.h"
|
#include "Gen.h"
|
||||||
|
#include "rendering/Rendering.h"
|
||||||
|
|
||||||
namespace Tools
|
namespace Tools
|
||||||
{
|
{
|
||||||
void ModelDropdown(Generated::ModelHandle& modelHandle);
|
void ModelDropdown(Generated::ModelHandle& modelHandle);
|
||||||
void TextureDropdown(Generated::TextureHandle& texHandle);
|
void TextureDropdown(Generated::TextureHandle& texHandle);
|
||||||
|
void RenderDebugUI(Game::GameRendering& rendering);
|
||||||
} // namespace Tools
|
} // namespace Tools
|
||||||
|
|||||||
120
src/game/rendering/Dither.cpp
Normal file
120
src/game/rendering/Dither.cpp
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
#include "../Log.h"
|
||||||
|
#include "Dither.h"
|
||||||
|
|
||||||
|
void DitherGen(DitherData& data, int32_t recursion)
|
||||||
|
{
|
||||||
|
data.Points[0] = {0.0f, 0.0f};
|
||||||
|
data.Points[1] = {0.5f, 0.5f};
|
||||||
|
data.Points[2] = {0.5f, 0.0f};
|
||||||
|
data.Points[3] = {0.0f, 0.5f};
|
||||||
|
data.PointCount = 4;
|
||||||
|
for (int32_t i = 0; i < data.BrightnessBucketCount; ++i)
|
||||||
|
data.BrightnessBuckets[i] = 0;
|
||||||
|
|
||||||
|
for (int32_t recursionLevel = 0; recursionLevel < recursion; ++recursionLevel)
|
||||||
|
{
|
||||||
|
int32_t startCount = data.PointCount;
|
||||||
|
float offset = bx::pow(0.5f, recursionLevel + 1);
|
||||||
|
for (int32_t i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
for (int32_t j = 0; j < startCount; ++j)
|
||||||
|
{
|
||||||
|
data.Points[data.PointCount] = data.Points[j] + data.Points[i] * offset;
|
||||||
|
data.PointCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t dotsPerSide = bx::round(bx::pow(2, recursion));
|
||||||
|
data.DitherTexDepth = dotsPerSide * dotsPerSide;
|
||||||
|
data.DitherTexWH = 16 * dotsPerSide;
|
||||||
|
uint64_t texPixelCount = data.DitherTexWH * data.DitherTexWH * data.DitherTexDepth;
|
||||||
|
|
||||||
|
if (BX_COUNTOF(DitherData::DitherTex) < texPixelCount)
|
||||||
|
{
|
||||||
|
LOG_ERROR("Too many pixels: %llu", texPixelCount);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float invRes = 1.0f / data.DitherTexWH;
|
||||||
|
for (int32_t z = 0; z < data.DitherTexDepth; ++z)
|
||||||
|
{
|
||||||
|
int32_t dotCount = z + 1;
|
||||||
|
float dotArea = 0.5f / dotCount;
|
||||||
|
float dotRadius = bx::sqrt(dotArea / bx::kPi);
|
||||||
|
|
||||||
|
int zOffset = z * data.DitherTexWH * data.DitherTexWH;
|
||||||
|
for (int32_t y = 0; y < data.DitherTexWH; ++y)
|
||||||
|
{
|
||||||
|
int32_t yOffset = y * data.DitherTexWH;
|
||||||
|
for (int32_t x = 0; x < data.DitherTexWH; ++x)
|
||||||
|
{
|
||||||
|
Vec2 point{(x + 0.5f) * invRes, (y + 0.5f) * invRes};
|
||||||
|
float dist = bx::kFloatInfinity;
|
||||||
|
for (int32_t i = 0; i < dotCount; ++i)
|
||||||
|
{
|
||||||
|
Vec2 vec = point - data.Points[i];
|
||||||
|
Vec2 wrappedVec{bx::mod(vec.x + 0.5f, 1.0f) - 0.5f, bx::mod(vec.y + 0.5f, 1.0f) - 0.5f};
|
||||||
|
float curDist = wrappedVec.Magnitude();
|
||||||
|
dist = bx::min(dist, curDist);
|
||||||
|
}
|
||||||
|
|
||||||
|
dist = dist / (dotRadius * 2.4f);
|
||||||
|
float val = bx::clamp(1.0f - dist, 0.0f, 1.0f);
|
||||||
|
data.DitherTex[x + yOffset + zOffset] = Vec4{val, val, val, 1.0f};
|
||||||
|
// data.DitherTex[x + yOffset + zOffset] = Vec4{1.0, 0.0f, 0.0f, 1.0f};
|
||||||
|
int32_t bucket = bx::clamp(
|
||||||
|
uint32_t(val * DitherData::BrightnessBucketCount), 0, DitherData::BrightnessBucketCount - 1);
|
||||||
|
data.BrightnessBuckets[bucket] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Brightness ramp
|
||||||
|
int32_t sum = 0;
|
||||||
|
for (int32_t i = 0; i < data.BrightnessBucketCount; ++i)
|
||||||
|
{
|
||||||
|
sum += data.BrightnessBuckets[data.BrightnessBucketCount - 1 - i];
|
||||||
|
data.BrightnessRamp[i + 1] = sum / (float)texPixelCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload textures
|
||||||
|
if (isValid(data.PreviewTex))
|
||||||
|
{
|
||||||
|
bgfx::destroy(data.PreviewTex);
|
||||||
|
data.PreviewTex = BGFX_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
if (isValid(data.FinalTex))
|
||||||
|
{
|
||||||
|
bgfx::destroy(data.FinalTex);
|
||||||
|
data.FinalTex = BGFX_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
if (isValid(data.RampTex))
|
||||||
|
{
|
||||||
|
bgfx::destroy(data.RampTex);
|
||||||
|
data.RampTex = BGFX_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
const bgfx::Memory* memPreview = bgfx::makeRef(data.DitherTex, texPixelCount * sizeof(Vec4));
|
||||||
|
const bgfx::Memory* memFinal = bgfx::makeRef(data.DitherTex, texPixelCount * sizeof(Vec4));
|
||||||
|
const bgfx::Memory* memRamp = bgfx::makeRef(data.BrightnessRamp, sizeof(data.BrightnessRamp));
|
||||||
|
data.PreviewTex = bgfx::createTexture2D(data.DitherTexWH,
|
||||||
|
data.DitherTexWH * data.DitherTexDepth,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
bgfx::TextureFormat::RGBA32F,
|
||||||
|
0,
|
||||||
|
memPreview);
|
||||||
|
data.FinalTex = bgfx::createTexture3D(
|
||||||
|
data.DitherTexWH, data.DitherTexWH, data.DitherTexDepth, false, bgfx::TextureFormat::RGBA32F, 0, memFinal);
|
||||||
|
data.RampTex =
|
||||||
|
bgfx::createTexture2D(BX_COUNTOF(data.BrightnessRamp), 1, false, 1, bgfx::TextureFormat::R32F, 0, memRamp);
|
||||||
|
|
||||||
|
if (!isValid(data.DitherSampler))
|
||||||
|
{
|
||||||
|
data.DitherSampler = bgfx::createUniform("s_ditherSampler", bgfx::UniformType::Sampler);
|
||||||
|
}
|
||||||
|
if (!isValid(data.RampSampler))
|
||||||
|
{
|
||||||
|
data.RampSampler = bgfx::createUniform("s_rampSampler", bgfx::UniformType::Sampler);
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/game/rendering/Dither.h
Normal file
26
src/game/rendering/Dither.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../Global.h"
|
||||||
|
|
||||||
|
#include <bgfx/bgfx.h>
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
|
struct DitherData
|
||||||
|
{
|
||||||
|
static constexpr uint32_t BrightnessBucketCount = 256;
|
||||||
|
Vec2 Points[4096];
|
||||||
|
uint32_t PointCount = 0;
|
||||||
|
Vec4 DitherTex[256 * 256 * 64];
|
||||||
|
uint32_t DitherTexWH = 0;
|
||||||
|
uint32_t DitherTexDepth = 0;
|
||||||
|
int32_t BrightnessBuckets[BrightnessBucketCount];
|
||||||
|
float BrightnessRamp[BrightnessBucketCount + 1];
|
||||||
|
bgfx::TextureHandle PreviewTex = BGFX_INVALID_HANDLE;
|
||||||
|
bgfx::TextureHandle FinalTex = BGFX_INVALID_HANDLE;
|
||||||
|
bgfx::TextureHandle RampTex = BGFX_INVALID_HANDLE;
|
||||||
|
|
||||||
|
bgfx::UniformHandle DitherSampler = BGFX_INVALID_HANDLE;
|
||||||
|
bgfx::UniformHandle RampSampler = BGFX_INVALID_HANDLE;
|
||||||
|
ImTextureID PreviewID = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void DitherGen(DitherData& data, int32_t recursion);
|
||||||
@@ -206,130 +206,6 @@ namespace Game
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DitherGen(DitherData& data, int32_t recursion)
|
|
||||||
{
|
|
||||||
data.Points[0] = {0.0f, 0.0f};
|
|
||||||
data.Points[1] = {0.5f, 0.5f};
|
|
||||||
data.Points[2] = {0.5f, 0.0f};
|
|
||||||
data.Points[3] = {0.0f, 0.5f};
|
|
||||||
data.PointCount = 4;
|
|
||||||
for (int32_t i = 0; i < data.BrightnessBucketCount; ++i)
|
|
||||||
data.BrightnessBuckets[i] = 0;
|
|
||||||
|
|
||||||
for (int32_t recursionLevel = 0; recursionLevel < recursion; ++recursionLevel)
|
|
||||||
{
|
|
||||||
int32_t startCount = data.PointCount;
|
|
||||||
float offset = bx::pow(0.5f, recursionLevel + 1);
|
|
||||||
for (int32_t i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
for (int32_t j = 0; j < startCount; ++j)
|
|
||||||
{
|
|
||||||
data.Points[data.PointCount] = data.Points[j] + data.Points[i] * offset;
|
|
||||||
data.PointCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t dotsPerSide = bx::round(bx::pow(2, recursion));
|
|
||||||
data.DitherTexDepth = dotsPerSide * dotsPerSide;
|
|
||||||
data.DitherTexWH = 16 * dotsPerSide;
|
|
||||||
uint64_t texPixelCount = data.DitherTexWH * data.DitherTexWH * data.DitherTexDepth;
|
|
||||||
|
|
||||||
if (BX_COUNTOF(DitherData::DitherTex) < texPixelCount)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Too many pixels: %llu", texPixelCount);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float invRes = 1.0f / data.DitherTexWH;
|
|
||||||
for (int32_t z = 0; z < data.DitherTexDepth; ++z)
|
|
||||||
{
|
|
||||||
int32_t dotCount = z + 1;
|
|
||||||
float dotArea = 0.5f / dotCount;
|
|
||||||
float dotRadius = bx::sqrt(dotArea / bx::kPi);
|
|
||||||
|
|
||||||
int zOffset = z * data.DitherTexWH * data.DitherTexWH;
|
|
||||||
for (int32_t y = 0; y < data.DitherTexWH; ++y)
|
|
||||||
{
|
|
||||||
int32_t yOffset = y * data.DitherTexWH;
|
|
||||||
for (int32_t x = 0; x < data.DitherTexWH; ++x)
|
|
||||||
{
|
|
||||||
Vec2 point{(x + 0.5f) * invRes, (y + 0.5f) * invRes};
|
|
||||||
float dist = bx::kFloatInfinity;
|
|
||||||
for (int32_t i = 0; i < dotCount; ++i)
|
|
||||||
{
|
|
||||||
Vec2 vec = point - data.Points[i];
|
|
||||||
Vec2 wrappedVec{bx::mod(vec.x + 0.5f, 1.0f) - 0.5f, bx::mod(vec.y + 0.5f, 1.0f) - 0.5f};
|
|
||||||
float curDist = wrappedVec.Magnitude();
|
|
||||||
dist = bx::min(dist, curDist);
|
|
||||||
}
|
|
||||||
|
|
||||||
dist = dist / (dotRadius * 2.4f);
|
|
||||||
float val = bx::clamp(1.0f - dist, 0.0f, 1.0f);
|
|
||||||
data.DitherTex[x + yOffset + zOffset] = Vec4{val, val, val, 1.0f};
|
|
||||||
// data.DitherTex[x + yOffset + zOffset] = Vec4{1.0, 0.0f, 0.0f, 1.0f};
|
|
||||||
int32_t bucket = bx::clamp(uint32_t(val * DitherData::BrightnessBucketCount),
|
|
||||||
0,
|
|
||||||
DitherData::BrightnessBucketCount - 1);
|
|
||||||
data.BrightnessBuckets[bucket] += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Brightness ramp
|
|
||||||
int32_t sum = 0;
|
|
||||||
for (int32_t i = 0; i < data.BrightnessBucketCount; ++i)
|
|
||||||
{
|
|
||||||
sum += data.BrightnessBuckets[data.BrightnessBucketCount - 1 - i];
|
|
||||||
data.BrightnessRamp[i + 1] = sum / (float)texPixelCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload textures
|
|
||||||
if (isValid(data.PreviewTex))
|
|
||||||
{
|
|
||||||
bgfx::destroy(data.PreviewTex);
|
|
||||||
data.PreviewTex = BGFX_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (isValid(data.FinalTex))
|
|
||||||
{
|
|
||||||
bgfx::destroy(data.FinalTex);
|
|
||||||
data.FinalTex = BGFX_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
if (isValid(data.RampTex))
|
|
||||||
{
|
|
||||||
bgfx::destroy(data.RampTex);
|
|
||||||
data.RampTex = BGFX_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
const bgfx::Memory* memPreview = bgfx::makeRef(data.DitherTex, texPixelCount * sizeof(Vec4));
|
|
||||||
const bgfx::Memory* memFinal = bgfx::makeRef(data.DitherTex, texPixelCount * sizeof(Vec4));
|
|
||||||
const bgfx::Memory* memRamp = bgfx::makeRef(data.BrightnessRamp, sizeof(data.BrightnessRamp));
|
|
||||||
data.PreviewTex = bgfx::createTexture2D(data.DitherTexWH,
|
|
||||||
data.DitherTexWH * data.DitherTexDepth,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
bgfx::TextureFormat::RGBA32F,
|
|
||||||
0,
|
|
||||||
memPreview);
|
|
||||||
data.FinalTex = bgfx::createTexture3D(data.DitherTexWH,
|
|
||||||
data.DitherTexWH,
|
|
||||||
data.DitherTexDepth,
|
|
||||||
false,
|
|
||||||
bgfx::TextureFormat::RGBA32F,
|
|
||||||
0,
|
|
||||||
memFinal);
|
|
||||||
data.RampTex = bgfx::createTexture2D(
|
|
||||||
BX_COUNTOF(data.BrightnessRamp), 1, false, 1, bgfx::TextureFormat::R32F, 0, memRamp);
|
|
||||||
|
|
||||||
if (!isValid(data.DitherSampler))
|
|
||||||
{
|
|
||||||
data.DitherSampler = bgfx::createUniform("s_ditherSampler", bgfx::UniformType::Sampler);
|
|
||||||
}
|
|
||||||
if (!isValid(data.RampSampler))
|
|
||||||
{
|
|
||||||
data.RampSampler = bgfx::createUniform("s_rampSampler", bgfx::UniformType::Sampler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GameRendering* Instance = nullptr;
|
GameRendering* Instance = nullptr;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -351,7 +227,7 @@ namespace Game
|
|||||||
bgfx::Init init;
|
bgfx::Init init;
|
||||||
init.type = bgfx::RendererType::Direct3D12;
|
init.type = bgfx::RendererType::Direct3D12;
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
init.debug = true;
|
// init.debug = true;
|
||||||
#endif
|
#endif
|
||||||
init.platformData.nwh = shared.Window.Handle;
|
init.platformData.nwh = shared.Window.Handle;
|
||||||
init.platformData.ndt = nullptr;
|
init.platformData.ndt = nullptr;
|
||||||
@@ -455,258 +331,6 @@ namespace Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameRendering::RenderDebugUI()
|
|
||||||
{
|
|
||||||
ZoneScopedN("DebugUI");
|
|
||||||
|
|
||||||
auto& shared = GetShared();
|
|
||||||
auto& debug = GetInstance().DebugData;
|
|
||||||
auto& level = GetInstance().GameLevel;
|
|
||||||
auto& time = GetInstance().Time;
|
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right))
|
|
||||||
{
|
|
||||||
debug.DebugCardRotation++;
|
|
||||||
if (debug.DebugCardRotation >= 4) debug.DebugCardRotation = 0;
|
|
||||||
}
|
|
||||||
if (ImGui::Begin("Log"))
|
|
||||||
{
|
|
||||||
ImGui::Checkbox("Shorten File Names", &GetInstance().DebugData.ShortenLogFileNames);
|
|
||||||
ImGui::BeginTable(
|
|
||||||
"tbl", 4, ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit);
|
|
||||||
ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_NoResize);
|
|
||||||
ImGui::TableSetupColumn("Log");
|
|
||||||
ImGui::TableSetupColumn("Line", ImGuiTableColumnFlags_NoResize);
|
|
||||||
ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_NoResize);
|
|
||||||
ImGui::TableHeadersRow();
|
|
||||||
for (int32_t i = 0; i < bx::min(100, LogInternal::LogHistorySize); ++i)
|
|
||||||
{
|
|
||||||
int32_t idx = GetLogHistory().WriteIdx - i - 1;
|
|
||||||
if (idx < 0) idx += LogInternal::LogHistorySize;
|
|
||||||
const char* line = &GetLogHistory().LogBuffer[idx * LogInternal::MaxLineSize];
|
|
||||||
if (line[0] != 0)
|
|
||||||
{
|
|
||||||
int64_t timeOffset = GetLogHistory().WriteTime[idx] - GetInstance().Time.StartTime;
|
|
||||||
double writeTime = (double)timeOffset / bx::getHPFrequency();
|
|
||||||
uint32_t fileLine = GetLogHistory().LineBuffer[idx];
|
|
||||||
const char* filePath = &GetLogHistory().FileBuffer[idx * LogInternal::MaxLineSize];
|
|
||||||
const char* filePathRes = GetInstance().DebugData.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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::EndTable();
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
if (ImGui::Begin("Rendering"))
|
|
||||||
{
|
|
||||||
if (LastShaderLoadTime >= 0.0f)
|
|
||||||
{
|
|
||||||
ImGui::TextColored({0.2f, 0.9f, 0.2f, 1.0f},
|
|
||||||
"Shader loaded %.0f seconds ago",
|
|
||||||
GetInstance().Time.Now - LastShaderLoadTime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui::TextColored({0.9f, 0.2f, 0.2f, 1.0f}, "Shader load Failiure!");
|
|
||||||
}
|
|
||||||
if (ImGui::Button("Reload Meshes"))
|
|
||||||
{
|
|
||||||
LoadModels(Models, ModelCount);
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Reload Level"))
|
|
||||||
{
|
|
||||||
level = {};
|
|
||||||
level.Setup(shared.Game);
|
|
||||||
}
|
|
||||||
ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo);
|
|
||||||
if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo);
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled);
|
|
||||||
ImGui::Checkbox("Tests", &level.Tests.IsEnabled);
|
|
||||||
ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled);
|
|
||||||
ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled);
|
|
||||||
|
|
||||||
if (ImGui::Button("Dithergen"))
|
|
||||||
{
|
|
||||||
DitherGen(DitherTextures, DitherRecursion);
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::SliderInt("Recursion", &DitherRecursion, 1, 4);
|
|
||||||
ImGui::Text(
|
|
||||||
"%ux%ux%u", DitherTextures.DitherTexWH, DitherTextures.DitherTexWH, DitherTextures.DitherTexDepth);
|
|
||||||
if (!isValid(DitherTextures.PreviewTex))
|
|
||||||
{
|
|
||||||
ImGui::Text("Invalid Texture");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui::Image(DitherTextures.PreviewTex.idx,
|
|
||||||
{(float)DitherTextures.DitherTexWH,
|
|
||||||
(float)DitherTextures.DitherTexWH * DitherTextures.DitherTexDepth});
|
|
||||||
}
|
|
||||||
if (isValid(DitherTextures.RampTex))
|
|
||||||
{
|
|
||||||
ImGui::Image(DitherTextures.RampTex.idx, {BX_COUNTOF(DitherTextures.BrightnessRamp), 8});
|
|
||||||
}
|
|
||||||
Vec3 quadPos = level.UIQuads.Get({0}).EData.Transform.GetPosition();
|
|
||||||
ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z);
|
|
||||||
|
|
||||||
if (ImGui::ColorEdit3("Base Color", &DefaultBaseColor.x))
|
|
||||||
{
|
|
||||||
auto& tiles = GetInstance().GameLevel.PuzzleTiles;
|
|
||||||
for (int32_t i = 0; i < tiles.Count; ++i)
|
|
||||||
{
|
|
||||||
tiles.Data[i].EData.BaseColor = DefaultBaseColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImGui::ColorEdit3("Dot Color", &DefaultTileColor.x))
|
|
||||||
{
|
|
||||||
auto& tiles = GetInstance().GameLevel.PuzzleTiles;
|
|
||||||
for (int32_t i = 0; i < tiles.Count; ++i)
|
|
||||||
{
|
|
||||||
tiles.Data[i].EData.TestColor = DefaultTileColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Shader log:");
|
|
||||||
ImGui::TextWrapped("%s", GetShared().Dev.ShaderLog);
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
if (ImGui::Begin("Textures"))
|
|
||||||
{
|
|
||||||
if (ImGui::Button("Reload"))
|
|
||||||
{
|
|
||||||
LoadTextures();
|
|
||||||
}
|
|
||||||
for (int32_t i = 0; i < MaxTextures; ++i)
|
|
||||||
{
|
|
||||||
if (!isValid(Textures[i].RenderHandle)) continue;
|
|
||||||
ImGui::Text("%i", i);
|
|
||||||
float width = bx::min<float>(ImGui::GetContentRegionAvail().x, Textures[i].Info.width);
|
|
||||||
float height = bx::min<float>(ImGui::GetContentRegionAvail().x, Textures[i].Info.height);
|
|
||||||
ImGui::Image(Textures[i].RenderHandle.idx, {width, height});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
if (ImGui::Begin("Puzzles"))
|
|
||||||
{
|
|
||||||
if (ImGui::Button("Add"))
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
|
||||||
{
|
|
||||||
auto& puz = level.Puzzles[i].Data;
|
|
||||||
if (puz.ID == UINT16_MAX)
|
|
||||||
{
|
|
||||||
bx::strCopy(puz.PuzzleName, sizeof(puz.PuzzleName), "Unnamed Puzzle");
|
|
||||||
puz.ID = i;
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
LOG_ERROR("Too many puzzles!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::Separator();
|
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
|
||||||
{
|
|
||||||
auto& puzzleData = level.Puzzles[i].Data;
|
|
||||||
if (puzzleData.ID == UINT16_MAX) continue;
|
|
||||||
|
|
||||||
bool isSelected = debug.SelectedDebugLevel == i;
|
|
||||||
ImGui::PushID("selectable");
|
|
||||||
if (ImGui::Selectable(puzzleData.PuzzleName, isSelected))
|
|
||||||
{
|
|
||||||
debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i;
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
if (debug.SelectedDebugLevel < BX_COUNTOF(level.Puzzles))
|
|
||||||
{
|
|
||||||
if (!Puzzle::RenderDebugUI(level.Puzzles[debug.SelectedDebugLevel].Data))
|
|
||||||
{
|
|
||||||
debug.SelectedDebugLevel = UINT16_MAX;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ImGui::Begin("Cards"))
|
|
||||||
{
|
|
||||||
Generated::StaticPuzzleData& staticData = Puzzle::GetStaticPuzzleData();
|
|
||||||
if (ImGui::Button("Save"))
|
|
||||||
{
|
|
||||||
Puzzle::SaveStaticPuzzleData();
|
|
||||||
}
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (ImGui::Button("Reload"))
|
|
||||||
{
|
|
||||||
Puzzle::LoadStaticPuzzleData();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i)
|
|
||||||
{
|
|
||||||
ImGui::Separator();
|
|
||||||
|
|
||||||
Generated::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.ModelHandle);
|
|
||||||
Tools::TextureDropdown(card.BoardTextureHandle);
|
|
||||||
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(Generated::PuzzleElementType::ShortName[node], {26, 24}))
|
|
||||||
{
|
|
||||||
int32_t newVal = int32_t(node) + 1;
|
|
||||||
if (newVal >= Generated::PuzzleElementType::EntryCount)
|
|
||||||
{
|
|
||||||
newVal = 0;
|
|
||||||
}
|
|
||||||
node = Generated::PuzzleElementType::Enum(newVal);
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameRendering::LoadTextures()
|
void GameRendering::LoadTextures()
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < MaxTextures; ++i)
|
for (int32_t i = 0; i < MaxTextures; ++i)
|
||||||
@@ -791,26 +415,7 @@ namespace Game
|
|||||||
ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode);
|
ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIVisible == UIVisibilityState::Debug)
|
Tools::RenderDebugUI(*this);
|
||||||
{
|
|
||||||
RenderDebugUI();
|
|
||||||
}
|
|
||||||
ImGui::SetNextWindowPos({0, 0});
|
|
||||||
if (ImGui::Begin("Stats",
|
|
||||||
nullptr,
|
|
||||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoInputs |
|
|
||||||
ImGuiWindowFlags_AlwaysAutoResize))
|
|
||||||
{
|
|
||||||
if (GetInstance().Player.CameraM == 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);
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
GetInstance().GameLevel.Update();
|
GetInstance().GameLevel.Update();
|
||||||
GetInstance().GameLevel.Render(MainViewID, Models, Materials, Textures);
|
GetInstance().GameLevel.Render(MainViewID, Models, Materials, Textures);
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "bgfx/defines.h"
|
#include "bgfx/defines.h"
|
||||||
#include "imgui.h"
|
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
#include <bx/string.h>
|
#include <bx/string.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "../Gen.h"
|
#include "../Gen.h"
|
||||||
#include "../Global.h"
|
#include "../Global.h"
|
||||||
|
#include "Dither.h"
|
||||||
|
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
|
||||||
@@ -65,25 +65,6 @@ namespace Game
|
|||||||
Debug,
|
Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DitherData
|
|
||||||
{
|
|
||||||
static constexpr uint32_t BrightnessBucketCount = 256;
|
|
||||||
Vec2 Points[4096];
|
|
||||||
uint32_t PointCount = 0;
|
|
||||||
Vec4 DitherTex[256 * 256 * 64];
|
|
||||||
uint32_t DitherTexWH = 0;
|
|
||||||
uint32_t DitherTexDepth = 0;
|
|
||||||
int32_t BrightnessBuckets[BrightnessBucketCount];
|
|
||||||
float BrightnessRamp[BrightnessBucketCount + 1];
|
|
||||||
bgfx::TextureHandle PreviewTex = BGFX_INVALID_HANDLE;
|
|
||||||
bgfx::TextureHandle FinalTex = BGFX_INVALID_HANDLE;
|
|
||||||
bgfx::TextureHandle RampTex = BGFX_INVALID_HANDLE;
|
|
||||||
|
|
||||||
bgfx::UniformHandle DitherSampler = BGFX_INVALID_HANDLE;
|
|
||||||
bgfx::UniformHandle RampSampler = BGFX_INVALID_HANDLE;
|
|
||||||
ImTextureID PreviewID = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EMaterial : uint16_t
|
enum class EMaterial : uint16_t
|
||||||
{
|
{
|
||||||
Default = 0,
|
Default = 0,
|
||||||
@@ -110,7 +91,7 @@ namespace Game
|
|||||||
Model Models[MaxModels];
|
Model Models[MaxModels];
|
||||||
int32_t LastWidth = 0;
|
int32_t LastWidth = 0;
|
||||||
int32_t LastHeight = 0;
|
int32_t LastHeight = 0;
|
||||||
uint32_t ResetFlags = BGFX_RESET_NONE;
|
uint32_t ResetFlags = BGFX_RESET_VSYNC;
|
||||||
uint16_t MainViewID = 10;
|
uint16_t MainViewID = 10;
|
||||||
float LastShaderLoadTime = 0.0f;
|
float LastShaderLoadTime = 0.0f;
|
||||||
int32_t DitherRecursion = 1;
|
int32_t DitherRecursion = 1;
|
||||||
@@ -121,7 +102,6 @@ namespace Game
|
|||||||
void Setup();
|
void Setup();
|
||||||
void Update();
|
void Update();
|
||||||
void HandleEvents();
|
void HandleEvents();
|
||||||
void RenderDebugUI();
|
|
||||||
void LoadTextures();
|
void LoadTextures();
|
||||||
void ReloadShaders();
|
void ReloadShaders();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|||||||
Reference in New Issue
Block a user