summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-01-23 21:57:31 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-01-23 21:57:31 -0500
commite93eb289ca44e98967482ab80fd5329f85ccd03e (patch)
tree4164b6d5b9ac2e40d18ec3eea52730c9f9606ccb /editor
parent846a6e1185417ee3e187edc06ef327d180bf0d9b (diff)
pke: first-pass 2d overlay render pass scaffolding
Diffstat (limited to 'editor')
-rw-r--r--editor/editor.cpp156
1 files changed, 150 insertions, 6 deletions
diff --git a/editor/editor.cpp b/editor/editor.cpp
index a15c838..9f6b492 100644
--- a/editor/editor.cpp
+++ b/editor/editor.cpp
@@ -3,14 +3,20 @@
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
#include "array.hpp"
+#include "asset-manager.hpp"
#include "camera.hpp"
#include "ecs.hpp"
#include "entities.hpp"
+#include "font.hpp"
#include "game-settings.hpp"
#include "game.hpp"
#include "imgui.h"
#include "level.hpp"
#include "math-helpers.hpp"
+#include "msdf-atlas-gen/GlyphGeometry.h"
+#include "msdf-atlas-gen/glyph-generators.h"
+#include "msdf-atlas-gen/image-save.h"
+#include "msdf-atlas-gen/types.h"
#include "player-input.hpp"
#include "plugins.hpp"
#include "project.hpp"
@@ -19,11 +25,14 @@
#include "vendor-tinyfiledialogs.h"
#include "window.hpp"
#include "pk.h"
+#include "msdf-atlas-gen/msdf-atlas-gen.h"
#include <GLFW/glfw3.h>
#include <compare>
+#include <cstdio>
#include <filesystem>
#include <future>
+#include <glm/fwd.hpp>
#include <regex>
#ifdef WIN32
@@ -230,7 +239,7 @@ void PkeEditor_Tick(double delta) {
if (focusedInst != nullptr) {
const auto *grBinds = ECS_GetGrBinds(focusedInst->grBindsHandle);
if (grBinds != nullptr) {
- pkeDebugHitbox.instanceBuffer = grBinds->instanceBuffer;
+ pkeDebugHitbox.instanceBuffer = grBinds->instanceBD.buffer;
pkeDebugHitbox.instanceStartingIndex = focusedInst->index;
found = true;
}
@@ -706,6 +715,140 @@ void RecordImGuiEntityTypes() {
ImGui::End();
}
+void GenerateMTSDF(const Asset *a) {
+ std::error_code e;
+ std::filesystem::create_directory("./cache", e);
+ if (msdfgen::FreetypeHandle *ft = msdfgen::initializeFreetype()) {
+ // Load font file
+ if (msdfgen::FontHandle *font = msdfgen::loadFont(ft, a->basePath)) {
+ // Storage for glyph geometry and their coordinates in the atlas
+ std::vector<msdf_atlas::GlyphGeometry> glyphs;
+ // FontGeometry is a helper class that loads a set of glyphs from a single font.
+ // It can also be used to get additional font metrics, kerning information, etc.
+ msdf_atlas::FontGeometry fontGeometry(&glyphs);
+ // Load a set of character glyphs:
+ // The second argument can be ignored unless you mix different font sizes in one atlas.
+ // In the last argument, you can specify a charset other than ASCII.
+ // To load specific glyph indices, use loadGlyphs instead.
+ fontGeometry.loadCharset(font, 1.0, msdf_atlas::Charset::ASCII);
+ // Apply MSDF edge coloring. See edge-coloring.h for other coloring strategies.
+ const double maxCornerAngle = 3.0;
+ for (msdf_atlas::GlyphGeometry &glyph : glyphs)
+ glyph.edgeColoring(&msdfgen::edgeColoringInkTrap, maxCornerAngle, 0);
+ // TightAtlasPacker class computes the layout of the atlas.
+ msdf_atlas::TightAtlasPacker packer;
+ // Set atlas parameters:
+ // setDimensions or setDimensionsConstraint to find the best value
+ packer.setDimensionsConstraint(msdf_atlas::DimensionsConstraint::SQUARE);
+ // setScale for a fixed size or setMinimumScale to use the largest that fits
+ packer.setMinimumScale(24.0);
+ // setPixelRange or setUnitRange
+ packer.setPixelRange(2.0);
+ packer.setMiterLimit(1.0);
+ // Compute atlas layout - pack glyphs
+ packer.pack(glyphs.data(), glyphs.size());
+ // Get final atlas dimensions
+ int width = 0, height = 0;
+ packer.getDimensions(width, height);
+ // The ImmediateAtlasGenerator class facilitates the generation of the atlas bitmap.
+ msdf_atlas::ImmediateAtlasGenerator<
+ float, // pixel type of buffer for individual glyphs depends on generator function
+ 4, // number of atlas color channels
+ &msdf_atlas::mtsdfGenerator, // function to generate bitmaps for individual glyphs
+ msdf_atlas::BitmapAtlasStorage<float, 4> // class that stores the atlas bitmap
+ // For example, a custom atlas storage class that stores it in VRAM can be used.
+ > generator(width, height);
+ // GeneratorAttributes can be modified to change the generator's default settings.
+ msdf_atlas::GeneratorAttributes attributes;
+ generator.setAttributes(attributes);
+ // generator.setThreadCount(4);
+ // Generate atlas bitmap
+ generator.generate(glyphs.data(), glyphs.size());
+ // The atlas bitmap can now be retrieved via atlasStorage as a BitmapConstRef.
+ // The glyphs array (or fontGeometry) contains positioning data for typesetting text.
+ msdf_atlas::BitmapAtlasStorage<float, 4> storage = generator.atlasStorage();
+ msdf_atlas::saveImage<4>(storage, msdf_atlas::ImageFormat::PNG, "cache/test-font.png", msdf_atlas::YDirection::TOP_DOWN);
+
+ auto f = fopen("cache/test-font.glyphs", "w");
+ pk_arr arr_glyphs = {};
+ arr_glyphs.alignment = 8;
+ arr_glyphs.stride = sizeof(FontGlyphChar);
+ pk_arr_resize(&arr_glyphs, glyphs.size());
+ FontGlyphChar *arr = reinterpret_cast<FontGlyphChar *>(arr_glyphs.data);
+ for (uint64_t i = 0; i < glyphs.size(); ++i) {
+ arr[i].unicode = glyphs[i].getCodepoint();
+ glyphs[i].getBoxRect(arr[i].bounds.x, arr[i].bounds.y, arr[i].bounds.z, arr[i].bounds.a);
+ }
+
+ fwrite(glyphs.data(), sizeof(msdf_atlas::GlyphGeometry) * glyphs.size(), 1, f);
+ fclose(f);
+ // _ = myProject::submitAtlasBitmapAndLayout(generator.atlasStorage(), glyphs);
+ // Cleanup
+ msdfgen::destroyFont(font);
+ }
+ msdfgen::deinitializeFreetype(ft);
+ }
+}
+
+void RecordImGuiAssets() {
+ if (!ImGui::Begin("AssetList")) {
+ ImGui::End();
+ return;
+ }
+
+ static ImGuiTableFlags tableFlags{
+ ImGuiTableFlags_Borders |
+ ImGuiTableFlags_RowBg
+ };
+ if (ImGui::BeginTable("Assets", 7, tableFlags)) {
+ ImGui::TableSetupColumn("Controls");
+ ImGui::TableSetupColumn("Type");
+ ImGui::TableSetupColumn("Handle");
+ ImGui::TableSetupColumn("Key");
+ ImGui::TableSetupColumn("Data");
+ ImGui::TableSetupColumn("Size");
+ ImGui::TableSetupColumn("Ref Count");
+ ImGui::TableHeadersRow();
+
+ pk_handle_bucket_index_T asset_bucket_count = AM_GetBucketCount();
+ for (pk_handle_bucket_index_T b = 0; b < asset_bucket_count; ++b) {
+ pk_handle_item_index_T count;
+ auto *assets = AM_GetAssets(b, count);
+ ImGui::PushID(b);
+ for (pk_handle_item_index_T i = 0; i < count; ++i) {
+ const auto &asset = assets[i];
+ if (asset.handle == EntityHandle_MAX)
+ continue;
+ ImGui::PushID(i);
+ ImGui::TableNextRow();
+ ImGui::TableSetColumnIndex(0);
+ if ((asset.type & PKE_ASSET_TYPE_FONT) != PKE_ASSET_TYPE_UNSET) {
+ if (ImGui::Button("Create MTSDF")) {
+ GenerateMTSDF(&asset);
+ }
+ }
+ ImGui::TableSetColumnIndex(1);
+ ImGui::Text("%i", (uint8_t)asset.type);
+ ImGui::TableSetColumnIndex(2);
+ ImGui::Text("0x%08X 0x%08X", asset.handle.bucketIndex, asset.handle.itemIndex);
+ ImGui::TableSetColumnIndex(3);
+ ImGui::Text("%.16s", asset.key);
+ ImGui::TableSetColumnIndex(4);
+ ImGui::Text("%p", asset.ptr);
+ ImGui::TableSetColumnIndex(5);
+ ImGui::Text("%li", asset.size);
+ ImGui::TableSetColumnIndex(6);
+ ImGui::Text("%hhi", asset.referenceCount);
+ ImGui::PopID();
+ }
+ ImGui::PopID();
+ }
+ ImGui::EndTable();
+
+ }
+ ImGui::End();
+}
+
void RecordImGuiCameras() {
CompInstance *activeInst = nullptr;
// CompInstance *activeTargetInst = nullptr;
@@ -1044,11 +1187,11 @@ void RecordImGui_CompGrBinds(bool readonly, CompGrBinds *component) {
ImGui::InputScalar("IndexOffsets", ImGuiDataType_U64, &component->indexBD.offsets[0], nullptr, nullptr, nullptr, inputTextFlags);
ImGui::InputScalar("IndexCount", ImGuiDataType_U32, &component->indexCount, nullptr, nullptr, nullptr, inputTextFlags);
- if (component->instanceBuffer)
- ImGui::InputScalar("VkInstanceBuffer", ImGuiDataType_U64, &component->instanceBuffer, nullptr, nullptr, "0x%016lX", ImGuiInputTextFlags_ReadOnly);
- ImGui::InputScalar("InstanceFirstBinding", ImGuiDataType_U32, &component->instanceFirstBinding, nullptr, nullptr, nullptr, inputTextFlags);
- ImGui::InputScalar("InstanceBindingCount", ImGuiDataType_U32, &component->instanceBindingCount, nullptr, nullptr, nullptr, inputTextFlags);
- ImGui::InputScalar("InstanceOffsets", ImGuiDataType_U64, &component->instanceOffsets, nullptr, nullptr, nullptr, inputTextFlags);
+ if (component->instanceBD.buffer)
+ ImGui::InputScalar("VkInstanceBuffer", ImGuiDataType_U64, &component->instanceBD.buffer, nullptr, nullptr, "0x%016lX", ImGuiInputTextFlags_ReadOnly);
+ ImGui::InputScalar("InstanceFirstBinding", ImGuiDataType_U32, &component->instanceBD.firstBinding, nullptr, nullptr, nullptr, inputTextFlags);
+ ImGui::InputScalar("InstanceBindingCount", ImGuiDataType_U32, &component->instanceBD.bindingCount, nullptr, nullptr, nullptr, inputTextFlags);
+ ImGui::InputScalar("InstanceOffsets", ImGuiDataType_U64, &component->instanceBD.offsets[0], nullptr, nullptr, nullptr, inputTextFlags);
ImGui::InputScalar("InstanceBufferMaxCount", ImGuiDataType_U32, &component->instanceBufferMaxCount, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly);
ImGui::InputScalar("Instance Count", ImGuiDataType_U32, &component->instanceCounter, nullptr, nullptr, nullptr, ImGuiInputTextFlags_ReadOnly);
@@ -1366,6 +1509,7 @@ void PkeEditor_RecordImGui() {
RecordImGuiCameras();
RecordImGuiLevels();
RecordImGuiEntityTypes();
+ RecordImGuiAssets();
Game_RecordImGui();
}
}