prep vis renderer
This commit is contained in:
parent
030d9ad6a8
commit
fe34752146
@ -493,4 +493,4 @@ void GPU_YieldOnSwapchain(GPU_Swapchain *swapchain);
|
|||||||
* 2. Blits `texture` into position `dst` in the backbuffer
|
* 2. Blits `texture` into position `dst` in the backbuffer
|
||||||
* 3. Presents the backbuffer
|
* 3. Presents the backbuffer
|
||||||
* 4. Returns the value that the Direct queue fence will reach once GPU completes blitting (`texture` shouldn't be released while blit is in flight) */
|
* 4. Returns the value that the Direct queue fence will reach once GPU completes blitting (`texture` shouldn't be released while blit is in flight) */
|
||||||
i64 GPU_PresentSwapchain(GPU_Swapchain *swapchain, GPU_Resource *texture, i32 vsync, Vec2I32 backbuffer_size, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1);
|
i64 GPU_PresentSwapchain(GPU_Swapchain *swapchain, GPU_Resource *texture, i32 vsync, Vec2I32 backbuffer_size, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color);
|
||||||
|
|||||||
@ -1960,7 +1960,7 @@ GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, V
|
|||||||
return &swapchain->buffers[backbuffer_index];
|
return &swapchain->buffers[backbuffer_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1)
|
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color)
|
||||||
{
|
{
|
||||||
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
||||||
|
|
||||||
@ -1986,8 +1986,7 @@ i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *text
|
|||||||
|
|
||||||
/* Clear */
|
/* Clear */
|
||||||
{
|
{
|
||||||
f32 clear_color[4] = ZI;
|
ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, (f32 *)&clear_color, 0, 0);
|
||||||
ID3D12GraphicsCommandList_ClearRenderTargetView(rcl, dst->rtv_descriptor->handle, clear_color, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -2194,7 +2193,7 @@ void GPU_YieldOnSwapchain(GPU_Swapchain *gpu_swapchain)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture, i32 vsync, Vec2I32 backbuffer_size, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1)
|
i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture, i32 vsync, Vec2I32 backbuffer_size, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color)
|
||||||
{
|
{
|
||||||
GPU_D12_Swapchain *swapchain = (GPU_D12_Swapchain *)gpu_swapchain;
|
GPU_D12_Swapchain *swapchain = (GPU_D12_Swapchain *)gpu_swapchain;
|
||||||
GPU_D12_Resource *texture = (GPU_D12_Resource *)gpu_texture;
|
GPU_D12_Resource *texture = (GPU_D12_Resource *)gpu_texture;
|
||||||
@ -2214,7 +2213,7 @@ i64 GPU_PresentSwapchain(GPU_Swapchain *gpu_swapchain, GPU_Resource *gpu_texture
|
|||||||
if (is_blitable)
|
if (is_blitable)
|
||||||
{
|
{
|
||||||
/* Blit */
|
/* Blit */
|
||||||
fence_target = GPU_D12_BlitToSwapchain(swapchain_buffer, texture, dst_p0, dst_p1, src_p0, src_p1);
|
fence_target = GPU_D12_BlitToSwapchain(swapchain_buffer, texture, dst_p0, dst_p1, src_p0, src_p1, clear_color);
|
||||||
|
|
||||||
u32 present_flags = 0;
|
u32 present_flags = 0;
|
||||||
if (GPU_D12_TearingIsAllowed && vsync == 0)
|
if (GPU_D12_TearingIsAllowed && vsync == 0)
|
||||||
|
|||||||
@ -380,7 +380,7 @@ u64 GPU_D12_EndRawCommandList(GPU_D12_RawCommandList *cl);
|
|||||||
|
|
||||||
void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain);
|
void GPU_D12_InitSwapchainResources(GPU_D12_Swapchain *swapchain);
|
||||||
GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution);
|
GPU_D12_SwapchainBuffer *GPU_D12_UpdateSwapchain(GPU_D12_Swapchain *swapchain, Vec2I32 resolution);
|
||||||
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1);
|
i64 GPU_D12_BlitToSwapchain(GPU_D12_SwapchainBuffer *dst, GPU_D12_Resource *texture, Vec2I32 dst_p0, Vec2I32 dst_p1, Vec2I32 src_p0, Vec2I32 src_p1, Vec4 clear_color);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Sync job
|
//~ Sync job
|
||||||
|
|||||||
@ -48,6 +48,117 @@ b32 S_IsEntNil(S_Ent *ent)
|
|||||||
return ent == 0 || ent == &S_nil_ent;
|
return ent == 0 || ent == &S_nil_ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b32 S_MatchEntKey(S_EntKey a, S_EntKey b)
|
||||||
|
{
|
||||||
|
return a.v.hi == b.v.hi && a.v.lo == b.v.lo;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Lookup helpers
|
||||||
|
|
||||||
|
S_Ent *S_EntFromKey(S_World *world, S_EntKey key)
|
||||||
|
{
|
||||||
|
S_Ent *ent = &S_nil_ent;
|
||||||
|
if (!S_IsKeyNil(key))
|
||||||
|
{
|
||||||
|
S_EntLookupNode *n = world->ent_bins[key.v.lo % world->ent_bins_count];
|
||||||
|
for (; n; n = n->next)
|
||||||
|
{
|
||||||
|
if (S_MatchEntKey(n->ent->key, key))
|
||||||
|
{
|
||||||
|
ent = n->ent;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Snapshot helpers
|
||||||
|
|
||||||
|
S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot)
|
||||||
|
{
|
||||||
|
TempArena scratch = BeginScratch(arena);
|
||||||
|
S_World *world = PushStruct(arena, S_World);
|
||||||
|
|
||||||
|
/* Copy ents */
|
||||||
|
world->ents = PushStructsNoZero(arena, S_Ent, snapshot->ents_count);
|
||||||
|
CopyStructs(world->ents, snapshot->ents, snapshot->ents_count);
|
||||||
|
world->ents_count = snapshot->ents_count;
|
||||||
|
world->tick = snapshot->tick;
|
||||||
|
|
||||||
|
/* Init lookup */
|
||||||
|
world->ent_bins_count = 4096;
|
||||||
|
world->ent_bins = PushStructs(arena, S_EntLookupNode *, world->ent_bins_count);
|
||||||
|
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
||||||
|
{
|
||||||
|
S_Ent *ent = &world->ents[ent_idx];
|
||||||
|
S_EntKey key = ent->key;
|
||||||
|
S_EntLookupNode *n = PushStruct(arena, S_EntLookupNode);
|
||||||
|
n->ent = ent;
|
||||||
|
S_EntLookupNode **bin = &world->ent_bins[ent->key.v.lo % world->ent_bins_count];
|
||||||
|
SllStackPush(*bin, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sort tree */
|
||||||
|
{
|
||||||
|
i64 ents_count = world->ents_count;
|
||||||
|
S_Ent **ents_pre = PushStructsNoZero(arena, S_Ent *, ents_count);
|
||||||
|
S_Ent **ents_post = PushStructsNoZero(arena, S_Ent *, ents_count);
|
||||||
|
{
|
||||||
|
Struct(EntNode) { EntNode *next; b32 visited; S_Ent *ent; };
|
||||||
|
EntNode *first_dfs = 0;
|
||||||
|
i64 pre_idx = 0;
|
||||||
|
i64 post_idx = 0;
|
||||||
|
{
|
||||||
|
EntNode *n = PushStruct(scratch.arena, EntNode);
|
||||||
|
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
||||||
|
{
|
||||||
|
S_Ent *ent = &world->ents[ent_idx];
|
||||||
|
if (S_MatchEntKey(ent->key, S_RootEntKey))
|
||||||
|
{
|
||||||
|
n->ent = ent;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SllStackPush(first_dfs, n);
|
||||||
|
}
|
||||||
|
while (first_dfs)
|
||||||
|
{
|
||||||
|
EntNode *n = first_dfs;
|
||||||
|
S_Ent *ent = n->ent;
|
||||||
|
if (!n->visited)
|
||||||
|
{
|
||||||
|
/* Push children to dfs stack */
|
||||||
|
for (S_Ent *child = S_EntFromKey(world, ent->first); !S_IsEntNil(child); child = S_EntFromKey(world, child->prev))
|
||||||
|
{
|
||||||
|
EntNode *child_n = PushStruct(scratch.arena, EntNode);
|
||||||
|
child_n->ent = child;
|
||||||
|
SllStackPush(first_dfs, child_n);
|
||||||
|
}
|
||||||
|
ent->pre_idx = pre_idx++;
|
||||||
|
ents_pre[ent->pre_idx] = ent;
|
||||||
|
n->visited = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SllStackPop(first_dfs);
|
||||||
|
ent->post_idx = post_idx++;
|
||||||
|
ents_post[ent->post_idx] = ent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assert(pre_idx == ents_count);
|
||||||
|
Assert(post_idx == ents_count);
|
||||||
|
world->ents_pre = ents_pre;
|
||||||
|
world->ents_post = ents_post;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndScratch(scratch);
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Sim worker
|
//~ Sim worker
|
||||||
|
|
||||||
@ -58,24 +169,34 @@ JobDef(S_SimWorker, sig, job_id)
|
|||||||
Arena *perm = PermArena();
|
Arena *perm = PermArena();
|
||||||
|
|
||||||
//- World data
|
//- World data
|
||||||
Arena *ents_arena = AcquireArena(Gibi(64));
|
Arena *world_arena = AcquireArena(Gibi(64));
|
||||||
S_Ent *ents = ArenaFirst(ents_arena, S_Ent);
|
S_World *world = 0;
|
||||||
i64 tick = 0;
|
|
||||||
|
|
||||||
/* Create root ent */
|
|
||||||
{
|
{
|
||||||
S_Ent *root_ent = PushStruct(ents_arena, S_Ent);
|
S_Snapshot *empty_ss = PushStruct(frame_arena, S_Snapshot);
|
||||||
*root_ent = S_nil_ent;
|
{
|
||||||
root_ent->key = S_RootEntKey;
|
empty_ss->ents = PushStructs(frame_arena, S_Ent, 1024);
|
||||||
}
|
/* Create root ent */
|
||||||
|
S_Ent *root_ent = &empty_ss->ents[empty_ss->ents_count++];
|
||||||
|
{
|
||||||
|
*root_ent = S_nil_ent;
|
||||||
|
root_ent->key = S_RootEntKey;
|
||||||
|
}
|
||||||
|
/* Create test ent */
|
||||||
|
S_Ent *test_ent = &empty_ss->ents[empty_ss->ents_count++];
|
||||||
|
{
|
||||||
|
*test_ent = S_nil_ent;
|
||||||
|
test_ent->shape.points_count = 1;
|
||||||
|
test_ent->shape.radius = 0.25;
|
||||||
|
test_ent->key = ((S_EntKey) { .v.hi = 0x66444f20b7e41f3d, .v.lo = 0x5a2df684b9430943 });
|
||||||
|
|
||||||
/* Create test ent */
|
test_ent->parent = root_ent->key;
|
||||||
{
|
root_ent->first = test_ent->key;
|
||||||
S_Ent *test_ent = PushStruct(ents_arena, S_Ent);
|
root_ent->last = test_ent->key;
|
||||||
*test_ent = S_nil_ent;
|
++root_ent->count;
|
||||||
test_ent->parent = S_RootEntKey;
|
}
|
||||||
test_ent->shape.points_count = 1;
|
}
|
||||||
test_ent->shape.radius = 0.25;
|
world = S_WorldFromSnapshot(world_arena, empty_ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -127,17 +248,18 @@ JobDef(S_SimWorker, sig, job_id)
|
|||||||
LockTicketMutex(&shared->output_back_tm);
|
LockTicketMutex(&shared->output_back_tm);
|
||||||
{
|
{
|
||||||
S_OutputState *output = &shared->output_states[shared->output_back_idx];
|
S_OutputState *output = &shared->output_states[shared->output_back_idx];
|
||||||
S_WorldNode *world_node = PushStruct(output->arena, S_WorldNode);
|
S_SnapshotNode *snapshot_node = PushStruct(output->arena, S_SnapshotNode);
|
||||||
S_World *world = &world_node->world;
|
S_Snapshot *snapshot = &snapshot_node->snapshot;
|
||||||
SllQueuePush(output->first_world_node, output->last_world_node, world_node);
|
SllQueuePush(output->first_snapshot_node, output->last_snapshot_node, snapshot_node);
|
||||||
++output->worlds_count;
|
++output->snapshots_count;
|
||||||
world->ents_count = ArenaCount(ents_arena, S_Ent);
|
snapshot->ents_count = world->ents_count;
|
||||||
world->tick = tick;
|
snapshot->tick = world->tick;
|
||||||
world->ents = PushStructsNoZero(output->arena, S_Ent, world->ents_count);
|
snapshot->ents = PushStructsNoZero(output->arena, S_Ent, snapshot->ents_count);
|
||||||
for (i64 ent_idx = 0; ent_idx < world->ents_count; ++ent_idx)
|
for (i64 ent_idx = 0; ent_idx < snapshot->ents_count; ++ent_idx)
|
||||||
{
|
{
|
||||||
S_Ent *ent = &ents[ent_idx];
|
S_Ent *src = &world->ents[ent_idx];
|
||||||
world->ents[ent_idx] = *ent;
|
S_Ent *dst = &snapshot->ents[ent_idx];
|
||||||
|
*dst = *src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UnlockTicketMutex(&shared->output_back_tm);
|
UnlockTicketMutex(&shared->output_back_tm);
|
||||||
@ -155,7 +277,7 @@ JobDef(S_SimWorker, sig, job_id)
|
|||||||
|
|
||||||
|
|
||||||
i64 frame_end_ns = TimeNs();
|
i64 frame_end_ns = TimeNs();
|
||||||
++tick;
|
++world->tick;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Sleep
|
//- Sleep
|
||||||
|
|||||||
@ -35,19 +35,32 @@ Enum(S_EntProp)
|
|||||||
|
|
||||||
Struct(S_Ent)
|
Struct(S_Ent)
|
||||||
{
|
{
|
||||||
|
//- Tree data
|
||||||
S_EntKey parent;
|
S_EntKey parent;
|
||||||
S_EntKey first;
|
S_EntKey first;
|
||||||
S_EntKey last;
|
S_EntKey last;
|
||||||
S_EntKey next;
|
S_EntKey next;
|
||||||
S_EntKey prev;
|
S_EntKey prev;
|
||||||
|
i64 count;
|
||||||
|
|
||||||
|
//- Persistent data
|
||||||
S_EntKey key;
|
S_EntKey key;
|
||||||
|
|
||||||
S_Shape shape;
|
S_Shape shape;
|
||||||
|
|
||||||
|
//- Per-world data
|
||||||
|
i64 pre_idx;
|
||||||
|
i64 post_idx;
|
||||||
} extern Readonly S_nil_ent;
|
} extern Readonly S_nil_ent;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Ent list
|
//- Ent containers
|
||||||
|
|
||||||
|
Struct(S_EntArray)
|
||||||
|
{
|
||||||
|
i64 count;
|
||||||
|
S_Ent *ents;
|
||||||
|
};
|
||||||
|
|
||||||
Struct(S_EntListNode)
|
Struct(S_EntListNode)
|
||||||
{
|
{
|
||||||
@ -62,28 +75,40 @@ Struct(S_EntList)
|
|||||||
u64 count;
|
u64 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
Struct(S_EntLookupNode)
|
||||||
//~ Lookup types
|
|
||||||
|
|
||||||
Struct(S_EntLookupBin)
|
|
||||||
{
|
{
|
||||||
i32 _;
|
S_EntLookupNode *next;
|
||||||
|
S_Ent *ent;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ World types
|
//~ World types
|
||||||
|
|
||||||
Struct(S_World)
|
Struct(S_World)
|
||||||
|
{
|
||||||
|
i64 tick;
|
||||||
|
|
||||||
|
S_Ent *ents;
|
||||||
|
i64 ents_count;
|
||||||
|
|
||||||
|
S_EntLookupNode **ent_bins;
|
||||||
|
i64 ent_bins_count;
|
||||||
|
|
||||||
|
S_Ent **ents_pre;
|
||||||
|
S_Ent **ents_post;
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(S_Snapshot)
|
||||||
{
|
{
|
||||||
i64 tick;
|
i64 tick;
|
||||||
S_Ent *ents;
|
S_Ent *ents;
|
||||||
i64 ents_count;
|
i64 ents_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(S_WorldNode)
|
Struct(S_SnapshotNode)
|
||||||
{
|
{
|
||||||
S_WorldNode *next;
|
S_SnapshotNode *next;
|
||||||
S_World world;
|
S_Snapshot snapshot;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -124,9 +149,9 @@ Struct(S_InputState)
|
|||||||
Struct(S_OutputState)
|
Struct(S_OutputState)
|
||||||
{
|
{
|
||||||
Arena *arena;
|
Arena *arena;
|
||||||
S_WorldNode *first_world_node;
|
S_SnapshotNode *first_snapshot_node;
|
||||||
S_WorldNode *last_world_node;
|
S_SnapshotNode *last_snapshot_node;
|
||||||
u64 worlds_count;
|
u64 snapshots_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(S_SharedState)
|
Struct(S_SharedState)
|
||||||
@ -158,6 +183,17 @@ void S_Shutdown(void);
|
|||||||
|
|
||||||
b32 S_IsKeyNil(S_EntKey key);
|
b32 S_IsKeyNil(S_EntKey key);
|
||||||
b32 S_IsEntNil(S_Ent *ent);
|
b32 S_IsEntNil(S_Ent *ent);
|
||||||
|
b32 S_MatchEntKey(S_EntKey a, S_EntKey b);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Lookup helpers
|
||||||
|
|
||||||
|
S_Ent *S_EntFromKey(S_World *world, S_EntKey key);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Snapshot helpers
|
||||||
|
|
||||||
|
S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Sim worker
|
//~ Sim worker
|
||||||
|
|||||||
@ -15,14 +15,21 @@
|
|||||||
|
|
||||||
//- Api
|
//- Api
|
||||||
@IncludeC pp_vis_widgets.h
|
@IncludeC pp_vis_widgets.h
|
||||||
|
@IncludeC pp_vis_draw.h
|
||||||
@IncludeC pp_vis_core.h
|
@IncludeC pp_vis_core.h
|
||||||
|
@IncludeGpu pp_vis_draw.h
|
||||||
|
|
||||||
//- Impl
|
//- Impl
|
||||||
@IncludeC pp_vis_widgets.c
|
@IncludeC pp_vis_widgets.c
|
||||||
@IncludeC pp_vis_core.c
|
@IncludeC pp_vis_core.c
|
||||||
|
@IncludeGpu pp_vis_draw.gpu
|
||||||
|
|
||||||
//- Embeds
|
//- Embeds
|
||||||
@EmbedDir V_Resources pp_vis_res
|
@EmbedDir V_Resources pp_vis_res
|
||||||
|
|
||||||
|
//- Shaders
|
||||||
|
@VertexShader V_DQuadVS
|
||||||
|
@PixelShader V_DQuadPS
|
||||||
|
|
||||||
//- Startup
|
//- Startup
|
||||||
@Startup V_Startup
|
@Startup V_Startup
|
||||||
|
|||||||
@ -32,17 +32,22 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
Arena *frame_arena = AcquireArena(Gibi(64));
|
Arena *frame_arena = AcquireArena(Gibi(64));
|
||||||
Arena *perm = PermArena();
|
Arena *perm = PermArena();
|
||||||
|
|
||||||
i64 gpu_fence_target = 0;
|
//////////////////////////////
|
||||||
u64 frame_gen = 0;
|
//- State
|
||||||
|
|
||||||
Struct(VisPersist)
|
Fence *gpu_fence = GPU_FenceFromQueue(GPU_QueueKind_Direct);
|
||||||
|
i64 gpu_fence_target = 0;
|
||||||
|
i64 frame_gen = 0;
|
||||||
|
GPU_Resource *draw_target = 0;
|
||||||
|
|
||||||
|
Struct(Persist)
|
||||||
{
|
{
|
||||||
V_CommandsWidget commands_widget;
|
V_CommandsWidget commands_widget;
|
||||||
b32 ui_debug;
|
b32 ui_debug;
|
||||||
b32 show_command_palette;
|
b32 show_command_palette;
|
||||||
b32 show_console;
|
b32 show_console;
|
||||||
};
|
};
|
||||||
VisPersist persist = ZI;
|
Persist persist = ZI;
|
||||||
String window_restore = ZI;
|
String window_restore = ZI;
|
||||||
|
|
||||||
Button held_buttons[Button_Count] = ZI;
|
Button held_buttons[Button_Count] = ZI;
|
||||||
@ -87,7 +92,7 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
BB_Reader br = BB_ReaderFromBuff(&bb);
|
BB_Reader br = BB_ReaderFromBuff(&bb);
|
||||||
|
|
||||||
String swap_str = BB_ReadString(scratch.arena, &br);
|
String swap_str = BB_ReadString(scratch.arena, &br);
|
||||||
if (swap_str.len == sizeof(VisPersist))
|
if (swap_str.len == sizeof(Persist))
|
||||||
{
|
{
|
||||||
CopyBytes(&persist, swap_str.text, swap_str.len);
|
CopyBytes(&persist, swap_str.text, swap_str.len);
|
||||||
}
|
}
|
||||||
@ -102,14 +107,8 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Arena *world_arena = AcquireArena(Gibi(64));
|
||||||
Arena *ents_arena = AcquireArena(Gibi(64));
|
S_World *world = PushStruct(world_arena, S_World);
|
||||||
S_Ent *ents = ArenaFirst(ents_arena, S_Ent);
|
|
||||||
i64 tick = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
b32 shutdown = 0;
|
b32 shutdown = 0;
|
||||||
while (!shutdown)
|
while (!shutdown)
|
||||||
@ -120,11 +119,13 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
//- Begin vis frame
|
//- Begin vis frame
|
||||||
|
|
||||||
UI_FrameFlag ui_frame_flags = 0;
|
UI_FrameFlag ui_frame_flags = 0;
|
||||||
|
Vec4 swapchain_color = V_GetWidgetTheme().window_background_color;
|
||||||
ui_frame_flags |= UI_FrameFlag_Debug * !!persist.ui_debug;
|
ui_frame_flags |= UI_FrameFlag_Debug * !!persist.ui_debug;
|
||||||
ui_frame_flags |= UI_FrameFlag_Vsync * !!VSYNC;
|
ui_frame_flags |= UI_FrameFlag_Vsync * !!VSYNC;
|
||||||
UI_Frame ui_frame = UI_BeginFrame(ui_frame_flags);
|
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 */
|
||||||
{
|
{
|
||||||
@ -142,8 +143,8 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
UI_Push(ChildLayoutAxis, Axis_Y);
|
UI_Push(ChildLayoutAxis, Axis_Y);
|
||||||
UI_Push(Width, UI_GROW(1, 0));
|
UI_Push(Width, UI_GROW(1, 0));
|
||||||
UI_Push(Height, UI_GROW(1, 0));
|
UI_Push(Height, UI_GROW(1, 0));
|
||||||
UI_Push(Parent, UI_BuildColumnEx(UI_KeyF("AAH")));
|
UI_Key vis_box = UI_KeyF("vis box");
|
||||||
|
UI_Push(Parent, UI_BuildColumnEx(vis_box));
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Pop sim output
|
//- Pop sim output
|
||||||
@ -160,6 +161,12 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
}
|
}
|
||||||
UnlockTicketMutex(&sim_shared->output_back_tm);
|
UnlockTicketMutex(&sim_shared->output_back_tm);
|
||||||
|
|
||||||
|
if (sim_output->last_snapshot_node && sim_output->last_snapshot_node->snapshot.tick > world->tick)
|
||||||
|
{
|
||||||
|
ResetArena(world_arena);
|
||||||
|
world = S_WorldFromSnapshot(world_arena, &sim_output->last_snapshot_node->snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process controller events vis cmds
|
//- Process controller events vis cmds
|
||||||
|
|
||||||
@ -329,13 +336,53 @@ JobDef(V_VisWorker, sig, job_id)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Render
|
//- Render
|
||||||
|
|
||||||
|
/* Acquire draw target */
|
||||||
{
|
{
|
||||||
|
if (draw_target && !MatchVec2I32(draw_size, GPU_GetTextureSize2D(draw_target)))
|
||||||
|
{
|
||||||
|
YieldOnFence(gpu_fence, gpu_fence_target);
|
||||||
|
GPU_ReleaseResource(draw_target, GPU_ReleaseFlag_None);
|
||||||
|
draw_target = 0;
|
||||||
|
}
|
||||||
|
if (!draw_target)
|
||||||
|
{
|
||||||
|
GPU_ResourceDesc desc = ZI;
|
||||||
|
desc.kind = GPU_ResourceKind_Texture2D;
|
||||||
|
desc.flags = GPU_ResourceFlag_Writable | GPU_ResourceFlag_Renderable;
|
||||||
|
desc.texture.format = GPU_Format_R16G16B16A16_Float;
|
||||||
|
desc.clear_color = LinearFromSrgb(swapchain_color);
|
||||||
|
draw_target = GPU_AcquireResource(desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GPU_CommandList *cl = GPU_BeginCommandList(GPU_QueueKind_Direct);
|
||||||
|
{
|
||||||
|
/* Prep draw target */
|
||||||
|
{
|
||||||
|
GPU_TransitionToRenderable(cl, draw_target, 0);
|
||||||
|
GPU_ClearRenderable(cl, draw_target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prep shapes pass */
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Shapes pass */
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Transition draw target for UI composition */
|
||||||
|
{
|
||||||
|
GPU_TransitionToReadable(cl, draw_target);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gpu_fence_target = GPU_EndCommandList(cl);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- End vis frame
|
//- End vis frame
|
||||||
|
|
||||||
|
UI_SetRawTexture(vis_box, draw_target, VEC2(0, 0), VEC2(1, 1));
|
||||||
gpu_fence_target = UI_EndFrame(ui_frame);
|
gpu_fence_target = UI_EndFrame(ui_frame);
|
||||||
|
|
||||||
++frame_gen;
|
++frame_gen;
|
||||||
|
|||||||
49
src/proto/pp_vis/pp_vis_draw.gpu
Normal file
49
src/proto/pp_vis/pp_vis_draw.gpu
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
ConstantBuffer<V_DQuadSig> V_dquad_sig : register (b0);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Quad
|
||||||
|
|
||||||
|
Struct(V_DQuadPS_Input)
|
||||||
|
{
|
||||||
|
|
||||||
|
Semantic(Vec4, sv_position);
|
||||||
|
Semantic(nointerpolation u32, quad_idx);
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(V_DQuadPS_Output)
|
||||||
|
{
|
||||||
|
Semantic(Vec4, sv_target0);
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Vertex shader
|
||||||
|
|
||||||
|
V_DQuadPS_Input VSDef(V_DQuadVS, Semantic(u32, sv_instanceid), Semantic(u32, sv_vertexid))
|
||||||
|
{
|
||||||
|
ConstantBuffer<V_DQuadSig> sig = V_dquad_sig;
|
||||||
|
StructuredBuffer<V_DQuad> quads = UniformResourceFromRid(sig.quads);
|
||||||
|
V_DQuad quad = quads[sv_instanceid];
|
||||||
|
|
||||||
|
Vec2 rect_uv = RectUvFromVertexId(sv_vertexid);
|
||||||
|
// Vec2 tex_uv = lerp(quad.tex_uv0, quad.tex_uv1, rect_uv);
|
||||||
|
// Vec2 screen_vert = lerp(quad.p0, quad.p1, rect_uv);
|
||||||
|
Vec2 screen_vert = 0;
|
||||||
|
|
||||||
|
V_DQuadPS_Input result;
|
||||||
|
result.sv_position = Vec4(NdcFromViewport(sig.viewport_size, screen_vert).xy, 0, 1);
|
||||||
|
result.quad_idx = sv_instanceid;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Pixel shader
|
||||||
|
V_DQuadPS_Output PSDef(V_DQuadPS, V_DQuadPS_Input input)
|
||||||
|
{
|
||||||
|
ConstantBuffer<V_DQuadSig> sig = V_dquad_sig;
|
||||||
|
StructuredBuffer<V_DQuad> quads = UniformResourceFromRid(sig.quads);
|
||||||
|
V_DQuad quad = quads[input.quad_idx];
|
||||||
|
|
||||||
|
Vec4 final_color = 0;
|
||||||
|
|
||||||
|
V_DQuadPS_Output output;
|
||||||
|
output.sv_target0 = final_color;
|
||||||
|
return output;
|
||||||
|
}
|
||||||
28
src/proto/pp_vis/pp_vis_draw.h
Normal file
28
src/proto/pp_vis/pp_vis_draw.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ 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;
|
||||||
|
};
|
||||||
341
src/ui/ui_core.c
341
src/ui/ui_core.c
@ -376,31 +376,48 @@ UI_Key UI_BuildBoxEx(UI_Key key)
|
|||||||
{
|
{
|
||||||
UI_State *g = &UI_state;
|
UI_State *g = &UI_state;
|
||||||
UI_CmdNode *n = PushStruct(g->bframe.cmds_arena, UI_CmdNode);
|
UI_CmdNode *n = PushStruct(g->bframe.cmds_arena, UI_CmdNode);
|
||||||
|
n->cmd.kind = UI_CmdKind_BuildBox;
|
||||||
{
|
{
|
||||||
n->cmd.key = key;
|
n->cmd.box.key = key;
|
||||||
n->cmd.parent = UI_UseTop(Parent);
|
n->cmd.box.parent = UI_UseTop(Parent);
|
||||||
n->cmd.flags = UI_UseTop(Flags);
|
n->cmd.box.flags = UI_UseTop(Flags);
|
||||||
n->cmd.pref_size[Axis_X] = UI_UseTop(Width);
|
n->cmd.box.pref_size[Axis_X] = UI_UseTop(Width);
|
||||||
n->cmd.pref_size[Axis_Y] = UI_UseTop(Height);
|
n->cmd.box.pref_size[Axis_Y] = UI_UseTop(Height);
|
||||||
n->cmd.child_alignment[Axis_X] = UI_UseTop(ChildAlignmentX);
|
n->cmd.box.child_alignment[Axis_X] = UI_UseTop(ChildAlignmentX);
|
||||||
n->cmd.child_alignment[Axis_Y] = UI_UseTop(ChildAlignmentY);
|
n->cmd.box.child_alignment[Axis_Y] = UI_UseTop(ChildAlignmentY);
|
||||||
n->cmd.child_layout_axis = UI_UseTop(ChildLayoutAxis);
|
n->cmd.box.child_layout_axis = UI_UseTop(ChildLayoutAxis);
|
||||||
n->cmd.background_color = UI_UseTop(BackgroundColor);
|
n->cmd.box.background_color = UI_UseTop(BackgroundColor);
|
||||||
n->cmd.border_color = UI_UseTop(BorderColor);
|
n->cmd.box.border_color = UI_UseTop(BorderColor);
|
||||||
n->cmd.debug_color = UI_UseTop(DebugColor);
|
n->cmd.box.debug_color = UI_UseTop(DebugColor);
|
||||||
n->cmd.tint = UI_UseTop(Tint);
|
n->cmd.box.tint = UI_UseTop(Tint);
|
||||||
n->cmd.border = UI_UseTop(Border);
|
n->cmd.box.border = UI_UseTop(Border);
|
||||||
n->cmd.font_resource = UI_UseTop(Font);
|
n->cmd.box.font_resource = UI_UseTop(Font);
|
||||||
n->cmd.font_size = UI_UseTop(FontSize);
|
n->cmd.box.font_size = UI_UseTop(FontSize);
|
||||||
n->cmd.rounding = UI_UseTop(Rounding);
|
n->cmd.box.rounding = UI_UseTop(Rounding);
|
||||||
n->cmd.text = UI_UseTop(Text);
|
n->cmd.box.text = UI_UseTop(Text);
|
||||||
n->cmd.floating_pos = UI_UseTop(FloatingPos);
|
n->cmd.box.floating_pos = UI_UseTop(FloatingPos);
|
||||||
}
|
}
|
||||||
++g->bframe.cmds_count;
|
++g->bframe.cmds_count;
|
||||||
SllQueuePush(g->bframe.first_cmd_node, g->bframe.last_cmd_node, n);
|
SllQueuePush(g->bframe.first_cmd_node, g->bframe.last_cmd_node, n);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UI_SetRawTexture(UI_Key key, GPU_Resource *texture, Vec2 uv0, Vec2 uv1)
|
||||||
|
{
|
||||||
|
UI_State *g = &UI_state;
|
||||||
|
UI_CmdNode *n = PushStruct(g->bframe.cmds_arena, UI_CmdNode);
|
||||||
|
n->cmd.kind = UI_CmdKind_SetRawTexture;
|
||||||
|
{
|
||||||
|
n->cmd.set_raw_texture.key = key;
|
||||||
|
n->cmd.set_raw_texture.texture = texture;
|
||||||
|
n->cmd.set_raw_texture.uv0 = uv0;
|
||||||
|
n->cmd.set_raw_texture.uv1 = uv1;
|
||||||
|
}
|
||||||
|
++g->bframe.cmds_count;
|
||||||
|
SllQueuePush(g->bframe.first_cmd_node, g->bframe.last_cmd_node, n);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Report
|
//~ Report
|
||||||
|
|
||||||
@ -421,7 +438,7 @@ UI_Report UI_ReportFromKey(UI_Key key)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Begin frame
|
//~ Begin frame
|
||||||
|
|
||||||
UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags)
|
UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
|
||||||
{
|
{
|
||||||
UI_State *g = &UI_state;
|
UI_State *g = &UI_state;
|
||||||
UI_Frame result = ZI;
|
UI_Frame result = ZI;
|
||||||
@ -474,6 +491,7 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g->bframe.frame_flags = frame_flags;
|
g->bframe.frame_flags = frame_flags;
|
||||||
|
g->bframe.swapchain_color = swapchain_color;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Begin window frame
|
//- Begin window frame
|
||||||
@ -509,7 +527,7 @@ UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags)
|
|||||||
for (u64 pre_index = g->boxes_count; pre_index-- > 0;)
|
for (u64 pre_index = g->boxes_count; pre_index-- > 0;)
|
||||||
{
|
{
|
||||||
UI_Box *box = g->eframe.boxes_pre[pre_index];
|
UI_Box *box = g->eframe.boxes_pre[pre_index];
|
||||||
if (hovered_box == 0 && box->cmd.flags & UI_BoxFlag_Interactable)
|
if (hovered_box == 0 && box->desc.flags & UI_BoxFlag_Interactable)
|
||||||
{
|
{
|
||||||
b32 is_cursor_in_box = 0;
|
b32 is_cursor_in_box = 0;
|
||||||
{
|
{
|
||||||
@ -713,104 +731,125 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Process commands
|
//- Process commands
|
||||||
|
|
||||||
|
/* FIXME: Reset raw texture data */
|
||||||
|
|
||||||
g->boxes_count = 0;
|
g->boxes_count = 0;
|
||||||
|
|
||||||
for (UI_CmdNode *cmd_node = g->bframe.first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
for (UI_CmdNode *cmd_node = g->bframe.first_cmd_node; cmd_node; cmd_node = cmd_node->next)
|
||||||
{
|
{
|
||||||
UI_Cmd cmd = cmd_node->cmd;
|
UI_Cmd cmd = cmd_node->cmd;
|
||||||
|
|
||||||
UI_Key key = cmd.key;
|
switch (cmd.kind)
|
||||||
if (key.hash == 0)
|
|
||||||
{
|
{
|
||||||
key = UI_TransKey();
|
case UI_CmdKind_BuildBox:
|
||||||
}
|
|
||||||
|
|
||||||
b32 is_root = g->eframe.root_box == 0;
|
|
||||||
UI_Box *parent = 0;
|
|
||||||
if (!is_root)
|
|
||||||
{
|
|
||||||
parent = UI_BoxFromKey(cmd.parent);
|
|
||||||
if (!parent)
|
|
||||||
{
|
{
|
||||||
parent = g->eframe.root_box;
|
UI_Key key = cmd.box.key;
|
||||||
}
|
if (key.hash == 0)
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate box */
|
|
||||||
UI_Box *box = 0;
|
|
||||||
{
|
|
||||||
UI_BoxBin *bin = &g->box_bins[key.hash % UI_NumBoxLookupBins];
|
|
||||||
for (UI_Box *tmp = bin->first; tmp && !box; tmp = tmp->next_in_bin)
|
|
||||||
{
|
|
||||||
if (tmp->key.hash == key.hash)
|
|
||||||
{
|
{
|
||||||
box = tmp;
|
key = UI_TransKey();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (box)
|
b32 is_root = g->eframe.root_box == 0;
|
||||||
{
|
UI_Box *parent = 0;
|
||||||
/* Remove box from old parent */
|
if (!is_root)
|
||||||
if (box->parent)
|
|
||||||
{
|
{
|
||||||
DllQueueRemove(box->parent->first, box->parent->last, box);
|
parent = UI_BoxFromKey(cmd.box.parent);
|
||||||
--box->parent->count;
|
if (!parent)
|
||||||
|
{
|
||||||
|
parent = g->eframe.root_box;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
/* Allocate box */
|
||||||
|
UI_Box *box = 0;
|
||||||
|
{
|
||||||
|
UI_BoxBin *bin = &g->box_bins[key.hash % UI_NumBoxLookupBins];
|
||||||
|
for (UI_Box *tmp = bin->first; tmp && !box; tmp = tmp->next_in_bin)
|
||||||
|
{
|
||||||
|
if (tmp->key.hash == key.hash)
|
||||||
|
{
|
||||||
|
box = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (box)
|
||||||
|
{
|
||||||
|
/* Remove box from old parent */
|
||||||
|
if (box->parent)
|
||||||
|
{
|
||||||
|
DllQueueRemove(box->parent->first, box->parent->last, box);
|
||||||
|
--box->parent->count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box = g->first_free_box;
|
||||||
|
if (box)
|
||||||
|
{
|
||||||
|
SllStackPop(g->first_free_box);
|
||||||
|
ZeroStruct(box);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
box = PushStruct(g->box_arena, UI_Box);
|
||||||
|
}
|
||||||
|
DllQueuePushNP(bin->first, bin->last, box, next_in_bin, prev_in_bin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++g->boxes_count;
|
||||||
|
|
||||||
|
/* Reset box */
|
||||||
|
UI_Box old_box = *box;
|
||||||
|
{
|
||||||
|
ZeroStruct(box);
|
||||||
|
box->next_in_bin = old_box.next_in_bin;
|
||||||
|
box->prev_in_bin = old_box.prev_in_bin;
|
||||||
|
box->report = old_box.report;
|
||||||
|
}
|
||||||
|
box->key = key;
|
||||||
|
box->last_updated_tick = g->eframe.tick;
|
||||||
|
|
||||||
|
/* Update box */
|
||||||
|
{
|
||||||
|
box->desc = cmd.box;
|
||||||
|
|
||||||
|
/* Insert box into parent */
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
DllQueuePush(parent->first, parent->last, box);
|
||||||
|
box->parent = parent;
|
||||||
|
++parent->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prefetch font */
|
||||||
|
if (box->desc.text.len > 0)
|
||||||
|
{
|
||||||
|
box->font = F_LoadFontAsync(box->desc.font_resource, box->desc.font_size);
|
||||||
|
if (box->font)
|
||||||
|
{
|
||||||
|
box->glyph_run = F_RunFromString(g->eframe.layout_arena, box->font, box->desc.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_root)
|
||||||
|
{
|
||||||
|
g->eframe.root_box = box;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case UI_CmdKind_SetRawTexture:
|
||||||
{
|
{
|
||||||
box = g->first_free_box;
|
UI_Key key = cmd.set_raw_texture.key;
|
||||||
|
UI_Box *box = UI_BoxFromKey(key);
|
||||||
if (box)
|
if (box)
|
||||||
{
|
{
|
||||||
SllStackPop(g->first_free_box);
|
box->raw_texture = cmd.set_raw_texture.texture;
|
||||||
ZeroStruct(box);
|
box->raw_texture_uv0 = cmd.set_raw_texture.uv0;
|
||||||
|
box->raw_texture_uv1 = cmd.set_raw_texture.uv1;
|
||||||
}
|
}
|
||||||
else
|
} break;
|
||||||
{
|
|
||||||
box = PushStruct(g->box_arena, UI_Box);
|
|
||||||
}
|
|
||||||
DllQueuePushNP(bin->first, bin->last, box, next_in_bin, prev_in_bin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++g->boxes_count;
|
|
||||||
|
|
||||||
/* Reset box */
|
|
||||||
UI_Box old_box = *box;
|
|
||||||
{
|
|
||||||
ZeroStruct(box);
|
|
||||||
box->next_in_bin = old_box.next_in_bin;
|
|
||||||
box->prev_in_bin = old_box.prev_in_bin;
|
|
||||||
box->report = old_box.report;
|
|
||||||
}
|
|
||||||
box->key = key;
|
|
||||||
box->last_updated_tick = g->eframe.tick;
|
|
||||||
|
|
||||||
/* Update box */
|
|
||||||
{
|
|
||||||
box->cmd = cmd;
|
|
||||||
|
|
||||||
/* Insert box into parent */
|
|
||||||
if (parent)
|
|
||||||
{
|
|
||||||
DllQueuePush(parent->first, parent->last, box);
|
|
||||||
box->parent = parent;
|
|
||||||
++parent->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prefetch font */
|
|
||||||
if (box->cmd.text.len > 0)
|
|
||||||
{
|
|
||||||
box->font = F_LoadFontAsync(box->cmd.font_resource, box->cmd.font_size);
|
|
||||||
if (box->font)
|
|
||||||
{
|
|
||||||
box->glyph_run = F_RunFromString(g->eframe.layout_arena, box->font, box->cmd.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_root)
|
|
||||||
{
|
|
||||||
g->eframe.root_box = box;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
@ -855,7 +894,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
/* Push floating children to dfs stack */
|
/* Push floating children to dfs stack */
|
||||||
for (UI_Box *child = box->last; child; child = child->prev)
|
for (UI_Box *child = box->last; child; child = child->prev)
|
||||||
{
|
{
|
||||||
if (AnyBit(child->cmd.flags, UI_BoxFlag_Floating))
|
if (AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
BoxNode *child_n = PushStruct(scratch.arena, BoxNode);
|
BoxNode *child_n = PushStruct(scratch.arena, BoxNode);
|
||||||
child_n->box = child;
|
child_n->box = child;
|
||||||
@ -865,7 +904,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
/* Push non-floating children to dfs stack */
|
/* Push non-floating children to dfs stack */
|
||||||
for (UI_Box *child = box->last; child; child = child->prev)
|
for (UI_Box *child = box->last; child; child = child->prev)
|
||||||
{
|
{
|
||||||
if (!AnyBit(child->cmd.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
BoxNode *child_n = PushStruct(scratch.arena, BoxNode);
|
BoxNode *child_n = PushStruct(scratch.arena, BoxNode);
|
||||||
child_n->box = child;
|
child_n->box = child;
|
||||||
@ -893,12 +932,12 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
|
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
|
||||||
{
|
{
|
||||||
UI_Size pref_size = box->cmd.pref_size[axis];
|
UI_Size pref_size = box->desc.pref_size[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Pixel)
|
if (pref_size.kind == UI_SizeKind_Pixel)
|
||||||
{
|
{
|
||||||
box->solved_dims[axis] = pref_size.v;
|
box->solved_dims[axis] = pref_size.v;
|
||||||
}
|
}
|
||||||
else if (pref_size.kind == UI_SizeKind_Shrink && AnyBit(box->cmd.flags, UI_BoxFlag_DrawText))
|
else if (pref_size.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
||||||
{
|
{
|
||||||
/* TODO: Distinguish between baseline alignment & visual alignment */
|
/* TODO: Distinguish between baseline alignment & visual alignment */
|
||||||
f32 text_size = 0;
|
f32 text_size = 0;
|
||||||
@ -929,16 +968,16 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
if (box->parent)
|
if (box->parent)
|
||||||
{
|
{
|
||||||
Axis axis = box->parent->cmd.child_layout_axis;
|
Axis axis = box->parent->desc.child_layout_axis;
|
||||||
UI_Size pref_size = box->cmd.pref_size[axis];
|
UI_Size pref_size = box->desc.pref_size[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Grow)
|
if (pref_size.kind == UI_SizeKind_Grow)
|
||||||
{
|
{
|
||||||
f32 match_size = 0;
|
f32 match_size = 0;
|
||||||
b32 found_match = 0;
|
b32 found_match = 0;
|
||||||
for (UI_Box *ancestor = box->parent; ancestor != 0 && !found_match; ancestor = ancestor->parent)
|
for (UI_Box *ancestor = box->parent; ancestor != 0 && !found_match; ancestor = ancestor->parent)
|
||||||
{
|
{
|
||||||
UI_Size ancestor_size = ancestor->cmd.pref_size[axis];
|
UI_Size ancestor_size = ancestor->desc.pref_size[axis];
|
||||||
if (ancestor_size.kind == UI_SizeKind_Pixel || (ancestor_size.kind == UI_SizeKind_Shrink && AnyBit(box->cmd.flags, UI_BoxFlag_DrawText)))
|
if (ancestor_size.kind == UI_SizeKind_Pixel || (ancestor_size.kind == UI_SizeKind_Shrink && AnyBit(box->desc.flags, UI_BoxFlag_DrawText)))
|
||||||
{
|
{
|
||||||
/* Match independent ancestor */
|
/* Match independent ancestor */
|
||||||
match_size = ancestor->solved_dims[axis];
|
match_size = ancestor->solved_dims[axis];
|
||||||
@ -956,15 +995,15 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
UI_Box *box = boxes_post[post_index];
|
UI_Box *box = boxes_post[post_index];
|
||||||
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
|
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
|
||||||
{
|
{
|
||||||
UI_Size pref_size = box->cmd.pref_size[axis];
|
UI_Size pref_size = box->desc.pref_size[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Shrink && !AnyBit(box->cmd.flags, UI_BoxFlag_DrawText))
|
if (pref_size.kind == UI_SizeKind_Shrink && !AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
|
||||||
{
|
{
|
||||||
f32 accum = 0;
|
f32 accum = 0;
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
{
|
{
|
||||||
if (!AnyBit(child->cmd.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
if (axis == box->cmd.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
{
|
{
|
||||||
accum += child->solved_dims[axis];
|
accum += child->solved_dims[axis];
|
||||||
}
|
}
|
||||||
@ -985,8 +1024,8 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
if (box->parent)
|
if (box->parent)
|
||||||
{
|
{
|
||||||
Axis axis = !box->parent->cmd.child_layout_axis;
|
Axis axis = !box->parent->desc.child_layout_axis;
|
||||||
UI_Size pref_size = box->cmd.pref_size[axis];
|
UI_Size pref_size = box->desc.pref_size[axis];
|
||||||
if (pref_size.kind == UI_SizeKind_Grow)
|
if (pref_size.kind == UI_SizeKind_Grow)
|
||||||
{
|
{
|
||||||
box->solved_dims[axis] = box->parent->solved_dims[axis] * pref_size.v;
|
box->solved_dims[axis] = box->parent->solved_dims[axis] * pref_size.v;
|
||||||
@ -1007,12 +1046,12 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
f32 flex_accum = 0;
|
f32 flex_accum = 0;
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
{
|
{
|
||||||
if (!AnyBit(child->cmd.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->cmd.pref_size[axis].strictness;
|
f32 strictness = child->desc.pref_size[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
if (axis == box->cmd.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
{
|
{
|
||||||
size_accum += size;
|
size_accum += size;
|
||||||
flex_accum += flex;
|
flex_accum += flex;
|
||||||
@ -1030,13 +1069,13 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
f32 adjusted_size_accum = 0;
|
f32 adjusted_size_accum = 0;
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
{
|
{
|
||||||
if (!AnyBit(child->cmd.flags, UI_BoxFlag_Floating))
|
if (!AnyBit(child->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
f32 strictness = child->cmd.pref_size[axis].strictness;
|
f32 strictness = child->desc.pref_size[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
f32 new_size = size;
|
f32 new_size = size;
|
||||||
if (axis == box->cmd.child_layout_axis)
|
if (axis == box->desc.child_layout_axis)
|
||||||
{
|
{
|
||||||
f32 chopoff = MinF32(flex, violation * (flex / flex_accum));
|
f32 chopoff = MinF32(flex, violation * (flex / flex_accum));
|
||||||
new_size = size - chopoff;
|
new_size = size - chopoff;
|
||||||
@ -1059,12 +1098,12 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
/* Solve floating violations */
|
/* Solve floating violations */
|
||||||
for (UI_Box *child = box->first; child; child = child->next)
|
for (UI_Box *child = box->first; child; child = child->next)
|
||||||
{
|
{
|
||||||
if (AnyBit(child->cmd.flags, UI_BoxFlag_Floating) && !AnyBit(child->cmd.flags, UI_BoxFlag_NoFloatingClamp))
|
if (AnyBit(child->desc.flags, UI_BoxFlag_Floating) && !AnyBit(child->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
f32 size = child->solved_dims[axis];
|
f32 size = child->solved_dims[axis];
|
||||||
if (size > box_size)
|
if (size > box_size)
|
||||||
{
|
{
|
||||||
f32 strictness = child->cmd.pref_size[axis].strictness;
|
f32 strictness = child->desc.pref_size[axis].strictness;
|
||||||
f32 flex = size * (1.0 - strictness);
|
f32 flex = size * (1.0 - strictness);
|
||||||
child->solved_dims[axis] = MaxF32(size - flex, box_size);
|
child->solved_dims[axis] = MaxF32(size - flex, box_size);
|
||||||
}
|
}
|
||||||
@ -1081,8 +1120,8 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
|
|
||||||
/* Initialize layout cursor based on alignment */
|
/* Initialize layout cursor based on alignment */
|
||||||
{
|
{
|
||||||
Axis axis = box->cmd.child_layout_axis;
|
Axis axis = box->desc.child_layout_axis;
|
||||||
UI_AxisAlignment alignment = box->cmd.child_alignment[axis];
|
UI_AxisAlignment alignment = box->desc.child_alignment[axis];
|
||||||
f32 box_size = box->solved_dims[axis];
|
f32 box_size = box->solved_dims[axis];
|
||||||
f32 size_accum = box->final_children_size_accum[axis];
|
f32 size_accum = box->final_children_size_accum[axis];
|
||||||
switch(alignment)
|
switch(alignment)
|
||||||
@ -1106,11 +1145,11 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
Vec2 final_pos = ZI;
|
Vec2 final_pos = ZI;
|
||||||
|
|
||||||
/* Floating box position */
|
/* Floating box position */
|
||||||
if (AnyBit(box->cmd.flags, UI_BoxFlag_Floating))
|
if (AnyBit(box->desc.flags, UI_BoxFlag_Floating))
|
||||||
{
|
{
|
||||||
Vec2 offset = box->cmd.floating_pos;
|
Vec2 offset = box->desc.floating_pos;
|
||||||
final_pos = AddVec2(parent->p0, offset);
|
final_pos = AddVec2(parent->p0, offset);
|
||||||
if (!AnyBit(box->cmd.flags, UI_BoxFlag_NoFloatingClamp))
|
if (!AnyBit(box->desc.flags, UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->p1.x);
|
f32 overshoot = MaxF32(0, (final_pos.x + dims_vec.x) - parent->p1.x);
|
||||||
@ -1129,13 +1168,13 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
f32 offset[2] = ZI;
|
f32 offset[2] = ZI;
|
||||||
/* Calculate offset in layout direction */
|
/* Calculate offset in layout direction */
|
||||||
{
|
{
|
||||||
Axis axis = parent->cmd.child_layout_axis;
|
Axis axis = parent->desc.child_layout_axis;
|
||||||
offset[axis] = layout_cursor;
|
offset[axis] = layout_cursor;
|
||||||
}
|
}
|
||||||
/* Calculate offset in non-layout direction (based on alignment) */
|
/* Calculate offset in non-layout direction (based on alignment) */
|
||||||
{
|
{
|
||||||
Axis axis = !parent->cmd.child_layout_axis;
|
Axis axis = !parent->desc.child_layout_axis;
|
||||||
UI_AxisAlignment alignment = parent->cmd.child_alignment[axis];
|
UI_AxisAlignment alignment = parent->desc.child_alignment[axis];
|
||||||
switch(alignment)
|
switch(alignment)
|
||||||
{
|
{
|
||||||
default: break;
|
default: break;
|
||||||
@ -1155,7 +1194,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
}
|
}
|
||||||
final_pos.x = parent->p0.x + offset[0];
|
final_pos.x = parent->p0.x + offset[0];
|
||||||
final_pos.y = parent->p0.y + offset[1];
|
final_pos.y = parent->p0.y + offset[1];
|
||||||
parent->layout_cursor += dims_arr[parent->cmd.child_layout_axis];
|
parent->layout_cursor += dims_arr[parent->desc.child_layout_axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Submit position */
|
/* Submit position */
|
||||||
@ -1167,7 +1206,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
|
|
||||||
/* Rounding */
|
/* Rounding */
|
||||||
{
|
{
|
||||||
UI_Round rounding = box->cmd.rounding;
|
UI_Round rounding = box->desc.rounding;
|
||||||
Vec2 half_dims = MulVec2(SubVec2(box->p1, box->p0), 0.5);
|
Vec2 half_dims = MulVec2(SubVec2(box->p1, box->p0), 0.5);
|
||||||
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
f32 min_half_dims = MinF32(half_dims.x, half_dims.y);
|
||||||
f32 final_rounding_tl = 0;
|
f32 final_rounding_tl = 0;
|
||||||
@ -1194,7 +1233,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent && !AllBits(box->cmd.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
if (parent && !AllBits(box->desc.flags, UI_BoxFlag_Floating | UI_BoxFlag_NoFloatingClamp))
|
||||||
{
|
{
|
||||||
Vec2 vtl = SubVec2(VEC2(parent->p0.x, parent->p0.y), VEC2(box->p0.x, box->p0.y));
|
Vec2 vtl = SubVec2(VEC2(parent->p0.x, parent->p0.y), VEC2(box->p0.x, box->p0.y));
|
||||||
Vec2 vtr = SubVec2(VEC2(parent->p1.x, parent->p0.y), VEC2(box->p1.x, box->p0.y));
|
Vec2 vtr = SubVec2(VEC2(parent->p1.x, parent->p0.y), VEC2(box->p1.x, box->p0.y));
|
||||||
@ -1225,7 +1264,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
{
|
{
|
||||||
UI_Box *box = boxes_pre[pre_index];
|
UI_Box *box = boxes_pre[pre_index];
|
||||||
b32 is_visible = 1;
|
b32 is_visible = 1;
|
||||||
is_visible = is_visible && (box->cmd.tint.w != 0);
|
is_visible = is_visible && (box->desc.tint.w != 0);
|
||||||
is_visible = is_visible && (box->p1.x > box->p0.x);
|
is_visible = is_visible && (box->p1.x > box->p0.x);
|
||||||
is_visible = is_visible && (box->p1.y > box->p0.y);
|
is_visible = is_visible && (box->p1.y > box->p0.y);
|
||||||
if (is_visible || AnyBit(g->bframe.frame_flags, UI_FrameFlag_Debug))
|
if (is_visible || AnyBit(g->bframe.frame_flags, UI_FrameFlag_Debug))
|
||||||
@ -1233,32 +1272,32 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
/* Box rect */
|
/* Box rect */
|
||||||
{
|
{
|
||||||
UI_DRect *rect = PushStruct(g->eframe.rects_arena, UI_DRect);
|
UI_DRect *rect = PushStruct(g->eframe.rects_arena, UI_DRect);
|
||||||
rect->flags |= UI_DRectFlag_DrawTexture * !!(box->cmd.background_texture != 0);
|
rect->flags |= UI_DRectFlag_DrawTexture * !!(box->raw_texture != 0);
|
||||||
rect->p0 = box->p0;
|
rect->p0 = box->p0;
|
||||||
rect->p1 = box->p1;
|
rect->p1 = box->p1;
|
||||||
rect->tex_uv0 = VEC2(0, 0);
|
rect->tex_uv0 = VEC2(0, 0);
|
||||||
rect->tex_uv1 = VEC2(1, 1);
|
rect->tex_uv1 = VEC2(1, 1);
|
||||||
rect->background_lin = LinearFromSrgb(box->cmd.background_color);
|
rect->background_lin = LinearFromSrgb(box->desc.background_color);
|
||||||
rect->border_lin = LinearFromSrgb(box->cmd.border_color);
|
rect->border_lin = LinearFromSrgb(box->desc.border_color);
|
||||||
rect->debug_lin = LinearFromSrgb(box->cmd.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
rect->tint_lin = LinearFromSrgb(box->cmd.tint);
|
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
||||||
rect->border = box->cmd.border;
|
rect->border = box->desc.border;
|
||||||
rect->tl_rounding = box->rounding_tl;
|
rect->tl_rounding = box->rounding_tl;
|
||||||
rect->tr_rounding = box->rounding_tr;
|
rect->tr_rounding = box->rounding_tr;
|
||||||
rect->br_rounding = box->rounding_br;
|
rect->br_rounding = box->rounding_br;
|
||||||
rect->bl_rounding = box->rounding_bl;
|
rect->bl_rounding = box->rounding_bl;
|
||||||
|
|
||||||
/* Texture */
|
/* Texture */
|
||||||
if (box->cmd.background_texture != 0)
|
if (box->raw_texture != 0)
|
||||||
{
|
{
|
||||||
rect->tex = GPU_Texture2DRidFromResource(box->cmd.background_texture);
|
rect->tex = GPU_Texture2DRidFromResource(box->raw_texture);
|
||||||
rect->tex_uv0 = box->cmd.background_texture_uv0;
|
rect->tex_uv0 = box->raw_texture_uv0;
|
||||||
rect->tex_uv1 = box->cmd.background_texture_uv1;
|
rect->tex_uv1 = box->raw_texture_uv1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text rects */
|
/* Text rects */
|
||||||
if (AnyBit(box->cmd.flags, UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font)
|
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText) && box->glyph_run.count > 0 && box->font)
|
||||||
{
|
{
|
||||||
Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture);
|
Texture2DRid tex_rid = GPU_Texture2DRidFromResource(box->font->texture);
|
||||||
Vec2 inv_font_image_size = VEC2(1.0f / (f32)box->font->image_width, 1.0f / (f32)box->font->image_height);
|
Vec2 inv_font_image_size = VEC2(1.0f / (f32)box->font->image_width, 1.0f / (f32)box->font->image_height);
|
||||||
@ -1268,7 +1307,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
b32 should_truncate = run.count > 0 && (run.rects[run.count - 1].pos + run.rects[run.count - 1].advance) > max_baseline;
|
b32 should_truncate = run.count > 0 && (run.rects[run.count - 1].pos + run.rects[run.count - 1].advance) > max_baseline;
|
||||||
|
|
||||||
/* Truncate run */
|
/* Truncate run */
|
||||||
if (should_truncate && !AnyBit(box->cmd.flags, UI_BoxFlag_NoTextTruncation))
|
if (should_truncate && !AnyBit(box->desc.flags, UI_BoxFlag_NoTextTruncation))
|
||||||
{
|
{
|
||||||
/* Get elipses run */
|
/* Get elipses run */
|
||||||
F_Run trunc_run = F_RunFromString(scratch.arena, box->font, Lit("..."));
|
F_Run trunc_run = F_RunFromString(scratch.arena, box->font, Lit("..."));
|
||||||
@ -1305,8 +1344,8 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
run.rects = new_rects;
|
run.rects = new_rects;
|
||||||
}
|
}
|
||||||
|
|
||||||
UI_AxisAlignment x_alignment = box->cmd.child_alignment[Axis_X];
|
UI_AxisAlignment x_alignment = box->desc.child_alignment[Axis_X];
|
||||||
UI_AxisAlignment y_alignment = box->cmd.child_alignment[Axis_Y];
|
UI_AxisAlignment y_alignment = box->desc.child_alignment[Axis_Y];
|
||||||
if (should_truncate)
|
if (should_truncate)
|
||||||
{
|
{
|
||||||
x_alignment = UI_AxisAlignment_Start;
|
x_alignment = UI_AxisAlignment_Start;
|
||||||
@ -1373,8 +1412,8 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
rect->p0 = AddVec2(baseline, VEC2(rr.pos, 0));
|
rect->p0 = AddVec2(baseline, VEC2(rr.pos, 0));
|
||||||
rect->p0 = AddVec2(rect->p0, rr.offset);
|
rect->p0 = AddVec2(rect->p0, rr.offset);
|
||||||
rect->p1 = AddVec2(rect->p0, glyph_size);
|
rect->p1 = AddVec2(rect->p0, glyph_size);
|
||||||
rect->debug_lin = LinearFromSrgb(box->cmd.debug_color);
|
rect->debug_lin = LinearFromSrgb(box->desc.debug_color);
|
||||||
rect->tint_lin = LinearFromSrgb(box->cmd.tint);
|
rect->tint_lin = LinearFromSrgb(box->desc.tint);
|
||||||
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size);
|
rect->tex_uv0 = MulVec2Vec2(atlas_p0, inv_font_image_size);
|
||||||
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size);
|
rect->tex_uv1 = MulVec2Vec2(atlas_p1, inv_font_image_size);
|
||||||
rect->tex = tex_rid;
|
rect->tex = tex_rid;
|
||||||
@ -1467,7 +1506,7 @@ i64 UI_EndFrame(UI_Frame frame)
|
|||||||
Vec2I32 dst_p1 = VEC2I32(0, 0);
|
Vec2I32 dst_p1 = VEC2I32(0, 0);
|
||||||
Vec2I32 src_p0 = VEC2I32(0, 0);
|
Vec2I32 src_p0 = VEC2I32(0, 0);
|
||||||
Vec2I32 src_p1 = draw_size;
|
Vec2I32 src_p1 = draw_size;
|
||||||
g->eframe.gpu_submit_fence_target = GPU_PresentSwapchain(g->eframe.swapchain, g->eframe.render_target, AnyBit(g->bframe.frame_flags, UI_FrameFlag_Vsync), backbuffer_size, dst_p0, dst_p1, src_p0, src_p1);
|
g->eframe.gpu_submit_fence_target = GPU_PresentSwapchain(g->eframe.swapchain, g->eframe.render_target, AnyBit(g->bframe.frame_flags, UI_FrameFlag_Vsync), backbuffer_size, dst_p0, dst_p1, src_p0, src_p1, LinearFromSrgb(g->bframe.swapchain_color));
|
||||||
}
|
}
|
||||||
WND_EndFrame(frame.window_frame);
|
WND_EndFrame(frame.window_frame);
|
||||||
|
|
||||||
|
|||||||
@ -194,17 +194,20 @@ Struct(UI_Report)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Command types
|
//~ Command types
|
||||||
|
|
||||||
Struct(UI_Cmd)
|
Enum(UI_CmdKind)
|
||||||
|
{
|
||||||
|
UI_CmdKind_None,
|
||||||
|
UI_CmdKind_BuildBox,
|
||||||
|
UI_CmdKind_SetRawTexture,
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(UI_BoxDesc)
|
||||||
{
|
{
|
||||||
UI_BoxFlag flags;
|
UI_BoxFlag flags;
|
||||||
|
|
||||||
UI_Key key;
|
UI_Key key;
|
||||||
UI_Key parent;
|
UI_Key parent;
|
||||||
|
|
||||||
GPU_Resource *background_texture;
|
|
||||||
Vec2 background_texture_uv0;
|
|
||||||
Vec2 background_texture_uv1;
|
|
||||||
|
|
||||||
UI_Size pref_size[Axis_CountXY];
|
UI_Size pref_size[Axis_CountXY];
|
||||||
UI_Round rounding;
|
UI_Round rounding;
|
||||||
Vec4 background_color;
|
Vec4 background_color;
|
||||||
@ -220,6 +223,22 @@ Struct(UI_Cmd)
|
|||||||
UI_AxisAlignment child_alignment[Axis_CountXY];
|
UI_AxisAlignment child_alignment[Axis_CountXY];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Struct(UI_Cmd)
|
||||||
|
{
|
||||||
|
UI_CmdKind kind;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
UI_BoxDesc box;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UI_Key key;
|
||||||
|
GPU_Resource *texture;
|
||||||
|
Vec2 uv0;
|
||||||
|
Vec2 uv1;
|
||||||
|
} set_raw_texture;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
Struct(UI_CmdNode)
|
Struct(UI_CmdNode)
|
||||||
{
|
{
|
||||||
UI_CmdNode *next;
|
UI_CmdNode *next;
|
||||||
@ -248,7 +267,10 @@ Struct(UI_Box)
|
|||||||
u64 count;
|
u64 count;
|
||||||
|
|
||||||
//- Cmd data
|
//- Cmd data
|
||||||
UI_Cmd cmd;
|
UI_BoxDesc desc;
|
||||||
|
GPU_Resource *raw_texture;
|
||||||
|
Vec2 raw_texture_uv0;
|
||||||
|
Vec2 raw_texture_uv1;
|
||||||
|
|
||||||
//- Pre-layout data
|
//- Pre-layout data
|
||||||
u64 pre_index;
|
u64 pre_index;
|
||||||
@ -333,6 +355,7 @@ Struct(UI_State)
|
|||||||
UI_Key active_box;
|
UI_Key active_box;
|
||||||
|
|
||||||
/* Cmds */
|
/* Cmds */
|
||||||
|
Vec4 swapchain_color;
|
||||||
UI_FrameFlag frame_flags;
|
UI_FrameFlag frame_flags;
|
||||||
UI_CmdNode *first_cmd_node;
|
UI_CmdNode *first_cmd_node;
|
||||||
UI_CmdNode *last_cmd_node;
|
UI_CmdNode *last_cmd_node;
|
||||||
@ -449,6 +472,8 @@ UI_Style UI_PopStyle(UI_StyleDesc desc);
|
|||||||
UI_Key UI_BuildBoxEx(UI_Key key);
|
UI_Key UI_BuildBoxEx(UI_Key key);
|
||||||
#define UI_BuildBox() UI_BuildBoxEx(UI_TransKey())
|
#define UI_BuildBox() UI_BuildBoxEx(UI_TransKey())
|
||||||
|
|
||||||
|
void UI_SetRawTexture(UI_Key key, GPU_Resource *texture, Vec2 uv0, Vec2 uv1);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Report
|
//~ Report
|
||||||
|
|
||||||
@ -457,7 +482,7 @@ UI_Report UI_ReportFromKey(UI_Key key);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Begin frame
|
//~ Begin frame
|
||||||
|
|
||||||
UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags);
|
UI_Frame UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Frame helpers
|
//~ Frame helpers
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user