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
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,6 +4,7 @@
|
|||||||
cbuffer RootConstants : register(b0, space0)
|
cbuffer RootConstants : register(b0, space0)
|
||||||
{
|
{
|
||||||
row_major float4x4 ViewProjection;
|
row_major float4x4 ViewProjection;
|
||||||
|
row_major float4x4 Model;
|
||||||
uint BufferIndex;
|
uint BufferIndex;
|
||||||
uint TextureIndex;
|
uint TextureIndex;
|
||||||
uint VertexOffset; // Base vertex for indexed drawing with bindless buffers
|
uint VertexOffset; // Base vertex for indexed drawing with bindless buffers
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Output main(uint vertexIndex : SV_VertexID)
|
|||||||
float4 col = asfloat(buffer.Load4(offset + 12));
|
float4 col = asfloat(buffer.Load4(offset + 12));
|
||||||
|
|
||||||
//output.Position = float4(pos, 1.0f);
|
//output.Position = float4(pos, 1.0f);
|
||||||
output.Position = mul(ViewProjection, float4(pos, 1.0f));
|
output.Position = mul(ViewProjection, mul(Model, float4(pos, 1.0f)));
|
||||||
output.Color = col;
|
output.Color = col;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ namespace Juliet
|
|||||||
struct Matrix
|
struct Matrix
|
||||||
{
|
{
|
||||||
float m[4][4];
|
float m[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
static Matrix Identity()
|
[[nodiscard]] inline Matrix MatrixIdentity()
|
||||||
{
|
{
|
||||||
Matrix result = {};
|
Matrix result = {};
|
||||||
result.m[0][0] = 1.0f;
|
result.m[0][0] = 1.0f;
|
||||||
@@ -19,7 +20,16 @@ namespace Juliet
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Matrix operator*(const Matrix& rhs) const
|
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z)
|
||||||
|
{
|
||||||
|
Matrix result = MatrixIdentity();
|
||||||
|
result.m[0][3] = x;
|
||||||
|
result.m[1][3] = y;
|
||||||
|
result.m[2][3] = z;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs)
|
||||||
{
|
{
|
||||||
Matrix result = {};
|
Matrix result = {};
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
@@ -28,13 +38,12 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
for (int k = 0; k < 4; ++k)
|
for (int k = 0; k < 4; ++k)
|
||||||
{
|
{
|
||||||
result.m[i][j] += m[i][k] * rhs.m[k][j];
|
result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <Core/Common/CoreTypes.h>
|
#include <Core/Common/CoreTypes.h>
|
||||||
#include <Core/Common/NonNullPtr.h>
|
#include <Core/Common/NonNullPtr.h>
|
||||||
|
#include <Core/Math/Matrix.h>
|
||||||
#include <Juliet.h>
|
#include <Juliet.h>
|
||||||
|
|
||||||
namespace Juliet
|
namespace Juliet
|
||||||
@@ -16,5 +17,7 @@ namespace Juliet
|
|||||||
|
|
||||||
index_t VertexOffset;
|
index_t VertexOffset;
|
||||||
index_t IndexOffset;
|
index_t IndexOffset;
|
||||||
|
|
||||||
|
Matrix Transform = MatrixIdentity();
|
||||||
};
|
};
|
||||||
} // namespace Juliet
|
} // namespace Juliet
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ namespace Juliet
|
|||||||
struct PushData
|
struct PushData
|
||||||
{
|
{
|
||||||
Matrix ViewProjection;
|
Matrix ViewProjection;
|
||||||
|
Matrix Model;
|
||||||
uint32 BufferIndex;
|
uint32 BufferIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ namespace Juliet
|
|||||||
// Utils
|
// Utils
|
||||||
[[nodiscard]] JULIET_API MeshID AddCube();
|
[[nodiscard]] JULIET_API MeshID AddCube();
|
||||||
[[nodiscard]] JULIET_API MeshID AddQuad();
|
[[nodiscard]] JULIET_API MeshID AddQuad();
|
||||||
|
JULIET_API void SetMeshTransform(MeshID id, const Matrix& transform);
|
||||||
|
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
JULIET_API void ReloadMeshRendererShaders();
|
JULIET_API void ReloadMeshRendererShaders();
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
// Find and destroy
|
// Find and destroy
|
||||||
VectorArena<Window>& windows = g_CurrentDisplayDevice->Windows;
|
VectorArena<Window>& 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];
|
Window& windowRef = windows[idx];
|
||||||
if (windowRef.ID == window->ID)
|
if (windowRef.ID == window->ID)
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Juliet::Win32
|
|||||||
|
|
||||||
device->PumpEvents = PumpEvents;
|
device->PumpEvents = PumpEvents;
|
||||||
|
|
||||||
device->Windows.Create(JULIET_DEBUG_ONLY("Display Windows"));
|
device->Windows.Create(arena JULIET_DEBUG_PARAM("Display Windows"));
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,12 +75,12 @@ namespace Juliet
|
|||||||
|
|
||||||
void ArenaRelease(NonNullPtr<Arena> arena)
|
void ArenaRelease(NonNullPtr<Arena> arena)
|
||||||
{
|
{
|
||||||
JULIET_DEBUG_ONLY(DebugUnregisterArena(arena);)
|
// Release active blocks (Current chain)
|
||||||
|
|
||||||
for (Arena *node = arena->Current, *previous = nullptr; node != nullptr; node = previous)
|
for (Arena *node = arena->Current, *previous = nullptr; node != nullptr; node = previous)
|
||||||
{
|
{
|
||||||
previous = node->Previous;
|
previous = node->Previous;
|
||||||
|
|
||||||
|
JULIET_DEBUG_ONLY(DebugUnregisterArena(node);)
|
||||||
JULIET_DEBUG_ONLY(DebugArenaFreeBlock(node);)
|
JULIET_DEBUG_ONLY(DebugArenaFreeBlock(node);)
|
||||||
|
|
||||||
Memory::OS_Release(node, node->Reserved);
|
Memory::OS_Release(node, node->Reserved);
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
arena->GlobalNext->GlobalPrev = arena->GlobalPrev;
|
arena->GlobalNext->GlobalPrev = arena->GlobalPrev;
|
||||||
}
|
}
|
||||||
|
arena->GlobalPrev = nullptr;
|
||||||
|
arena->GlobalNext = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name)
|
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name)
|
||||||
|
|||||||
@@ -300,15 +300,17 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
BindGraphicsPipeline(renderPass, g_DebugState.DepthTestedPipeline);
|
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
|
struct
|
||||||
{
|
{
|
||||||
Matrix vp;
|
Matrix vp;
|
||||||
|
Matrix model;
|
||||||
uint32 bufferIndex;
|
uint32 bufferIndex;
|
||||||
uint32 vertexOffset; // Offset in vertices (not bytes)
|
uint32 vertexOffset; // Offset in vertices (not bytes)
|
||||||
uint32 padding[2];
|
uint32 padding[2];
|
||||||
} pushData;
|
} pushData;
|
||||||
pushData.vp = Camera_GetViewProjectionMatrix(camera);
|
pushData.vp = Camera_GetViewProjectionMatrix(camera);
|
||||||
|
pushData.model = MatrixIdentity();
|
||||||
pushData.bufferIndex = bufferIndex;
|
pushData.bufferIndex = bufferIndex;
|
||||||
pushData.vertexOffset = 0; // Depth-tested vertices start at 0
|
pushData.vertexOffset = 0; // Depth-tested vertices start at 0
|
||||||
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData);
|
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData);
|
||||||
@@ -321,15 +323,17 @@ namespace Juliet
|
|||||||
{
|
{
|
||||||
BindGraphicsPipeline(renderPass, g_DebugState.OverlayPipeline);
|
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
|
struct
|
||||||
{
|
{
|
||||||
Matrix vp;
|
Matrix vp;
|
||||||
|
Matrix model;
|
||||||
uint32 bufferIndex;
|
uint32 bufferIndex;
|
||||||
uint32 vertexOffset; // Offset in vertices (not bytes)
|
uint32 vertexOffset; // Offset in vertices (not bytes)
|
||||||
uint32 padding[2];
|
uint32 padding[2];
|
||||||
} pushData;
|
} pushData;
|
||||||
pushData.vp = Camera_GetViewProjectionMatrix(camera);
|
pushData.vp = Camera_GetViewProjectionMatrix(camera);
|
||||||
|
pushData.model = MatrixIdentity();
|
||||||
pushData.bufferIndex = bufferIndex;
|
pushData.bufferIndex = bufferIndex;
|
||||||
pushData.vertexOffset = kMaxDebugVertices / 2; // Overlay vertices start at half
|
pushData.vertexOffset = kMaxDebugVertices / 2; // Overlay vertices start at half
|
||||||
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData);
|
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / sizeof(uint32), &pushData);
|
||||||
|
|||||||
@@ -187,12 +187,13 @@ namespace Juliet
|
|||||||
uint32 vertexDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.VertexBuffer);
|
uint32 vertexDescriptorIndex = GetDescriptorIndex(g_MeshRenderer.Device, g_MeshRenderer.VertexBuffer);
|
||||||
|
|
||||||
pushData.BufferIndex = vertexDescriptorIndex;
|
pushData.BufferIndex = vertexDescriptorIndex;
|
||||||
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
|
|
||||||
|
|
||||||
SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, g_MeshRenderer.Indices.Count, 0);
|
SetIndexBuffer(cmdList, g_MeshRenderer.IndexBuffer, IndexFormat::UInt16, g_MeshRenderer.Indices.Count, 0);
|
||||||
|
|
||||||
for (Mesh& mesh : g_MeshRenderer.Meshes)
|
for (Mesh& mesh : g_MeshRenderer.Meshes)
|
||||||
{
|
{
|
||||||
|
pushData.Model = mesh.Transform;
|
||||||
|
SetPushConstants(cmdList, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
|
||||||
DrawIndexedPrimitives(pass, static_cast<uint32>(mesh.IndexCount), 1, static_cast<uint32>(mesh.IndexOffset),
|
DrawIndexedPrimitives(pass, static_cast<uint32>(mesh.IndexCount), 1, static_cast<uint32>(mesh.IndexOffset),
|
||||||
static_cast<uint32>(mesh.VertexOffset), 0);
|
static_cast<uint32>(mesh.VertexOffset), 0);
|
||||||
}
|
}
|
||||||
@@ -292,6 +293,11 @@ namespace Juliet
|
|||||||
return g_MeshRenderer.Meshes.Count - 1;
|
return g_MeshRenderer.Meshes.Count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetMeshTransform(MeshID id, const Matrix& transform)
|
||||||
|
{
|
||||||
|
Assert(id < static_cast<MeshID>(g_MeshRenderer.Meshes.Count), "Invalid MeshID");
|
||||||
|
g_MeshRenderer.Meshes.Data[id].Transform = transform;
|
||||||
|
}
|
||||||
#if ALLOW_SHADER_HOT_RELOAD
|
#if ALLOW_SHADER_HOT_RELOAD
|
||||||
void ReloadMeshRendererShaders()
|
void ReloadMeshRendererShaders()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,7 +109,20 @@ void JulietApplication::Init()
|
|||||||
Running = false;
|
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<float>(col) * kSpacing - kOffset;
|
||||||
|
float y = static_cast<float>(row) * kSpacing - kOffset;
|
||||||
|
SetMeshTransform(cube, MatrixTranslation(x, y, 0.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CommandList* loadCmd = AcquireCommandList(GraphicsDevice);
|
CommandList* loadCmd = AcquireCommandList(GraphicsDevice);
|
||||||
LoadMeshesOnGPU(loadCmd);
|
LoadMeshesOnGPU(loadCmd);
|
||||||
@@ -275,8 +288,6 @@ void JulietApplication::OnRender(RenderPass* pass, CommandList* cmd)
|
|||||||
pushData.ViewProjection = Camera_GetViewProjectionMatrix(GetDebugCamera());
|
pushData.ViewProjection = Camera_GetViewProjectionMatrix(GetDebugCamera());
|
||||||
|
|
||||||
RenderMeshes(pass, cmd, pushData);
|
RenderMeshes(pass, cmd, pushData);
|
||||||
|
|
||||||
// SetPushConstants(cmd, ShaderStage::Vertex, 0, sizeof(pushData) / 4, &pushData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)
|
ColorTargetInfo JulietApplication::GetColorTargetInfo(Texture* swapchainTexture)
|
||||||
@@ -308,14 +319,14 @@ Camera JulietApplication::GetDebugCamera()
|
|||||||
float currentOrbitTime = time * orbitSpeed;
|
float currentOrbitTime = time * orbitSpeed;
|
||||||
|
|
||||||
// --- Adjusted for 1-Meter Scale ---
|
// --- 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;
|
float radius = baseRadius;
|
||||||
/* Uncomment for active zoom
|
//* Uncomment for active zoom
|
||||||
float zoomAmplitude = 1.0f; // Oscillate between 1.5m and 3.5m away
|
float zoomAmplitude = 10.0f; // Oscillate between 1.5m and 3.5m away
|
||||||
float zoomSpeed = 0.8f;
|
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
|
float zHeight = radius * 0.5f; // Keep a nice downward viewing angle
|
||||||
|
|
||||||
Camera cam = {};
|
Camera cam = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user