From 431e26319c074906e90a46f0ab3e2242cbfed64c Mon Sep 17 00:00:00 2001 From: Jonathan Hoffstadt Date: Tue, 11 Feb 2025 13:35:53 -0600 Subject: [PATCH] WIP --- .github/workflows/build.yml | 6 + examples/example_2.c | 3 + examples/example_3.c | 3 + examples/example_4.c | 8 +- examples/example_5.c | 8 +- examples/example_6.c | 8 +- examples/example_8.c | 3 + examples/example_9.c | 3 + extensions/pl_draw_backend_ext.c | 16 +- extensions/pl_ecs_ext.c | 7 +- extensions/pl_ecs_ext.h | 17 +- .../pl_ecs_tools_ext.c | 523 ++++++++++------ .../pl_ecs_tools_ext.h | 30 +- .../pl_gizmo.c => extensions/pl_gizmo_ext.c | 584 +++++++++--------- extensions/pl_gizmo_ext.h | 64 ++ extensions/pl_renderer_ext.c | 465 ++++++-------- extensions/pl_renderer_ext.h | 17 +- extensions/pl_renderer_internal.c | 274 +++++++- extensions/pl_renderer_internal.h | 9 +- extensions/pl_shader_ext.c | 306 +++++---- extensions/pl_shader_ext.h | 9 +- extensions/pl_unity_ext.c | 9 + extensions/pl_unity_ext.inc | 3 + sandbox/app.c | 32 +- sandbox/app.h | 9 +- sandbox/pl_gizmo.h | 47 -- scripts/gen_dev.py | 10 +- scripts/gen_distribute.py | 4 +- scripts/package.py | 4 + scripts/setup.py | 3 +- src/build_linux.sh | 4 +- src/build_macos.sh | 2 +- src/build_win32.bat | 4 +- src/pl_config.h | 1 + 34 files changed, 1494 insertions(+), 1001 deletions(-) rename sandbox/pl_ecs_tools.c => extensions/pl_ecs_tools_ext.c (50%) rename sandbox/pl_ecs_tools.h => extensions/pl_ecs_tools_ext.h (58%) rename sandbox/pl_gizmo.c => extensions/pl_gizmo_ext.c (69%) create mode 100644 extensions/pl_gizmo_ext.h delete mode 100644 sandbox/pl_gizmo.h diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eef1be9c..bb2f9e5f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,6 +105,8 @@ jobs: if not exist ../out/pl_draw_backend_ext.dll exit 1 if not exist ../out/pl_draw_ext.dll exit 1 if not exist ../out/pl_ecs_ext.dll exit 1 + if not exist ../out/pl_ecs_tools_ext.dll exit 1 + if not exist ../out/pl_gizmo_ext.dll exit 1 if not exist ../out/pl_gpu_allocators_ext.dll exit 1 if not exist ../out/pl_graphics_ext.dll exit 1 if not exist ../out/pl_image_ext.dll exit 1 @@ -237,6 +239,8 @@ jobs: test -f ./out/pl_draw_backend_ext.dylib || exit 1 test -f ./out/pl_draw_ext.dylib || exit 1 test -f ./out/pl_ecs_ext.dylib || exit 1 + test -f ./out/pl_ecs_tools_ext.dylib || exit 1 + test -f ./out/pl_gizmo_ext.dylib || exit 1 test -f ./out/pl_gpu_allocators_ext.dylib || exit 1 test -f ./out/pl_graphics_ext.dylib || exit 1 test -f ./out/pl_image_ext.dylib || exit 1 @@ -374,6 +378,8 @@ jobs: test -f ./out/pl_draw_backend_ext.so || exit 1 test -f ./out/pl_draw_ext.so || exit 1 test -f ./out/pl_ecs_ext.so || exit 1 + test -f ./out/pl_ecs_tools_ext.so || exit 1 + test -f ./out/pl_gizmo_ext.so || exit 1 test -f ./out/pl_gpu_allocators_ext.so || exit 1 test -f ./out/pl_graphics_ext.so || exit 1 test -f ./out/pl_image_ext.so || exit 1 diff --git a/examples/example_2.c b/examples/example_2.c index e0f0743e..7091d555 100644 --- a/examples/example_2.c +++ b/examples/example_2.c @@ -137,6 +137,9 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../shaders/" + }, + .apcDirectories = { + "../shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); diff --git a/examples/example_3.c b/examples/example_3.c index b3c71fe3..63f3a48a 100644 --- a/examples/example_3.c +++ b/examples/example_3.c @@ -149,6 +149,9 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../shaders/" + }, + .apcDirectories = { + "../shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); diff --git a/examples/example_4.c b/examples/example_4.c index 0e20b4ad..61264d50 100644 --- a/examples/example_4.c +++ b/examples/example_4.c @@ -218,6 +218,10 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../examples/shaders/" + }, + .apcDirectories = { + "../shaders/", + "../examples/shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); @@ -272,8 +276,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~shaders~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const plShaderDesc tShaderDesc = { - .tVertexShader = gptShader->load_glsl("../examples/shaders/example_4.vert", "main", NULL, NULL), - .tPixelShader = gptShader->load_glsl("../examples/shaders/example_4.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("example_4.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("example_4.frag", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, diff --git a/examples/example_5.c b/examples/example_5.c index 484559a8..5cb2e323 100644 --- a/examples/example_5.c +++ b/examples/example_5.c @@ -219,6 +219,10 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../examples/shaders/" + }, + .apcDirectories = { + "../shaders/", + "../examples/shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); @@ -346,8 +350,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~shaders~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const plShaderDesc tShaderDesc = { - .tVertexShader = gptShader->load_glsl("../examples/shaders/example_4.vert", "main", NULL, NULL), - .tPixelShader = gptShader->load_glsl("../examples/shaders/example_4.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("example_4.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("example_4.frag", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, diff --git a/examples/example_6.c b/examples/example_6.c index ee44f188..feb20562 100644 --- a/examples/example_6.c +++ b/examples/example_6.c @@ -249,6 +249,10 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../examples/shaders/" + }, + .apcDirectories = { + "../shaders/", + "../examples/shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); @@ -486,8 +490,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~shaders~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const plShaderDesc tShaderDesc = { - .tVertexShader = gptShader->load_glsl("../examples/shaders/example_6.vert", "main", NULL, NULL), - .tPixelShader = gptShader->load_glsl("../examples/shaders/example_6.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("example_6.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("example_6.frag", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, diff --git a/examples/example_8.c b/examples/example_8.c index b785ff2a..d59d9650 100644 --- a/examples/example_8.c +++ b/examples/example_8.c @@ -238,6 +238,9 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../examples/shaders/" + }, + .apcDirectories = { + "../shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); diff --git a/examples/example_9.c b/examples/example_9.c index 53ea4325..2a415f8d 100644 --- a/examples/example_9.c +++ b/examples/example_9.c @@ -280,6 +280,9 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plAppData* ptAppData) static const plShaderOptions tDefaultShaderOptions = { .apcIncludeDirectories = { "../examples/shaders/" + }, + .apcDirectories = { + "../shaders/" } }; gptShader->initialize(&tDefaultShaderOptions); diff --git a/extensions/pl_draw_backend_ext.c b/extensions/pl_draw_backend_ext.c index 38d9bb76..b39a2d92 100644 --- a/extensions/pl_draw_backend_ext.c +++ b/extensions/pl_draw_backend_ext.c @@ -386,8 +386,8 @@ pl__get_3d_pipeline(plRenderPassHandle tRenderPass, uint32_t uMSAASampleCount, p { const plShaderDesc t3DShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/draw_3d.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/draw_3d.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("draw_3d.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("draw_3d.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = tFlags & PL_DRAW_FLAG_DEPTH_WRITE ? 1 : 0, .ulDepthMode = tFlags & PL_DRAW_FLAG_DEPTH_TEST ? (tFlags & PL_DRAW_FLAG_REVERSE_Z_DEPTH ? PL_COMPARE_MODE_GREATER : PL_COMPARE_MODE_LESS) : PL_COMPARE_MODE_ALWAYS, @@ -430,8 +430,8 @@ pl__get_3d_pipeline(plRenderPassHandle tRenderPass, uint32_t uMSAASampleCount, p { const plShaderDesc t3DLineShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/draw_3d.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/draw_3d_line.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("draw_3d.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("draw_3d_line.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = tFlags & PL_DRAW_FLAG_DEPTH_WRITE, .ulDepthMode = tFlags & PL_DRAW_FLAG_DEPTH_TEST ? (tFlags & PL_DRAW_FLAG_REVERSE_Z_DEPTH ? PL_COMPARE_MODE_GREATER : PL_COMPARE_MODE_LESS) : PL_COMPARE_MODE_ALWAYS, @@ -499,8 +499,8 @@ pl__get_2d_pipeline(plRenderPassHandle tRenderPass, uint32_t uMSAASampleCount, u ptEntry->uSubpassIndex = uSubpassIndex; const plShaderDesc tRegularShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/draw_2d.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/draw_2d.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("draw_2d.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("draw_2d.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, @@ -554,8 +554,8 @@ pl__get_2d_pipeline(plRenderPassHandle tRenderPass, uint32_t uMSAASampleCount, u pl_temp_allocator_reset(&gptDrawBackendCtx->tTempAllocator); const plShaderDesc tSecondaryShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/draw_2d_sdf.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/draw_2d.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("draw_2d_sdf.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("draw_2d.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, diff --git a/extensions/pl_ecs_ext.c b/extensions/pl_ecs_ext.c index f1e40fed..6b2c255b 100644 --- a/extensions/pl_ecs_ext.c +++ b/extensions/pl_ecs_ext.c @@ -577,7 +577,11 @@ pl_ecs_add_component(plComponentLibrary* ptLibrary, plComponentType tType, plEnt if(bAddSlot) pl_sb_add(sbComponents); ptManager->pComponents = sbComponents; - sbComponents[uComponentIndex] = (plObjectComponent){.tMesh= {UINT32_MAX, UINT32_MAX}, .tTransform ={UINT32_MAX, UINT32_MAX}}; + sbComponents[uComponentIndex] = (plObjectComponent){ + .tFlags = PL_OBJECT_FLAGS_RENDERABLE | PL_OBJECT_FLAGS_CAST_SHADOW | PL_OBJECT_FLAGS_DYNAMIC, + .tMesh = {UINT32_MAX, UINT32_MAX}, + .tTransform = {UINT32_MAX, UINT32_MAX} + }; return &sbComponents[uComponentIndex]; } @@ -1962,6 +1966,7 @@ pl_load_ecs_ext(plApiRegistryI* ptApiRegistry, bool bReload) gptApiRegistry = ptApiRegistry; gptExtensionRegistry = pl_get_api_latest(ptApiRegistry, plExtensionRegistryI); + gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI); gptJob = pl_get_api_latest(ptApiRegistry, plJobI); gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI); gptLog = pl_get_api_latest(ptApiRegistry, plLogI); diff --git a/extensions/pl_ecs_ext.h b/extensions/pl_ecs_ext.h index 19cdd92a..3d3d64b9 100644 --- a/extensions/pl_ecs_ext.h +++ b/extensions/pl_ecs_ext.h @@ -88,6 +88,7 @@ typedef int plLightType; typedef int plHumanoidBone; typedef int plEnvironmentProbeFlags; typedef int plTransformFlags; +typedef int plObjectFlags; typedef union _plEntity { @@ -399,6 +400,15 @@ enum _plTransformFlags PL_TRANSFORM_FLAGS_DIRTY = 1 << 0, }; +enum _plObjectFlags +{ + PL_OBJECT_FLAGS_NONE = 0, + PL_OBJECT_FLAGS_RENDERABLE = 1 << 0, + PL_OBJECT_FLAGS_CAST_SHADOW = 1 << 1, + PL_OBJECT_FLAGS_DYNAMIC = 1 << 2, + PL_OBJECT_FLAGS_FOREGROUND = 1 << 3, +}; + //----------------------------------------------------------------------------- // [SECTION] structs //----------------------------------------------------------------------------- @@ -514,9 +524,10 @@ typedef struct _plLightComponent typedef struct _plObjectComponent { - plEntity tMesh; - plEntity tTransform; - plAABB tAABB; + plObjectFlags tFlags; + plEntity tMesh; + plEntity tTransform; + plAABB tAABB; } plObjectComponent; typedef struct _plHierarchyComponent diff --git a/sandbox/pl_ecs_tools.c b/extensions/pl_ecs_tools_ext.c similarity index 50% rename from sandbox/pl_ecs_tools.c rename to extensions/pl_ecs_tools_ext.c index b35f5984..820da608 100644 --- a/sandbox/pl_ecs_tools.c +++ b/extensions/pl_ecs_tools_ext.c @@ -1,123 +1,162 @@ /* - pl_ecs_tools.c + pl_ecs_tools_ext.c */ /* Index of this file: -// [SECTION] internal structs & enums -// [SECTION] internal api declarations +// [SECTION] includes // [SECTION] public api implementation -// [SECTION] internal api implementation +// [SECTION] extension loading +// [SECTION] unity build */ +//----------------------------------------------------------------------------- +// [SECTION] includes +//----------------------------------------------------------------------------- + #include "pl.h" +#include "pl_ecs_tools_ext.h" #include "pl_ecs_ext.h" #include "pl_renderer_ext.h" #include "pl_ui_ext.h" +#ifdef PL_UNITY_BUILD + #include "pl_unity_ext.inc" +#else + +static const plMemoryI* gptMemory = NULL; +static const plEcsI* gptECS = NULL; +static const plUiI* gptUI = NULL; +static const plRendererI* gptRenderer = NULL; + +#ifndef PL_DS_ALLOC + + #define PL_DS_ALLOC(x) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__) + #define PL_DS_ALLOC_INDIRECT(x, FILE, LINE) gptMemory->tracked_realloc(NULL, (x), FILE, LINE) + #define PL_DS_FREE(x) gptMemory->tracked_realloc((x), 0, __FILE__, __LINE__) +#endif + +#include "pl_ds.h" +#endif + //----------------------------------------------------------------------------- // [SECTION] public api implementation //----------------------------------------------------------------------------- -bool +static bool pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbShowWindow) { plComponentLibrary* ptLibrary = gptRenderer->get_component_library(uSceneHandle); bool bResult = false; - if(gptUi->begin_window("Entities", pbShowWindow, false)) + if(gptUI->begin_window("Entities", pbShowWindow, false)) { - const plVec2 tWindowSize = gptUi->get_window_size(); + const plVec2 tWindowSize = gptUI->get_window_size(); const float pfRatios[] = {0.5f, 0.5f}; - gptUi->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 2, pfRatios); - gptUi->text("Entities"); - gptUi->text("Components"); - gptUi->layout_dynamic(0.0f, 1); - gptUi->separator(); - gptUi->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, tWindowSize.y - 75.0f, 2, pfRatios); + gptUI->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 2, pfRatios); + gptUI->text("Entities"); + gptUI->text("Components"); + gptUI->layout_dynamic(0.0f, 1); + gptUI->separator(); + gptUI->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, tWindowSize.y - 75.0f, 2, pfRatios); - if(gptUi->begin_child("Entities", 0, 0)) + if(gptUI->begin_child("Entities", 0, 0)) { const float pfRatiosInner[] = {1.0f}; - gptUi->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatiosInner); + gptUI->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatiosInner); const uint32_t uEntityCount = pl_sb_size(ptLibrary->tTagComponentManager.sbtEntities); plTagComponent* sbtTags = ptLibrary->tTagComponentManager.pComponents; plUiClipper tClipper = {(uint32_t)uEntityCount}; - while(gptUi->step_clipper(&tClipper)) + while(gptUI->step_clipper(&tClipper)) { for(uint32_t i = tClipper.uDisplayStart; i < tClipper.uDisplayEnd; i++) { bool bSelected = ptSelectedEntity->ulData == ptLibrary->tTagComponentManager.sbtEntities[i].ulData; char atBuffer[1024] = {0}; pl_sprintf(atBuffer, "%s, %u", sbtTags[i].acName, ptLibrary->tTagComponentManager.sbtEntities[i].uIndex); - if(gptUi->selectable(atBuffer, &bSelected, 0)) + if(gptUI->selectable(atBuffer, &bSelected, 0)) { if(bSelected) { *ptSelectedEntity = ptLibrary->tTagComponentManager.sbtEntities[i]; if(ptSelectedEntity->uIndex != UINT32_MAX) bResult = true; - // gptRenderer->select_entities(ptAppData->uSceneHandle0, 1, &ptAppData->tSelectedEntity); } else { ptSelectedEntity->uIndex = UINT32_MAX; ptSelectedEntity->uGeneration = UINT32_MAX; bResult = true; - // gptRenderer->select_entities(ptAppData->uSceneHandle0, 0, NULL); } } } } - gptUi->end_child(); + gptUI->end_child(); } - if(gptUi->begin_child("Components", 0, 0)) + if(gptUI->begin_child("Components", 0, 0)) { const float pfRatiosInner[] = {1.0f}; - gptUi->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatiosInner); + gptUI->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatiosInner); if(ptSelectedEntity->ulData != UINT64_MAX) { - gptUi->push_id_uint(ptSelectedEntity->uIndex); - plTagComponent* ptTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, *ptSelectedEntity); - plTransformComponent* ptTransformComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TRANSFORM, *ptSelectedEntity); - plMeshComponent* ptMeshComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_MESH, *ptSelectedEntity); - plObjectComponent* ptObjectComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_OBJECT, *ptSelectedEntity); - plHierarchyComponent* ptHierarchyComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_HIERARCHY, *ptSelectedEntity); - plMaterialComponent* ptMaterialComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_MATERIAL, *ptSelectedEntity); - plSkinComponent* ptSkinComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_SKIN, *ptSelectedEntity); - plCameraComponent* ptCameraComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_CAMERA, *ptSelectedEntity); - plAnimationComponent* ptAnimationComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_ANIMATION, *ptSelectedEntity); - plInverseKinematicsComponent* ptIKComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_INVERSE_KINEMATICS, *ptSelectedEntity); - plLightComponent* ptLightComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_LIGHT, *ptSelectedEntity); - plEnvironmentProbeComponent* ptProbeComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_ENVIRONMENT_PROBE, *ptSelectedEntity); - plHumanoidComponent* ptHumanComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_HUMANOID, *ptSelectedEntity); - - - gptUi->text("Entity: %u, %u", ptSelectedEntity->uIndex, ptSelectedEntity->uGeneration); - - if(ptTagComp && gptUi->begin_collapsing_header("Tag", 0)) + gptUI->push_id_uint(ptSelectedEntity->uIndex); + plTagComponent* ptTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, *ptSelectedEntity); + plTransformComponent* ptTransformComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TRANSFORM, *ptSelectedEntity); + plMeshComponent* ptMeshComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_MESH, *ptSelectedEntity); + plObjectComponent* ptObjectComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_OBJECT, *ptSelectedEntity); + plHierarchyComponent* ptHierarchyComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_HIERARCHY, *ptSelectedEntity); + plMaterialComponent* ptMaterialComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_MATERIAL, *ptSelectedEntity); + plSkinComponent* ptSkinComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_SKIN, *ptSelectedEntity); + plCameraComponent* ptCameraComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_CAMERA, *ptSelectedEntity); + plAnimationComponent* ptAnimationComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_ANIMATION, *ptSelectedEntity); + plInverseKinematicsComponent* ptIKComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_INVERSE_KINEMATICS, *ptSelectedEntity); + plLightComponent* ptLightComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_LIGHT, *ptSelectedEntity); + plEnvironmentProbeComponent* ptProbeComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_ENVIRONMENT_PROBE, *ptSelectedEntity); + plHumanoidComponent* ptHumanComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_HUMANOID, *ptSelectedEntity); + + if(ptObjectComp) + { + gptUI->layout_dynamic(0.0f, 2); + gptUI->text("Entity: %u, %u", ptSelectedEntity->uIndex, ptSelectedEntity->uGeneration); + if(gptUI->button("Delete")) + { + gptRenderer->select_entities(uSceneHandle, 0, NULL); + gptRenderer->remove_objects_from_scene(uSceneHandle, 1, ptSelectedEntity); + ptSelectedEntity->ulData = UINT64_MAX; + + } + gptUI->layout_row(PL_UI_LAYOUT_ROW_TYPE_DYNAMIC, 0.0f, 1, pfRatiosInner); + } + else { - gptUi->text("Name: %s", ptTagComp->acName); - gptUi->end_collapsing_header(); + gptUI->text("Entity: %u, %u", ptSelectedEntity->uIndex, ptSelectedEntity->uGeneration); } - if(ptHumanComp && gptUi->begin_collapsing_header("Humanoid", 0)) + + + if(ptTagComp && gptUI->begin_collapsing_header("Tag", 0)) + { + gptUI->text("Name: %s", ptTagComp->acName); + gptUI->end_collapsing_header(); + } + + if(ptHumanComp && gptUI->begin_collapsing_header("Humanoid", 0)) { - gptUi->end_collapsing_header(); + gptUI->end_collapsing_header(); } - if(ptProbeComp && gptUi->begin_collapsing_header("Environment Probe", 0)) + if(ptProbeComp && gptUI->begin_collapsing_header("Environment Probe", 0)) { - gptUi->input_float3("Position", ptProbeComp->tPosition.d, NULL, 0); + gptUI->input_float3("Position", ptProbeComp->tPosition.d, NULL, 0); bool bRealTime = ptProbeComp->tFlags & PL_ENVIRONMENT_PROBE_FLAGS_REALTIME; - if(gptUi->checkbox("Real Time", &bRealTime)) + if(gptUI->checkbox("Real Time", &bRealTime)) { if(bRealTime) ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_REALTIME; @@ -126,7 +165,7 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh } bool bIncludeSky = ptProbeComp->tFlags & PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; - if(gptUi->checkbox("Include Sky", &bIncludeSky)) + if(gptUI->checkbox("Include Sky", &bIncludeSky)) { if(bIncludeSky) ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_INCLUDE_SKY; @@ -135,7 +174,7 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh } bool bParallaxCorrection = ptProbeComp->tFlags & PL_ENVIRONMENT_PROBE_FLAGS_PARALLAX_CORRECTION_BOX; - if(gptUi->checkbox("Box Parallax Correction", &bParallaxCorrection)) + if(gptUI->checkbox("Box Parallax Correction", &bParallaxCorrection)) { if(bParallaxCorrection) ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_PARALLAX_CORRECTION_BOX; @@ -143,11 +182,11 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh ptProbeComp->tFlags &= ~PL_ENVIRONMENT_PROBE_FLAGS_PARALLAX_CORRECTION_BOX; } - if(gptUi->button("Update")) + if(gptUI->button("Update")) { ptProbeComp->tFlags |= PL_ENVIRONMENT_PROBE_FLAGS_DIRTY; } - gptUi->input_float("Range:", &ptProbeComp->fRange, NULL, 0); + gptUI->input_float("Range:", &ptProbeComp->fRange, NULL, 0); uint32_t auSamples[] = { 32, @@ -164,96 +203,142 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh else if(ptProbeComp->uSamples == 256) iSelection = 3; else if(ptProbeComp->uSamples == 512) iSelection = 4; else if(ptProbeComp->uSamples == 1024) iSelection = 5; - gptUi->separator_text("Samples"); - gptUi->radio_button("32", &iSelection, 0); - gptUi->radio_button("64", &iSelection, 1); - gptUi->radio_button("128", &iSelection, 2); - gptUi->radio_button("256", &iSelection, 3); - gptUi->radio_button("512", &iSelection, 4); - gptUi->radio_button("1024", &iSelection, 5); + gptUI->separator_text("Samples"); + gptUI->radio_button("32", &iSelection, 0); + gptUI->radio_button("64", &iSelection, 1); + gptUI->radio_button("128", &iSelection, 2); + gptUI->radio_button("256", &iSelection, 3); + gptUI->radio_button("512", &iSelection, 4); + gptUI->radio_button("1024", &iSelection, 5); ptProbeComp->uSamples = auSamples[iSelection]; - gptUi->separator_text("Intervals"); + gptUI->separator_text("Intervals"); int iSelection0 = (int)ptProbeComp->uInterval; - gptUi->radio_button("1", &iSelection0, 1); - gptUi->radio_button("2", &iSelection0, 2); - gptUi->radio_button("3", &iSelection0, 3); - gptUi->radio_button("4", &iSelection0, 4); - gptUi->radio_button("5", &iSelection0, 5); - gptUi->radio_button("6", &iSelection0, 6); + gptUI->radio_button("1", &iSelection0, 1); + gptUI->radio_button("2", &iSelection0, 2); + gptUI->radio_button("3", &iSelection0, 3); + gptUI->radio_button("4", &iSelection0, 4); + gptUI->radio_button("5", &iSelection0, 5); + gptUI->radio_button("6", &iSelection0, 6); ptProbeComp->uInterval = (uint32_t)iSelection0; - gptUi->end_collapsing_header(); + gptUI->end_collapsing_header(); } - if(ptTransformComp && gptUi->begin_collapsing_header("Transform", 0)) + if(ptTransformComp && gptUI->begin_collapsing_header("Transform", 0)) { - gptUi->text("Scale: (%+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tScale.x, ptTransformComp->tScale.y, ptTransformComp->tScale.z); - gptUi->text("Translation: (%+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tTranslation.x, ptTransformComp->tTranslation.y, ptTransformComp->tTranslation.z); - gptUi->text("Rotation: (%+0.3f, %+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tRotation.x, ptTransformComp->tRotation.y, ptTransformComp->tRotation.z, ptTransformComp->tRotation.w); - gptUi->vertical_spacing(); - gptUi->text("Local World: |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].x, ptTransformComp->tWorld.col[1].x, ptTransformComp->tWorld.col[2].x, ptTransformComp->tWorld.col[3].x); - gptUi->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].y, ptTransformComp->tWorld.col[1].y, ptTransformComp->tWorld.col[2].y, ptTransformComp->tWorld.col[3].y); - gptUi->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].z, ptTransformComp->tWorld.col[1].z, ptTransformComp->tWorld.col[2].z, ptTransformComp->tWorld.col[3].z); - gptUi->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].w, ptTransformComp->tWorld.col[1].w, ptTransformComp->tWorld.col[2].w, ptTransformComp->tWorld.col[3].w); - gptUi->end_collapsing_header(); + gptUI->text("Scale: (%+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tScale.x, ptTransformComp->tScale.y, ptTransformComp->tScale.z); + gptUI->text("Translation: (%+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tTranslation.x, ptTransformComp->tTranslation.y, ptTransformComp->tTranslation.z); + gptUI->text("Rotation: (%+0.3f, %+0.3f, %+0.3f, %+0.3f)", ptTransformComp->tRotation.x, ptTransformComp->tRotation.y, ptTransformComp->tRotation.z, ptTransformComp->tRotation.w); + gptUI->vertical_spacing(); + gptUI->text("Local World: |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].x, ptTransformComp->tWorld.col[1].x, ptTransformComp->tWorld.col[2].x, ptTransformComp->tWorld.col[3].x); + gptUI->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].y, ptTransformComp->tWorld.col[1].y, ptTransformComp->tWorld.col[2].y, ptTransformComp->tWorld.col[3].y); + gptUI->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].z, ptTransformComp->tWorld.col[1].z, ptTransformComp->tWorld.col[2].z, ptTransformComp->tWorld.col[3].z); + gptUI->text(" |%+0.3f, %+0.3f, %+0.3f, %+0.3f|", ptTransformComp->tWorld.col[0].w, ptTransformComp->tWorld.col[1].w, ptTransformComp->tWorld.col[2].w, ptTransformComp->tWorld.col[3].w); + gptUI->end_collapsing_header(); } - if(ptMeshComp && gptUi->begin_collapsing_header("Mesh", 0)) + if(ptMeshComp && gptUI->begin_collapsing_header("Mesh", 0)) { - plTagComponent* ptMaterialTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptMeshComp->tMaterial); - plTagComponent* ptSkinTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptMeshComp->tSkinComponent); - gptUi->text("Material: %s, %u", ptMaterialTagComp->acName, ptMeshComp->tMaterial.uIndex); - gptUi->text("Skin: %s", ptSkinTagComp ? ptSkinTagComp->acName : " "); - - gptUi->vertical_spacing(); - gptUi->text("Vertex Data (%u verts, %u idx)", pl_sb_size(ptMeshComp->sbtVertexPositions), pl_sb_size(ptMeshComp->sbuIndices)); - gptUi->indent(15.0f); - gptUi->text("%s Positions", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_POSITION ? "ACTIVE" : " "); - gptUi->text("%s Normals", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_NORMAL ? "ACTIVE" : " "); - gptUi->text("%s Tangents", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TANGENT ? "ACTIVE" : " "); - gptUi->text("%s Texture Coordinates 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TEXCOORD_0 ? "ACTIVE" : " "); - gptUi->text("%s Texture Coordinates 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TEXCOORD_1 ? "ACTIVE" : " "); - gptUi->text("%s Colors 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_COLOR_0 ? "ACTIVE" : " "); - gptUi->text("%s Colors 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_COLOR_1 ? "ACTIVE" : " "); - gptUi->text("%s Joints 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_JOINTS_0 ? "ACTIVE" : " "); - gptUi->text("%s Joints 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_JOINTS_1 ? "ACTIVE" : " "); - gptUi->text("%s Weights 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_WEIGHTS_0 ? "ACTIVE" : " "); - gptUi->text("%s Weights 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_WEIGHTS_1 ? "ACTIVE" : " "); - gptUi->unindent(15.0f); - gptUi->end_collapsing_header(); + plTagComponent* ptMaterialTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptMeshComp->tMaterial); + plTagComponent* ptSkinTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptMeshComp->tSkinComponent); + gptUI->text("Material: %s, %u", ptMaterialTagComp->acName, ptMeshComp->tMaterial.uIndex); + gptUI->text("Skin: %s", ptSkinTagComp ? ptSkinTagComp->acName : " "); + + gptUI->vertical_spacing(); + gptUI->text("Vertex Data (%u verts, %u idx)", pl_sb_size(ptMeshComp->sbtVertexPositions), pl_sb_size(ptMeshComp->sbuIndices)); + gptUI->indent(15.0f); + gptUI->text("%s Positions", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_POSITION ? "ACTIVE" : " "); + gptUI->text("%s Normals", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_NORMAL ? "ACTIVE" : " "); + gptUI->text("%s Tangents", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TANGENT ? "ACTIVE" : " "); + gptUI->text("%s Texture Coordinates 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TEXCOORD_0 ? "ACTIVE" : " "); + gptUI->text("%s Texture Coordinates 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_TEXCOORD_1 ? "ACTIVE" : " "); + gptUI->text("%s Colors 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_COLOR_0 ? "ACTIVE" : " "); + gptUI->text("%s Colors 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_COLOR_1 ? "ACTIVE" : " "); + gptUI->text("%s Joints 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_JOINTS_0 ? "ACTIVE" : " "); + gptUI->text("%s Joints 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_JOINTS_1 ? "ACTIVE" : " "); + gptUI->text("%s Weights 0", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_WEIGHTS_0 ? "ACTIVE" : " "); + gptUI->text("%s Weights 1", ptMeshComp->ulVertexStreamMask & PL_MESH_FORMAT_FLAG_HAS_WEIGHTS_1 ? "ACTIVE" : " "); + gptUI->unindent(15.0f); + gptUI->end_collapsing_header(); } - if(ptObjectComp && gptUi->begin_collapsing_header("Object", 0)) + if(ptObjectComp && gptUI->begin_collapsing_header("Object", 0)) { - plTagComponent* ptMeshTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptObjectComp->tMesh); - plTagComponent* ptTransformTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptObjectComp->tTransform); - gptUi->text("Mesh Entity: %s, %u", ptMeshTagComp->acName, ptObjectComp->tMesh.uIndex); - gptUi->text("Transform Entity: %s, %u", ptTransformTagComp->acName, ptObjectComp->tTransform.uIndex); - gptUi->end_collapsing_header(); + plTagComponent* ptMeshTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptObjectComp->tMesh); + plTagComponent* ptTransformTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptObjectComp->tTransform); + + gptUI->text("Mesh Entity: %s, %u", ptMeshTagComp->acName, ptObjectComp->tMesh.uIndex); + gptUI->text("Transform Entity: %s, %u", ptTransformTagComp->acName, ptObjectComp->tTransform.uIndex); + + bool bObjectRenderable = ptObjectComp->tFlags & PL_OBJECT_FLAGS_RENDERABLE; + bool bObjectCastShadow = ptObjectComp->tFlags & PL_OBJECT_FLAGS_CAST_SHADOW; + bool bObjectDynamic = ptObjectComp->tFlags & PL_OBJECT_FLAGS_DYNAMIC; + bool bObjectForeground = ptObjectComp->tFlags & PL_OBJECT_FLAGS_FOREGROUND; + bool bObjectUpdateRequired = false; + + if(gptUI->checkbox("Renderable", &bObjectRenderable)) + { + bObjectUpdateRequired = true; + if(bObjectRenderable) + ptObjectComp->tFlags |= PL_OBJECT_FLAGS_RENDERABLE; + else + ptObjectComp->tFlags &= ~PL_OBJECT_FLAGS_RENDERABLE; + } + + if(gptUI->checkbox("Cast Shadow", &bObjectCastShadow)) + { + bObjectUpdateRequired = true; + bObjectUpdateRequired = true; + if(bObjectCastShadow) + ptObjectComp->tFlags |= PL_OBJECT_FLAGS_CAST_SHADOW; + else + ptObjectComp->tFlags &= ~PL_OBJECT_FLAGS_CAST_SHADOW; + } + + if(gptUI->checkbox("Dynamic", &bObjectDynamic)) + { + bObjectUpdateRequired = true; + if(bObjectDynamic) + ptObjectComp->tFlags |= PL_OBJECT_FLAGS_DYNAMIC; + else + ptObjectComp->tFlags &= ~PL_OBJECT_FLAGS_DYNAMIC; + } + + if(gptUI->checkbox("Foreground", &bObjectForeground)) + { + bObjectUpdateRequired = true; + if(bObjectForeground) + ptObjectComp->tFlags |= PL_OBJECT_FLAGS_FOREGROUND; + else + ptObjectComp->tFlags &= ~PL_OBJECT_FLAGS_FOREGROUND; + } + if(bObjectUpdateRequired) + gptRenderer->update_scene_objects(uSceneHandle, 1, ptSelectedEntity); + gptUI->end_collapsing_header(); } - if(ptHierarchyComp && gptUi->begin_collapsing_header("Hierarchy", 0)) + if(ptHierarchyComp && gptUI->begin_collapsing_header("Hierarchy", 0)) { - plTagComponent* ptParentTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptHierarchyComp->tParent); - gptUi->text("Parent Entity: %s , %u", ptParentTagComp->acName, ptHierarchyComp->tParent.uIndex); - gptUi->end_collapsing_header(); + plTagComponent* ptParentTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptHierarchyComp->tParent); + gptUI->text("Parent Entity: %s , %u", ptParentTagComp->acName, ptHierarchyComp->tParent.uIndex); + gptUI->end_collapsing_header(); } - if(ptLightComp && gptUi->begin_collapsing_header("Light", 0)) + if(ptLightComp && gptUI->begin_collapsing_header("Light", 0)) { static const char* apcLightTypes[] = { "PL_LIGHT_TYPE_DIRECTIONAL", "PL_LIGHT_TYPE_POINT", "PL_LIGHT_TYPE_SPOT", }; - gptUi->text("Type: %s", apcLightTypes[ptLightComp->tType]); + gptUI->text("Type: %s", apcLightTypes[ptLightComp->tType]); bool bShowVisualizer = ptLightComp->tFlags & PL_LIGHT_FLAG_VISUALIZER; - if(gptUi->checkbox("Visualizer:", &bShowVisualizer)) + if(gptUI->checkbox("Visualizer:", &bShowVisualizer)) { if(bShowVisualizer) ptLightComp->tFlags |= PL_LIGHT_FLAG_VISUALIZER; @@ -261,40 +346,40 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh ptLightComp->tFlags &= ~PL_LIGHT_FLAG_VISUALIZER; } - gptUi->input_float3("Position:", ptLightComp->tPosition.d, NULL, 0); + gptUI->input_float3("Position:", ptLightComp->tPosition.d, NULL, 0); - gptUi->separator_text("Color"); - gptUi->slider_float("r", &ptLightComp->tColor.x, 0.0f, 1.0f, 0); - gptUi->slider_float("g", &ptLightComp->tColor.y, 0.0f, 1.0f, 0); - gptUi->slider_float("b", &ptLightComp->tColor.z, 0.0f, 1.0f, 0); + gptUI->separator_text("Color"); + gptUI->slider_float("r", &ptLightComp->tColor.x, 0.0f, 1.0f, 0); + gptUI->slider_float("g", &ptLightComp->tColor.y, 0.0f, 1.0f, 0); + gptUI->slider_float("b", &ptLightComp->tColor.z, 0.0f, 1.0f, 0); - gptUi->slider_float("Intensity", &ptLightComp->fIntensity, 0.0f, 20.0f, 0); + gptUI->slider_float("Intensity", &ptLightComp->fIntensity, 0.0f, 20.0f, 0); if(ptLightComp->tType != PL_LIGHT_TYPE_DIRECTIONAL) { - gptUi->input_float("Radius:", &ptLightComp->fRadius, NULL, 0); - gptUi->input_float("Range", &ptLightComp->fRange, NULL, 0); + gptUI->input_float("Radius:", &ptLightComp->fRadius, NULL, 0); + gptUI->input_float("Range", &ptLightComp->fRange, NULL, 0); } if(ptLightComp->tType == PL_LIGHT_TYPE_SPOT) { - gptUi->slider_float("Inner Cone Angle:", &ptLightComp->fInnerConeAngle, 0.0f, PL_PI_2, 0); - gptUi->slider_float("Outer Cone Angle", &ptLightComp->fOuterConeAngle, 0.0f, PL_PI_2, 0); + gptUI->slider_float("Inner Cone Angle:", &ptLightComp->fInnerConeAngle, 0.0f, PL_PI_2, 0); + gptUI->slider_float("Outer Cone Angle", &ptLightComp->fOuterConeAngle, 0.0f, PL_PI_2, 0); } if(ptLightComp->tType != PL_LIGHT_TYPE_POINT) { - gptUi->separator_text("Direction"); - gptUi->slider_float("x", &ptLightComp->tDirection.x, -1.0f, 1.0f, 0); - gptUi->slider_float("y", &ptLightComp->tDirection.y, -1.0f, 1.0f, 0); - gptUi->slider_float("z", &ptLightComp->tDirection.z, -1.0f, 1.0f, 0); + gptUI->separator_text("Direction"); + gptUI->slider_float("x", &ptLightComp->tDirection.x, -1.0f, 1.0f, 0); + gptUI->slider_float("y", &ptLightComp->tDirection.y, -1.0f, 1.0f, 0); + gptUI->slider_float("z", &ptLightComp->tDirection.z, -1.0f, 1.0f, 0); } - gptUi->separator_text("Shadows"); + gptUI->separator_text("Shadows"); bool bCastShadow = ptLightComp->tFlags & PL_LIGHT_FLAG_CAST_SHADOW; - if(gptUi->checkbox("Cast Shadow:", &bCastShadow)) + if(gptUI->checkbox("Cast Shadow:", &bCastShadow)) { if(bCastShadow) ptLightComp->tFlags |= PL_LIGHT_FLAG_CAST_SHADOW; @@ -317,38 +402,38 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh else if(ptLightComp->uShadowResolution == 512) iSelection = 2; else if(ptLightComp->uShadowResolution == 1024) iSelection = 3; else if(ptLightComp->uShadowResolution == 2048) iSelection = 4; - gptUi->radio_button("Resolution: 128", &iSelection, 0); - gptUi->radio_button("Resolution: 256", &iSelection, 1); - gptUi->radio_button("Resolution: 512", &iSelection, 2); - gptUi->radio_button("Resolution: 1024", &iSelection, 3); - gptUi->radio_button("Resolution: 2048", &iSelection, 4); + gptUI->radio_button("Resolution: 128", &iSelection, 0); + gptUI->radio_button("Resolution: 256", &iSelection, 1); + gptUI->radio_button("Resolution: 512", &iSelection, 2); + gptUI->radio_button("Resolution: 1024", &iSelection, 3); + gptUI->radio_button("Resolution: 2048", &iSelection, 4); ptLightComp->uShadowResolution = auResolutions[iSelection]; } if(ptLightComp->tType == PL_LIGHT_TYPE_DIRECTIONAL) { int iCascadeCount = (int)ptLightComp->uCascadeCount; - if(gptUi->slider_int("Cascades", &iCascadeCount, 1, 4, 0)) + if(gptUI->slider_int("Cascades", &iCascadeCount, 1, 4, 0)) { ptLightComp->uCascadeCount = (uint32_t)iCascadeCount; } // int iResolution = (int)ptLight->uShadowResolution; - gptUi->input_float4("Cascade Splits", ptLightComp->afCascadeSplits, NULL, 0); + gptUI->input_float4("Cascade Splits", ptLightComp->afCascadeSplits, NULL, 0); } - gptUi->end_collapsing_header(); + gptUI->end_collapsing_header(); } - if(ptMaterialComp && gptUi->begin_collapsing_header("Material", 0)) + if(ptMaterialComp && gptUI->begin_collapsing_header("Material", 0)) { bool bMaterialModified = false; - if(gptUi->input_float("Roughness", &ptMaterialComp->fRoughness, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float("Metalness", &ptMaterialComp->fMetalness, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float("Alpha Cutoff", &ptMaterialComp->fAlphaCutoff, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float("Normal Map Strength", &ptMaterialComp->fNormalMapStrength, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float("Occulusion Map Strength", &ptMaterialComp->fOcclusionMapStrength, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float4("Base Factor", ptMaterialComp->tBaseColor.d, NULL, 0)) bMaterialModified = true; - if(gptUi->input_float4("Emmissive Factor", ptMaterialComp->tEmissiveColor.d, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float("Roughness", &ptMaterialComp->fRoughness, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float("Metalness", &ptMaterialComp->fMetalness, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float("Alpha Cutoff", &ptMaterialComp->fAlphaCutoff, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float("Normal Map Strength", &ptMaterialComp->fNormalMapStrength, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float("Occulusion Map Strength", &ptMaterialComp->fOcclusionMapStrength, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float4("Base Factor", ptMaterialComp->tBaseColor.d, NULL, 0)) bMaterialModified = true; + if(gptUI->input_float4("Emmissive Factor", ptMaterialComp->tEmissiveColor.d, NULL, 0)) bMaterialModified = true; if(bMaterialModified) gptRenderer->update_scene_materials(uSceneHandle, 1, ptSelectedEntity); @@ -362,7 +447,7 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh "PL_MATERIAL_BLEND_MODE_MULTIPLY", "PL_MATERIAL_BLEND_MODE_CLIP_MASK" }; - gptUi->text("Blend Mode: %s", apcBlendModeNames[ptMaterialComp->tBlendMode]); + gptUI->text("Blend Mode: %s", apcBlendModeNames[ptMaterialComp->tBlendMode]); static const char* apcShaderNames[] = { @@ -370,12 +455,12 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh "PL_SHADER_TYPE_UNLIT", "PL_SHADER_TYPE_CUSTOM" }; - gptUi->text("Shader Type: %s", apcShaderNames[ptMaterialComp->tShaderType]); - gptUi->text("Double Sided: %s", ptMaterialComp->tFlags & PL_MATERIAL_FLAG_DOUBLE_SIDED ? "true" : "false"); + gptUI->text("Shader Type: %s", apcShaderNames[ptMaterialComp->tShaderType]); + gptUI->text("Double Sided: %s", ptMaterialComp->tFlags & PL_MATERIAL_FLAG_DOUBLE_SIDED ? "true" : "false"); - gptUi->vertical_spacing(); - gptUi->text("Texture Maps"); - gptUi->indent(15.0f); + gptUI->vertical_spacing(); + gptUI->text("Texture Maps"); + gptUI->indent(15.0f); static const char* apcTextureSlotNames[] = { @@ -400,103 +485,143 @@ pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool* pbSh for(uint32_t i = 0; i < PL_TEXTURE_SLOT_COUNT; i++) { - gptUi->text("%s: %s", apcTextureSlotNames[i], ptMaterialComp->atTextureMaps[i].acName[0] == 0 ? " " : "present"); + gptUI->text("%s: %s", apcTextureSlotNames[i], ptMaterialComp->atTextureMaps[i].acName[0] == 0 ? " " : "present"); } - gptUi->unindent(15.0f); - gptUi->end_collapsing_header(); + gptUI->unindent(15.0f); + gptUI->end_collapsing_header(); } - if(ptSkinComp && gptUi->begin_collapsing_header("Skin", 0)) + if(ptSkinComp && gptUI->begin_collapsing_header("Skin", 0)) { - if(gptUi->tree_node("Joints", 0)) + if(gptUI->tree_node("Joints", 0)) { for(uint32_t i = 0; i < pl_sb_size(ptSkinComp->sbtJoints); i++) { - plTagComponent* ptJointTagComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptSkinComp->sbtJoints[i]); - gptUi->text("%s", ptJointTagComp->acName); + plTagComponent* ptJointTagComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptSkinComp->sbtJoints[i]); + gptUI->text("%s", ptJointTagComp->acName); } - gptUi->tree_pop(); + gptUI->tree_pop(); } - gptUi->end_collapsing_header(); + gptUI->end_collapsing_header(); } - if(ptCameraComp && gptUi->begin_collapsing_header("Camera", 0)) + if(ptCameraComp && gptUI->begin_collapsing_header("Camera", 0)) { - gptUi->text("Near Z: %+0.3f", ptCameraComp->fNearZ); - gptUi->text("Far Z: %+0.3f", ptCameraComp->fFarZ); - gptUi->text("Vertical Field of View: %+0.3f", ptCameraComp->fFieldOfView); - gptUi->text("Aspect Ratio: %+0.3f", ptCameraComp->fAspectRatio); - gptUi->text("Pitch: %+0.3f", ptCameraComp->fPitch); - gptUi->text("Yaw: %+0.3f", ptCameraComp->fYaw); - gptUi->text("Roll: %+0.3f", ptCameraComp->fRoll); - gptUi->text("Position: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->tPos.x, ptCameraComp->tPos.y, ptCameraComp->tPos.z); - gptUi->text("Up: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tUpVec.x, ptCameraComp->_tUpVec.y, ptCameraComp->_tUpVec.z); - gptUi->text("Forward: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tForwardVec.x, ptCameraComp->_tForwardVec.y, ptCameraComp->_tForwardVec.z); - gptUi->text("Right: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tRightVec.x, ptCameraComp->_tRightVec.y, ptCameraComp->_tRightVec.z); - gptUi->input_float3("Position", ptCameraComp->tPos.d, NULL, 0); - gptUi->input_float("Near Z Plane", &ptCameraComp->fNearZ, NULL, 0); - gptUi->input_float("Far Z Plane", &ptCameraComp->fFarZ, NULL, 0); - gptUi->end_collapsing_header(); + gptUI->text("Near Z: %+0.3f", ptCameraComp->fNearZ); + gptUI->text("Far Z: %+0.3f", ptCameraComp->fFarZ); + gptUI->text("Vertical Field of View: %+0.3f", ptCameraComp->fFieldOfView); + gptUI->text("Aspect Ratio: %+0.3f", ptCameraComp->fAspectRatio); + gptUI->text("Pitch: %+0.3f", ptCameraComp->fPitch); + gptUI->text("Yaw: %+0.3f", ptCameraComp->fYaw); + gptUI->text("Roll: %+0.3f", ptCameraComp->fRoll); + gptUI->text("Position: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->tPos.x, ptCameraComp->tPos.y, ptCameraComp->tPos.z); + gptUI->text("Up: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tUpVec.x, ptCameraComp->_tUpVec.y, ptCameraComp->_tUpVec.z); + gptUI->text("Forward: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tForwardVec.x, ptCameraComp->_tForwardVec.y, ptCameraComp->_tForwardVec.z); + gptUI->text("Right: (%+0.3f, %+0.3f, %+0.3f)", ptCameraComp->_tRightVec.x, ptCameraComp->_tRightVec.y, ptCameraComp->_tRightVec.z); + gptUI->input_float3("Position", ptCameraComp->tPos.d, NULL, 0); + gptUI->input_float("Near Z Plane", &ptCameraComp->fNearZ, NULL, 0); + gptUI->input_float("Far Z Plane", &ptCameraComp->fFarZ, NULL, 0); + gptUI->end_collapsing_header(); } - if(ptAnimationComp && gptUi->begin_collapsing_header("Animation", 0)) + if(ptAnimationComp && gptUI->begin_collapsing_header("Animation", 0)) { bool bPlaying = ptAnimationComp->tFlags & PL_ANIMATION_FLAG_PLAYING; bool bLooped = ptAnimationComp->tFlags & PL_ANIMATION_FLAG_LOOPED; if(bLooped && bPlaying) - gptUi->text("Status: playing & looped"); + gptUI->text("Status: playing & looped"); else if(bPlaying) - gptUi->text("Status: playing"); + gptUI->text("Status: playing"); else if(bLooped) - gptUi->text("Status: looped"); + gptUI->text("Status: looped"); else - gptUi->text("Status: not playing"); - if(gptUi->checkbox("Playing", &bPlaying)) + gptUI->text("Status: not playing"); + if(gptUI->checkbox("Playing", &bPlaying)) { if(bPlaying) ptAnimationComp->tFlags |= PL_ANIMATION_FLAG_PLAYING; else ptAnimationComp->tFlags &= ~PL_ANIMATION_FLAG_PLAYING; } - if(gptUi->checkbox("Looped", &bLooped)) + if(gptUI->checkbox("Looped", &bLooped)) { if(bLooped) ptAnimationComp->tFlags |= PL_ANIMATION_FLAG_LOOPED; else ptAnimationComp->tFlags &= ~PL_ANIMATION_FLAG_LOOPED; } - gptUi->text("Start: %0.3f s", ptAnimationComp->fStart); - gptUi->text("End: %0.3f s", ptAnimationComp->fEnd); - gptUi->progress_bar(ptAnimationComp->fTimer / (ptAnimationComp->fEnd - ptAnimationComp->fStart), (plVec2){-1.0f, 0.0f}, NULL); - gptUi->text("Speed: %0.3f s", ptAnimationComp->fSpeed); - gptUi->end_collapsing_header(); + gptUI->text("Start: %0.3f s", ptAnimationComp->fStart); + gptUI->text("End: %0.3f s", ptAnimationComp->fEnd); + gptUI->progress_bar(ptAnimationComp->fTimer / (ptAnimationComp->fEnd - ptAnimationComp->fStart), (plVec2){-1.0f, 0.0f}, NULL); + gptUI->text("Speed: %0.3f s", ptAnimationComp->fSpeed); + gptUI->end_collapsing_header(); } - if(ptIKComp && gptUi->begin_collapsing_header("Inverse Kinematics", 0)) + if(ptIKComp && gptUI->begin_collapsing_header("Inverse Kinematics", 0)) { - plTagComponent* ptTargetComp = gptEcs->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptIKComp->tTarget); - gptUi->text("Target Entity: %s , %u", ptTargetComp->acName, ptIKComp->tTarget.uIndex); + plTagComponent* ptTargetComp = gptECS->get_component(ptLibrary, PL_COMPONENT_TYPE_TAG, ptIKComp->tTarget); + gptUI->text("Target Entity: %s , %u", ptTargetComp->acName, ptIKComp->tTarget.uIndex); int iChainLength = (int)ptIKComp->uChainLength; - gptUi->slider_int("Chain Length", &iChainLength, 1, 5, 0); + gptUI->slider_int("Chain Length", &iChainLength, 1, 5, 0); ptIKComp->uChainLength = (uint32_t)iChainLength; - // gptUi->text("Chain Length: %u", ptIKComp->uChainLength); - gptUi->text("Iterations: %u", ptIKComp->uIterationCount); + // gptUI->text("Chain Length: %u", ptIKComp->uChainLength); + gptUI->text("Iterations: %u", ptIKComp->uIterationCount); - gptUi->checkbox("Enabled", &ptIKComp->bEnabled); - gptUi->end_collapsing_header(); + gptUI->checkbox("Enabled", &ptIKComp->bEnabled); + gptUI->end_collapsing_header(); } - gptUi->pop_id(); + gptUI->pop_id(); } - gptUi->end_child(); + gptUI->end_child(); } - gptUi->end_window(); + gptUI->end_window(); } return bResult; -} \ No newline at end of file +} + +//----------------------------------------------------------------------------- +// [SECTION] extension loading +//----------------------------------------------------------------------------- + +PL_EXPORT void +pl_load_ecs_tools_ext(plApiRegistryI* ptApiRegistry, bool bReload) +{ + const plEcsToolsI tApi = { + .show_ecs_window = pl_show_ecs_window + }; + pl_set_api(ptApiRegistry, plEcsToolsI, &tApi); + + gptMemory = pl_get_api_latest(ptApiRegistry, plMemoryI); + gptRenderer = pl_get_api_latest(ptApiRegistry, plRendererI); + gptUI = pl_get_api_latest(ptApiRegistry, plUiI); + gptECS = pl_get_api_latest(ptApiRegistry, plEcsI); +} + +PL_EXPORT void +pl_unload_ecs_tools_ext(plApiRegistryI* ptApiRegistry, bool bReload) +{ + if(bReload) + return; + + const plEcsToolsI* ptApi = pl_get_api_latest(ptApiRegistry, plEcsToolsI); + ptApiRegistry->remove_api(ptApi); +} + +//----------------------------------------------------------------------------- +// [SECTION] unity build +//----------------------------------------------------------------------------- + +#ifndef PL_UNITY_BUILD + #ifdef PL_USE_STB_SPRINTF + #define STB_SPRINTF_IMPLEMENTATION + #include "stb_sprintf.h" + #undef STB_SPRINTF_IMPLEMENTATION + #endif +#endif \ No newline at end of file diff --git a/sandbox/pl_ecs_tools.h b/extensions/pl_ecs_tools_ext.h similarity index 58% rename from sandbox/pl_ecs_tools.h rename to extensions/pl_ecs_tools_ext.h index 0e2d6e9b..aa286ec4 100644 --- a/sandbox/pl_ecs_tools.h +++ b/extensions/pl_ecs_tools_ext.h @@ -1,27 +1,34 @@ - /* - pl_ecs_tools.h + pl_ecs_tools_ext.h */ /* Index of this file: // [SECTION] header mess +// [SECTION] APIs // [SECTION] includes // [SECTION] forward declarations -// [SECTION] public api +// [SECTION] public api structs */ //----------------------------------------------------------------------------- // [SECTION] header mess //----------------------------------------------------------------------------- -#ifndef PL_ECS_TOOLS_H -#define PL_ECS_TOOLS_H +#ifndef PL_ECS_TOOLS_EXT_H +#define PL_ECS_TOOLS_EXT_H + +//----------------------------------------------------------------------------- +// [SECTION] APIs +//----------------------------------------------------------------------------- + +#define plEcsToolsI_version (plVersion){0, 1, 0} //----------------------------------------------------------------------------- // [SECTION] includes //----------------------------------------------------------------------------- +#include #include //----------------------------------------------------------------------------- @@ -29,14 +36,15 @@ Index of this file: //----------------------------------------------------------------------------- // external -typedef struct _plApiRegistryI plApiRegistryI; // pl.h -typedef struct _plComponentLibrary plComponentLibrary; // pl_ecs_ext.h -typedef union _plEntity plEntity; +typedef union _plEntity plEntity; // pl_ecs_ext.h //----------------------------------------------------------------------------- -// [SECTION] public api +// [SECTION] public api structs //----------------------------------------------------------------------------- -bool pl_show_ecs_window(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool*); +typedef struct _plEcsToolsI +{ + bool (*show_ecs_window)(plEntity* ptSelectedEntity, uint32_t uSceneHandle, bool*); +} plEcsToolsI; -#endif // PL_ECS_TOOLS_H \ No newline at end of file +#endif // PL_ECS_TOOLS_EXT_H \ No newline at end of file diff --git a/sandbox/pl_gizmo.c b/extensions/pl_gizmo_ext.c similarity index 69% rename from sandbox/pl_gizmo.c rename to extensions/pl_gizmo_ext.c index 3c5bbd3a..b2059344 100644 --- a/sandbox/pl_gizmo.c +++ b/extensions/pl_gizmo_ext.c @@ -1,29 +1,44 @@ /* - pl_gizmo.c - - TODO: lots of optimizing and cleanup + pl_gizmo_ext.c */ /* Index of this file: +// [SECTION] includes // [SECTION] internal structs & enums +// [SECTION] context // [SECTION] internal api declarations // [SECTION] public api implementation // [SECTION] internal api implementation +// [SECTION] extension loading +// [SECTION] unity build */ //----------------------------------------------------------------------------- -// [SECTION] internal structs & enums +// [SECTION] includes //----------------------------------------------------------------------------- -typedef enum _plSelectionMode -{ - PL_SELECTION_MODE_NONE, - PL_SELECTION_MODE_TRANSLATION, - PL_SELECTION_MODE_ROTATION, - PL_SELECTION_MODE_SCALE, +#include "pl.h" +#include +#include +#include "pl_gizmo_ext.h" +#include "pl_draw_ext.h" +#include "pl_ecs_ext.h" +#include "pl_ui_ext.h" +#define PL_MATH_INCLUDE_FUNCTIONS +#include "pl_math.h" + +#ifdef PL_UNITY_BUILD + #include "pl_unity_ext.inc" +#else +static const plUiI* gptUI = NULL; +static const plDrawI* gptDraw = NULL; +static const plIOI* gptIOI = NULL; +#endif - PL_SELECTION_MODE_COUNT, -} plSelectionMode; +//----------------------------------------------------------------------------- +// [SECTION] internal structs & enums +//----------------------------------------------------------------------------- typedef enum _plGizmoState { @@ -43,22 +58,28 @@ typedef enum _plGizmoState PL_GIZMO_STATE_SCALE, } plGizmoState; -typedef struct _plGizmoData +typedef struct _plGizmoContext { - plSelectionMode tSelectionMode; - plGizmoState tState; - float fCaptureScale; - plVec3 tBeginPos; - plVec3 tOriginalPos; - float fOriginalDist; - float fOriginalDistX; - float fOriginalDistY; - float fOriginalDistZ; - float fOriginalScaleX; - float fOriginalScaleY; - float fOriginalScaleZ; - plVec4 tOriginalRot; -} plGizmoData; + plGizmoMode tSelectionMode; + plGizmoState tState; + float fCaptureScale; + plVec3 tBeginPos; + plVec3 tOriginalPos; + float fOriginalDist; + float fOriginalDistX; + float fOriginalDistY; + float fOriginalDistZ; + float fOriginalScaleX; + float fOriginalScaleY; + float fOriginalScaleZ; + plVec4 tOriginalRot; +} plGizmoContext; + +//----------------------------------------------------------------------------- +// [SECTION] context +//----------------------------------------------------------------------------- + +static plGizmoContext* gptGizmoCtx = NULL; //----------------------------------------------------------------------------- // [SECTION] internal api declarations @@ -66,67 +87,53 @@ typedef struct _plGizmoData static bool pl__does_line_intersect_cylinder(plVec3 tP0, plVec3 tV0, plVec3 tP1, plVec3 tV1, float fRadius, float fHeight, float* pfDistance); static bool pl__does_line_intersect_plane (plVec3 tP0, plVec3 tV0, plVec4 tPlane, plVec3* ptQ); -static void pl__gizmo_translation(plGizmoData*, plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); -static void pl__gizmo_rotation(plGizmoData*, plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); -static void pl__gizmo_scale(plGizmoData*, plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); - +static void pl__gizmo_translation (plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); +static void pl__gizmo_rotation (plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); +static void pl__gizmo_scale (plDrawList3D*, plCameraComponent*, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform); //----------------------------------------------------------------------------- // [SECTION] public api implementation //----------------------------------------------------------------------------- -plGizmoData* -pl_initialize_gizmo_data(void) +static void +pl_gizmo_set_mode(plGizmoMode tMode) { - static plGizmoData tData = { - .tSelectionMode = PL_SELECTION_MODE_TRANSLATION - }; - return &tData; + gptGizmoCtx->tSelectionMode = tMode; } -void -pl_change_gizmo_mode(plGizmoData* ptGizmoData) +static void +pl_gizmo_next_mode(void) { - ptGizmoData->tSelectionMode = (ptGizmoData->tSelectionMode + 1) % PL_SELECTION_MODE_COUNT; + gptGizmoCtx->tSelectionMode = (gptGizmoCtx->tSelectionMode + 1) % PL_GIZMO_MODE_COUNT; } -void -pl_gizmo(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plComponentLibrary* ptMainComponentLibrary, plCameraComponent* ptCamera, plEntity tSelectedEntity) +static void +pl_gizmo(plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) { - plObjectComponent* ptSelectedObject = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tSelectedEntity); - plTransformComponent* ptSelectedTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, tSelectedEntity); - plTransformComponent* ptParentTransform = NULL; - plHierarchyComponent* ptHierarchyComp = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_HIERARCHY, tSelectedEntity); - if(ptHierarchyComp) - { - ptParentTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptHierarchyComp->tParent); - } - if(ptSelectedObject) - ptSelectedTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptSelectedObject->tTransform); if(ptSelectedTransform) { plVec3* ptCenter = &ptSelectedTransform->tWorld.col[3].xyz; - if(ptGizmoData->tState == PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_DEFAULT) { - ptGizmoData->fCaptureScale = pl_length_vec3(pl_sub_vec3(*ptCenter, ptCamera->tPos)) * 0.75f; + gptGizmoCtx->fCaptureScale = pl_length_vec3(pl_sub_vec3(*ptCenter, ptCamera->tPos)) * 0.75f; } - switch(ptGizmoData->tSelectionMode) + switch(gptGizmoCtx->tSelectionMode) { - case PL_SELECTION_MODE_TRANSLATION: - pl__gizmo_translation(ptGizmoData, ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); + case PL_GIZMO_MODE_TRANSLATION: + pl__gizmo_translation(ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); ptSelectedTransform->tFlags |= PL_TRANSFORM_FLAGS_DIRTY; break; - case PL_SELECTION_MODE_ROTATION: - pl__gizmo_rotation(ptGizmoData, ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); + case PL_GIZMO_MODE_ROTATION: + pl__gizmo_rotation(ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); ptSelectedTransform->tFlags |= PL_TRANSFORM_FLAGS_DIRTY; break; - case PL_SELECTION_MODE_SCALE: - pl__gizmo_scale(ptGizmoData, ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); + case PL_GIZMO_MODE_SCALE: + pl__gizmo_scale(ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); ptSelectedTransform->tFlags |= PL_TRANSFORM_FLAGS_DIRTY; break; - case PL_SELECTION_MODE_NONE: + case PL_GIZMO_MODE_NONE: default: break; @@ -138,34 +145,6 @@ pl_gizmo(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plComponentLib // [SECTION] internal api implementation //----------------------------------------------------------------------------- -// static float -// pl__distance_line_line(plVec3 tP0, plVec3 tV0, plVec3 tP1, plVec3 tV1) -// { -// plVec3 tDp = pl_sub_vec3(tP1, tP0); - -// float fV12 = pl_dot_vec3(tV0, tV0); -// float fV22 = pl_dot_vec3(tV1, tV1); -// float fV1V2 = pl_dot_vec3(tV0, tV1); - -// float fDet = fV1V2 * fV1V2 - fV12 * fV22; - -// if(fabsf(fDet) > FLT_MIN) -// { -// fDet = 1.0f / fDet; -// float fDpv1 = pl_dot_vec3(tDp, tV0); -// float fDpv2 = pl_dot_vec3(tDp, tV1); - -// float fT1 = (fV1V2 * fDpv2 - fV22 * fDpv1) * fDet; -// float fT2 = (fV12 * fDpv2 - fV1V2 * fDpv1) * fDet; - -// return pl_length_vec3(pl_add_vec3(tDp, pl_sub_vec3(pl_mul_vec3_scalarf(tV1, fT2), pl_mul_vec3_scalarf(tV0, fT1)))); -// } - -// // lines are nearly parallel -// plVec3 tA = pl_cross_vec3(tDp, tV1); -// return sqrtf(pl_dot_vec3(tA, tA) / fV12); -// } - static bool pl__does_line_intersect_cylinder(plVec3 tP0, plVec3 tV0, plVec3 tP1, plVec3 tV1, float fRadius, float fHeight, float* pfDistance) { @@ -211,14 +190,14 @@ pl__does_line_intersect_plane(plVec3 tP0, plVec3 tV0, plVec4 tPlane, plVec3* ptQ } static void -pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) +pl__gizmo_translation(plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) { plVec3* ptCenter = &ptSelectedTransform->tWorld.col[3].xyz; - plVec2 tMousePos = gptIO->get_mouse_pos(); + plVec2 tMousePos = gptIOI->get_mouse_pos(); - if(gptUi->wants_mouse_capture()) + if(gptUI->wants_mouse_capture()) { tMousePos.x = -1.0f; tMousePos.y = -1.0f; @@ -227,24 +206,24 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p plMat4 tTransform = pl_mul_mat4(&ptCamera->tProjMat, &ptCamera->tViewMat); tTransform = pl_mat4_invert(&tTransform); - plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIO->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIO->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; + plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIOI->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIOI->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; tNDC = pl_mul_mat4_vec4(&tTransform, tNDC); tNDC = pl_div_vec4_scalarf(tNDC, tNDC.w); - const float fAxisRadius = 0.0035f * ptGizmoData->fCaptureScale; - const float fArrowRadius = 0.0075f * ptGizmoData->fCaptureScale; - const float fArrowLength = 0.03f * ptGizmoData->fCaptureScale; - const float fLength = 0.15f * ptGizmoData->fCaptureScale; + const float fAxisRadius = 0.0035f * gptGizmoCtx->fCaptureScale; + const float fArrowRadius = 0.0075f * gptGizmoCtx->fCaptureScale; + const float fArrowLength = 0.03f * gptGizmoCtx->fCaptureScale; + const float fLength = 0.15f * gptGizmoCtx->fCaptureScale; - if(ptGizmoData->tState != PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState != PL_GIZMO_STATE_DEFAULT) { - gptDraw->add_3d_sphere_filled(ptGizmoDrawlist, (plDrawSphereDesc){.tCenter = ptGizmoData->tBeginPos, .fRadius = fAxisRadius * 2}, (plDrawSolidOptions){.uColor = PL_COLOR_32_RGBA(0.5f, 0.5f, 0.5f, 0.5f)}); - gptDraw->add_3d_line(ptGizmoDrawlist, ptGizmoData->tBeginPos, *ptCenter, (plDrawLineOptions){.uColor = PL_COLOR_32_YELLOW, .fThickness = fAxisRadius}); + gptDraw->add_3d_sphere_filled(ptGizmoDrawlist, (plDrawSphereDesc){.tCenter = gptGizmoCtx->tBeginPos, .fRadius = fAxisRadius * 2}, (plDrawSolidOptions){.uColor = PL_COLOR_32_RGBA(0.5f, 0.5f, 0.5f, 0.5f)}); + gptDraw->add_3d_line(ptGizmoDrawlist, gptGizmoCtx->tBeginPos, *ptCenter, (plDrawLineOptions){.uColor = PL_COLOR_32_YELLOW, .fThickness = fAxisRadius}); char acTextBuffer[256] = {0}; - pl_sprintf(acTextBuffer, "offset: %0.3f, %0.3f, %0.3f", ptCenter->x - ptGizmoData->tBeginPos.x, ptCenter->y - ptGizmoData->tBeginPos.y, ptCenter->z - ptGizmoData->tBeginPos.z); + pl_sprintf(acTextBuffer, "offset: %0.3f, %0.3f, %0.3f", ptCenter->x - gptGizmoCtx->tBeginPos.x, ptCenter->y - gptGizmoCtx->tBeginPos.y, ptCenter->z - gptGizmoCtx->tBeginPos.z); gptDraw->add_3d_text(ptGizmoDrawlist, (plVec3){ptCenter->x, ptCenter->y + fLength * 1.1f, ptCenter->z}, acTextBuffer, (plDrawTextOptions){ - .ptFont = gptUi->get_default_font(), + .ptFont = gptUI->get_default_font(), .uColor = PL_COLOR_32_YELLOW }); }; @@ -283,7 +262,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p (tXYIntersectionPoint.y > ptCenter->y + fLength * 0.125f) && (tXYIntersectionPoint.y < ptCenter->y + fLength * 0.375f); - if(ptGizmoData->tState == PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_DEFAULT) { const float apf[6] = { bXSelected ? pl_length_vec3(pl_sub_vec3((plVec3){ptCenter->x + fXDistanceAlong, ptCenter->y, ptCenter->z}, ptCamera->tPos)) : FLT_MAX, @@ -330,7 +309,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_X_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_X_TRANSLATION) { bXSelected = true; bYSelected = false; @@ -338,7 +317,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bXZSelected = false; bXYSelected = false; bYZSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){fXDistanceAlong - ptGizmoData->fOriginalDistX, 0.0f, 0.0f}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){fXDistanceAlong - gptGizmoCtx->fOriginalDistX, 0.0f, 0.0f}); if(ptParentTransform) { @@ -358,7 +337,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p ptSelectedTransform->tTranslation = *ptCenter; } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Y_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Y_TRANSLATION) { bYSelected = true; bXSelected = false; @@ -366,7 +345,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bXZSelected = false; bXYSelected = false; bYZSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, fYDistanceAlong - ptGizmoData->fOriginalDistY, 0.0f}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, fYDistanceAlong - gptGizmoCtx->fOriginalDistY, 0.0f}); if(ptParentTransform) { plVec4 tCurrentRot = {0}; @@ -385,7 +364,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p ptSelectedTransform->tTranslation = *ptCenter; } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Z_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Z_TRANSLATION) { bZSelected = true; bXSelected = false; @@ -393,7 +372,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bXZSelected = false; bXYSelected = false; bYZSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, 0.0f, fZDistanceAlong - ptGizmoData->fOriginalDistZ}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, 0.0f, fZDistanceAlong - gptGizmoCtx->fOriginalDistZ}); if(ptParentTransform) { plVec4 tCurrentRot = {0}; @@ -413,7 +392,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_YZ_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_YZ_TRANSLATION) { bYZSelected = true; bXSelected = false; @@ -421,7 +400,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bZSelected = false; bXZSelected = false; bXYSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, tYZIntersectionPoint.y - ptGizmoData->tOriginalPos.y - ptCenter->y, tYZIntersectionPoint.z - ptGizmoData->tOriginalPos.z - ptCenter->z}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){0.0f, tYZIntersectionPoint.y - gptGizmoCtx->tOriginalPos.y - ptCenter->y, tYZIntersectionPoint.z - gptGizmoCtx->tOriginalPos.z - ptCenter->z}); if(ptParentTransform) { plVec4 tCurrentRot = {0}; @@ -441,7 +420,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_XZ_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_XZ_TRANSLATION) { bXZSelected = true; bXSelected = false; @@ -449,7 +428,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bZSelected = false; bXYSelected = false; bYZSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){tXZIntersectionPoint.x - ptGizmoData->tOriginalPos.x - ptCenter->x, 0.0, tXZIntersectionPoint.z - ptGizmoData->tOriginalPos.z - ptCenter->z}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){tXZIntersectionPoint.x - gptGizmoCtx->tOriginalPos.x - ptCenter->x, 0.0, tXZIntersectionPoint.z - gptGizmoCtx->tOriginalPos.z - ptCenter->z}); if(ptParentTransform) { plVec4 tCurrentRot = {0}; @@ -469,7 +448,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_XY_TRANSLATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_XY_TRANSLATION) { bXYSelected = true; bXSelected = false; @@ -477,7 +456,7 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p bZSelected = false; bXZSelected = false; bYZSelected = false; - *ptCenter = pl_add_vec3(*ptCenter, (plVec3){tXYIntersectionPoint.x - ptGizmoData->tOriginalPos.x - ptCenter->x, tXYIntersectionPoint.y - ptGizmoData->tOriginalPos.y - ptCenter->y, 0.0f}); + *ptCenter = pl_add_vec3(*ptCenter, (plVec3){tXYIntersectionPoint.x - gptGizmoCtx->tOriginalPos.x - ptCenter->x, tXYIntersectionPoint.y - gptGizmoCtx->tOriginalPos.y - ptCenter->y, 0.0f}); if(ptParentTransform) { plVec4 tCurrentRot = {0}; @@ -497,57 +476,57 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } } - if(bXSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + if(bXSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalDistX = fXDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_X_TRANSLATION; + gptGizmoCtx->fOriginalDistX = fXDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_X_TRANSLATION; } - else if(bYSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bYSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalDistY = fYDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_Y_TRANSLATION; + gptGizmoCtx->fOriginalDistY = fYDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_Y_TRANSLATION; } - else if(bZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalDistZ = fZDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_Z_TRANSLATION; + gptGizmoCtx->fOriginalDistZ = fZDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_Z_TRANSLATION; } - else if(bYZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bYZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tOriginalPos = tYZIntersectionPoint; - ptGizmoData->tOriginalPos.y -= ptCenter->y; - ptGizmoData->tOriginalPos.z -= ptCenter->z; - ptGizmoData->tState = PL_GIZMO_STATE_YZ_TRANSLATION; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tOriginalPos = tYZIntersectionPoint; + gptGizmoCtx->tOriginalPos.y -= ptCenter->y; + gptGizmoCtx->tOriginalPos.z -= ptCenter->z; + gptGizmoCtx->tState = PL_GIZMO_STATE_YZ_TRANSLATION; } - else if(bXZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bXZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tOriginalPos = tXZIntersectionPoint; - ptGizmoData->tOriginalPos.x -= ptCenter->x; - ptGizmoData->tOriginalPos.z -= ptCenter->z; - ptGizmoData->tState = PL_GIZMO_STATE_XZ_TRANSLATION; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tOriginalPos = tXZIntersectionPoint; + gptGizmoCtx->tOriginalPos.x -= ptCenter->x; + gptGizmoCtx->tOriginalPos.z -= ptCenter->z; + gptGizmoCtx->tState = PL_GIZMO_STATE_XZ_TRANSLATION; } - else if(bXYSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bXYSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tOriginalPos = tXYIntersectionPoint; - ptGizmoData->tOriginalPos.x -= ptCenter->x; - ptGizmoData->tOriginalPos.y -= ptCenter->y; - ptGizmoData->tState = PL_GIZMO_STATE_XY_TRANSLATION; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tOriginalPos = tXYIntersectionPoint; + gptGizmoCtx->tOriginalPos.x -= ptCenter->x; + gptGizmoCtx->tOriginalPos.y -= ptCenter->y; + gptGizmoCtx->tState = PL_GIZMO_STATE_XY_TRANSLATION; } - if(gptIO->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) + if(gptIOI->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) { - ptGizmoData->tBeginPos = *ptCenter; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_DEFAULT; + gptGizmoCtx->tBeginPos = *ptCenter; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_DEFAULT; } plVec4 tXColor = (plVec4){1.0f, 0.0f, 0.0f, 1.0f}; @@ -621,14 +600,14 @@ pl__gizmo_translation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, p } static void -pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) +pl__gizmo_rotation(plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) { plVec3* ptCenter = &ptSelectedTransform->tWorld.col[3].xyz; - plVec2 tMousePos = gptIO->get_mouse_pos(); + plVec2 tMousePos = gptIOI->get_mouse_pos(); - if(gptUi->wants_mouse_capture()) + if(gptUI->wants_mouse_capture()) { tMousePos.x = -1.0f; tMousePos.y = -1.0f; @@ -637,12 +616,12 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa plMat4 tTransform = pl_mul_mat4(&ptCamera->tProjMat, &ptCamera->tViewMat); tTransform = pl_mat4_invert(&tTransform); - plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIO->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIO->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; + plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIOI->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIOI->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; tNDC = pl_mul_mat4_vec4(&tTransform, tNDC); tNDC = pl_div_vec4_scalarf(tNDC, tNDC.w); - const float fOuterRadius = 0.15f * ptGizmoData->fCaptureScale; - const float fInnerRadius = fOuterRadius - 0.03f * ptGizmoData->fCaptureScale; + const float fOuterRadius = 0.15f * gptGizmoCtx->fCaptureScale; + const float fInnerRadius = fOuterRadius - 0.03f * gptGizmoCtx->fCaptureScale; plVec4 tCurrentRot = {0}; plVec3 tCurrentTrans = {0}; @@ -660,7 +639,7 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa plVec4 tXColor = (plVec4){1.0f, 0.0f, 0.0f, 1.0f}; plVec4 tYColor = (plVec4){0.0f, 1.0f, 0.0f, 1.0f}; plVec4 tZColor = (plVec4){0.0f, 0.0f, 1.0f, 1.0f}; - if(ptGizmoData->tState == PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_DEFAULT) { const float fXDistance = pl_length_vec3(pl_sub_vec3(tXIntersectionPoint, *ptCenter)); @@ -706,41 +685,41 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa } } - if(ptGizmoData->tState == PL_GIZMO_STATE_X_ROTATION) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_X_ROTATION) { bXSelected = true; bYSelected = false; bZSelected = false; plVec3 tUpDir = {0.0f, 1.0f, 0.0f}; - plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(ptGizmoData->tOriginalPos, *ptCenter)); + plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(gptGizmoCtx->tOriginalPos, *ptCenter)); plVec3 tDir1 = pl_norm_vec3(pl_sub_vec3(tXIntersectionPoint, *ptCenter)); const float fAngleBetweenVec0 = acosf(pl_dot_vec3(tDir0, tUpDir)); const float fAngleBetweenVec1 = acosf(pl_dot_vec3(tDir1, tUpDir)); float fAngleBetweenVecs = fAngleBetweenVec1 - fAngleBetweenVec0; - if(ptGizmoData->tOriginalPos.z < ptCenter->z && tXIntersectionPoint.z < ptCenter->z) + if(gptGizmoCtx->tOriginalPos.z < ptCenter->z && tXIntersectionPoint.z < ptCenter->z) fAngleBetweenVecs *= -1.0f; - else if(ptGizmoData->tOriginalPos.z < ptCenter->z && tXIntersectionPoint.z > ptCenter->z) + else if(gptGizmoCtx->tOriginalPos.z < ptCenter->z && tXIntersectionPoint.z > ptCenter->z) fAngleBetweenVecs = fAngleBetweenVec1 + fAngleBetweenVec0; - else if(ptGizmoData->tOriginalPos.z > ptCenter->z && tXIntersectionPoint.z < ptCenter->z) + else if(gptGizmoCtx->tOriginalPos.z > ptCenter->z && tXIntersectionPoint.z < ptCenter->z) fAngleBetweenVecs = -(fAngleBetweenVec1 + fAngleBetweenVec0); char acTextBuffer[256] = {0}; pl_sprintf(acTextBuffer, "x-axis rotation: %0.0f degrees", fAngleBetweenVecs * 180.0f / PL_PI); gptDraw->add_3d_text(ptGizmoDrawlist, (plVec3){ptCenter->x, ptCenter->y + fOuterRadius * 1.1f, ptCenter->z}, acTextBuffer, (plDrawTextOptions){ - .ptFont = gptUi->get_default_font(), + .ptFont = gptUI->get_default_font(), .uColor = PL_COLOR_32_YELLOW }); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGBA(0.7f, 0.7f, 0.7f, 1.0f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGBA(1.0f, 1.0f, 0.0f, 1.0f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGBA(0.7f, 0.7f, 0.7f, 1.0f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGBA(1.0f, 1.0f, 0.0f, 1.0f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); if(fAngleBetweenVecs != 0.0f) { if(ptParentTransform) { - tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 1.0f, 0.0f, 0.0f), ptGizmoData->tOriginalRot); + tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 1.0f, 0.0f, 0.0f), gptGizmoCtx->tOriginalRot); plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -750,45 +729,45 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa } else { - ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 1.0f, 0.0f, 0.0f), ptGizmoData->tOriginalRot); + ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 1.0f, 0.0f, 0.0f), gptGizmoCtx->tOriginalRot); } } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Y_ROTATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Y_ROTATION) { bYSelected = true; bXSelected = false; bZSelected = false; plVec3 tUpDir = {0.0f, 0.0f, 1.0f}; - plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(ptGizmoData->tOriginalPos, *ptCenter)); + plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(gptGizmoCtx->tOriginalPos, *ptCenter)); plVec3 tDir1 = pl_norm_vec3(pl_sub_vec3(tYIntersectionPoint, *ptCenter)); const float fAngleBetweenVec0 = acosf(pl_dot_vec3(tDir0, tUpDir)); const float fAngleBetweenVec1 = acosf(pl_dot_vec3(tDir1, tUpDir)); float fAngleBetweenVecs = fAngleBetweenVec1 - fAngleBetweenVec0; - if(ptGizmoData->tOriginalPos.x < ptCenter->x && tYIntersectionPoint.x < ptCenter->x) + if(gptGizmoCtx->tOriginalPos.x < ptCenter->x && tYIntersectionPoint.x < ptCenter->x) fAngleBetweenVecs *= -1.0f; - else if(ptGizmoData->tOriginalPos.x < ptCenter->x && tYIntersectionPoint.x > ptCenter->x) + else if(gptGizmoCtx->tOriginalPos.x < ptCenter->x && tYIntersectionPoint.x > ptCenter->x) fAngleBetweenVecs = fAngleBetweenVec1 + fAngleBetweenVec0; - else if(ptGizmoData->tOriginalPos.x > ptCenter->x && tYIntersectionPoint.x < ptCenter->x) + else if(gptGizmoCtx->tOriginalPos.x > ptCenter->x && tYIntersectionPoint.x < ptCenter->x) fAngleBetweenVecs = -(fAngleBetweenVec1 + fAngleBetweenVec0); char acTextBuffer[256] = {0}; pl_sprintf(acTextBuffer, "y-axis rotation: %0.0f degrees", fAngleBetweenVecs * 180.0f / PL_PI); gptDraw->add_3d_text(ptGizmoDrawlist, (plVec3){ptCenter->x, ptCenter->y + fOuterRadius * 1.1f, ptCenter->z}, acTextBuffer, (plDrawTextOptions){ - .ptFont = gptUi->get_default_font(), + .ptFont = gptUI->get_default_font(), .uColor = PL_COLOR_32_YELLOW }); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(0.7f, 0.7f, 0.7f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 1.0f, 0.0f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(0.7f, 0.7f, 0.7f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 1.0f, 0.0f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); if(fAngleBetweenVecs != 0.0f) { if(ptParentTransform) { - tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 1.0f, 0.0f), ptGizmoData->tOriginalRot); + tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 1.0f, 0.0f), gptGizmoCtx->tOriginalRot); plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -798,45 +777,45 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa } else { - ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 1.0f, 0.0f), ptGizmoData->tOriginalRot); + ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 1.0f, 0.0f), gptGizmoCtx->tOriginalRot); } } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Z_ROTATION) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Z_ROTATION) { bXSelected = false; bYSelected = false; bZSelected = true; plVec3 tUpDir = {0.0f, 1.0f, 0.0f}; - plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(ptGizmoData->tOriginalPos, *ptCenter)); + plVec3 tDir0 = pl_norm_vec3(pl_sub_vec3(gptGizmoCtx->tOriginalPos, *ptCenter)); plVec3 tDir1 = pl_norm_vec3(pl_sub_vec3(tZIntersectionPoint, *ptCenter)); const float fAngleBetweenVec0 = acosf(pl_dot_vec3(tDir0, tUpDir)); const float fAngleBetweenVec1 = acosf(pl_dot_vec3(tDir1, tUpDir)); float fAngleBetweenVecs = fAngleBetweenVec1 - fAngleBetweenVec0; - if(ptGizmoData->tOriginalPos.x < ptCenter->x && tZIntersectionPoint.x < ptCenter->x) + if(gptGizmoCtx->tOriginalPos.x < ptCenter->x && tZIntersectionPoint.x < ptCenter->x) fAngleBetweenVecs *= -1.0f; - else if(ptGizmoData->tOriginalPos.x < ptCenter->x && tZIntersectionPoint.x > ptCenter->x) + else if(gptGizmoCtx->tOriginalPos.x < ptCenter->x && tZIntersectionPoint.x > ptCenter->x) fAngleBetweenVecs = fAngleBetweenVec1 + fAngleBetweenVec0; - else if(ptGizmoData->tOriginalPos.x > ptCenter->x && tZIntersectionPoint.x < ptCenter->x) + else if(gptGizmoCtx->tOriginalPos.x > ptCenter->x && tZIntersectionPoint.x < ptCenter->x) fAngleBetweenVecs = -(fAngleBetweenVec1 + fAngleBetweenVec0); char acTextBuffer[256] = {0}; pl_sprintf(acTextBuffer, "z-axis rotation: %0.0f degrees", fAngleBetweenVecs * 180.0f / PL_PI); gptDraw->add_3d_text(ptGizmoDrawlist, (plVec3){ptCenter->x, ptCenter->y + fOuterRadius * 1.1f, ptCenter->z}, acTextBuffer, (plDrawTextOptions){ - .ptFont = gptUi->get_default_font(), + .ptFont = gptUI->get_default_font(), .uColor = PL_COLOR_32_YELLOW }); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(0.7f, 0.7f, 0.7f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); - gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 1.0f, 0.0f), .fThickness = 0.0035f * ptGizmoData->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir0, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(0.7f, 0.7f, 0.7f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); + gptDraw->add_3d_line(ptGizmoDrawlist, *ptCenter, pl_add_vec3(*ptCenter, pl_mul_vec3_scalarf(tDir1, fInnerRadius)), (plDrawLineOptions){.uColor = PL_COLOR_32_RGB(1.0f, 1.0f, 0.0f), .fThickness = 0.0035f * gptGizmoCtx->fCaptureScale}); if(fAngleBetweenVecs != 0.0f) { if(ptParentTransform) { - tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 0.0f, -1.0f), ptGizmoData->tOriginalRot); + tCurrentRot = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 0.0f, -1.0f), gptGizmoCtx->tOriginalRot); plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -846,7 +825,7 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa } else { - ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 0.0f, -1.0f), ptGizmoData->tOriginalRot); + ptSelectedTransform->tRotation = pl_mul_quat(pl_quat_rotation(fAngleBetweenVecs, 0.0f, 0.0f, -1.0f), gptGizmoCtx->tOriginalRot); } } } @@ -864,44 +843,44 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa tZColor = (plVec4){1.0f, 1.0f, 0.0f, 1.0f}; } - if(bXSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + if(bXSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tOriginalPos = tXIntersectionPoint; + gptGizmoCtx->tOriginalPos = tXIntersectionPoint; if(ptParentTransform) { - pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &ptGizmoData->tOriginalRot, &tCurrentTrans); + pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &gptGizmoCtx->tOriginalRot, &tCurrentTrans); } else - ptGizmoData->tOriginalRot = ptSelectedTransform->tRotation; - ptGizmoData->tState = PL_GIZMO_STATE_X_ROTATION; + gptGizmoCtx->tOriginalRot = ptSelectedTransform->tRotation; + gptGizmoCtx->tState = PL_GIZMO_STATE_X_ROTATION; } - else if(bYSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bYSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tOriginalPos = tYIntersectionPoint; + gptGizmoCtx->tOriginalPos = tYIntersectionPoint; if(ptParentTransform) { - pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &ptGizmoData->tOriginalRot, &tCurrentTrans); + pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &gptGizmoCtx->tOriginalRot, &tCurrentTrans); } else - ptGizmoData->tOriginalRot = ptSelectedTransform->tRotation; - ptGizmoData->tState = PL_GIZMO_STATE_Y_ROTATION; + gptGizmoCtx->tOriginalRot = ptSelectedTransform->tRotation; + gptGizmoCtx->tState = PL_GIZMO_STATE_Y_ROTATION; } - else if(bZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->tOriginalPos = tZIntersectionPoint; + gptGizmoCtx->tOriginalPos = tZIntersectionPoint; if(ptParentTransform) { - pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &ptGizmoData->tOriginalRot, &tCurrentTrans); + pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &gptGizmoCtx->tOriginalRot, &tCurrentTrans); } else - ptGizmoData->tOriginalRot = ptSelectedTransform->tRotation; - ptGizmoData->tState = PL_GIZMO_STATE_Z_ROTATION; + gptGizmoCtx->tOriginalRot = ptSelectedTransform->tRotation; + gptGizmoCtx->tState = PL_GIZMO_STATE_Z_ROTATION; } - if(gptIO->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) + if(gptIOI->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) { - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_DEFAULT; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_DEFAULT; } gptDraw->add_3d_band_yz_filled(ptGizmoDrawlist, *ptCenter, fInnerRadius, fOuterRadius, 36, (plDrawSolidOptions){.uColor = PL_COLOR_32_VEC4(tXColor)}); @@ -910,14 +889,14 @@ pl__gizmo_rotation(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCa } static void -pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) +pl__gizmo_scale(plDrawList3D* ptGizmoDrawlist, plCameraComponent* ptCamera, plTransformComponent* ptSelectedTransform, plTransformComponent* ptParentTransform) { plVec3* ptCenter = &ptSelectedTransform->tWorld.col[3].xyz; - plVec2 tMousePos = gptIO->get_mouse_pos(); + plVec2 tMousePos = gptIOI->get_mouse_pos(); - if(gptUi->wants_mouse_capture()) + if(gptUI->wants_mouse_capture()) { tMousePos.x = -1.0f; tMousePos.y = -1.0f; @@ -926,13 +905,13 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer plMat4 tTransform = pl_mul_mat4(&ptCamera->tProjMat, &ptCamera->tViewMat); tTransform = pl_mat4_invert(&tTransform); - plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIO->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIO->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; + plVec4 tNDC = {-1.0f + 2.0f * tMousePos.x / gptIOI->get_io()->tMainViewportSize.x, -1.0f + 2.0f * tMousePos.y / gptIOI->get_io()->tMainViewportSize.y, 1.0f, 1.0f}; tNDC = pl_mul_mat4_vec4(&tTransform, tNDC); tNDC = pl_div_vec4_scalarf(tNDC, tNDC.w); - const float fAxisRadius = 0.0035f * ptGizmoData->fCaptureScale; - const float fArrowRadius = 0.0075f * ptGizmoData->fCaptureScale; - const float fLength = 0.15f * ptGizmoData->fCaptureScale; + const float fAxisRadius = 0.0035f * gptGizmoCtx->fCaptureScale; + const float fArrowRadius = 0.0075f * gptGizmoCtx->fCaptureScale; + const float fLength = 0.15f * gptGizmoCtx->fCaptureScale; float fXDistanceAlong = 0.0f; float fYDistanceAlong = 0.0f; @@ -947,14 +926,14 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer bool bXYZSelected = pl__does_line_intersect_plane(ptCamera->tPos, tCameraDir, (plVec4){-tCameraDir.x, -tCameraDir.y, -tCameraDir.z, pl_dot_vec3(tCameraDir, *ptCenter)}, &tXYZIntersectionPoint); - if(ptGizmoData->tState != PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState != PL_GIZMO_STATE_DEFAULT) { - float fScaleX = ptGizmoData->tState == PL_GIZMO_STATE_X_SCALE ? ptGizmoData->fOriginalScaleX + (fXDistanceAlong - ptGizmoData->fOriginalDistX) * ptGizmoData->fOriginalScaleX : ptGizmoData->fOriginalScaleX; - float fScaleY = ptGizmoData->tState == PL_GIZMO_STATE_Y_SCALE ? ptGizmoData->fOriginalScaleY + (fYDistanceAlong - ptGizmoData->fOriginalDistY) * ptGizmoData->fOriginalScaleY : ptGizmoData->fOriginalScaleY; - float fScaleZ = ptGizmoData->tState == PL_GIZMO_STATE_Z_SCALE ? ptGizmoData->fOriginalScaleZ + (fZDistanceAlong - ptGizmoData->fOriginalDistZ) * ptGizmoData->fOriginalScaleZ : ptGizmoData->fOriginalScaleZ; - if(ptGizmoData->tState == PL_GIZMO_STATE_SCALE) + float fScaleX = gptGizmoCtx->tState == PL_GIZMO_STATE_X_SCALE ? gptGizmoCtx->fOriginalScaleX + (fXDistanceAlong - gptGizmoCtx->fOriginalDistX) * gptGizmoCtx->fOriginalScaleX : gptGizmoCtx->fOriginalScaleX; + float fScaleY = gptGizmoCtx->tState == PL_GIZMO_STATE_Y_SCALE ? gptGizmoCtx->fOriginalScaleY + (fYDistanceAlong - gptGizmoCtx->fOriginalDistY) * gptGizmoCtx->fOriginalScaleY : gptGizmoCtx->fOriginalScaleY; + float fScaleZ = gptGizmoCtx->tState == PL_GIZMO_STATE_Z_SCALE ? gptGizmoCtx->fOriginalScaleZ + (fZDistanceAlong - gptGizmoCtx->fOriginalDistZ) * gptGizmoCtx->fOriginalScaleZ : gptGizmoCtx->fOriginalScaleZ; + if(gptGizmoCtx->tState == PL_GIZMO_STATE_SCALE) { - float fScale = ptGizmoData->fOriginalScaleX + ptGizmoData->fOriginalScaleX * pl_length_vec3((plVec3){fXDistanceAlong - ptGizmoData->fOriginalDistX, fYDistanceAlong - ptGizmoData->fOriginalDistY, fZDistanceAlong - ptGizmoData->fOriginalDistZ}); + float fScale = gptGizmoCtx->fOriginalScaleX + gptGizmoCtx->fOriginalScaleX * pl_length_vec3((plVec3){fXDistanceAlong - gptGizmoCtx->fOriginalDistX, fYDistanceAlong - gptGizmoCtx->fOriginalDistY, fZDistanceAlong - gptGizmoCtx->fOriginalDistZ}); fScaleX = fScale; fScaleY = fScale; fScaleZ = fScale; @@ -963,12 +942,12 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer pl_sprintf(acTextBuffer, "scaling: %0.3f, %0.3f, %0.3f", fScaleX, fScaleY, fScaleZ); gptDraw->add_3d_text(ptGizmoDrawlist, (plVec3){ptCenter->x, ptCenter->y + fLength * 1.2f, ptCenter->z}, acTextBuffer, (plDrawTextOptions){ - .ptFont = gptUi->get_default_font(), + .ptFont = gptUI->get_default_font(), .uColor = PL_COLOR_32_YELLOW }); } - if(ptGizmoData->tState == PL_GIZMO_STATE_DEFAULT) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_DEFAULT) { const float fXYZDistance = pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, *ptCenter)); @@ -1014,7 +993,7 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer } } - if(ptGizmoData->tState == PL_GIZMO_STATE_X_SCALE) + if(gptGizmoCtx->tState == PL_GIZMO_STATE_X_SCALE) { bXSelected = true; bYSelected = false; @@ -1029,7 +1008,7 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer plVec3 tCurrentScale = {0}; pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &tCurrentRot, &tCurrentTrans); - tCurrentScale.x = ptGizmoData->fOriginalScaleX + (fXDistanceAlong - ptGizmoData->fOriginalDistX) * ptGizmoData->fOriginalScaleX; + tCurrentScale.x = gptGizmoCtx->fOriginalScaleX + (fXDistanceAlong - gptGizmoCtx->fOriginalDistX) * gptGizmoCtx->fOriginalScaleX; plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -1039,12 +1018,12 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer } else { - ptSelectedTransform->tScale.x = ptGizmoData->fOriginalScaleX + (fXDistanceAlong - ptGizmoData->fOriginalDistX) * ptGizmoData->fOriginalScaleX; + ptSelectedTransform->tScale.x = gptGizmoCtx->fOriginalScaleX + (fXDistanceAlong - gptGizmoCtx->fOriginalDistX) * gptGizmoCtx->fOriginalScaleX; } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Y_SCALE) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Y_SCALE) { bXSelected = false; bYSelected = true; @@ -1060,7 +1039,7 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &tCurrentRot, &tCurrentTrans); - tCurrentScale.y = ptGizmoData->fOriginalScaleY + (fYDistanceAlong - ptGizmoData->fOriginalDistY) * ptGizmoData->fOriginalScaleY; + tCurrentScale.y = gptGizmoCtx->fOriginalScaleY + (fYDistanceAlong - gptGizmoCtx->fOriginalDistY) * gptGizmoCtx->fOriginalScaleY; plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -1070,11 +1049,11 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer } else { - ptSelectedTransform->tScale.y = ptGizmoData->fOriginalScaleY + (fYDistanceAlong - ptGizmoData->fOriginalDistY) * ptGizmoData->fOriginalScaleY; + ptSelectedTransform->tScale.y = gptGizmoCtx->fOriginalScaleY + (fYDistanceAlong - gptGizmoCtx->fOriginalDistY) * gptGizmoCtx->fOriginalScaleY; } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_Z_SCALE) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_Z_SCALE) { bXSelected = false; bYSelected = false; @@ -1090,7 +1069,7 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &tCurrentRot, &tCurrentTrans); - tCurrentScale.z = ptGizmoData->fOriginalScaleZ + (fZDistanceAlong - ptGizmoData->fOriginalDistZ) * ptGizmoData->fOriginalScaleZ; + tCurrentScale.z = gptGizmoCtx->fOriginalScaleZ + (fZDistanceAlong - gptGizmoCtx->fOriginalDistZ) * gptGizmoCtx->fOriginalScaleZ; plMat4 tDesired = pl_rotation_translation_scale(tCurrentRot, tCurrentTrans, tCurrentScale); @@ -1100,11 +1079,11 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer } else { - ptSelectedTransform->tScale.z = ptGizmoData->fOriginalScaleZ + (fZDistanceAlong - ptGizmoData->fOriginalDistZ) * ptGizmoData->fOriginalScaleZ; + ptSelectedTransform->tScale.z = gptGizmoCtx->fOriginalScaleZ + (fZDistanceAlong - gptGizmoCtx->fOriginalDistZ) * gptGizmoCtx->fOriginalScaleZ; } } - else if(ptGizmoData->tState == PL_GIZMO_STATE_SCALE) + else if(gptGizmoCtx->tState == PL_GIZMO_STATE_SCALE) { bXSelected = false; bYSelected = false; @@ -1119,10 +1098,10 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer plVec3 tCurrentScale = {0}; pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &tCurrentRot, &tCurrentTrans); - if(fYDistanceAlong - ptGizmoData->fOriginalDistY > 0) - tCurrentScale.x = ptGizmoData->fOriginalScaleX + pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, ptGizmoData->tOriginalPos)) * ptGizmoData->fOriginalScaleX; + if(fYDistanceAlong - gptGizmoCtx->fOriginalDistY > 0) + tCurrentScale.x = gptGizmoCtx->fOriginalScaleX + pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, gptGizmoCtx->tOriginalPos)) * gptGizmoCtx->fOriginalScaleX; else - tCurrentScale.x = ptGizmoData->fOriginalScaleX - pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, ptGizmoData->tOriginalPos)) * ptGizmoData->fOriginalScaleX; + tCurrentScale.x = gptGizmoCtx->fOriginalScaleX - pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, gptGizmoCtx->tOriginalPos)) * gptGizmoCtx->fOriginalScaleX; tCurrentScale.y = tCurrentScale.x; tCurrentScale.z = tCurrentScale.x; @@ -1134,10 +1113,10 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer } else { - if(fYDistanceAlong - ptGizmoData->fOriginalDistY > 0) - ptSelectedTransform->tScale.x = ptGizmoData->fOriginalScaleX + pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, ptGizmoData->tOriginalPos)) * ptGizmoData->fOriginalScaleX; + if(fYDistanceAlong - gptGizmoCtx->fOriginalDistY > 0) + ptSelectedTransform->tScale.x = gptGizmoCtx->fOriginalScaleX + pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, gptGizmoCtx->tOriginalPos)) * gptGizmoCtx->fOriginalScaleX; else - ptSelectedTransform->tScale.x = ptGizmoData->fOriginalScaleX - pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, ptGizmoData->tOriginalPos)) * ptGizmoData->fOriginalScaleX; + ptSelectedTransform->tScale.x = gptGizmoCtx->fOriginalScaleX - pl_length_vec3(pl_sub_vec3(tXYZIntersectionPoint, gptGizmoCtx->tOriginalPos)) * gptGizmoCtx->fOriginalScaleX; ptSelectedTransform->tScale.y = ptSelectedTransform->tScale.x; ptSelectedTransform->tScale.z = ptSelectedTransform->tScale.x; @@ -1151,52 +1130,52 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer // pl_decompose_matrix(&ptSelectedTransform->tWorld, &tCurrentScale, &tCurrentRot, &tCurrentTrans); - if(bXSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + if(bXSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalScaleX = tCurrentScale.x; - ptGizmoData->fOriginalScaleY = tCurrentScale.y; - ptGizmoData->fOriginalScaleZ = tCurrentScale.z; - ptGizmoData->fOriginalDistX = fXDistanceAlong; - ptGizmoData->fOriginalDistY = fYDistanceAlong; - ptGizmoData->fOriginalDistZ = fZDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_X_SCALE; + gptGizmoCtx->fOriginalScaleX = tCurrentScale.x; + gptGizmoCtx->fOriginalScaleY = tCurrentScale.y; + gptGizmoCtx->fOriginalScaleZ = tCurrentScale.z; + gptGizmoCtx->fOriginalDistX = fXDistanceAlong; + gptGizmoCtx->fOriginalDistY = fYDistanceAlong; + gptGizmoCtx->fOriginalDistZ = fZDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_X_SCALE; } - else if(bYSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bYSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalScaleX = tCurrentScale.x; - ptGizmoData->fOriginalScaleY = tCurrentScale.y; - ptGizmoData->fOriginalScaleZ = tCurrentScale.z; - ptGizmoData->fOriginalDistX = fXDistanceAlong; - ptGizmoData->fOriginalDistY = fYDistanceAlong; - ptGizmoData->fOriginalDistZ = fZDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_Y_SCALE; + gptGizmoCtx->fOriginalScaleX = tCurrentScale.x; + gptGizmoCtx->fOriginalScaleY = tCurrentScale.y; + gptGizmoCtx->fOriginalScaleZ = tCurrentScale.z; + gptGizmoCtx->fOriginalDistX = fXDistanceAlong; + gptGizmoCtx->fOriginalDistY = fYDistanceAlong; + gptGizmoCtx->fOriginalDistZ = fZDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_Y_SCALE; } - else if(bZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalScaleX = tCurrentScale.x; - ptGizmoData->fOriginalScaleY = tCurrentScale.y; - ptGizmoData->fOriginalScaleZ = tCurrentScale.z; - ptGizmoData->fOriginalDistX = fXDistanceAlong; - ptGizmoData->fOriginalDistY = fYDistanceAlong; - ptGizmoData->fOriginalDistZ = fZDistanceAlong; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_Z_SCALE; + gptGizmoCtx->fOriginalScaleX = tCurrentScale.x; + gptGizmoCtx->fOriginalScaleY = tCurrentScale.y; + gptGizmoCtx->fOriginalScaleZ = tCurrentScale.z; + gptGizmoCtx->fOriginalDistX = fXDistanceAlong; + gptGizmoCtx->fOriginalDistY = fYDistanceAlong; + gptGizmoCtx->fOriginalDistZ = fZDistanceAlong; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_Z_SCALE; } - else if(bXYZSelected && gptIO->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) + else if(bXYZSelected && gptIOI->is_mouse_clicked(PL_MOUSE_BUTTON_LEFT, false)) { - ptGizmoData->fOriginalScaleX = tCurrentScale.x; - ptGizmoData->fOriginalScaleY = tCurrentScale.y; - ptGizmoData->fOriginalScaleZ = tCurrentScale.z; - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_SCALE; + gptGizmoCtx->fOriginalScaleX = tCurrentScale.x; + gptGizmoCtx->fOriginalScaleY = tCurrentScale.y; + gptGizmoCtx->fOriginalScaleZ = tCurrentScale.z; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_SCALE; } - if(gptIO->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) + if(gptIOI->is_mouse_released(PL_MOUSE_BUTTON_LEFT)) { - ptGizmoData->tOriginalPos = *ptCenter; - ptGizmoData->tState = PL_GIZMO_STATE_DEFAULT; + gptGizmoCtx->tOriginalPos = *ptCenter; + gptGizmoCtx->tState = PL_GIZMO_STATE_DEFAULT; } plVec4 tXColor = (plVec4){1.0f, 0.0f, 0.0f, 1.0f}; @@ -1261,4 +1240,59 @@ pl__gizmo_scale(plGizmoData* ptGizmoData, plDrawList3D* ptGizmoDrawlist, plCamer fAxisRadius * 4, fAxisRadius * 4, (plDrawSolidOptions){.uColor = PL_COLOR_32_VEC4(tXYZColor)}); -} \ No newline at end of file +} + +//----------------------------------------------------------------------------- +// [SECTION] extension loading +//----------------------------------------------------------------------------- + +PL_EXPORT void +pl_load_gizmo_ext(plApiRegistryI* ptApiRegistry, bool bReload) +{ + const plGizmoI tApi = { + .set_mode = pl_gizmo_set_mode, + .next_mode = pl_gizmo_next_mode, + .gizmo = pl_gizmo + }; + pl_set_api(ptApiRegistry, plGizmoI, &tApi); + + gptIOI = pl_get_api_latest(ptApiRegistry, plIOI); + gptUI = pl_get_api_latest(ptApiRegistry, plUiI); + gptDraw = pl_get_api_latest(ptApiRegistry, plDrawI); + + const plDataRegistryI* ptDataRegistry = pl_get_api_latest(ptApiRegistry, plDataRegistryI); + if(bReload) + { + gptGizmoCtx = ptDataRegistry->get_data("plGizmoContext"); + } + else + { + static plGizmoContext gtGizmoCtx = { + .tSelectionMode = PL_GIZMO_MODE_TRANSLATION + }; + gptGizmoCtx = >GizmoCtx; + ptDataRegistry->set_data("plGizmoContext", gptGizmoCtx); + } +} + +PL_EXPORT void +pl_unload_gizmo_ext(plApiRegistryI* ptApiRegistry, bool bReload) +{ + if(bReload) + return; + + const plGizmoI* ptApi = pl_get_api_latest(ptApiRegistry, plGizmoI); + ptApiRegistry->remove_api(ptApi); +} + +//----------------------------------------------------------------------------- +// [SECTION] unity build +//----------------------------------------------------------------------------- + +#ifndef PL_UNITY_BUILD + #ifdef PL_USE_STB_SPRINTF + #define STB_SPRINTF_IMPLEMENTATION + #include "stb_sprintf.h" + #undef STB_SPRINTF_IMPLEMENTATION + #endif +#endif \ No newline at end of file diff --git a/extensions/pl_gizmo_ext.h b/extensions/pl_gizmo_ext.h new file mode 100644 index 00000000..cb2d31b0 --- /dev/null +++ b/extensions/pl_gizmo_ext.h @@ -0,0 +1,64 @@ +/* + pl_gizmo_ext.h +*/ + +/* +Index of this file: +// [SECTION] header mess +// [SECTION] APIs +// [SECTION] forward declarations +// [SECTION] public api structs +// [SECTION] enums +*/ + +//----------------------------------------------------------------------------- +// [SECTION] header mess +//----------------------------------------------------------------------------- + +#ifndef PL_GIZMO_EXT_H +#define PL_GIZMO_EXT_H + +//----------------------------------------------------------------------------- +// [SECTION] APIs +//----------------------------------------------------------------------------- + +#define plGizmoI_version (plVersion){0, 1, 0} + +//----------------------------------------------------------------------------- +// [SECTION] forward declarations +//----------------------------------------------------------------------------- + +// enums +typedef int plGizmoMode; + +// external +typedef struct _plTransformComponent plTransformComponent; // pl_ecs_ext.h +typedef struct _plCameraComponent plCameraComponent; // pl_ecs_ext.h +typedef struct _plDrawList3D plDrawList3D; // pl_draw_ext.h + +//----------------------------------------------------------------------------- +// [SECTION] public api structs +//----------------------------------------------------------------------------- + +typedef struct _plGizmoI +{ + void (*set_mode)(plGizmoMode); + void (*next_mode)(void); + void (*gizmo)(plDrawList3D*, plCameraComponent*, plTransformComponent* selectedTransform, plTransformComponent* parentTransform); +} plGizmoI; + +//----------------------------------------------------------------------------- +// [SECTION] enums +//----------------------------------------------------------------------------- + +enum _plGizmoMode +{ + PL_GIZMO_MODE_NONE, + PL_GIZMO_MODE_TRANSLATION, + PL_GIZMO_MODE_ROTATION, + PL_GIZMO_MODE_SCALE, + + PL_GIZMO_MODE_COUNT, +}; + +#endif // PL_GIZMO_EXT_H \ No newline at end of file diff --git a/extensions/pl_renderer_ext.c b/extensions/pl_renderer_ext.c index b96a85cc..30781ee1 100644 --- a/extensions/pl_renderer_ext.c +++ b/extensions/pl_renderer_ext.c @@ -29,6 +29,8 @@ static void pl_refr_cleanup(void); static uint32_t pl_refr_create_scene(void); static void pl_add_drawable_objects_to_scene(uint32_t, uint32_t, const plEntity*, uint32_t, const plEntity*); static void pl_refr_add_materials_to_scene(uint32_t, uint32_t, const plEntity* atMaterials); +static void pl_refr_remove_objects_from_scene(uint32_t sceneHandle, uint32_t objectCount, const plEntity* objects); +static void pl_refr_update_scene_objects(uint32_t sceneHandle, uint32_t objectCount, const plEntity* objects); // views static uint32_t pl_refr_create_view(uint32_t, plVec2); @@ -377,7 +379,7 @@ pl_refr_initialize(plWindow* ptWindow) pl_refr_create_global_shaders(); const plComputeShaderDesc tComputeShaderDesc = { - .tShader = gptShader->load_glsl("../shaders/jumpfloodalgo.comp", "main", NULL, NULL), + .tShader = gptShader->load_glsl("jumpfloodalgo.comp", "main", NULL, NULL), .atBindGroupLayouts = { { .atTextureBindings = { @@ -512,7 +514,7 @@ pl_refr_initialize(plWindow* ptWindow) gptData->tMainRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tMainRenderPassDesc, atMainAttachmentSets); plComputeShaderDesc tFilterComputeShaderDesc = { - .tShader = gptShader->load_glsl("../shaders/filter_environment.comp", "main", NULL, NULL), + .tShader = gptShader->load_glsl("filter_environment.comp", "main", NULL, NULL), .atBindGroupLayouts = { { .atTextureBindings = { @@ -538,7 +540,13 @@ static uint32_t pl_refr_create_scene(void) { const uint32_t uSceneHandle = pl_sb_size(gptData->sbtScenes); - plRefScene tScene = {0}; + plRefScene tScene = { + .tIndexBuffer = {.uData = UINT32_MAX}, + .tVertexBuffer = {.uData = UINT32_MAX}, + .tStorageBuffer = {.uData = UINT32_MAX}, + .tSkinStorageBuffer = {.uData = UINT32_MAX}, + .uGPUMaterialBufferCapacity = 512 + }; pl_sb_push(gptData->sbtScenes, tScene); plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; @@ -708,6 +716,98 @@ pl_refr_create_scene(void) } } + ptScene->uShadowAtlasResolution = 1024 * 8; + + const plTextureDesc tShadowDepthTextureDesc = { + .tDimensions = {(float)ptScene->uShadowAtlasResolution, (float)ptScene->uShadowAtlasResolution, 1}, + .tFormat = PL_FORMAT_D16_UNORM, + .uLayers = 1, + .uMips = 1, + .tType = PL_TEXTURE_TYPE_2D, + .tUsage = PL_TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT | PL_TEXTURE_USAGE_SAMPLED, + .pcDebugName = "shadow map" + }; + + const plRenderPassDesc tDepthRenderPassDesc = { + .tLayout = gptData->tDepthRenderPassLayout, + .tDepthTarget = { + .tLoadOp = PL_LOAD_OP_LOAD, + .tStoreOp = PL_STORE_OP_STORE, + .tStencilLoadOp = PL_LOAD_OP_CLEAR, + .tStencilStoreOp = PL_STORE_OP_DONT_CARE, + .tCurrentUsage = PL_TEXTURE_USAGE_SAMPLED, + .tNextUsage = PL_TEXTURE_USAGE_SAMPLED, + .fClearZ = 0.0f + }, + .tDimensions = {.x = (float)ptScene->uShadowAtlasResolution, .y = (float)ptScene->uShadowAtlasResolution} + }; + + const plRenderPassDesc tFirstDepthRenderPassDesc = { + .tLayout = gptData->tDepthRenderPassLayout, + .tDepthTarget = { + .tLoadOp = PL_LOAD_OP_CLEAR, + .tStoreOp = PL_STORE_OP_STORE, + .tStencilLoadOp = PL_LOAD_OP_CLEAR, + .tStencilStoreOp = PL_STORE_OP_DONT_CARE, + .tCurrentUsage = PL_TEXTURE_USAGE_SAMPLED, + .tNextUsage = PL_TEXTURE_USAGE_SAMPLED, + .fClearZ = 0.0f + }, + .tDimensions = {.x = (float)ptScene->uShadowAtlasResolution, .y = (float)ptScene->uShadowAtlasResolution} + }; + + plRenderPassAttachments atShadowAttachmentSets[PL_MAX_FRAMES_IN_FLIGHT] = {0}; + ptScene->tShadowTexture = pl__refr_create_local_texture(&tShadowDepthTextureDesc, "shadow map", 0, PL_TEXTURE_USAGE_SAMPLED); + ptScene->atShadowTextureBindlessIndices = pl__get_bindless_texture_index(uSceneHandle, ptScene->tShadowTexture); + for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++) + { + atShadowAttachmentSets[i].atViewAttachments[0] = ptScene->tShadowTexture; + } + + ptScene->tShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tDepthRenderPassDesc, atShadowAttachmentSets); + ptScene->tFirstShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tFirstDepthRenderPassDesc, atShadowAttachmentSets); + + const plShaderDesc tTonemapShaderDesc = { + .tPixelShader = gptShader->load_glsl("tonemap.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("full_quad.vert", "main", NULL, NULL), + .tGraphicsState = { + .ulDepthWriteEnabled = 0, + .ulDepthMode = PL_COMPARE_MODE_ALWAYS, + .ulCullMode = PL_CULL_MODE_NONE, + .ulStencilMode = PL_COMPARE_MODE_ALWAYS, + .ulStencilRef = 0xff, + .ulStencilMask = 0xff, + .ulStencilOpFail = PL_STENCIL_OP_KEEP, + .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, + .ulStencilOpPass = PL_STENCIL_OP_KEEP + }, + .atVertexBufferLayouts = { + { + .uByteStride = sizeof(float) * 4, + .atAttributes = { + {.uByteOffset = 0, .tFormat = PL_VERTEX_FORMAT_FLOAT2}, + {.uByteOffset = sizeof(float) * 2, .tFormat = PL_VERTEX_FORMAT_FLOAT2} + } + } + }, + .atBlendStates = { + pl__get_blend_state(PL_BLEND_MODE_OPAQUE) + }, + .tRenderPassLayout = gptData->tPostProcessRenderPassLayout, + .atBindGroupLayouts = { + { + .atSamplerBindings = { + { .uSlot = 0, .tStages = PL_STAGE_PIXEL} + }, + .atTextureBindings = { + {.uSlot = 1, .tStages = PL_STAGE_PIXEL, .tType = PL_TEXTURE_BINDING_TYPE_SAMPLED}, + {.uSlot = 2, .tStages = PL_STAGE_PIXEL, .tType = PL_TEXTURE_BINDING_TYPE_SAMPLED} + } + } + } + }; + ptScene->tTonemapShader = gptGfx->create_shader(gptData->ptDevice, &tTonemapShaderDesc); + return uSceneHandle; } @@ -1364,14 +1464,15 @@ pl_refr_load_skybox_from_panorama(uint32_t uSceneHandle, const char* pcPath, int plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; plDevice* ptDevice = gptData->ptDevice; plCommandPool* ptCmdPool = gptData->atCmdPools[gptGfx->get_current_frame_index()]; + ptScene->bShowSkybox = true; // create skybox shader if we haven't if(gptData->tSkyboxShader.uIndex == 0) { // create skybox shader plShaderDesc tSkyboxShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/skybox.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/skybox.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("skybox.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("skybox.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_EQUAL, @@ -1438,7 +1539,7 @@ pl_refr_load_skybox_from_panorama(uint32_t uSceneHandle, const char* pcPath, int { int aiSkyboxSpecializationData[] = {iResolution, iPanoramaWidth, iPanoramaHeight}; const plComputeShaderDesc tSkyboxComputeShaderDesc = { - .tShader = gptShader->load_glsl("../shaders/panorama_to_cubemap.comp", "main", NULL, NULL), + .tShader = gptShader->load_glsl("panorama_to_cubemap.comp", "main", NULL, NULL), .pTempConstantData = aiSkyboxSpecializationData, .atConstants = { { .uID = 0, .uOffset = 0, .tType = PL_DATA_TYPE_INT}, @@ -1618,72 +1719,7 @@ pl_refr_load_skybox_from_panorama(uint32_t uSceneHandle, const char* pcPath, int gptGfx->update_bind_group(ptDevice, ptScene->tSkyboxBindGroup, &tBGData1); } - const uint32_t uStartIndex = pl_sb_size(ptScene->sbtVertexPosBuffer); - const uint32_t uIndexStart = pl_sb_size(ptScene->sbuIndexBuffer); - const uint32_t uDataStartIndex = pl_sb_size(ptScene->sbtVertexDataBuffer); - - const plDrawable tDrawable = { - .uIndexCount = 36, - .uVertexCount = 8, - .uIndexOffset = uIndexStart, - .uVertexOffset = uStartIndex, - .uDataOffset = uDataStartIndex, - }; - ptScene->tSkyboxDrawable = tDrawable; - - // indices - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); - - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); - - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); - - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); - - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); - - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); - pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); - - // vertices (position) - const float fCubeSide = 1.0f; - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, -fCubeSide, -fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, -fCubeSide, -fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, fCubeSide, -fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, fCubeSide, -fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, -fCubeSide, fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, -fCubeSide, fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, fCubeSide, fCubeSide})); - pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, fCubeSide, fCubeSide})); + pl__refr_add_skybox_drawable(uSceneHandle); } pl_end_cpu_sample(gptProfile, 0); @@ -1942,8 +1978,8 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData), pl_sb_size(ptScene->sbtProbeData)}; plShaderDesc tLightingShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/lighting.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/lighting.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("lighting.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("lighting.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, @@ -2030,8 +2066,8 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) } const plShaderDesc tTonemapShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/tonemap.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/full_quad.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("tonemap.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("full_quad.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, @@ -2070,16 +2106,9 @@ pl_refr_reload_scene_shaders(uint32_t uSceneHandle) }; ptScene->tTonemapShader = gptGfx->create_shader(gptData->ptDevice, &tTonemapShaderDesc); - pl__refr_process_drawables(uSceneHandle); + pl__refr_unstage_drawables(uSceneHandle); pl__refr_set_drawable_shaders(uSceneHandle); - - uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); - for(uint32_t i = 0; i < uDrawableCount; i++) - { - ptScene->sbtDrawables[i].tIndexBuffer = ptScene->sbtDrawables[i].uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer; - } - - pl_end_cpu_sample(gptProfile, 0); + pl__refr_sort_drawables(uSceneHandle); } static void @@ -2119,45 +2148,18 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) pl_sb_reserve(ptScene->sbtPLightData, iPLightCount); pl_sb_reserve(ptScene->sbtSLightData, iSLightCount); - pl__refr_process_drawables(uSceneHandle); + pl__refr_unstage_drawables(uSceneHandle); pl__refr_set_drawable_shaders(uSceneHandle); + pl__refr_sort_drawables(uSceneHandle); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~GPU Buffers~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - pl_begin_cpu_sample(gptProfile, 0, "fill GPU buffers"); - - - ptScene->uGPUMaterialBufferCapacity = 512; - const plBufferDesc tShaderBufferDesc = { + const plBufferDesc tMaterialDataBufferDesc = { .tUsage = PL_BUFFER_USAGE_STORAGE, .szByteSize = sizeof(plGPUMaterial) * ptScene->uGPUMaterialBufferCapacity, - .pcDebugName = "shader buffer" + .pcDebugName = "material buffer" }; - const plBufferDesc tIndexBufferDesc = { - .tUsage = PL_BUFFER_USAGE_INDEX, - .szByteSize = pl_max(sizeof(uint32_t) * pl_sb_size(ptScene->sbuIndexBuffer), 1024), - .pcDebugName = "index buffer" - }; - - const plBufferDesc tVertexBufferDesc = { - .tUsage = PL_BUFFER_USAGE_VERTEX | PL_BUFFER_USAGE_STORAGE, - .szByteSize = sizeof(plVec3) * pl_sb_size(ptScene->sbtVertexPosBuffer), - .pcDebugName = "vertex buffer" - }; - - const plBufferDesc tStorageBufferDesc = { - .tUsage = PL_BUFFER_USAGE_STORAGE, - .szByteSize = sizeof(plVec4) * pl_sb_size(ptScene->sbtVertexDataBuffer), - .pcDebugName = "storage buffer" - }; - - const plBufferDesc tSkinStorageBufferDesc = { - .tUsage = PL_BUFFER_USAGE_STORAGE, - .szByteSize = sizeof(plVec4) * pl_sb_size(ptScene->sbtSkinVertexDataBuffer), - .pcDebugName = "skin buffer" - }; - const plBufferDesc tDLightBufferDesc = { .tUsage = PL_BUFFER_USAGE_UNIFORM, .szByteSize = sizeof(plGPULight) * PL_MAX_LIGHTS, @@ -2181,51 +2183,7 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) ptScene->atDLightBuffer[i] = pl__refr_create_staging_buffer(&tDLightBufferDesc, "d light", i); ptScene->atPLightBuffer[i] = pl__refr_create_staging_buffer(&tPLightBufferDesc, "p light", i); ptScene->atSLightBuffer[i] = pl__refr_create_staging_buffer(&tSLightBufferDesc, "s light", i); - ptScene->atMaterialDataBuffer[i] = pl__refr_create_local_buffer(&tShaderBufferDesc, "shader", uSceneHandle, ptScene->sbtMaterialBuffer); - } - - ptScene->tIndexBuffer = pl__refr_create_local_buffer(&tIndexBufferDesc, "index", uSceneHandle, ptScene->sbuIndexBuffer); - ptScene->tVertexBuffer = pl__refr_create_local_buffer(&tVertexBufferDesc, "vertex", uSceneHandle, ptScene->sbtVertexPosBuffer); - ptScene->tStorageBuffer = pl__refr_create_local_buffer(&tStorageBufferDesc, "storage", uSceneHandle, ptScene->sbtVertexDataBuffer); - - if(tSkinStorageBufferDesc.szByteSize > 0) - { - ptScene->tSkinStorageBuffer = pl__refr_create_local_buffer(&tSkinStorageBufferDesc, "skin storage", uSceneHandle, ptScene->sbtSkinVertexDataBuffer); - - const plBindGroupLayout tSkinBindGroupLayout0 = { - .atSamplerBindings = { - {.uSlot = 3, .tStages = PL_STAGE_COMPUTE} - }, - .atBufferBindings = { - { .uSlot = 0, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, - { .uSlot = 1, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, - { .uSlot = 2, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, - } - }; - const plBindGroupDesc tSkinBindGroupDesc = { - .ptPool = gptData->ptBindGroupPool, - .ptLayout = &tSkinBindGroupLayout0, - .pcDebugName = "skin bind group" - }; - ptScene->tSkinBindGroup0 = gptGfx->create_bind_group(ptDevice, &tSkinBindGroupDesc); - - const plBindGroupUpdateSamplerData atSamplerData[] = { - { .uSlot = 3, .tSampler = gptData->tDefaultSampler} - }; - const plBindGroupUpdateBufferData atBufferData[] = - { - { .uSlot = 0, .tBuffer = ptScene->tSkinStorageBuffer, .szBufferRange = tSkinStorageBufferDesc.szByteSize}, - { .uSlot = 1, .tBuffer = ptScene->tVertexBuffer, .szBufferRange = tVertexBufferDesc.szByteSize}, - { .uSlot = 2, .tBuffer = ptScene->tStorageBuffer, .szBufferRange = tStorageBufferDesc.szByteSize} - - }; - plBindGroupUpdateData tBGData0 = { - .uBufferCount = 3, - .atBufferBindings = atBufferData, - .uSamplerCount = 1, - .atSamplerBindings = atSamplerData, - }; - gptGfx->update_bind_group(gptData->ptDevice, ptScene->tSkinBindGroup0, &tBGData0); + ptScene->atMaterialDataBuffer[i] = pl__refr_create_local_buffer(&tMaterialDataBufferDesc, "material buffer", uSceneHandle, ptScene->sbtMaterialBuffer); } int iSceneWideRenderingFlags = PL_RENDERING_FLAG_SHADOWS; @@ -2238,8 +2196,8 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) { int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtDLightData), pl_sb_capacity(ptScene->sbtPLightData), pl_sb_capacity(ptScene->sbtSLightData), pl_sb_size(ptScene->sbtProbeData)}; plShaderDesc tLightingShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/lighting.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/lighting.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("lighting.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("lighting.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, @@ -2325,63 +2283,10 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) ptScene->tEnvLightingShader = gptGfx->create_shader(gptData->ptDevice, &tLightingShaderDesc); } - const plShaderDesc tTonemapShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/tonemap.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/full_quad.vert", "main", NULL, NULL), - .tGraphicsState = { - .ulDepthWriteEnabled = 0, - .ulDepthMode = PL_COMPARE_MODE_ALWAYS, - .ulCullMode = PL_CULL_MODE_NONE, - .ulStencilMode = PL_COMPARE_MODE_ALWAYS, - .ulStencilRef = 0xff, - .ulStencilMask = 0xff, - .ulStencilOpFail = PL_STENCIL_OP_KEEP, - .ulStencilOpDepthFail = PL_STENCIL_OP_KEEP, - .ulStencilOpPass = PL_STENCIL_OP_KEEP - }, - .atVertexBufferLayouts = { - { - .uByteStride = sizeof(float) * 4, - .atAttributes = { - {.uByteOffset = 0, .tFormat = PL_VERTEX_FORMAT_FLOAT2}, - {.uByteOffset = sizeof(float) * 2, .tFormat = PL_VERTEX_FORMAT_FLOAT2} - } - } - }, - .atBlendStates = { - pl__get_blend_state(PL_BLEND_MODE_OPAQUE) - }, - .tRenderPassLayout = gptData->tPostProcessRenderPassLayout, - .atBindGroupLayouts = { - { - .atSamplerBindings = { - { .uSlot = 0, .tStages = PL_STAGE_PIXEL} - }, - .atTextureBindings = { - {.uSlot = 1, .tStages = PL_STAGE_PIXEL, .tType = PL_TEXTURE_BINDING_TYPE_SAMPLED}, - {.uSlot = 2, .tStages = PL_STAGE_PIXEL, .tType = PL_TEXTURE_BINDING_TYPE_SAMPLED} - } - } - } - }; - ptScene->tTonemapShader = gptGfx->create_shader(gptData->ptDevice, &tTonemapShaderDesc); - - pl_sb_free(ptScene->sbtVertexPosBuffer); - pl_sb_free(ptScene->sbtVertexDataBuffer); - pl_sb_free(ptScene->sbuIndexBuffer); - - plBuffer* ptStorageBuffer = gptGfx->get_buffer(ptDevice, ptScene->tStorageBuffer); - - for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++) { const plBindGroupUpdateBufferData atGlobalBufferData[] = { - { - .tBuffer = ptScene->tStorageBuffer, - .uSlot = 0, - .szBufferRange = ptStorageBuffer->tDesc.szByteSize - }, { .tBuffer = ptScene->atMaterialDataBuffer[i], .uSlot = 1, @@ -2390,71 +2295,12 @@ pl_refr_finalize_scene(uint32_t uSceneHandle) }; plBindGroupUpdateData tGlobalBindGroupData = { - .uBufferCount = 2, - .atBufferBindings = atGlobalBufferData + .uBufferCount = 1, + .atBufferBindings = atGlobalBufferData, }; gptGfx->update_bind_group(gptData->ptDevice, ptScene->atGlobalBindGroup[i], &tGlobalBindGroupData); } - - ptScene->uShadowAtlasResolution = 1024 * 8; - - const plTextureDesc tShadowDepthTextureDesc = { - .tDimensions = {(float)ptScene->uShadowAtlasResolution, (float)ptScene->uShadowAtlasResolution, 1}, - .tFormat = PL_FORMAT_D16_UNORM, - .uLayers = 1, - .uMips = 1, - .tType = PL_TEXTURE_TYPE_2D, - .tUsage = PL_TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT | PL_TEXTURE_USAGE_SAMPLED, - .pcDebugName = "shadow map" - }; - - const plRenderPassDesc tDepthRenderPassDesc = { - .tLayout = gptData->tDepthRenderPassLayout, - .tDepthTarget = { - .tLoadOp = PL_LOAD_OP_LOAD, - .tStoreOp = PL_STORE_OP_STORE, - .tStencilLoadOp = PL_LOAD_OP_CLEAR, - .tStencilStoreOp = PL_STORE_OP_DONT_CARE, - .tCurrentUsage = PL_TEXTURE_USAGE_SAMPLED, - .tNextUsage = PL_TEXTURE_USAGE_SAMPLED, - .fClearZ = 0.0f - }, - .tDimensions = {.x = (float)ptScene->uShadowAtlasResolution, .y = (float)ptScene->uShadowAtlasResolution} - }; - - const plRenderPassDesc tFirstDepthRenderPassDesc = { - .tLayout = gptData->tDepthRenderPassLayout, - .tDepthTarget = { - .tLoadOp = PL_LOAD_OP_CLEAR, - .tStoreOp = PL_STORE_OP_STORE, - .tStencilLoadOp = PL_LOAD_OP_CLEAR, - .tStencilStoreOp = PL_STORE_OP_DONT_CARE, - .tCurrentUsage = PL_TEXTURE_USAGE_SAMPLED, - .tNextUsage = PL_TEXTURE_USAGE_SAMPLED, - .fClearZ = 0.0f - }, - .tDimensions = {.x = (float)ptScene->uShadowAtlasResolution, .y = (float)ptScene->uShadowAtlasResolution} - }; - - plRenderPassAttachments atShadowAttachmentSets[PL_MAX_FRAMES_IN_FLIGHT] = {0}; - ptScene->tShadowTexture = pl__refr_create_local_texture(&tShadowDepthTextureDesc, "shadow map", 0, PL_TEXTURE_USAGE_SAMPLED); - ptScene->atShadowTextureBindlessIndices = pl__get_bindless_texture_index(uSceneHandle, ptScene->tShadowTexture); - for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++) - { - atShadowAttachmentSets[i].atViewAttachments[0] = ptScene->tShadowTexture; - } - - ptScene->tShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tDepthRenderPassDesc, atShadowAttachmentSets); - ptScene->tFirstShadowRenderPass = gptGfx->create_render_pass(gptData->ptDevice, &tFirstDepthRenderPassDesc, atShadowAttachmentSets); - - uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); - for(uint32_t i = 0; i < uDrawableCount; i++) - { - ptScene->sbtDrawables[i].tIndexBuffer = ptScene->sbtDrawables[i].uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer; - } - - pl_end_cpu_sample(gptProfile, 0); } static void @@ -3064,7 +2910,7 @@ pl_refr_render_scene(uint32_t uSceneHandle, const uint32_t* auViewHandles, const gptGfx->next_subpass(ptSceneEncoder, NULL); - if(ptScene->tSkyboxTexture.uIndex != 0) + if(ptScene->tSkyboxTexture.uIndex != 0 && ptScene->bShowSkybox) { const plBindGroupUpdateBufferData tSkyboxBG0BufferData = { @@ -3908,6 +3754,7 @@ pl_refr_get_view_color_texture(uint32_t uSceneHandle, uint32_t uViewHandle) static void pl_add_drawable_objects_to_scene(uint32_t uSceneHandle, uint32_t uDeferredCount, const plEntity* atDeferredObjects, uint32_t uForwardCount, const plEntity* atForwardObjects) { + pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__); plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; uint32_t uStart = pl_sb_size(ptScene->sbtStagedDrawables); @@ -3927,6 +3774,8 @@ pl_add_drawable_objects_to_scene(uint32_t uSceneHandle, uint32_t uDeferredCount, ptScene->sbtStagedDrawables[uStart + i].tEntity = atForwardObjects[i]; ptScene->sbtStagedDrawables[uStart + i].tFlags = PL_DRAWABLE_FLAG_FORWARD; } + + pl_end_cpu_sample(gptProfile, 0); } static void @@ -3940,7 +3789,7 @@ pl_refr_update_scene_materials(uint32_t uSceneHandle, uint32_t uMaterialCount, c plMaterialComponent* ptMaterial = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MATERIAL, tMaterialComp); uint32_t uMaterialIndex = uMaterialIndex = (uint32_t)pl_hm_lookup(ptScene->ptMaterialHashmap, tMaterialComp.ulData); - if(uMaterialIndex == UINT64_MAX) + if(uMaterialIndex == UINT32_MAX) { PL_ASSERT(false && "material isn't in scene"); } @@ -3985,12 +3834,55 @@ pl_refr_update_scene_materials(uint32_t uSceneHandle, uint32_t uMaterialCount, c pl_end_cpu_sample(gptProfile, 0); } +static void +pl_refr_remove_objects_from_scene(uint32_t uSceneHandle, uint32_t uObjectCount, const plEntity* atObjects) +{ + pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__); + plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; + + for(uint32_t i = 0; i < uObjectCount; i++) + { + const plEntity tObject = atObjects[i]; + + uint32_t uDrawableCount = pl_sb_size(ptScene->sbtStagedDrawables); + for(uint32_t j = 0; j < uDrawableCount; j++) + { + if(ptScene->sbtStagedDrawables[j].tEntity.ulData == tObject.ulData) + { + pl_hm_remove(ptScene->ptDrawableHashmap, tObject.ulData); + pl_sb_del_swap(ptScene->sbtStagedDrawables, j); + j--; + uDrawableCount--; + } + } + } + + pl__refr_unstage_drawables(uSceneHandle); + pl__refr_set_drawable_shaders(uSceneHandle); + pl__refr_sort_drawables(uSceneHandle); + + pl_end_cpu_sample(gptProfile, 0); +} + +static void +pl_refr_update_scene_objects(uint32_t uSceneHandle, uint32_t uObjectCount, const plEntity* atObjects) +{ + pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__); + plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; + + pl__refr_sort_drawables(uSceneHandle); + + pl_end_cpu_sample(gptProfile, 0); +} + static void pl_refr_add_materials_to_scene(uint32_t uSceneHandle, uint32_t uMaterialCount, const plEntity* atMaterials) { pl_begin_cpu_sample(gptProfile, 0, __FUNCTION__); plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; + pl_sb_reset(ptScene->sbtMaterialBuffer); + for(uint32_t i = 0; i < uMaterialCount; i++) { const plEntity tMaterialComp = atMaterials[i]; @@ -4173,6 +4065,19 @@ pl_show_graphics_options(const char* pcTitle) { gptData->uOutlineWidth = (uint32_t)iOutlineWidth; } + + for(uint32_t i = 0; i < pl_sb_size(gptData->sbtScenes); i++) + { + if(bReloadShaders) + pl_refr_reload_scene_shaders(i); + + if(gptUI->tree_node("Scene", 0)) + { + gptUI->checkbox("Show Skybox", &gptData->sbtScenes[i].bShowSkybox); + gptUI->tree_pop(); + } + } + gptUI->end_collapsing_header(); } } @@ -4197,6 +4102,8 @@ pl_load_renderer_ext(plApiRegistryI* ptApiRegistry, bool bReload) .create_scene = pl_refr_create_scene, .add_drawable_objects_to_scene = pl_add_drawable_objects_to_scene, .add_materials_to_scene = pl_refr_add_materials_to_scene, + .remove_objects_from_scene = pl_refr_remove_objects_from_scene, + .update_scene_objects = pl_refr_update_scene_objects, .update_scene_materials = pl_refr_update_scene_materials, .create_view = pl_refr_create_view, .run_ecs = pl_refr_run_ecs, diff --git a/extensions/pl_renderer_ext.h b/extensions/pl_renderer_ext.h index 37198212..3dca3181 100644 --- a/extensions/pl_renderer_ext.h +++ b/extensions/pl_renderer_ext.h @@ -63,21 +63,24 @@ typedef struct _plRendererI // scenes uint32_t (*create_scene)(void); - void (*add_drawable_objects_to_scene)(uint32_t uSceneHandle, uint32_t uOpaqueCount, const plEntity* atOpaqueObjects, uint32_t uTransparentCount, const plEntity* atTransparentObjects); + void (*load_skybox_from_panorama)(uint32_t uSceneHandle, const char* pcPath, int iResolution); + void (*add_drawable_objects_to_scene)(uint32_t uSceneHandle, uint32_t uOpaqueCount, const plEntity* atOpaqueObjects, uint32_t uTransparentCount, const plEntity* atTransparentObjects); + void (*finalize_scene)(uint32_t uSceneHandle); - void (*add_materials_to_scene)(uint32_t sceneHandle, uint32_t materialCount, const plEntity* materials); + // scenes - runtime + void (*reload_scene_shaders)(uint32_t uSceneHandle); + void (*remove_objects_from_scene)(uint32_t sceneHandle, uint32_t objectCount, const plEntity* objects); void (*update_scene_materials)(uint32_t sceneHandle, uint32_t materialCount, const plEntity* materials); + void (*update_scene_objects)(uint32_t sceneHandle, uint32_t objectCount, const plEntity* objects); // call if you change flags for objects + + // scenes - not ready + void (*add_materials_to_scene)(uint32_t sceneHandle, uint32_t materialCount, const plEntity* materials); // views uint32_t (*create_view)(uint32_t uSceneHandle, plVec2 tDimensions); plBindGroupHandle (*get_view_color_texture)(uint32_t uSceneHandle, uint32_t uViewHandle); void (*resize_view)(uint32_t uSceneHandle, uint32_t uViewHandle, plVec2 tDimensions); void (*resize)(void); - - // loading - void (*load_skybox_from_panorama)(uint32_t uSceneHandle, const char* pcPath, int iResolution); - void (*finalize_scene)(uint32_t uSceneHandle); - void (*reload_scene_shaders)(uint32_t uSceneHandle); // ui void (*show_graphics_options)(const char* pcTitle); diff --git a/extensions/pl_renderer_internal.c b/extensions/pl_renderer_internal.c index 5d502e3b..8cc4f84c 100644 --- a/extensions/pl_renderer_internal.c +++ b/extensions/pl_renderer_internal.c @@ -30,9 +30,12 @@ pl__refr_cull_job(plInvocationData tInvoData, void* pData) plDrawable tDrawable = ptCullData->atDrawables[tInvoData.uGlobalIndex]; plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tDrawable.tEntity); ptCullData->atDrawables[tInvoData.uGlobalIndex].bCulled = true; - if(pl__sat_visibility_test(ptCullData->ptCullCamera, &ptObject->tAABB)) + if(ptObject->tFlags & PL_OBJECT_FLAGS_RENDERABLE) { - ptCullData->atDrawables[tInvoData.uGlobalIndex].bCulled = false; + if(pl__sat_visibility_test(ptCullData->ptCullCamera, &ptObject->tAABB)) + { + ptCullData->atDrawables[tInvoData.uGlobalIndex].bCulled = false; + } } } @@ -2102,7 +2105,7 @@ pl_refr_create_global_shaders(void) { plComputeShaderDesc tFilterComputeShaderDesc = { - .tShader = gptShader->load_glsl("../shaders/filter_environment.comp", "main", NULL, NULL), + .tShader = gptShader->load_glsl("filter_environment.comp", "main", NULL, NULL), .atBindGroupLayouts = { { .atTextureBindings = { @@ -2126,8 +2129,8 @@ pl_refr_create_global_shaders(void) int aiConstantData[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; plShaderDesc tDeferredShaderDescription = { - .tPixelShader = gptShader->load_glsl("../shaders/primitive.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/primitive.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("primitive.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("primitive.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 1, .ulDepthMode = PL_COMPARE_MODE_GREATER, @@ -2198,8 +2201,8 @@ pl_refr_create_global_shaders(void) gptData->tDeferredShader = gptGfx->create_shader(gptData->ptDevice, &tDeferredShaderDescription); plShaderDesc tForwardShaderDescription = { - .tPixelShader = gptShader->load_glsl("../shaders/transparent.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/transparent.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("transparent.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("transparent.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, @@ -2283,13 +2286,16 @@ pl_refr_create_global_shaders(void) .apcIncludeDirectories = { "../shaders/" }, + .apcDirectories = { + "../shaders/" + }, #ifndef PL_OFFLINE_SHADERS_ONLY .tFlags = PL_SHADER_FLAGS_ALWAYS_COMPILE | PL_SHADER_FLAGS_INCLUDE_DEBUG #endif }; - plShaderModule tShadowPixelShader = gptShader->load_glsl("../shaders/shadow.frag", "main", NULL, NULL); - plShaderModule tVertexShader = gptShader->load_glsl("../shaders/shadow.vert", "main", NULL, gptData->bMultiViewportShadows ? &tShadowShaderOptions : NULL); + plShaderModule tShadowPixelShader = gptShader->load_glsl("shadow.frag", "main", NULL, NULL); + plShaderModule tVertexShader = gptShader->load_glsl("shadow.vert", "main", NULL, gptData->bMultiViewportShadows ? &tShadowShaderOptions : NULL); plShaderDesc tShadowShaderDescription = { .tPixelShader = tShadowPixelShader, @@ -2363,8 +2369,8 @@ pl_refr_create_global_shaders(void) gptData->tShadowShader = gptGfx->create_shader(gptData->ptDevice, &tShadowShaderDescription); const plShaderDesc tPickShaderDescription = { - .tPixelShader = gptShader->load_glsl("../shaders/picking.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/picking.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("picking.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("picking.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 1, .ulDepthMode = PL_COMPARE_MODE_GREATER_OR_EQUAL, @@ -2399,8 +2405,8 @@ pl_refr_create_global_shaders(void) gptData->tPickShader = gptGfx->create_shader(gptData->ptDevice, &tPickShaderDescription); const plShaderDesc tUVShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/uvmap.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/uvmap.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("uvmap.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("uvmap.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_ALWAYS, @@ -2434,8 +2440,8 @@ pl_refr_create_global_shaders(void) // create skybox shader plShaderDesc tSkyboxShaderDesc = { - .tPixelShader = gptShader->load_glsl("../shaders/skybox.frag", "main", NULL, NULL), - .tVertexShader = gptShader->load_glsl("../shaders/skybox.vert", "main", NULL, NULL), + .tPixelShader = gptShader->load_glsl("skybox.frag", "main", NULL, NULL), + .tVertexShader = gptShader->load_glsl("skybox.vert", "main", NULL, NULL), .tGraphicsState = { .ulDepthWriteEnabled = 0, .ulDepthMode = PL_COMPARE_MODE_EQUAL, @@ -2622,7 +2628,7 @@ pl__add_drawable_skin_data_to_global_buffer(plRefScene* ptScene, uint32_t uDrawa int aiSpecializationData[] = {(int)ulVertexStreamMask, (int)uStride, (int)ptMesh->ulVertexStreamMask, (int)uDestStride}; const plComputeShaderDesc tComputeShaderDesc = { - .tShader = gptShader->load_glsl("../shaders/skinning.comp", "main", NULL, NULL), + .tShader = gptShader->load_glsl("skinning.comp", "main", NULL, NULL), .pTempConstantData = aiSpecializationData, .atConstants = { { .uID = 0, .uOffset = 0, .tType = PL_DATA_TYPE_INT}, @@ -4285,13 +4291,6 @@ pl__refr_set_drawable_shaders(uint32_t uSceneHandle) { iObjectRenderingFlags |= PL_RENDERING_FLAG_SHADOWS; } - if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_SHADOW) - { - if(ptScene->sbtDrawables[i].tFlags & PL_DRAWABLE_FLAG_FORWARD) - pl_sb_push(ptScene->sbuShadowForwardDrawables, i); - else if(ptScene->sbtDrawables[i].tFlags & PL_DRAWABLE_FLAG_DEFERRED) - pl_sb_push(ptScene->sbuShadowDeferredDrawables, i); - } // choose shader variant int aiConstantData0[] = { @@ -4384,7 +4383,111 @@ pl__refr_set_drawable_shaders(uint32_t uSceneHandle) } static void -pl__refr_process_drawables(uint32_t uSceneHandle) +pl__refr_sort_drawables(uint32_t uSceneHandle) +{ + plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; + plDevice* ptDevice = gptData->ptDevice; + + pl_sb_reset(ptScene->sbuShadowDeferredDrawables); + pl_sb_reset(ptScene->sbuShadowForwardDrawables); + + const uint32_t uDrawableCount = pl_sb_size(ptScene->sbtDrawables); + for(uint32_t i = 0; i < uDrawableCount; i++) + { + + plEntity tEntity = ptScene->sbtDrawables[i].tEntity; + + // get actual components + plObjectComponent* ptObject = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_OBJECT, tEntity); + plMeshComponent* ptMesh = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MESH, ptObject->tMesh); + plMaterialComponent* ptMaterial = gptECS->get_component(&ptScene->tComponentLibrary, PL_COMPONENT_TYPE_MATERIAL, ptMesh->tMaterial); + + if(ptMaterial->tFlags & PL_MATERIAL_FLAG_CAST_SHADOW && ptObject->tFlags & PL_OBJECT_FLAGS_CAST_SHADOW) + { + if(ptScene->sbtDrawables[i].tFlags & PL_DRAWABLE_FLAG_FORWARD) + pl_sb_push(ptScene->sbuShadowForwardDrawables, i); + else if(ptScene->sbtDrawables[i].tFlags & PL_DRAWABLE_FLAG_DEFERRED) + pl_sb_push(ptScene->sbuShadowDeferredDrawables, i); + } + + ptScene->sbtDrawables[i].tIndexBuffer = ptScene->sbtDrawables[i].uIndexCount == 0 ? (plBufferHandle){0} : ptScene->tIndexBuffer; + } +} + +static void +pl__refr_add_skybox_drawable(uint32_t uSceneHandle) +{ + plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; + const uint32_t uStartIndex = pl_sb_size(ptScene->sbtVertexPosBuffer); + const uint32_t uIndexStart = pl_sb_size(ptScene->sbuIndexBuffer); + const uint32_t uDataStartIndex = pl_sb_size(ptScene->sbtVertexDataBuffer); + + const plDrawable tDrawable = { + .uIndexCount = 36, + .uVertexCount = 8, + .uIndexOffset = uIndexStart, + .uVertexOffset = uStartIndex, + .uDataOffset = uDataStartIndex, + }; + ptScene->tSkyboxDrawable = tDrawable; + + // indices + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); + + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); + + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 3); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); + + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 7); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); + + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 2); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 6); + + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 0); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 1); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 5); + pl_sb_push(ptScene->sbuIndexBuffer, uStartIndex + 4); + + // vertices (position) + const float fCubeSide = 1.0f; + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, -fCubeSide, -fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, -fCubeSide, -fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, fCubeSide, -fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, fCubeSide, -fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, -fCubeSide, fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, -fCubeSide, fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){-fCubeSide, fCubeSide, fCubeSide})); + pl_sb_push(ptScene->sbtVertexPosBuffer, ((plVec3){ fCubeSide, fCubeSide, fCubeSide})); +} + +static void +pl__refr_unstage_drawables(uint32_t uSceneHandle) { plRefScene* ptScene = &gptData->sbtScenes[uSceneHandle]; plDevice* ptDevice = gptData->ptDevice; @@ -4394,8 +4497,7 @@ pl__refr_process_drawables(uint32_t uSceneHandle) // fill CPU buffers & drawable list pl_sb_reset(ptScene->sbtDrawables); - pl_sb_reset(ptScene->sbuShadowDeferredDrawables); - pl_sb_reset(ptScene->sbuShadowForwardDrawables); + pl_sb_reset(ptScene->sbtSkinData); const uint32_t uDrawableCount = pl_sb_size(ptScene->sbtStagedDrawables); pl_sb_reserve(ptScene->sbtDrawables, uDrawableCount); @@ -4406,14 +4508,14 @@ pl__refr_process_drawables(uint32_t uSceneHandle) ptScene->sbtStagedDrawables[i].uSkinIndex = UINT32_MAX; plEntity tEntity = ptScene->sbtStagedDrawables[i].tEntity; - // add entity to hashmap if first time - if(!pl_hm_has_key(ptScene->ptDrawableHashmap, tEntity.ulData)) + if(pl_hm_has_key(ptScene->ptDrawableHashmap, tEntity.ulData)) { - pl_hm_insert(ptScene->ptDrawableHashmap, tEntity.ulData, i); + pl_hm_remove(ptScene->ptDrawableHashmap, tEntity.ulData); } + pl_hm_insert(ptScene->ptDrawableHashmap, tEntity.ulData, i); // add data to global buffers - if(ptScene->sbtStagedDrawables[i].uVertexCount == 0) // first time + // if(ptScene->sbtStagedDrawables[i].uVertexCount == 0) // first time { pl__add_drawable_data_to_global_buffer(ptScene, i, ptScene->sbtStagedDrawables); pl__add_drawable_skin_data_to_global_buffer(ptScene, i, ptScene->sbtStagedDrawables); @@ -4424,4 +4526,116 @@ pl__refr_process_drawables(uint32_t uSceneHandle) ptScene->sbtStagedDrawables[i].uDynamicVertexOffset = ptScene->sbtStagedDrawables[i].uIndexCount == 0 ? 0 : ptScene->sbtStagedDrawables[i].uVertexOffset; pl_sb_push(ptScene->sbtDrawables, ptScene->sbtStagedDrawables[i]); } + + if(ptScene->tSkyboxTexture.uIndex != 0) + { + pl__refr_add_skybox_drawable(uSceneHandle); + } + + const plBufferDesc tIndexBufferDesc = { + .tUsage = PL_BUFFER_USAGE_INDEX, + .szByteSize = pl_max(sizeof(uint32_t) * pl_sb_size(ptScene->sbuIndexBuffer), 1024), + .pcDebugName = "index buffer" + }; + + const plBufferDesc tVertexBufferDesc = { + .tUsage = PL_BUFFER_USAGE_VERTEX | PL_BUFFER_USAGE_STORAGE, + .szByteSize = sizeof(plVec3) * pl_sb_size(ptScene->sbtVertexPosBuffer), + .pcDebugName = "vertex buffer" + }; + + const plBufferDesc tStorageBufferDesc = { + .tUsage = PL_BUFFER_USAGE_STORAGE, + .szByteSize = sizeof(plVec4) * pl_sb_size(ptScene->sbtVertexDataBuffer), + .pcDebugName = "storage buffer" + }; + + const plBufferDesc tSkinStorageBufferDesc = { + .tUsage = PL_BUFFER_USAGE_STORAGE, + .szByteSize = sizeof(plVec4) * pl_sb_size(ptScene->sbtSkinVertexDataBuffer), + .pcDebugName = "skin buffer" + }; + + if(ptScene->tIndexBuffer.uData != UINT32_MAX) gptGfx->queue_buffer_for_deletion(ptDevice, ptScene->tIndexBuffer); + if(ptScene->tVertexBuffer.uData != UINT32_MAX) gptGfx->queue_buffer_for_deletion(ptDevice, ptScene->tVertexBuffer); + if(ptScene->tStorageBuffer.uData != UINT32_MAX) + { + gptGfx->queue_buffer_for_deletion(ptDevice, ptScene->tStorageBuffer); + } + if(ptScene->tSkinStorageBuffer.uData != UINT32_MAX) + { + gptGfx->queue_buffer_for_deletion(ptDevice, ptScene->tSkinStorageBuffer); + gptGfx->queue_bind_group_for_deletion(ptDevice, ptScene->tSkinBindGroup0); + } + + ptScene->tIndexBuffer = pl__refr_create_local_buffer(&tIndexBufferDesc, "index", uSceneHandle, ptScene->sbuIndexBuffer); + ptScene->tVertexBuffer = pl__refr_create_local_buffer(&tVertexBufferDesc, "vertex", uSceneHandle, ptScene->sbtVertexPosBuffer); + ptScene->tStorageBuffer = pl__refr_create_local_buffer(&tStorageBufferDesc, "storage", uSceneHandle, ptScene->sbtVertexDataBuffer); + + if(tSkinStorageBufferDesc.szByteSize > 0) + { + ptScene->tSkinStorageBuffer = pl__refr_create_local_buffer(&tSkinStorageBufferDesc, "skin storage", uSceneHandle, ptScene->sbtSkinVertexDataBuffer); + + const plBindGroupLayout tSkinBindGroupLayout0 = { + .atSamplerBindings = { + {.uSlot = 3, .tStages = PL_STAGE_COMPUTE} + }, + .atBufferBindings = { + { .uSlot = 0, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, + { .uSlot = 1, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, + { .uSlot = 2, .tType = PL_BUFFER_BINDING_TYPE_STORAGE, .tStages = PL_STAGE_COMPUTE}, + } + }; + const plBindGroupDesc tSkinBindGroupDesc = { + .ptPool = gptData->ptBindGroupPool, + .ptLayout = &tSkinBindGroupLayout0, + .pcDebugName = "skin bind group" + }; + ptScene->tSkinBindGroup0 = gptGfx->create_bind_group(ptDevice, &tSkinBindGroupDesc); + + const plBindGroupUpdateSamplerData atSamplerData[] = { + { .uSlot = 3, .tSampler = gptData->tDefaultSampler} + }; + const plBindGroupUpdateBufferData atBufferData[] = + { + { .uSlot = 0, .tBuffer = ptScene->tSkinStorageBuffer, .szBufferRange = tSkinStorageBufferDesc.szByteSize}, + { .uSlot = 1, .tBuffer = ptScene->tVertexBuffer, .szBufferRange = tVertexBufferDesc.szByteSize}, + { .uSlot = 2, .tBuffer = ptScene->tStorageBuffer, .szBufferRange = tStorageBufferDesc.szByteSize} + + }; + plBindGroupUpdateData tBGData0 = { + .uBufferCount = 3, + .atBufferBindings = atBufferData, + .uSamplerCount = 1, + .atSamplerBindings = atSamplerData, + }; + gptGfx->update_bind_group(gptData->ptDevice, ptScene->tSkinBindGroup0, &tBGData0); + } + + plBuffer* ptStorageBuffer = gptGfx->get_buffer(ptDevice, ptScene->tStorageBuffer); + + + for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++) + { + const plBindGroupUpdateBufferData atGlobalBufferData[] = + { + { + .tBuffer = ptScene->tStorageBuffer, + .uSlot = 0, + .szBufferRange = ptStorageBuffer->tDesc.szByteSize + } + }; + + plBindGroupUpdateData tGlobalBindGroupData = { + .uBufferCount = 1, + .atBufferBindings = atGlobalBufferData, + }; + + gptGfx->update_bind_group(gptData->ptDevice, ptScene->atGlobalBindGroup[i], &tGlobalBindGroupData); + } + + pl_sb_free(ptScene->sbtVertexPosBuffer); + pl_sb_free(ptScene->sbtVertexDataBuffer); + pl_sb_free(ptScene->sbuIndexBuffer); + pl_sb_free(ptScene->sbtSkinVertexDataBuffer); } \ No newline at end of file diff --git a/extensions/pl_renderer_internal.h b/extensions/pl_renderer_internal.h index 0aefa655..aa5cd131 100644 --- a/extensions/pl_renderer_internal.h +++ b/extensions/pl_renderer_internal.h @@ -376,6 +376,7 @@ typedef struct _plRefScene plDrawable tSkyboxDrawable; plTextureHandle tSkyboxTexture; plBindGroupHandle tSkyboxBindGroup; + bool bShowSkybox; // shared bind groups plBindGroupHandle tSkinBindGroup0; @@ -668,8 +669,12 @@ static size_t pl__get_data_type_size2(plDataType tType); static plBlendState pl__get_blend_state(plBlendMode tBlendMode); static uint32_t pl__get_bindless_texture_index(uint32_t uSceneHandle, plTextureHandle); static uint32_t pl__get_bindless_cube_texture_index(uint32_t uSceneHandle, plTextureHandle); -static void pl__refr_process_drawables(uint32_t uSceneHandle); -static void pl__refr_set_drawable_shaders(uint32_t uSceneHandle); + +// drawable ops +static void pl__refr_add_skybox_drawable (uint32_t uSceneHandle); +static void pl__refr_unstage_drawables (uint32_t uSceneHandle); +static void pl__refr_set_drawable_shaders(uint32_t uSceneHandle); +static void pl__refr_sort_drawables (uint32_t uSceneHandle); // environment probes static void pl__create_probe_data(uint32_t uSceneHandle, plEntity tProbeHandle); diff --git a/extensions/pl_shader_ext.c b/extensions/pl_shader_ext.c index 09542fb2..d6c7a49f 100644 --- a/extensions/pl_shader_ext.c +++ b/extensions/pl_shader_ext.c @@ -48,7 +48,7 @@ Index of this file: #ifndef PL_OFFLINE_SHADERS_ONLY #include "shaderc/shaderc.h" -#ifdef PL_METAL_BACKEND +#ifdef PL_INCLUDE_SPIRV_CROSS #include "spirv_cross/spirv_cross_c.h" #endif @@ -59,7 +59,7 @@ Index of this file: //----------------------------------------------------------------------------- #ifndef PL_OFFLINE_SHADERS_ONLY -#ifdef PL_METAL_BACKEND +#ifdef PL_INCLUDE_SPIRV_CROSS static spvc_context tSpirvCtx; #endif #endif @@ -139,12 +139,15 @@ pl_initialize_shader_ext(const plShaderOptions* ptShaderOptions) return true; gptShaderCtx->bInitialized = true; - - gptShaderCtx->tDefaultShaderOptions.tFlags = ptShaderOptions->tFlags; + #ifdef PL_METAL_BACKEND + gptShaderCtx->tDefaultShaderOptions.tFlags |= PL_SHADER_FLAGS_METAL_OUTPUT; + #endif gptShaderCtx->tDefaultShaderOptions.apcIncludeDirectories[0] = "./"; gptShaderCtx->tDefaultShaderOptions._uIncludeDirectoriesCount = 1; + gptShaderCtx->tDefaultShaderOptions._uDirectoriesCount = 0; + if(ptShaderOptions) { for(uint32_t i = 0; i < PL_MAX_SHADER_INCLUDE_DIRECTORIES; i++) @@ -155,10 +158,19 @@ pl_initialize_shader_ext(const plShaderOptions* ptShaderOptions) break; gptShaderCtx->tDefaultShaderOptions._uIncludeDirectoriesCount++; } + + for(uint32_t i = 0; i < PL_MAX_SHADER_DIRECTORIES; i++) + { + if(ptShaderOptions->apcDirectories[i]) + gptShaderCtx->tDefaultShaderOptions.apcDirectories[i] = ptShaderOptions->apcDirectories[i]; + else + break; + gptShaderCtx->tDefaultShaderOptions._uDirectoriesCount++; + } } #ifndef PL_OFFLINE_SHADERS_ONLY - #ifdef PL_METAL_BACKEND + #ifdef PL_INCLUDE_SPIRV_CROSS spvc_context_create(&tSpirvCtx); spvc_context_set_error_callback(tSpirvCtx, pl_spvc_error_callback, NULL); #endif @@ -196,11 +208,12 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* #ifndef PL_OFFLINE_SHADERS_ONLY shaderc_compiler_t tCompiler = shaderc_compiler_initialize(); - shaderc_compile_options_t tOptions = shaderc_compile_options_initialize(); + shaderc_compile_options_t tShaderRcOptions = shaderc_compile_options_initialize(); if(ptOptions) { ptOptions->_uIncludeDirectoriesCount = 0; + ptOptions->_uDirectoriesCount = 0; for(uint32_t i = 0; i < PL_MAX_SHADER_INCLUDE_DIRECTORIES; i++) { if(ptOptions->apcIncludeDirectories[i]) @@ -208,35 +221,63 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* else break; } + for(uint32_t i = 0; i < PL_MAX_SHADER_DIRECTORIES; i++) + { + if(ptOptions->apcDirectories[i]) + ptOptions->_uDirectoriesCount++; + else + break; + } } - shaderc_compile_options_set_include_callbacks(tOptions, pl_shaderc_include_resolve_fn, pl_shaderc_include_result_release_fn, ptOptions); + shaderc_compile_options_set_include_callbacks(tShaderRcOptions, pl_shaderc_include_resolve_fn, pl_shaderc_include_result_release_fn, ptOptions); if(ptOptions == NULL) ptOptions = &gptShaderCtx->tDefaultShaderOptions; + + const char* pcLocatedShader = NULL; + + for(uint32_t i = 0; i < ptOptions->_uDirectoriesCount; i++) + { + pcLocatedShader = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s%s", ptOptions->apcDirectories[i], pcShader); + if(gptFile->exists(pcLocatedShader)) + { + break; + } + pcLocatedShader = NULL; + } + + if(pcLocatedShader == NULL) + pcLocatedShader = pcShader; + + if(!gptFile->exists(pcLocatedShader)) + { + pl_temp_allocator_reset(&gptShaderCtx->tTempAllocator2); + return tModule; + } switch(ptOptions->tOptimizationLevel) { case PL_SHADER_OPTIMIZATION_SIZE: - shaderc_compile_options_set_optimization_level(tOptions, shaderc_optimization_level_size); + shaderc_compile_options_set_optimization_level(tShaderRcOptions, shaderc_optimization_level_size); break; case PL_SHADER_OPTIMIZATION_PERFORMANCE: - shaderc_compile_options_set_optimization_level(tOptions, shaderc_optimization_level_performance); + shaderc_compile_options_set_optimization_level(tShaderRcOptions, shaderc_optimization_level_performance); break; case PL_SHADER_OPTIMIZATION_NONE: default: - shaderc_compile_options_set_optimization_level(tOptions, shaderc_optimization_level_zero); + shaderc_compile_options_set_optimization_level(tShaderRcOptions, shaderc_optimization_level_zero); break; } if(ptOptions->tFlags & PL_SHADER_FLAGS_INCLUDE_DEBUG) - shaderc_compile_options_set_generate_debug_info(tOptions); + shaderc_compile_options_set_generate_debug_info(tShaderRcOptions); for(uint32_t i = 0; i < ptOptions->uMacroDefinitionCount; i++) { - shaderc_compile_options_add_macro_definition(tOptions, + shaderc_compile_options_add_macro_definition(tShaderRcOptions, ptOptions->ptMacroDefinitions[i].pcName, ptOptions->ptMacroDefinitions[i].szNameLength, ptOptions->ptMacroDefinitions[i].pcValue, @@ -246,10 +287,10 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* // shaderc_compile_options_set_forced_version_profile(tOptions, 450, shaderc_profile_core); size_t szShaderSize = 0; - gptFile->binary_read(pcShader, &szShaderSize, NULL); + gptFile->binary_read(pcLocatedShader, &szShaderSize, NULL); uint8_t* puShaderCode = PL_ALLOC(szShaderSize); memset(puShaderCode, 0, szShaderSize); - gptFile->binary_read(pcShader, &szShaderSize, puShaderCode); + gptFile->binary_read(pcLocatedShader, &szShaderSize, puShaderCode); pl_sb_push(gptShaderCtx->sbptShaderBytecodeCache, puShaderCode); char acExtension[64] = {0}; @@ -272,9 +313,9 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* (const char*)puShaderCode, szShaderSize, tShaderKind, - pcShader, + pcLocatedShader, pcEntryFunc, - tOptions); + tShaderRcOptions); size_t uNumErrors = shaderc_result_get_num_errors(tresult); if(uNumErrors) @@ -292,119 +333,123 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* tModule.pcEntryFunc = pcEntryFunc; } - #ifdef PL_METAL_BACKEND - if(tShaderKind == shaderc_glsl_vertex_shader) + #ifdef PL_INCLUDE_SPIRV_CROSS + if(ptOptions->tFlags & PL_SHADER_FLAGS_METAL_OUTPUT) { - spvc_parsed_ir ir = NULL; - spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); + if(tShaderKind == shaderc_glsl_vertex_shader) + { + spvc_parsed_ir ir = NULL; + spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); - spvc_compiler tMslCompiler; - spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); + spvc_compiler tMslCompiler; + spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); - spvc_compiler_options tOptions; - spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); + spvc_compiler_options tOptions; + spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); - spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); + spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_FLIP_VERTEX_Y, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); - spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "vertex_main", SpvExecutionModelVertex); + spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "vertex_main", SpvExecutionModelVertex); - const spvc_reflected_resource *list = NULL; - spvc_resources resources = NULL; - size_t count = 0; - spvc_compiler_create_shader_resources(tMslCompiler, &resources); - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); + const spvc_reflected_resource *list = NULL; + spvc_resources resources = NULL; + size_t count = 0; + spvc_compiler_create_shader_resources(tMslCompiler, &resources); + spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); - for (size_t i = 0; i < count; i++) - { - if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + for (size_t i = 0; i < count; i++) { - spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); - break; + if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + { + spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); + break; + } } - } - spvc_compiler_install_compiler_options(tMslCompiler, tOptions); - spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); - } - else if(tShaderKind == shaderc_glsl_fragment_shader) - { - spvc_parsed_ir ir = NULL; - spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); + spvc_compiler_install_compiler_options(tMslCompiler, tOptions); + spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); + } + else if(tShaderKind == shaderc_glsl_fragment_shader) + { + spvc_parsed_ir ir = NULL; + spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); - spvc_compiler tMslCompiler; - spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); + spvc_compiler tMslCompiler; + spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); - spvc_compiler_options tOptions; - spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); + spvc_compiler_options tOptions; + spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); - spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); + spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); - spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "fragment_main", SpvExecutionModelFragment); + spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "fragment_main", SpvExecutionModelFragment); - const spvc_reflected_resource *list = NULL; - spvc_resources resources = NULL; - size_t count = 0; - spvc_compiler_create_shader_resources(tMslCompiler, &resources); - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); + const spvc_reflected_resource *list = NULL; + spvc_resources resources = NULL; + size_t count = 0; + spvc_compiler_create_shader_resources(tMslCompiler, &resources); + spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); - for (size_t i = 0; i < count; i++) - { - if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + for (size_t i = 0; i < count; i++) { - spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); - break; + if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + { + spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); + break; + } } - } - spvc_compiler_install_compiler_options(tMslCompiler, tOptions); - spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); - } - else if(tShaderKind == shaderc_glsl_compute_shader) - { - spvc_parsed_ir ir = NULL; - spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); + spvc_compiler_install_compiler_options(tMslCompiler, tOptions); + spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); + } + else if(tShaderKind == shaderc_glsl_compute_shader) + { + spvc_parsed_ir ir = NULL; + spvc_context_parse_spirv(tSpirvCtx, (const SpvId*)tModule.puCode, tModule.szCodeSize / sizeof(SpvId) , &ir); - spvc_compiler tMslCompiler; - spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); + spvc_compiler tMslCompiler; + spvc_context_create_compiler(tSpirvCtx, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_TAKE_OWNERSHIP, &tMslCompiler); - spvc_compiler_options tOptions; - spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); + spvc_compiler_options tOptions; + spvc_compiler_create_compiler_options(tMslCompiler, &tOptions); - spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); - spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); + spvc_compiler_options_set_uint(tOptions, SPVC_COMPILER_OPTION_MSL_VERSION, 30000); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); + spvc_compiler_options_set_bool(tOptions, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); - spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "kernel_main", SpvExecutionModelGLCompute); + spvc_compiler_rename_entry_point(tMslCompiler, tModule.pcEntryFunc, "kernel_main", SpvExecutionModelGLCompute); - const spvc_reflected_resource *list = NULL; - spvc_resources resources = NULL; - size_t count = 0; - spvc_compiler_create_shader_resources(tMslCompiler, &resources); - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); + const spvc_reflected_resource *list = NULL; + spvc_resources resources = NULL; + size_t count = 0; + spvc_compiler_create_shader_resources(tMslCompiler, &resources); + spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); - for (size_t i = 0; i < count; i++) - { - if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + for (size_t i = 0; i < count; i++) { - spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); - break; + if(spvc_compiler_get_decoration(tMslCompiler, list[i].id, SpvDecorationDescriptorSet) == 3) + { + spvc_compiler_msl_add_inline_uniform_block(tMslCompiler, 3, 0); + break; + } } - } - spvc_compiler_install_compiler_options(tMslCompiler, tOptions); - spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); + spvc_compiler_install_compiler_options(tMslCompiler, tOptions); + spvc_compiler_compile(tMslCompiler, (const char**)&tModule.puCode); + } + if(tModule.puCode) + tModule.szCodeSize = strlen((const char*)tModule.puCode); } - if(tModule.puCode) - tModule.szCodeSize = strlen((const char*)tModule.puCode); - #endif // PL_METAL_BACKEND + #endif // PL_INCLUDE_SPIRV_CROSS + pl_temp_allocator_reset(&gptShaderCtx->tTempAllocator2); #endif // PL_OFFLINE_SHADERS_ONLY return tModule; } @@ -412,6 +457,26 @@ pl_compile_glsl(const char* pcShader, const char* pcEntryFunc, plShaderOptions* static plShaderModule pl_load_glsl(const char* pcShader, const char* pcEntryFunc, const char* pcFile, plShaderOptions* ptOptions) { + if(ptOptions) + { + ptOptions->_uIncludeDirectoriesCount = 0; + ptOptions->_uDirectoriesCount = 0; + for(uint32_t i = 0; i < PL_MAX_SHADER_INCLUDE_DIRECTORIES; i++) + { + if(ptOptions->apcIncludeDirectories[i]) + ptOptions->_uIncludeDirectoriesCount++; + else + break; + } + for(uint32_t i = 0; i < PL_MAX_SHADER_DIRECTORIES; i++) + { + if(ptOptions->apcDirectories[i]) + ptOptions->_uDirectoriesCount++; + else + break; + } + } + if(ptOptions == NULL) ptOptions = &gptShaderCtx->tDefaultShaderOptions; @@ -420,11 +485,34 @@ pl_load_glsl(const char* pcShader, const char* pcEntryFunc, const char* pcFile, { // char acTempBuffer[1024] = {0}; const char* pcFileNameOnly = pl_str_get_file_name(pcShader, NULL, 0); - #ifdef PL_METAL_BACKEND - pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.metal", pcFileNameOnly); - #else - pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.spv", pcFileNameOnly); - #endif + + for(uint32_t i = 0; i < ptOptions->_uDirectoriesCount; i++) + { + if(ptOptions->tFlags & PL_SHADER_FLAGS_METAL_OUTPUT) + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s%s.metal", ptOptions->apcDirectories[i], pcFileNameOnly); + else + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s%s.spv", ptOptions->apcDirectories[i], pcFileNameOnly); + if(gptFile->exists(pcCacheFile)) + { + break; + } + else + pcCacheFile = NULL; + + } + + if(pcCacheFile == NULL) + { + if(ptOptions->tFlags & PL_SHADER_FLAGS_METAL_OUTPUT) + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.metal", pcFileNameOnly); + else + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.spv", pcFileNameOnly); + } + + // if(ptOptions->tFlags & PL_SHADER_FLAGS_METAL_OUTPUT) + // pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.metal", pcFileNameOnly); + // else + // pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.spv", pcFileNameOnly); } plShaderModule tModule = {0}; @@ -436,6 +524,12 @@ pl_load_glsl(const char* pcShader, const char* pcEntryFunc, const char* pcFile, // no precompiled shader available, compile it ourselves if(tModule.szCodeSize == 0) { + const char* pcFileNameOnly = pl_str_get_file_name(pcShader, NULL, 0); + if(ptOptions->tFlags & PL_SHADER_FLAGS_METAL_OUTPUT) + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.metal", pcFileNameOnly); + else + pcCacheFile = pl_temp_allocator_sprintf(&gptShaderCtx->tTempAllocator2, "%s.spv", pcFileNameOnly); + tModule = pl_compile_glsl(pcShader, pcEntryFunc, ptOptions); if(!(ptOptions->tFlags & PL_SHADER_FLAGS_NEVER_CACHE) && tModule.szCodeSize > 0) pl_write_to_disk(pcCacheFile, &tModule); @@ -491,7 +585,7 @@ pl_unload_shader_ext(plApiRegistryI* ptApiRegistry, bool bReload) ptApiRegistry->remove_api(ptApi); #ifndef PL_OFFLINE_SHADERS_ONLY - #ifdef PL_METAL_BACKEND + #ifdef PL_INCLUDE_SPIRV_CROSS spvc_context_destroy(tSpirvCtx); #endif #endif diff --git a/extensions/pl_shader_ext.h b/extensions/pl_shader_ext.h index 1d91c999..40f06590 100644 --- a/extensions/pl_shader_ext.h +++ b/extensions/pl_shader_ext.h @@ -26,6 +26,10 @@ Index of this file: #define PL_MAX_SHADER_INCLUDE_DIRECTORIES 16 #endif +#ifndef PL_MAX_SHADER_DIRECTORIES + #define PL_MAX_SHADER_DIRECTORIES 16 +#endif + //----------------------------------------------------------------------------- // [SECTION] includes //----------------------------------------------------------------------------- @@ -37,7 +41,7 @@ Index of this file: // [SECTION] APIs //----------------------------------------------------------------------------- -#define plShaderI_version (plVersion){1, 0, 2} +#define plShaderI_version (plVersion){1, 1, 0} //----------------------------------------------------------------------------- // [SECTION] forward declarations @@ -93,8 +97,10 @@ typedef struct _plShaderOptions const plShaderMacroDefinition* ptMacroDefinitions; uint32_t uMacroDefinitionCount; const char* apcIncludeDirectories[PL_MAX_SHADER_INCLUDE_DIRECTORIES + 1]; + const char* apcDirectories[PL_MAX_SHADER_DIRECTORIES]; // [INTERNAL] + uint32_t _uDirectoriesCount; uint32_t _uIncludeDirectoriesCount; } plShaderOptions; @@ -108,6 +114,7 @@ enum _plShaderFlags PL_SHADER_FLAGS_INCLUDE_DEBUG = 1 << 0, // include debug information PL_SHADER_FLAGS_ALWAYS_COMPILE = 1 << 1, // ignore cached shader modules PL_SHADER_FLAGS_NEVER_CACHE = 1 << 2, // never cache shaders to disk + PL_SHADER_FLAGS_METAL_OUTPUT = 1 << 3, // output metal shader }; enum _plShaderOptimizationLevel diff --git a/extensions/pl_unity_ext.c b/extensions/pl_unity_ext.c index 02a0f724..211f129b 100644 --- a/extensions/pl_unity_ext.c +++ b/extensions/pl_unity_ext.c @@ -39,6 +39,8 @@ Index of this file: #include "pl_debug_ext.c" #include "pl_profile_ext.c" #include "pl_log_ext.c" +#include "pl_ecs_tools_ext.c" +#include "pl_gizmo_ext.c" //----------------------------------------------------------------------------- // [SECTION] extension loading @@ -70,6 +72,9 @@ pl_load_ext(plApiRegistryI* ptApiRegistry, bool bReload) gptResource = pl_get_api_latest(ptApiRegistry, plResourceI); gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI); gptLog = pl_get_api_latest(ptApiRegistry, plLogI); + gptRenderer = pl_get_api_latest(ptApiRegistry, plRendererI); + gptEcsTools = pl_get_api_latest(ptApiRegistry, plEcsToolsI); + gptGizmo = pl_get_api_latest(ptApiRegistry, plGizmoI); gptIO = gptIOI->get_io(); pl_load_log_ext(ptApiRegistry, bReload); @@ -93,6 +98,8 @@ pl_load_ext(plApiRegistryI* ptApiRegistry, bool bReload) pl_load_resource_ext(ptApiRegistry, bReload); pl_load_model_loader_ext(ptApiRegistry, bReload); pl_load_renderer_ext(ptApiRegistry, bReload); + pl_load_ecs_tools_ext(ptApiRegistry, bReload); + pl_load_gizmo_ext(ptApiRegistry, bReload); pl_load_debug_ext(ptApiRegistry, bReload); pl_load_profile_ext(ptApiRegistry, bReload); } @@ -117,6 +124,8 @@ pl_unload_ext(plApiRegistryI* ptApiRegistry, bool bReload) pl_unload_resource_ext(ptApiRegistry, bReload); pl_unload_model_loader_ext(ptApiRegistry, bReload); pl_unload_renderer_ext(ptApiRegistry, bReload); + pl_unload_ecs_tools_ext(ptApiRegistry, bReload); + pl_unload_gizmo_ext(ptApiRegistry, bReload); pl_unload_debug_ext(ptApiRegistry, bReload); pl_unload_profile_ext(ptApiRegistry, bReload); pl_unload_log_ext(ptApiRegistry, bReload); diff --git a/extensions/pl_unity_ext.inc b/extensions/pl_unity_ext.inc index f1b2475c..1a9fd940 100644 --- a/extensions/pl_unity_ext.inc +++ b/extensions/pl_unity_ext.inc @@ -37,6 +37,9 @@ static const struct _plLogI* gptLog = 0; static const struct _plCameraI* gptCamera = 0; static const struct _plResourceI* gptResource = 0; static const struct _plEcsI* gptECS = 0; +static const struct _plRendererI* gptRenderer = 0; +static const struct _plEcsToolsI* gptEcsTools = 0; +static const struct _plGizmoI* gptGizmo = 0; // context static struct _plIO* gptIO = 0; diff --git a/sandbox/app.c b/sandbox/app.c index f6dc606e..758e207e 100644 --- a/sandbox/app.c +++ b/sandbox/app.c @@ -55,6 +55,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plEditorData* ptEditorData) gptString = pl_get_api_latest(ptApiRegistry, plStringInternI); gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI); gptFile = pl_get_api_latest(ptApiRegistry, plFileI); + gptEcsTools = pl_get_api_latest(ptApiRegistry, plEcsToolsI); + gptGizmo = pl_get_api_latest(ptApiRegistry, plGizmoI); return ptEditorData; } @@ -83,6 +85,8 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plEditorData* ptEditorData) gptString = pl_get_api_latest(ptApiRegistry, plStringInternI); gptProfile = pl_get_api_latest(ptApiRegistry, plProfileI); gptFile = pl_get_api_latest(ptApiRegistry, plFileI); + gptEcsTools = pl_get_api_latest(ptApiRegistry, plEcsToolsI); + gptGizmo = pl_get_api_latest(ptApiRegistry, plGizmoI); gptProfile->begin_frame(); @@ -96,15 +100,15 @@ pl_app_load(plApiRegistryI* ptApiRegistry, plEditorData* ptEditorData) .apcIncludeDirectories = { "../shaders/" }, + .apcDirectories = { + "../shaders/" + }, #ifndef PL_OFFLINE_SHADERS_ONLY .tFlags = PL_SHADER_FLAGS_ALWAYS_COMPILE | PL_SHADER_FLAGS_INCLUDE_DEBUG #endif }; gptShader->initialize(&tDefaultShaderOptions); - // initialize gizmo stuff - ptEditorData->ptGizmoData = pl_initialize_gizmo_data(); - // initialize job system gptJobs->initialize(0); @@ -340,11 +344,11 @@ pl_app_update(plEditorData* ptEditorData) } if(gptIO->is_key_pressed(PL_KEY_M, true)) - pl_change_gizmo_mode(ptEditorData->ptGizmoData); + gptGizmo->next_mode(); if(ptEditorData->bShowEntityWindow) { - if(pl_show_ecs_window(&ptEditorData->tSelectedEntity, ptEditorData->uSceneHandle0, &ptEditorData->bShowEntityWindow)) + if(gptEcsTools->show_ecs_window(&ptEditorData->tSelectedEntity, ptEditorData->uSceneHandle0, &ptEditorData->bShowEntityWindow)) { if(ptEditorData->tSelectedEntity.ulData == UINT64_MAX) gptRenderer->select_entities(ptEditorData->uSceneHandle0, 0, NULL); @@ -356,7 +360,20 @@ pl_app_update(plEditorData* ptEditorData) if(ptEditorData->tSelectedEntity.uIndex != UINT32_MAX) { plDrawList3D* ptGizmoDrawlist = gptRenderer->get_gizmo_drawlist(ptEditorData->uSceneHandle0, ptEditorData->uViewHandle0); - pl_gizmo(ptEditorData->ptGizmoData, ptGizmoDrawlist, ptMainComponentLibrary, ptCamera, ptEditorData->tSelectedEntity); + plObjectComponent* ptSelectedObject = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_OBJECT, ptEditorData->tSelectedEntity); + plTransformComponent* ptSelectedTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptEditorData->tSelectedEntity); + plTransformComponent* ptParentTransform = NULL; + plHierarchyComponent* ptHierarchyComp = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_HIERARCHY, ptEditorData->tSelectedEntity); + if(ptHierarchyComp) + { + ptParentTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptHierarchyComp->tParent); + } + if(ptSelectedObject) + { + ptSelectedTransform = gptEcs->get_component(ptMainComponentLibrary, PL_COMPONENT_TYPE_TRANSFORM, ptSelectedObject->tTransform); + gptGizmo->gizmo(ptGizmoDrawlist, ptCamera, ptSelectedTransform, ptParentTransform); + ptSelectedTransform->tFlags |= PL_TRANSFORM_FLAGS_DIRTY; + } } const plViewOptions tViewOptions = { @@ -570,9 +587,6 @@ pl_app_update(plEditorData* ptEditorData) // [SECTION] unity build //----------------------------------------------------------------------------- -#include "pl_gizmo.c" -#include "pl_ecs_tools.c" - #ifdef PL_USE_STB_SPRINTF #define STB_SPRINTF_IMPLEMENTATION #include "stb_sprintf.h" diff --git a/sandbox/app.h b/sandbox/app.h index a994c9bf..ae425314 100644 --- a/sandbox/app.h +++ b/sandbox/app.h @@ -41,10 +41,10 @@ #include "pl_window_ext.h" #include "pl_library_ext.h" #include "pl_file_ext.h" +#include "pl_ecs_tools_ext.h" +#include "pl_gizmo_ext.h" // editor -#include "pl_gizmo.h" -#include "pl_ecs_tools.h" #include "pl_icons.h" //----------------------------------------------------------------------------- @@ -70,6 +70,8 @@ static const plNetworkI* gptNetwork = NULL; static const plStringInternI* gptString = NULL; static const plProfileI* gptProfile = NULL; static const plFileI* gptFile = NULL; +static const plEcsToolsI* gptEcsTools = NULL; +static const plGizmoI* gptGizmo = NULL; #define PL_ALLOC(x) gptMemory->tracked_realloc(NULL, (x), __FILE__, __LINE__) #define PL_REALLOC(x, y) gptMemory->tracked_realloc((x), (y), __FILE__, __LINE__) @@ -117,9 +119,6 @@ typedef struct _plEditorData // selection stuff plEntity tSelectedEntity; - // gizmo data - plGizmoData* ptGizmoData; - // fonts plFont* tDefaultFont; diff --git a/sandbox/pl_gizmo.h b/sandbox/pl_gizmo.h deleted file mode 100644 index ff91900f..00000000 --- a/sandbox/pl_gizmo.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - pl_gizmo.h -*/ - -/* -Index of this file: -// [SECTION] header mess -// [SECTION] includes -// [SECTION] forward declarations -// [SECTION] public api -*/ - -//----------------------------------------------------------------------------- -// [SECTION] header mess -//----------------------------------------------------------------------------- - -#ifndef PL_GIZMO_H -#define PL_GIZMO_H - -//----------------------------------------------------------------------------- -// [SECTION] includes -//----------------------------------------------------------------------------- - -#include - -//----------------------------------------------------------------------------- -// [SECTION] forward declarations -//----------------------------------------------------------------------------- - -// basic types -typedef struct _plGizmoData plGizmoData; - -// external -typedef struct _plDrawList3D plDrawList3D; // pl_draw_ext.h -typedef struct _plComponentLibrary plComponentLibrary; // pl_ecs_ext.h -typedef struct _plCameraComponent plCameraComponent; // pl_ecs_ext.h -typedef union _plEntity plEntity; - -//----------------------------------------------------------------------------- -// [SECTION] public api -//----------------------------------------------------------------------------- - -plGizmoData* pl_initialize_gizmo_data(void); -void pl_change_gizmo_mode(plGizmoData*); -void pl_gizmo(plGizmoData*, plDrawList3D*, plComponentLibrary*, plCameraComponent*, plEntity); - -#endif // PL_GIZMO_H \ No newline at end of file diff --git a/scripts/gen_dev.py b/scripts/gen_dev.py index 7c901a64..d30e5210 100644 --- a/scripts/gen_dev.py +++ b/scripts/gen_dev.py @@ -118,7 +118,7 @@ with pl.platform("Windows"): with pl.compiler("msvc"): - pl.add_static_link_libraries("shaderc_combined") + pl.add_static_link_libraries("shaderc_combined", "spirv-cross-c-shared") pl.add_include_directories("%VULKAN_SDK%\\Include") pl.add_link_directories('%VULKAN_SDK%\\Lib') pl.add_static_link_libraries("vulkan-1") @@ -127,7 +127,7 @@ # linux with pl.platform("Linux"): with pl.compiler("gcc"): - pl.add_dynamic_link_libraries("shaderc_shared", "xcb", "X11", "X11-xcb", "xkbcommon", "xcb-cursor", "xcb-xfixes", "xcb-keysyms", "pthread") + pl.add_dynamic_link_libraries("spirv-cross-c-shared", "shaderc_shared", "xcb", "X11", "X11-xcb", "xkbcommon", "xcb-cursor", "xcb-xfixes", "xcb-keysyms", "pthread") pl.add_include_directories('$VULKAN_SDK/include', '/usr/include/vulkan') pl.add_link_directories('$VULKAN_SDK/lib') pl.add_dynamic_link_libraries("vulkan") @@ -145,7 +145,7 @@ with pl.platform("Windows"): with pl.compiler("msvc"): - pl.add_static_link_libraries("shaderc_combined") + pl.add_static_link_libraries("shaderc_combined", "spirv-cross-c-shared") pl.add_include_directories("%VULKAN_SDK%\\Include") pl.add_link_directories('%VULKAN_SDK%\\Lib') pl.add_static_link_libraries("vulkan-1") @@ -154,7 +154,7 @@ # linux with pl.platform("Linux"): with pl.compiler("gcc"): - pl.add_dynamic_link_libraries("shaderc_shared", "xcb", "X11", "X11-xcb", "xkbcommon", "xcb-cursor", "xcb-xfixes", "xcb-keysyms", "pthread") + pl.add_dynamic_link_libraries("spirv-cross-c-shared", "shaderc_shared", "xcb", "X11", "X11-xcb", "xkbcommon", "xcb-cursor", "xcb-xfixes", "xcb-keysyms", "pthread") pl.add_include_directories('$VULKAN_SDK/include', '/usr/include/vulkan') pl.add_link_directories('$VULKAN_SDK/lib') pl.add_dynamic_link_libraries("vulkan") @@ -172,7 +172,7 @@ with pl.platform("Darwin"): with pl.compiler("clang"): - pl.add_dynamic_link_libraries("shaderc_shared", "pthread") + pl.add_dynamic_link_libraries("spirv-cross-c-shared", "shaderc_shared", "pthread") pl.add_dynamic_link_libraries("vulkan") #----------------------------------------------------------------------------- diff --git a/scripts/gen_distribute.py b/scripts/gen_distribute.py index 13c2e9e0..d8539300 100644 --- a/scripts/gen_distribute.py +++ b/scripts/gen_distribute.py @@ -114,7 +114,9 @@ "pl_draw_backend_ext", "pl_resource_ext", "pl_model_loader_ext", - "pl_ui_ext" + "pl_ui_ext", + "pl_ecs_tools_ext", + "pl_gizmo_ext", ] for extension in extensions: diff --git a/scripts/package.py b/scripts/package.py index 51199420..3bc28aaf 100644 --- a/scripts/package.py +++ b/scripts/package.py @@ -32,6 +32,8 @@ "pl_draw_backend_ext.h", "pl_draw_ext.h", "pl_ecs_ext.h", + "pl_ecs_tools_ext.h", + "pl_gizmo_ext.h", "pl_file_ext.h", "pl_gpu_allocators_ext.h", "pl_graphics_ext.h", @@ -60,6 +62,8 @@ "pl_draw_backend_ext", "pl_draw_ext", "pl_ecs_ext", + "pl_ecs_tools_ext", + "pl_gizmo_ext", "pl_gpu_allocators_ext", "pl_graphics_ext", "pl_image_ext", diff --git a/scripts/setup.py b/scripts/setup.py index acc210de..1afa523e 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -16,7 +16,8 @@ "PL_VULKAN_BACKEND", "PL_METAL_BACKEND", "PL_TEST_IMPLEMENTATION", - "PL_CONFIG_DEBUG" + "PL_CONFIG_DEBUG", + "PL_INCLUDE_SPIRV_CROSS", ] includes = [ diff --git a/src/build_linux.sh b/src/build_linux.sh index ce9016a9..71bab80a 100644 --- a/src/build_linux.sh +++ b/src/build_linux.sh @@ -90,7 +90,7 @@ PL_LINK_DIRECTORIES="-L../out -L/usr/lib/x86_64-linux-gnu -L$VULKAN_SDK/lib " PL_COMPILER_FLAGS="-std=gnu11 -fPIC --debug -g " PL_LINKER_FLAGS="-ldl -lm " PL_STATIC_LINK_LIBRARIES="" -PL_DYNAMIC_LINK_LIBRARIES="-lshaderc_shared -lxcb -lX11 -lX11-xcb -lxkbcommon -lxcb-cursor -lxcb-xfixes -lxcb-keysyms -lpthread -lvulkan " +PL_DYNAMIC_LINK_LIBRARIES="-lspirv-cross-c-shared -lshaderc_shared -lxcb -lX11 -lX11-xcb -lxkbcommon -lxcb-cursor -lxcb-xfixes -lxcb-keysyms -lpthread -lvulkan " PL_SOURCES="../extensions/pl_unity_ext.c " # run compiler (and linker) @@ -253,7 +253,7 @@ PL_LINK_DIRECTORIES="-L../out -L/usr/lib/x86_64-linux-gnu -L$VULKAN_SDK/lib " PL_COMPILER_FLAGS="-std=gnu11 -fPIC " PL_LINKER_FLAGS="-ldl -lm " PL_STATIC_LINK_LIBRARIES="" -PL_DYNAMIC_LINK_LIBRARIES="-lshaderc_shared -lxcb -lX11 -lX11-xcb -lxkbcommon -lxcb-cursor -lxcb-xfixes -lxcb-keysyms -lpthread -lvulkan " +PL_DYNAMIC_LINK_LIBRARIES="-lspirv-cross-c-shared -lshaderc_shared -lxcb -lX11 -lX11-xcb -lxkbcommon -lxcb-cursor -lxcb-xfixes -lxcb-keysyms -lpthread -lvulkan " PL_SOURCES="../extensions/pl_unity_ext.c " # run compiler (and linker) diff --git a/src/build_macos.sh b/src/build_macos.sh index 0b5040e9..03168e4d 100644 --- a/src/build_macos.sh +++ b/src/build_macos.sh @@ -485,7 +485,7 @@ PL_LINK_DIRECTORIES="-L../out " PL_COMPILER_FLAGS="-std=c99 -fmodules -ObjC -fPIC --debug -g " PL_LINKER_FLAGS="-Wl,-rpath,/usr/local/lib " PL_STATIC_LINK_LIBRARIES="" -PL_DYNAMIC_LINK_LIBRARIES="-lshaderc_shared -lpthread -lvulkan " +PL_DYNAMIC_LINK_LIBRARIES="-lspirv-cross-c-shared -lshaderc_shared -lpthread -lvulkan " PL_SOURCES="../extensions/pl_unity_ext.c " PL_LINK_FRAMEWORKS="-framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore " diff --git a/src/build_win32.bat b/src/build_win32.bat index e53339ae..e0a30c8d 100644 --- a/src/build_win32.bat +++ b/src/build_win32.bat @@ -94,7 +94,7 @@ @set PL_LINK_DIRECTORIES=-LIBPATH:"../out" -LIBPATH:"%VULKAN_SDK%\Lib" @set PL_COMPILER_FLAGS=-Zc:preprocessor -nologo -std:c11 -W4 -WX -wd4201 -wd4100 -wd4996 -wd4505 -wd4189 -wd5105 -wd4115 -permissive- -Od -MDd -Zi @set PL_LINKER_FLAGS=-noimplib -noexp -incremental:no -nodefaultlib:MSVCRT -@set PL_STATIC_LINK_LIBRARIES=shaderc_combined.lib vulkan-1.lib +@set PL_STATIC_LINK_LIBRARIES=shaderc_combined.lib spirv-cross-c-shared.lib vulkan-1.lib @set PL_SOURCES="../extensions/pl_unity_ext.c" :: run compiler (and linker) @@ -281,7 +281,7 @@ goto ExitLabel @set PL_LINK_DIRECTORIES=-LIBPATH:"../out" -LIBPATH:"%VULKAN_SDK%\Lib" @set PL_COMPILER_FLAGS=-Zc:preprocessor -nologo -std:c11 -W4 -WX -wd4201 -wd4100 -wd4996 -wd4505 -wd4189 -wd5105 -wd4115 -permissive- -O2 -MD @set PL_LINKER_FLAGS=-noimplib -noexp -incremental:no -@set PL_STATIC_LINK_LIBRARIES=shaderc_combined.lib vulkan-1.lib +@set PL_STATIC_LINK_LIBRARIES=shaderc_combined.lib spirv-cross-c.lib vulkan-1.lib @set PL_SOURCES="../extensions/pl_unity_ext.c" :: run compiler (and linker) diff --git a/src/pl_config.h b/src/pl_config.h index f2f5d7fc..6f4935d4 100644 --- a/src/pl_config.h +++ b/src/pl_config.h @@ -29,6 +29,7 @@ // shaders // #define PL_OFFLINE_SHADERS_ONLY +// #define PL_INCLUDE_SPIRV_CROSS // core extension options #define PL_CORE_EXTENSION_INCLUDE_SHADER