shape drawing

This commit is contained in:
jacob 2025-11-12 21:21:30 -06:00
parent fe34752146
commit 03eed624c9
18 changed files with 243 additions and 62 deletions

View File

@ -491,9 +491,9 @@ void __asan_unpoison_memory_region(void const volatile *add, size_t);
//- struct region //- struct region
#define BeginFieldRegion(name) i8 __begfieldreg__##name #define BeginFieldRegion(name) i8 __begfieldreg__##name
#define EndFieldRegion(name) i8 __endfieldreg___##name #define EndFieldRegion(name) i8 __endfieldreg__##name
#define CopyFieldRegion(dst, src, r) CopyBytes(&dst->(__begfieldreg__##r), &src->(__begfieldreg__##r), (u8 *)&dst->(__endfieldreg__##r) - (u8 *)&dst->(__begfieldreg__##r)) #define CopyFieldRegion(dst, src, r) CopyBytes(&dst->__begfieldreg__##r, &src->__begfieldreg__##r, (u8 *)&dst->__endfieldreg__##r - (u8 *)&dst->__begfieldreg__##r)
#define ZeroFieldRegion(dst, src, r) ZeroBytes(&dst->(__begfieldreg__##r), &src->(__begfieldreg__##r), (u8 *)&dst->(__endfieldreg__##r) - (u8 *)&dst->(__begfieldreg__##r)) #define ZeroFieldRegion(dst, src, r) ZeroBytes(&dst->__begfieldreg__##r, &src->__begfieldreg__##r, (u8 *)&dst->__endfieldreg__##r - (u8 *)&dst->__begfieldreg__##r)
//- Packed //- Packed
#if CompilerIsMsvc #if CompilerIsMsvc

View File

@ -55,7 +55,7 @@ void *ResetArena(Arena *arena);
#define PushStructNoZero(a, type) PushStructsNoZero((a), type, 1) #define PushStructNoZero(a, type) PushStructsNoZero((a), type, 1)
#define PopStructs(a, type, dst, n) PopBytes((a), sizeof(type) * (n), dst) #define PopStructs(a, type, dst, n) PopBytes((a), sizeof(type) * (n), dst)
#define PopStruct(a, type, dst) PopStructs((a), type, 1, (dst)) #define PopStruct(a, type, dst) PopStructs((a), type, (dst), 1)
#define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n)) #define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n))
#define PopStructNoCopy(a, type) PopStructsNoCopy((a), type, 1) #define PopStructNoCopy(a, type) PopStructsNoCopy((a), type, 1)

View File

@ -328,6 +328,8 @@ Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Vec2I32 Operations //~ Vec2I32 Operations
#define Vec2I32FromFields(v) VEC2I32((v).x, (v).y)
b32 MatchVec2I32(Vec2I32 a, Vec2I32 b); b32 MatchVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 NegVec2I32(Vec2I32 a); Vec2I32 NegVec2I32(Vec2I32 a);
Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b); Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b);

View File

@ -1986,7 +1986,8 @@ i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *text
/* Clear */ /* Clear */
{ {
ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, (f32 *)&clear_color, 0, 0); f32 clear_color_arr[4] = { clear_color.x, clear_color.y, clear_color.z, clear_color.w };
ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, clear_color_arr, 0, 0);
} }
{ {

View File

@ -85,13 +85,13 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
/* Copy ents */ /* Copy ents */
world->ents = PushStructsNoZero(arena, S_Ent, snapshot->ents_count); world->ents = PushStructsNoZero(arena, S_Ent, snapshot->ents_count);
CopyStructs(world->ents, snapshot->ents, snapshot->ents_count); CopyStructs(world->ents, snapshot->ents, snapshot->ents_count);
world->ents_count = snapshot->ents_count; world->allocated_ents_count = snapshot->ents_count;
world->tick = snapshot->tick; world->tick = snapshot->tick;
/* Init lookup */ /* Init lookup */
world->ent_bins_count = 4096; world->ent_bins_count = 4096;
world->ent_bins = PushStructs(arena, S_EntLookupNode *, world->ent_bins_count); world->ent_bins = PushStructs(arena, S_EntLookupNode *, world->ent_bins_count);
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx) for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
{ {
S_Ent *ent = &world->ents[ent_idx]; S_Ent *ent = &world->ents[ent_idx];
S_EntKey key = ent->key; S_EntKey key = ent->key;
@ -103,7 +103,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
/* Sort tree */ /* Sort tree */
{ {
i64 ents_count = world->ents_count; i64 ents_count = world->allocated_ents_count;
S_Ent **ents_pre = PushStructsNoZero(arena, S_Ent *, ents_count); S_Ent **ents_pre = PushStructsNoZero(arena, S_Ent *, ents_count);
S_Ent **ents_post = PushStructsNoZero(arena, S_Ent *, ents_count); S_Ent **ents_post = PushStructsNoZero(arena, S_Ent *, ents_count);
{ {
@ -113,7 +113,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
i64 post_idx = 0; i64 post_idx = 0;
{ {
EntNode *n = PushStruct(scratch.arena, EntNode); EntNode *n = PushStruct(scratch.arena, EntNode);
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx) for (i64 ent_idx = 0; ent_idx < world->allocated_ents_count; ++ent_idx)
{ {
S_Ent *ent = &world->ents[ent_idx]; S_Ent *ent = &world->ents[ent_idx];
if (S_MatchEntKey(ent->key, S_RootEntKey)) if (S_MatchEntKey(ent->key, S_RootEntKey))
@ -148,8 +148,8 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
ents_post[ent->post_idx] = ent; ents_post[ent->post_idx] = ent;
} }
} }
Assert(pre_idx == ents_count); Assert(pre_idx == post_idx);
Assert(post_idx == ents_count); world->active_ents_count = pre_idx;
world->ents_pre = ents_pre; world->ents_pre = ents_pre;
world->ents_post = ents_post; world->ents_post = ents_post;
} }
@ -162,7 +162,7 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Sim worker //~ Sim worker
JobDef(S_SimWorker, sig, job_id) JobDef(S_SimWorker, _, __)
{ {
S_SharedState *shared = &S_shared_state; S_SharedState *shared = &S_shared_state;
Arena *frame_arena = AcquireArena(Gibi(64)); Arena *frame_arena = AcquireArena(Gibi(64));
@ -186,10 +186,28 @@ JobDef(S_SimWorker, sig, job_id)
S_Ent *test_ent = &empty_ss->ents[empty_ss->ents_count++]; S_Ent *test_ent = &empty_ss->ents[empty_ss->ents_count++];
{ {
*test_ent = S_nil_ent; *test_ent = S_nil_ent;
test_ent->shape.points_count = 1; // test_ent->shape.points_count = 1;
test_ent->shape.radius = 0.25; // test_ent->shape.radius = 0.25;
test_ent->key = ((S_EntKey) { .v.hi = 0x66444f20b7e41f3d, .v.lo = 0x5a2df684b9430943 }); test_ent->key = ((S_EntKey) { .v.hi = 0x66444f20b7e41f3d, .v.lo = 0x5a2df684b9430943 });
{
S_Shape *shape = &test_ent->shape;
shape->points_count = 4;
shape->points[0] = VEC2(100, 100);
shape->points[1] = VEC2(200, 100);
shape->points[2] = VEC2(150, 200);
shape->points[3] = VEC2(125, 200);
// test_ent->shape.radius = 0.25;
}
test_ent->parent = root_ent->key; test_ent->parent = root_ent->key;
root_ent->first = test_ent->key; root_ent->first = test_ent->key;
root_ent->last = test_ent->key; root_ent->last = test_ent->key;
@ -252,7 +270,7 @@ JobDef(S_SimWorker, sig, job_id)
S_Snapshot *snapshot = &snapshot_node->snapshot; S_Snapshot *snapshot = &snapshot_node->snapshot;
SllQueuePush(output->first_snapshot_node, output->last_snapshot_node, snapshot_node); SllQueuePush(output->first_snapshot_node, output->last_snapshot_node, snapshot_node);
++output->snapshots_count; ++output->snapshots_count;
snapshot->ents_count = world->ents_count; snapshot->ents_count = world->allocated_ents_count;
snapshot->tick = world->tick; snapshot->tick = world->tick;
snapshot->ents = PushStructsNoZero(output->arena, S_Ent, snapshot->ents_count); snapshot->ents = PushStructsNoZero(output->arena, S_Ent, snapshot->ents_count);
for (i64 ent_idx = 0; ent_idx < snapshot->ents_count; ++ent_idx) for (i64 ent_idx = 0; ent_idx < snapshot->ents_count; ++ent_idx)

View File

@ -46,6 +46,7 @@ Struct(S_Ent)
//- Persistent data //- Persistent data
S_EntKey key; S_EntKey key;
//- Build data
S_Shape shape; S_Shape shape;
//- Per-world data //- Per-world data
@ -56,12 +57,6 @@ Struct(S_Ent)
////////////////////////////// //////////////////////////////
//- Ent containers //- Ent containers
Struct(S_EntArray)
{
i64 count;
S_Ent *ents;
};
Struct(S_EntListNode) Struct(S_EntListNode)
{ {
S_EntListNode *next; S_EntListNode *next;
@ -89,13 +84,14 @@ Struct(S_World)
i64 tick; i64 tick;
S_Ent *ents; S_Ent *ents;
i64 ents_count; i64 allocated_ents_count;
S_EntLookupNode **ent_bins; S_EntLookupNode **ent_bins;
i64 ent_bins_count; i64 ent_bins_count;
S_Ent **ents_pre; S_Ent **ents_pre;
S_Ent **ents_post; S_Ent **ents_post;
i64 active_ents_count;
}; };
Struct(S_Snapshot) Struct(S_Snapshot)

View File

@ -15,14 +15,16 @@
//- Api //- Api
@IncludeC pp_vis_widgets.h @IncludeC pp_vis_widgets.h
@IncludeC pp_vis_gpu.h
@IncludeC pp_vis_draw.h @IncludeC pp_vis_draw.h
@IncludeC pp_vis_core.h @IncludeC pp_vis_core.h
@IncludeGpu pp_vis_draw.h @IncludeGpu pp_vis_gpu.h
//- Impl //- Impl
@IncludeC pp_vis_widgets.c @IncludeC pp_vis_widgets.c
@IncludeC pp_vis_draw.c
@IncludeC pp_vis_core.c @IncludeC pp_vis_core.c
@IncludeGpu pp_vis_draw.gpu @IncludeGpu pp_vis_gpu.gpu
//- Embeds //- Embeds
@EmbedDir V_Resources pp_vis_res @EmbedDir V_Resources pp_vis_res
@ -30,6 +32,8 @@
//- Shaders //- Shaders
@VertexShader V_DQuadVS @VertexShader V_DQuadVS
@PixelShader V_DQuadPS @PixelShader V_DQuadPS
@VertexShader V_DVertVS
@PixelShader V_DVertPS
//- Startup //- Startup
@Startup V_Startup @Startup V_Startup

View File

@ -25,7 +25,7 @@ void V_Shutdown(void)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Vis worker //~ Vis worker
JobDef(V_VisWorker, sig, job_id) JobDef(V_VisWorker, _, __)
{ {
V_SharedState *vis_shared = &V_shared_state; V_SharedState *vis_shared = &V_shared_state;
S_SharedState *sim_shared = &S_shared_state; S_SharedState *sim_shared = &S_shared_state;
@ -40,6 +40,11 @@ JobDef(V_VisWorker, sig, job_id)
i64 frame_gen = 0; i64 frame_gen = 0;
GPU_Resource *draw_target = 0; GPU_Resource *draw_target = 0;
Arena *dverts_arena = AcquireArena(Gibi(64));
Arena *dvert_idx_arena = AcquireArena(Gibi(64));
GPU_TransientBuffer dverts_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(V_DVert));
GPU_TransientBuffer dvert_idx_tbuff = GPU_AcquireTransientBuffer(GPU_QueueKind_Direct, sizeof(i32));
Struct(Persist) Struct(Persist)
{ {
V_CommandsWidget commands_widget; V_CommandsWidget commands_widget;
@ -105,8 +110,6 @@ JobDef(V_VisWorker, sig, job_id)
////////////////////////////// //////////////////////////////
//- Begin vis loop //- Begin vis loop
Arena *world_arena = AcquireArena(Gibi(64)); Arena *world_arena = AcquireArena(Gibi(64));
S_World *world = PushStruct(world_arena, S_World); S_World *world = PushStruct(world_arena, S_World);
@ -125,7 +128,6 @@ JobDef(V_VisWorker, sig, job_id)
UI_Frame ui_frame = UI_BeginFrame(ui_frame_flags, swapchain_color); UI_Frame ui_frame = UI_BeginFrame(ui_frame_flags, swapchain_color);
WND_Frame window_frame = ui_frame.window_frame; WND_Frame window_frame = ui_frame.window_frame;
Vec2 ui_cursor = ui_frame.cursor_pos; Vec2 ui_cursor = ui_frame.cursor_pos;
Vec2I32 draw_size = window_frame.monitor_size;
/* Restore window */ /* Restore window */
{ {
@ -146,6 +148,13 @@ JobDef(V_VisWorker, sig, job_id)
UI_Key vis_box = UI_KeyF("vis box"); UI_Key vis_box = UI_KeyF("vis box");
UI_Push(Parent, UI_BuildColumnEx(vis_box)); UI_Push(Parent, UI_BuildColumnEx(vis_box));
Vec2I32 draw_size = ZI;
{
/* TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing */
UI_Report vis_rep = UI_ReportFromKey(vis_box);
draw_size = Vec2I32FromFields(SubVec2(vis_rep.screen_p1, vis_rep.screen_p0));
}
////////////////////////////// //////////////////////////////
//- Pop sim output //- Pop sim output
@ -333,6 +342,27 @@ JobDef(V_VisWorker, sig, job_id)
} }
UnlockTicketMutex(&sim_shared->input_back_tm); UnlockTicketMutex(&sim_shared->input_back_tm);
//////////////////////////////
//- Build render data
/* Build shapes */
for (i64 pre_idx = 0; pre_idx < world->active_ents_count; ++pre_idx)
{
S_Ent *ent = &world->ents[pre_idx];
// Xform xf = ent->final_to_world_xf;
Xform xf = XformIdentity;
S_Shape shape = ent->shape;
for (u32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
{
Vec2 *p = &shape.points[point_idx];
*p = MulXformV2(xf, *p);
}
Vec4 color = Color_Red;
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color));
}
////////////////////////////// //////////////////////////////
//- Render //- Render
@ -350,13 +380,24 @@ JobDef(V_VisWorker, sig, job_id)
desc.kind = GPU_ResourceKind_Texture2D; desc.kind = GPU_ResourceKind_Texture2D;
desc.flags = GPU_ResourceFlag_Writable | GPU_ResourceFlag_Renderable; desc.flags = GPU_ResourceFlag_Writable | GPU_ResourceFlag_Renderable;
desc.texture.format = GPU_Format_R16G16B16A16_Float; desc.texture.format = GPU_Format_R16G16B16A16_Float;
desc.texture.size = VEC3I32(draw_size.x, draw_size.y, 1);
desc.clear_color = LinearFromSrgb(swapchain_color); desc.clear_color = LinearFromSrgb(swapchain_color);
draw_target = GPU_AcquireResource(desc); draw_target = GPU_AcquireResource(desc);
} }
} }
/* Upload transient buffers */
GPU_Resource *dverts_buffer = GPU_UploadTransientBufferFromArena(&dverts_tbuff, dverts_arena);
GPU_Resource *dvert_idx_buffer = GPU_UploadTransientBufferFromArena(&dvert_idx_tbuff, dvert_idx_arena);
u64 dverts_count = GPU_GetBufferCount(dverts_buffer);
u64 dvert_idx_count = GPU_GetBufferCount(dvert_idx_buffer);
GPU_Viewport viewport = GPU_ViewportFromRect(RectFromVec2(VEC2(0, 0), Vec2FromFields(draw_size)));
GPU_Scissor scissor = GPU_ScissorFromRect(RectFromVec2(VEC2(0, 0), Vec2FromFields(draw_size)));
GPU_CommandList *cl = GPU_BeginCommandList(GPU_QueueKind_Direct); GPU_CommandList *cl = GPU_BeginCommandList(GPU_QueueKind_Direct);
{ {
/* Prep draw target */ /* Prep draw target */
{ {
GPU_TransitionToRenderable(cl, draw_target, 0); GPU_TransitionToRenderable(cl, draw_target, 0);
@ -365,11 +406,23 @@ JobDef(V_VisWorker, sig, job_id)
/* Prep shapes pass */ /* Prep shapes pass */
{ {
} }
/* Shapes pass */ /* Shapes pass */
{ {
V_DVertSig sig = ZI;
sig.viewport_size = draw_size;
sig.sampler = GPU_SamplerStateRidFromResource(GPU_GetCommonPointSampler());
sig.verts = GPU_StructuredBufferRidFromResource(dverts_buffer);
GPU_Rasterize(cl,
&sig,
V_DVertVS, V_DVertPS,
1,
viewport,
scissor,
1,
dvert_idx_buffer,
GPU_RasterizeMode_TriangleList);
} }
/* Transition draw target for UI composition */ /* Transition draw target for UI composition */
@ -379,6 +432,14 @@ JobDef(V_VisWorker, sig, job_id)
} }
gpu_fence_target = GPU_EndCommandList(cl); gpu_fence_target = GPU_EndCommandList(cl);
/* Reset transient buffers */
{
GPU_ResetTransientBuffer(&dverts_tbuff, gpu_fence_target);
GPU_ResetTransientBuffer(&dvert_idx_tbuff, gpu_fence_target);
ResetArena(dverts_arena);
ResetArena(dvert_idx_arena);
}
////////////////////////////// //////////////////////////////
//- End vis frame //- End vis frame

View File

@ -7,7 +7,7 @@
X(toggle_command_palette, Toggle Command Palette, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \ X(toggle_command_palette, Toggle Command Palette, V_CmdDescFlag_HideFromPalette, V_HOTKEY( Button_P, .ctrl = 1, .shift = 1 ), ) \
X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \ X(toggle_ui_debug, Toggle UI Debug, V_CmdDescFlag_None, V_HOTKEY( Button_F5 ), ) \
X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \ X(toggle_console, Toggle Developer Console, V_CmdDescFlag_None, V_HOTKEY( Button_GraveAccent ), ) \
X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ), V_HOTKEY( Button_F11 ) ) \ X(toggle_fullscreen, Toggle Fullscreen Mode, V_CmdDescFlag_None, V_HOTKEY( Button_Enter, .alt = 1 ) ) \
X(toggle_window_topmost, Toggle Window Topmost, V_CmdDescFlag_None, V_HOTKEY( Button_F4 ), ) \ X(toggle_window_topmost, Toggle Window Topmost, V_CmdDescFlag_None, V_HOTKEY( Button_F4 ), ) \
X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \ X(spawn, Spawn, V_CmdDescFlag_None, V_HOTKEY( Button_S, .ctrl = 1 ), ) \
/* -------------------------------------------------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------------------------------------------------- */

View File

@ -0,0 +1,30 @@
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin)
{
/* FIXME: Rounding */
i32 verts_count = shape.points_count;
if (verts_count >= 3)
{
i32 idx_offset = ArenaCount(verts_arena, V_DVert);
V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, verts_count);
for (i32 point_idx = 0; point_idx < (i32)shape.points_count; ++point_idx)
{
V_DVert *dvert = &dverts[point_idx];
dvert->pos = shape.points[point_idx];
dvert->color_lin = color_lin;
}
i32 tris_count = verts_count - 2;
i32 idx_count = tris_count * 3;
i32 *indices = PushStructsNoZero(idx_arena, i32, idx_count);
/* Generate indices in a fan pattern */
for (i32 i = 0; i < tris_count; ++i)
{
i32 tri_offset = idx_offset + (i * 3);
indices[tri_offset + 0] = idx_offset;
indices[tri_offset + 1] = i + 1;
indices[tri_offset + 2] = i + 2;
}
}
}

View File

@ -1,28 +1 @@
//////////////////////////////////////////////////////////// void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin);
//~ Quad types
Struct(V_DQuadSig)
{
/* ----------------------------------------------------- */
Vec2I32 viewport_size; /* 02 consts */
StructuredBufferRid quads; /* 01 consts */
SamplerStateRid sampler; /* 01 consts */
/* ----------------------------------------------------- */
b32 debug_enabled; /* 01 consts */
u32 _pad0; /* 01 consts (padding) */
u32 _pad1; /* 01 consts (padding) */
u32 _pad2; /* 01 consts (padding) */
/* ----------------------------------------------------- */
};
AssertRootConst(V_DQuadSig, 8);
Enum(V_DQuadFlag)
{
V_DQuadFlag_None = 0,
V_DQuadFlag_DrawGrid = (1 << 0),
};
Struct(V_DQuad)
{
V_DQuadFlag flags;
};

View File

@ -1,4 +1,5 @@
ConstantBuffer<V_DQuadSig> V_dquad_sig : register (b0); ConstantBuffer<V_DQuadSig> V_dquad_sig : register (b0);
ConstantBuffer<V_DVertSig> V_dvert_sig : register (b0);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
//~ Quad //~ Quad
@ -47,3 +48,42 @@ V_DQuadPS_Output PSDef(V_DQuadPS, V_DQuadPS_Input input)
output.sv_target0 = final_color; output.sv_target0 = final_color;
return output; return output;
} }
////////////////////////////////////////////////////////////
//~ Shape
Struct(V_DVertPS_Input)
{
Semantic(Vec4, sv_position);
Semantic(Vec4, color_lin);
};
Struct(V_DVertPS_Output)
{
Semantic(Vec4, sv_target0);
};
//- Vertex shader
V_DVertPS_Input VSDef(V_DVertVS, Semantic(u32, sv_vertexid))
{
ConstantBuffer<V_DVertSig> sig = V_dvert_sig;
StructuredBuffer<V_DVert> verts = UniformResourceFromRid(sig.verts);
V_DVert vert = verts[sv_vertexid];
Vec2 screen_vert = vert.pos;
V_DVertPS_Input result;
result.sv_position = Vec4(NdcFromViewport(sig.viewport_size, screen_vert).xy, 0, 1);
result.color_lin = vert.color_lin;
return result;
}
//- Pixel shader
V_DVertPS_Output PSDef(V_DVertPS, V_DVertPS_Input input)
{
V_DVertPS_Output output;
output.sv_target0 = input.color_lin;
return output;
}

View File

@ -0,0 +1,52 @@
////////////////////////////////////////////////////////////
//~ Quad types
Struct(V_DQuadSig)
{
/* ----------------------------------------------------- */
Vec2I32 viewport_size; /* 02 consts */
StructuredBufferRid quads; /* 01 consts */
SamplerStateRid sampler; /* 01 consts */
/* ----------------------------------------------------- */
b32 debug_enabled; /* 01 consts */
u32 _pad0; /* 01 consts (padding) */
u32 _pad1; /* 01 consts (padding) */
u32 _pad2; /* 01 consts (padding) */
/* ----------------------------------------------------- */
};
AssertRootConst(V_DQuadSig, 8);
Enum(V_DQuadFlag)
{
V_DQuadFlag_None = 0,
V_DQuadFlag_DrawGrid = (1 << 0),
};
Struct(V_DQuad)
{
V_DQuadFlag flags;
};
////////////////////////////////////////////////////////////
//~ Shape types
Struct(V_DVertSig)
{
/* ----------------------------------------------------- */
Vec2I32 viewport_size; /* 02 consts */
StructuredBufferRid verts; /* 01 consts */
SamplerStateRid sampler; /* 01 consts */
/* ----------------------------------------------------- */
b32 debug_enabled; /* 01 consts */
u32 _pad0; /* 01 consts (padding) */
u32 _pad1; /* 01 consts (padding) */
u32 _pad2; /* 01 consts (padding) */
/* ----------------------------------------------------- */
};
AssertRootConst(V_DVertSig, 8);
Struct(V_DVert)
{
Vec2 pos;
Vec4 color_lin;
};

View File

@ -102,7 +102,8 @@ void V_EndCommandsWidget(V_CommandsWidget *widget)
{ {
widget->pos = SubVec2(cursor_pos, rep.last_m1_offset); widget->pos = SubVec2(cursor_pos, rep.last_m1_offset);
} }
window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot); // window_border_color = BlendSrgb(window_border_color, Rgb(0.5, 0.5, 0.5), rep.hot);
window_border_color = BlendSrgb(window_border_color, Rgb32(0x0078a6), rep.hot);
} }
UI_Push(BackgroundColor, window_background_color); UI_Push(BackgroundColor, window_background_color);

View File

@ -8,13 +8,13 @@
//- Api //- Api
@IncludeC ui_core.h @IncludeC ui_core.h
@IncludeC ui_common.h @IncludeC ui_common.h
@IncludeC ui_draw.h @IncludeC ui_gpu.h
@IncludeGpu ui_draw.h @IncludeGpu ui_gpu.h
//- Impl //- Impl
@IncludeC ui_core.c @IncludeC ui_core.c
@IncludeC ui_common.c @IncludeC ui_common.c
@IncludeGpu ui_draw.gpu @IncludeGpu ui_gpu.gpu
//- Shaders //- Shaders
@VertexShader UI_DRectVS @VertexShader UI_DRectVS

View File

@ -626,6 +626,9 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
report->hot = LerpF32(report->hot, target_hot, hot_blend_rate); report->hot = LerpF32(report->hot, target_hot, hot_blend_rate);
report->active = LerpF32(report->active, target_active, active_blend_rate); report->active = LerpF32(report->active, target_active, active_blend_rate);
report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate); report->hovered = LerpF32(report->hovered, target_hovered, hovered_blend_rate);
report->screen_p0 = box->p0;
report->screen_p1 = box->p1;
} }
g->bframe.hovered_box = hovered_box ? hovered_box->key : UI_NilKey; g->bframe.hovered_box = hovered_box ? hovered_box->key : UI_NilKey;