From a7947bfa17bb5d7d51c20a98ae1b716b9bf44c29 Mon Sep 17 00:00:00 2001 From: Patedam Date: Sat, 21 Feb 2026 23:27:27 -0500 Subject: [PATCH] Made MeshRenderer able to take a matrix transform for each mesh, and we are now able to draw 100 cubes. Claude OPus helpes with implementation --- Assets/compiled/Debug.vert.dxil | Bin 4796 -> 4832 bytes Assets/compiled/ImGui.frag.dxil | Bin 4324 -> 4348 bytes Assets/compiled/ImGui.vert.dxil | Bin 4752 -> 4776 bytes Assets/compiled/Triangle.vert.dxil | Bin 4800 -> 5116 bytes Assets/source/RootConstants.hlsl | 1 + Assets/source/Triangle.vert.hlsl | 2 +- Juliet/include/Core/Math/Matrix.h | 47 +++++++++++------- Juliet/include/Graphics/Mesh.h | 3 ++ Juliet/include/Graphics/MeshRenderer.h | 2 + Juliet/src/Core/HAL/Display/Display.cpp | 2 +- .../HAL/Display/Win32/Win32DisplayDevice.cpp | 2 +- Juliet/src/Core/Memory/MemoryArena.cpp | 4 +- Juliet/src/Core/Memory/MemoryArenaDebug.cpp | 2 + Juliet/src/Graphics/DebugDisplayRenderer.cpp | 8 ++- Juliet/src/Graphics/MeshRenderer.cpp | 8 ++- JulietApp/main.cpp | 27 +++++++--- 16 files changed, 73 insertions(+), 35 deletions(-) diff --git a/Assets/compiled/Debug.vert.dxil b/Assets/compiled/Debug.vert.dxil index 6175834e472245955910fb3170a935557e762d33..add627d3df9b04709fd5a74916793723fbd50a74 100644 GIT binary patch delta 1371 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 KW)}O^$Nd+1BaL(b delta 1104 zcmZ9LUr-xW6vppnm)*@0m@TxhA%O-03^Y7!5(uTxDH|aC3GJkUEgexqMle;N(5Maa zkZcmD17sRZ6>NM+j6*BMOekmt>kJ84krpjOt+5Pk+CkKoY9GX5#0L}UlTY{j&OP`0 zzK3)FNncCnmp3TO2#4u>?c<9NAGO3E8p7vknlj|w|i3=+~ zA?zguh4AZ}wQYGL*Mp&jY~1!)K=hqk2|v~;vy#^p-z2GyD;Sf=7l(S#A5t2AL~Vin zGzH76U`2?gG=f?Z(Zc>FIt=0!NTp*XjW>x<0q1~dDe3)nm2DJ%{ny{B`}7u# zKGCLIA*n>0#UZ{Q14D4Fkn9){(o~`719_tHS>Lt3}gOT+ZOqu)26#C-zE*-ukPcveM?`{c+>TVPBgyNYqKb z2uesl{dG{&V_)hOydBk4 zOTJWRxIT*YN?ZxIn5dSl@W52brK|ac(^I+ZzBkCo6u@NR9hI&Pe zawGcM`9LqK59`G!79sj8=FJW-m!Wm$sL7&G4z+o(9jT3FGkME@qNhl7S+4{G*?2(j93fLm5{Q##%t&K%?=T#*h!S}msL_nw er+3m<<$MgKg;^oK6Ul5-ri7t1BgBb*PVg@@f_m)$ diff --git a/Assets/compiled/ImGui.vert.dxil b/Assets/compiled/ImGui.vert.dxil index ab4d30bc84c58e74c4544457ed54f22276e78864..d980a68867a3ada6d1bc7d104a51f4beb008a35e 100644 GIT binary patch delta 1343 zcmZuve@qi+82+xb*X!Mt9Y4LJC0;2Ipq(DIqr;i32c4qmQb)y-L2S|bV^hZ{W;&+y z+79b14pS15nx(ZwnL4c^D$HbUnMyD3m@6uOxN>V#UGF`cZqqGu&h1eh1OVteOvyw93V`~2`8lW{9|2%9fPh2* zfWf?SHO$Wt{20#nD=H&X3Y@?6vuHPzN(h|83~sGzOvUZOfbRiz$j1r~SDOO}8pKC~ z`6v?rqE$gcguWGEM5rlX5sikJPtF#3iat&!p`rtMMQ#m!0`61m`4Z-A0Ur6gNcZc? z_hA6`kN`w|rP9}YW)TiWeKt`6)ag4Ydbv&AGc_`rC`4QrA%*6^DeaFld8RF!YYUIe zF0XCZvE&I!OuvTc)+8K6{dnEf)5F1%;m~QHs=8UJ8urupIP5}Pt8n$F-gQUi4b+tH z=y&zhU7>x^N5@GT_cC41 z`{I*f1zCoy8?aIaYvx~cR+W|hIQo)_yV*6q;Lb#SPQ&;92_Z+jqzAu7Lu2S(BU)Kp zwXX@4!6vh4eS&evR3O8xVO&yY8n#}BmXD;EcW>g_sfoAAyOTm|!rVI;za3vgz=sSy zvb*w*!HfNi%QQLmZCf_jTQb~1WySjTU$6a=z5M#|Me&ZEJ6)C7fCankz-kuZLt*Ty z@u^^~&yZU6=Cmnq*dDy;Qen;Z)({q|ZngXUc@Z}Ej$+t;zFPHVb)Nq?7E<}sC)r%h zvLhPZ(!phYm$kZ~!D3F`!Vgicr|lt?&+kuvBIr*={(#CODQfX6}(}l~Xa5R<_>=$K^4Kxfo{|yaobF7y(X8WuhfUQj(q#Phl?kVhR>L?UOJdnUaliC(SgfD5EBh|_4Ax)1S z$s&!>d?k$XqToKeLb!o)M7LG|Zy^$u-1w|%JGGIwe1`rWC5u?<3`co+#jQ@_Skptv zjqFO8X$&N-iQ--;^9+|8PSQ;Q_`~Sh?A?!xXQW|)ZVWqgL66VYcw`n)TXSH6+{RHO zC&{u1->0RsOXi;RjXJ?nSDw3bl4BpOo}OLOV?;ud>lQays1*L@CG+{UpvTw=BQ`LN zj(gbTUi4QMbijz6BRXD$BWV0z@TtHY+nS_1lJv=W{0dJG&(nz{9Gi#FC)MZ8c{qaZ WV&=YlWN~+e`i`??4C1r#to{MD(9Jdg delta 1403 zcmZ8gYfMvT82(OsT23$2g9SaMMOrQeMcLsJ1S9UWFubxSddUF*yPS6klA{O!2LJ?M1^|U+ zTX(SO9+Yl-9sz)|z;{>12Ve>E2pFd!!4xDI#x1huJbWUGWH^?1Ee-|TwmsK{aJ%_| z?j$bmisojxq)cv>i(qndTpPJPk4~AJcBPu4$o5pTGL>0=hzu}b7%p@jVUuH*8_5@0 z%Ma3a0DOu8aMcmV+6Z0k`hjVNTwE@SNSzDMnK^#+wcc8GA>DJ-%K#&6;aqF}dIh|4ws-nWz=Q{t$`@;rk(J$#CQK@0c6MnEAm5*)m)Hd_$xn9_?P^kFBq7 zPw0}OT3lh2`n6`FiGp=wImqqQ$}-!#z?whRpu!5NAahp`<%=yBX5D-v;GWQOyK#%( z9r3k~_T(*ArQ6e=PF9%-8`b#UHkL}o%15n==yUl}Yh=M{mw!zq_L7VtIZBa}Vp9fd zHIf&Q@J*#w*s|G|nwNTA**HC}GlG-7=z?omnXs*}VgvOL_FY`l7ni zhL_4u@Dlg!JiSn~{tDI1Qg^cU^jXJOH173THGQ?FKL5ypUl!VnN@+Y9xzKvg8|)aL z>>ctJbDHG)>(Y7|L}zbE_F(EWnxDmLQOF5a7c@RpCw!3eduhu0(wz0l zhBa;Xyi*UT4wlzDG;N)xH71LrW(mP!ShTm}PI6l@UG6C6JaW-u+s}x<)U3L-w@Z9y z&N&}5NH^JrZhNO`_hL>h-~LQf>4^X*W0mUuDwPO;17|o^!YzJwV!@eenK}xag8o=Ub{Y?@{ zG*D(2fy7`cQ&J+EON)X#ip}sU(a9bTgm+2d6v+wyWqlo9?g}fb;%%not)^HfRiOkn zIYMzp&l)N-_R$0V#kDJA2~+GXD%K{43DzOkN{QZRO8F|`7DzKNhvrjx*N9El0jN|O zQBUn$(P=t)O3l1Vmv0iA64?>7J3elXb3*Yn-B)2oJALD$@cWy3I99w%%P&HnWhlv? zniSzvNPkdq2MFFpl^sh0h#9)i>m_&t^W5n-;QlFF&HwRMZs0Y3g{J#n(+y#I=r!!7 kVX5suHVDJi8*slWB9YCZrzW2(SNj<2&N1So^y2{VC#s|Mu>b%7 diff --git a/Assets/compiled/Triangle.vert.dxil b/Assets/compiled/Triangle.vert.dxil index 9416589a2df4f1c1cee238328945015d93b0337d..7e88767e82a37918302a435e9595820fff5e5724 100644 GIT binary patch delta 1701 zcmZ`)4NMbf7{0q+uh;f01&UltU9V6pf7S!LI&jloDF{fm;!rU|)537*DkCu6md&-4 zAJJ7Us}2Os%9=2Y$oSbr*g|NlrVzxU(||){nYt#ciJ&gbuw>VvY%cDSOTK*X^FHtQ zKJWA88(coWLZr>tqG9FP1PB1Ye0aS`#GGUUz+6{K1-LvB1%RCZ z2yh_)(B^05AT)?i;{^1+CT(y^iU9!B19H9udHh^)tpVQG`0hm3XGQvO*x7WkM zn0yDyX~BkDWE|1~Ftc0uOwJ|;$>iiY^vq!=c_`IE*oWW*u+RP&-T;9j`#Po!bl8iS zD@<0QQCFAwRlKKPVNJglwN3aFY-m))R?Bm*@7x}FDZOoUq&-J5bhsUR&qC_Lt6OfG z`P=VqyIoV?67O-Iu_tUSk4f+}6W9%;3a!e<+K*Z{pAc^sPT5aP6bNs@hVv>M7UmV} z_iG0nZm;+1?<0Ft&XN7yY`0?% zS*L279PC%gaxPW6@J341>54Mq7|N5QP$xJ};uRz-3Q8R(v2qIv_ z@k?^?5rpyHQ1Gl9XX|n`~Od3{~oeQ}j<9>lKHC_*|Cy_fGFR#<}^rH264Ufltj zRB<+-IA}biuyz=;%UD6O;Yt6US;y4XN&mf8_!}Qxxj1lk^e|n$G~31ndIne=C`I<` zo}~U$P@I3}$wMLUgMy&D=V{*u-ER7i+wai(&)mN6g>LWQDnO9ga|=7lFx{l@M>tF+ z2JZ=v{*{8Q6UQ~u5kL@7Z{r*bsCNmpW4vSOKMOKK`MJEi)Cdafsz8gTN2HBZ+AXp6 znlge;17Z*qu;`~xRfb!^q{1?QK#{jZT6$>idF3?Qi#!@{qGs0%YV*%6xYFQ2Zw~yF4p<>pI>ucDcJ7`}SN|>BJWL#vG!-FLj zzEzI7OQ0kxE~XPIYdGb;i>?w4V3nh;5;tL$^F0g1`De>mg=UVE4U$a+>||GwO=>I# zVbS&VLy+VonD9K|xB!_ICaD2F%m^&aFmS5$7XVPr$H)T0R1=3mT)Dq7ZxLdQe4UD4 zgzQi=PtypQKmXVwA`rPnn!Si9)7Qipk-9SG6m)Jw;BVUhom z!6=)OCNDPmx%of|_N+v9^h?nsitT3n@swy^*hAnnMHZTa4#Km2jQ5ehX-zb5Ty6+o z2*)67dVb~~;MZ($)*K_jipzp0m<@ZR4wKDt)Y{AEZ4sGoR+8*{l0&4 z{^!3N>xvfT6zQ_Jr-RCy)QZ^Jv)+f^3G4?50N@I46N#A92LSL5AFhUCFctu100J-r zfSjTudX$EEH1|sY0J?0~h6DrPcWCqubP3{etMDdL+`QO8wg5gDeIE{nAOY2e2qQBb zEVdI{a7x(<2cMndAYgWyLj$u_j!bqx4pU1=0yIMXhU76Cgp`gch3cs{nXz@4u)<)= z?~nIPCD}hRT9lnj!R2q&R4X^{EPw6unk9>$UVLw9HOQIZ z`J?0HdweksHzx8QmU{K?m0)o@!b30Cn41`(pJ#Z*TCBPLP_}IXtdTpGuvalxY)3Hv-s< z!`EJ$^q)3=(JWVY)R+g&d3|1^mi|4E{k?mtUn^5`mb`F}xN<|IK7Jo+d030z0f z*$qLo^1TcP(pSkZl(nCdECT+vrkLHnttsa}(iHOxNIn$wlObZ(4q8m{0v40MTN`47Qc5ZT!9v4D8oF%VE16>bX$^Ww`DAcB+{k#ohxc@6C2|(x zOK;g`pn3wYIBQ_$hql`BIKZ+%%76}@senof5(hkL_#81A8mX6p2%>)o^+niY5SQ7) zv&Ud=Gb6>0i|K`ici5FHAG@ixpiuNnLqLfGrJTW`=$s{@4~nOzgN1dAVL2q*YMKR* zhKCKkiZ{wI1}A2#%ZUCgOwj-y0_z2OZTvoQDuX#l6Vk1s_I+YeV3Zu)CtfdVj0 #include +#include #include namespace Juliet @@ -16,5 +17,7 @@ namespace Juliet index_t VertexOffset; index_t IndexOffset; + + Matrix Transform = MatrixIdentity(); }; } // namespace Juliet diff --git a/Juliet/include/Graphics/MeshRenderer.h b/Juliet/include/Graphics/MeshRenderer.h index 769001f..9ead3d3 100644 --- a/Juliet/include/Graphics/MeshRenderer.h +++ b/Juliet/include/Graphics/MeshRenderer.h @@ -43,6 +43,7 @@ namespace Juliet struct PushData { Matrix ViewProjection; + Matrix Model; uint32 BufferIndex; }; @@ -55,6 +56,7 @@ namespace Juliet // Utils [[nodiscard]] JULIET_API MeshID AddCube(); [[nodiscard]] JULIET_API MeshID AddQuad(); + JULIET_API void SetMeshTransform(MeshID id, const Matrix& transform); #if ALLOW_SHADER_HOT_RELOAD JULIET_API void ReloadMeshRendererShaders(); diff --git a/Juliet/src/Core/HAL/Display/Display.cpp b/Juliet/src/Core/HAL/Display/Display.cpp index 2142fc2..c81287d 100644 --- a/Juliet/src/Core/HAL/Display/Display.cpp +++ b/Juliet/src/Core/HAL/Display/Display.cpp @@ -123,7 +123,7 @@ namespace Juliet { // Find and destroy VectorArena& windows = g_CurrentDisplayDevice->Windows; - for (index_t idx = windows.Size() - 1; idx != 0; --idx) + for (index_t idx = windows.Size(); idx-- > 0;) { Window& windowRef = windows[idx]; if (windowRef.ID == window->ID) diff --git a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp index 29a3ffa..a493d4b 100644 --- a/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp +++ b/Juliet/src/Core/HAL/Display/Win32/Win32DisplayDevice.cpp @@ -36,7 +36,7 @@ namespace Juliet::Win32 device->PumpEvents = PumpEvents; - device->Windows.Create(JULIET_DEBUG_ONLY("Display Windows")); + device->Windows.Create(arena JULIET_DEBUG_PARAM("Display Windows")); return device; } diff --git a/Juliet/src/Core/Memory/MemoryArena.cpp b/Juliet/src/Core/Memory/MemoryArena.cpp index 9941f47..ebc59e8 100644 --- a/Juliet/src/Core/Memory/MemoryArena.cpp +++ b/Juliet/src/Core/Memory/MemoryArena.cpp @@ -75,12 +75,12 @@ namespace Juliet void ArenaRelease(NonNullPtr arena) { - JULIET_DEBUG_ONLY(DebugUnregisterArena(arena);) - + // Release active blocks (Current chain) for (Arena *node = arena->Current, *previous = nullptr; node != nullptr; node = previous) { previous = node->Previous; + JULIET_DEBUG_ONLY(DebugUnregisterArena(node);) JULIET_DEBUG_ONLY(DebugArenaFreeBlock(node);) Memory::OS_Release(node, node->Reserved); diff --git a/Juliet/src/Core/Memory/MemoryArenaDebug.cpp b/Juliet/src/Core/Memory/MemoryArenaDebug.cpp index b4b8060..4822079 100644 --- a/Juliet/src/Core/Memory/MemoryArenaDebug.cpp +++ b/Juliet/src/Core/Memory/MemoryArenaDebug.cpp @@ -68,6 +68,8 @@ namespace Juliet { arena->GlobalNext->GlobalPrev = arena->GlobalPrev; } + arena->GlobalPrev = nullptr; + arena->GlobalNext = nullptr; } void DebugArenaSetDebugName(NonNullPtr arena, const char* name) diff --git a/Juliet/src/Graphics/DebugDisplayRenderer.cpp b/Juliet/src/Graphics/DebugDisplayRenderer.cpp index af2c337..464c4d4 100644 --- a/Juliet/src/Graphics/DebugDisplayRenderer.cpp +++ b/Juliet/src/Graphics/DebugDisplayRenderer.cpp @@ -300,15 +300,17 @@ namespace Juliet { BindGraphicsPipeline(renderPass, g_DebugState.DepthTestedPipeline); - // Pack VP matrix + buffer index into push constants + // Pack VP matrix + Model (identity for debug) + buffer index into push constants struct { Matrix vp; + Matrix model; uint32 bufferIndex; uint32 vertexOffset; // Offset in vertices (not bytes) uint32 padding[2]; } pushData; pushData.vp = Camera_GetViewProjectionMatrix(camera); + pushData.model = MatrixIdentity(); pushData.bufferIndex = bufferIndex; pushData.vertexOffset = 0; // Depth-tested vertices start at 0 SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData); @@ -321,15 +323,17 @@ namespace Juliet { BindGraphicsPipeline(renderPass, g_DebugState.OverlayPipeline); - // Pack VP matrix + buffer index into push constants + // Pack VP matrix + Model (identity for debug) + buffer index into push constants struct { Matrix vp; + Matrix model; uint32 bufferIndex; uint32 vertexOffset; // Offset in vertices (not bytes) uint32 padding[2]; } pushData; pushData.vp = Camera_GetViewProjectionMatrix(camera); + pushData.model = MatrixIdentity(); pushData.bufferIndex = bufferIndex; pushData.vertexOffset = kMaxDebugVertices / 2; // Overlay vertices start at half SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData); diff --git a/Juliet/src/Graphics/MeshRenderer.cpp b/Juliet/src/Graphics/MeshRenderer.cpp index 9d168c2..1785b28 100644 --- a/Juliet/src/Graphics/MeshRenderer.cpp +++ b/Juliet/src/Graphics/MeshRenderer.cpp @@ -187,12 +187,13 @@ namespace Juliet uint32 vertexDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.VertexBuffer); pushData.BufferIndex = vertexDescriptorIndex; - SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData); SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, g_MeshRenderer.Indices.Count, 0); for (Mesh& mesh : g_MeshRenderer.Meshes) { + pushData.Model = mesh.Transform; + SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData); DrawIndexedPrimitives(pass, static_cast(mesh.IndexCount), 1, static_cast(mesh.IndexOffset), static_cast(mesh.VertexOffset), 0); } @@ -292,6 +293,11 @@ namespace Juliet return g_MeshRenderer.Meshes.Count - 1; } + void SetMeshTransform(MeshID id, const Matrix& transform) + { + Assert(id < static_cast(g_MeshRenderer.Meshes.Count), "Invalid MeshID"); + g_MeshRenderer.Meshes.Data[id].Transform = transform; + } #if ALLOW_SHADER_HOT_RELOAD void ReloadMeshRendererShaders() { diff --git a/JulietApp/main.cpp b/JulietApp/main.cpp index 0fcac63..f221c93 100644 --- a/JulietApp/main.cpp +++ b/JulietApp/main.cpp @@ -109,7 +109,20 @@ void JulietApplication::Init() Running = false; } - std::ignore = AddCube(); + constexpr int kGridSize = 10; + constexpr float kSpacing = 2.5f; + constexpr float kOffset = (kGridSize - 1) * kSpacing * 0.5f; + + for (int row = 0; row < kGridSize; ++row) + { + for (int col = 0; col < kGridSize; ++col) + { + MeshID cube = AddCube(); + float x = static_cast(col) * kSpacing - kOffset; + float y = static_cast(row) * kSpacing - kOffset; + SetMeshTransform(cube, MatrixTranslation(x, y, 0.0f)); + } + } CommandList* loadCmd = AcquireCommandList(GraphicsDevice); LoadMeshesOnGPU(loadCmd); @@ -275,8 +288,6 @@ void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd) pushData.ViewProjection = Camera_GetViewProjectionMatrix(GetDebugCamera()); RenderMeshes(pass, cmd, pushData); - - // SetPushConstants(cmd, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData); } ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture) @@ -308,14 +319,14 @@ Camera JulietApplication::GetDebugCamera() float currentOrbitTime = time * orbitSpeed; // --- Adjusted for 1-Meter Scale --- - float baseRadius = 2.5f; // Hover 2.5 meters away (down from 15.0f) + float baseRadius = 25.0f; // Increased to see 10x10 cube grid float radius = baseRadius; - /* Uncomment for active zoom - float zoomAmplitude = 1.0f; // Oscillate between 1.5m and 3.5m away + //* Uncomment for active zoom + float zoomAmplitude = 10.0f; // Oscillate between 1.5m and 3.5m away float zoomSpeed = 0.8f; - radius = baseRadius + (sinf(time * zoomSpeed) * zoomAmplitude); - */ + radius = baseRadius + (sinf(time * zoomSpeed) * zoomAmplitude); + //*/ float zHeight = radius * 0.5f; // Keep a nice downward viewing angle Camera cam = {};