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)
|
||||
{
|
||||
row_major float4x4 ViewProjection;
|
||||
row_major float4x4 Model;
|
||||
uint BufferIndex;
|
||||
uint TextureIndex;
|
||||
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));
|
||||
|
||||
//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;
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,9 @@ namespace Juliet
|
||||
struct Matrix
|
||||
{
|
||||
float m[4][4];
|
||||
};
|
||||
|
||||
static Matrix Identity()
|
||||
[[nodiscard]] inline Matrix MatrixIdentity()
|
||||
{
|
||||
Matrix result = {};
|
||||
result.m[0][0] = 1.0f;
|
||||
@@ -19,7 +20,16 @@ namespace Juliet
|
||||
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 = {};
|
||||
for (int i = 0; i < 4; ++i)
|
||||
@@ -28,13 +38,12 @@ namespace Juliet
|
||||
{
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Core/Common/CoreTypes.h>
|
||||
#include <Core/Common/NonNullPtr.h>
|
||||
#include <Core/Math/Matrix.h>
|
||||
#include <Juliet.h>
|
||||
|
||||
namespace Juliet
|
||||
@@ -16,5 +17,7 @@ namespace Juliet
|
||||
|
||||
index_t VertexOffset;
|
||||
index_t IndexOffset;
|
||||
|
||||
Matrix Transform = MatrixIdentity();
|
||||
};
|
||||
} // namespace Juliet
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace Juliet
|
||||
{
|
||||
// Find and destroy
|
||||
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];
|
||||
if (windowRef.ID == window->ID)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -75,12 +75,12 @@ namespace Juliet
|
||||
|
||||
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)
|
||||
{
|
||||
previous = node->Previous;
|
||||
|
||||
JULIET_DEBUG_ONLY(DebugUnregisterArena(node);)
|
||||
JULIET_DEBUG_ONLY(DebugArenaFreeBlock(node);)
|
||||
|
||||
Memory::OS_Release(node, node->Reserved);
|
||||
|
||||
@@ -68,6 +68,8 @@ namespace Juliet
|
||||
{
|
||||
arena->GlobalNext->GlobalPrev = arena->GlobalPrev;
|
||||
}
|
||||
arena->GlobalPrev = nullptr;
|
||||
arena->GlobalNext = nullptr;
|
||||
}
|
||||
|
||||
void DebugArenaSetDebugName(NonNullPtr<Arena> arena, const char* name)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<uint32>(mesh.IndexCount), 1, static_cast<uint32>(mesh.IndexOffset),
|
||||
static_cast<uint32>(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<MeshID>(g_MeshRenderer.Meshes.Count), "Invalid MeshID");
|
||||
g_MeshRenderer.Meshes.Data[id].Transform = transform;
|
||||
}
|
||||
#if ALLOW_SHADER_HOT_RELOAD
|
||||
void ReloadMeshRendererShaders()
|
||||
{
|
||||
|
||||
@@ -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<float>(col) * kSpacing - kOffset;
|
||||
float y = static_cast<float>(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);
|
||||
*/
|
||||
//*/
|
||||
float zHeight = radius * 0.5f; // Keep a nice downward viewing angle
|
||||
|
||||
Camera cam = {};
|
||||
|
||||
Reference in New Issue
Block a user