line shape drawing
This commit is contained in:
parent
df2f7f0f1b
commit
331da6edba
@ -3,6 +3,7 @@ S_SharedState S_shared_state = ZI;
|
|||||||
Readonly S_Ent S_nil_ent = {
|
Readonly S_Ent S_nil_ent = {
|
||||||
.local_to_parent_xf = CompXformIdentity,
|
.local_to_parent_xf = CompXformIdentity,
|
||||||
.final_local_to_world_xf = CompXformIdentity,
|
.final_local_to_world_xf = CompXformIdentity,
|
||||||
|
.tint = { 0.5, 0.5, 0.5, 1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -151,7 +152,7 @@ S_Ent *S_EntFromKey(S_Lookup *lookup, S_Key key)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Iteration helpers
|
//~ Iteration helpers
|
||||||
|
|
||||||
void S_ResetIter(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind)
|
S_Ent *S_FirstEntEx(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind)
|
||||||
{
|
{
|
||||||
iter->kind = kind;
|
iter->kind = kind;
|
||||||
iter->lookup = lookup;
|
iter->lookup = lookup;
|
||||||
@ -175,6 +176,7 @@ void S_ResetIter(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_Iter
|
|||||||
n->ent_key = key;
|
n->ent_key = key;
|
||||||
SllStackPush(iter->first_dfs, n);
|
SllStackPush(iter->first_dfs, n);
|
||||||
}
|
}
|
||||||
|
return S_NextEnt(arena, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter)
|
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter)
|
||||||
@ -374,7 +376,7 @@ JobDef(S_SimWorker, _, __)
|
|||||||
lookup = S_LookupFromWorld(frame_arena, world);
|
lookup = S_LookupFromWorld(frame_arena, world);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Rebuild entity tree
|
//- Build entity tree
|
||||||
|
|
||||||
{
|
{
|
||||||
/* Reset tree links */
|
/* Reset tree links */
|
||||||
@ -454,9 +456,21 @@ JobDef(S_SimWorker, _, __)
|
|||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Update entities from user control
|
//- Update entities from user control
|
||||||
|
|
||||||
S_ResetIter(frame_arena, &iter, &lookup, S_RootKey, S_IterKind_Pre);
|
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter))
|
||||||
for (S_Ent *ent = S_NextEnt(frame_arena, &iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter))
|
|
||||||
{
|
{
|
||||||
|
if (!S_IsKeyNil(ent->camera))
|
||||||
|
{
|
||||||
|
ent->local_to_parent_xf.og.x += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Compute final world transforms
|
||||||
|
|
||||||
|
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter))
|
||||||
|
{
|
||||||
|
S_Ent *parent = S_EntFromKey(&lookup, ent->parent);
|
||||||
|
ent->final_local_to_world_xf = MulXform(parent->final_local_to_world_xf, ent->local_to_parent_xf);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
//~ Key types
|
//~ Key types
|
||||||
|
|
||||||
#define S_NilKey ((S_Key) { 0 })
|
#define S_NilKey ((S_Key) { 0 })
|
||||||
#define S_RootKey ((S_Key) { .v.hi = 0x75ebb7a47d1ca753, .v.lo = 0x2d505fc8961e5576 })
|
#define S_RootKey ((S_Key) { .v.hi = 0xaaaaaaaaaaaaaaaa, .v.lo = 0xaaaaaaaaaaaaaaaa })
|
||||||
|
|
||||||
Struct(S_Key)
|
Struct(S_Key)
|
||||||
{
|
{
|
||||||
@ -43,7 +43,9 @@ Struct(S_Ent)
|
|||||||
S_Key key;
|
S_Key key;
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
//- Pre-solve data
|
//- Build data
|
||||||
|
|
||||||
|
Vec4 tint;
|
||||||
|
|
||||||
S_Key follow;
|
S_Key follow;
|
||||||
S_Key camera;
|
S_Key camera;
|
||||||
@ -241,7 +243,8 @@ S_Ent *S_EntFromKey(S_Lookup *lookup, S_Key key);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Iteration helpers
|
//~ Iteration helpers
|
||||||
|
|
||||||
void S_ResetIter(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind);
|
#define S_FirstEnt(arena, iter, lookup) S_FirstEntEx((arena), (iter), (lookup), S_RootKey, S_IterKind_Pre)
|
||||||
|
S_Ent *S_FirstEntEx(Arena *arena, S_Iter *iter, S_Lookup *lookup, S_Key key, S_IterKind kind);
|
||||||
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter);
|
S_Ent *S_NextEnt(Arena *arena, S_Iter *iter);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@ -28,9 +28,10 @@ void V_Shutdown(void)
|
|||||||
void V_PushTestEnts(Arena *arena, S_EntList *list)
|
void V_PushTestEnts(Arena *arena, S_EntList *list)
|
||||||
{
|
{
|
||||||
S_Key player_key = S_RandKey();
|
S_Key player_key = S_RandKey();
|
||||||
|
S_Key child_key = S_RandKey();
|
||||||
S_Key camera_key = S_RandKey();
|
S_Key camera_key = S_RandKey();
|
||||||
|
|
||||||
i32 count = 2;
|
i32 count = 3;
|
||||||
for (u64 i = 0; i < count; ++i)
|
for (u64 i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
S_EntListNode *n = PushStruct(arena, S_EntListNode);
|
S_EntListNode *n = PushStruct(arena, S_EntListNode);
|
||||||
@ -43,24 +44,42 @@ void V_PushTestEnts(Arena *arena, S_EntList *list)
|
|||||||
/* Test player */
|
/* Test player */
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
|
ent->tint = Color_Red;
|
||||||
ent->key = player_key;
|
ent->key = player_key;
|
||||||
ent->camera = camera_key;
|
ent->camera = camera_key;
|
||||||
|
|
||||||
{
|
{
|
||||||
S_Shape *shape = &ent->local_shape;
|
S_Shape *shape = &ent->local_shape;
|
||||||
shape->points_count = 4;
|
shape->points_count = 4;
|
||||||
shape->points[0] = VEC2(100, 100);
|
shape->points[0] = VEC2(100, 100);
|
||||||
shape->points[1] = VEC2(200, 100);
|
shape->points[1] = VEC2(200, 100);
|
||||||
shape->points[2] = VEC2(150, 200);
|
shape->points[2] = VEC2(200, 200);
|
||||||
shape->points[3] = VEC2(125, 200);
|
shape->points[3] = VEC2(100, 200);
|
||||||
// shape->radius = 1;
|
shape->radius = 0;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
/* Test child */
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
ent->tint = Color_Cyan;
|
||||||
|
ent->key = child_key;
|
||||||
|
ent->parent = player_key;
|
||||||
|
{
|
||||||
|
S_Shape *shape = &ent->local_shape;
|
||||||
|
shape->points_count = 1;
|
||||||
|
shape->points[0] = VEC2(100, 100);
|
||||||
|
// shape->points[1] = VEC2(200, 100);
|
||||||
|
// shape->points[2] = VEC2(150, 200);
|
||||||
|
// shape->points[3] = VEC2(125, 200);
|
||||||
|
shape->radius = 20;
|
||||||
|
// ent->local_to_parent_xf = XformFromPos(VEC2(500, 500));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
/* Test camera */
|
/* Test camera */
|
||||||
case 1:
|
case 2:
|
||||||
{
|
{
|
||||||
ent->key = camera_key;
|
// ent->key = camera_key;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -417,19 +436,16 @@ JobDef(V_VisWorker, _, __)
|
|||||||
//- Build render data
|
//- Build render data
|
||||||
|
|
||||||
/* Build shapes */
|
/* Build shapes */
|
||||||
S_ResetIter(frame_arena, &iter, &lookup, S_RootKey, S_IterKind_Pre);
|
for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter))
|
||||||
for (S_Ent *ent = S_NextEnt(frame_arena, &iter); !S_IsEntNil(ent); ent = S_NextEnt(frame_arena, &iter))
|
{
|
||||||
|
b32 is_visible = ent->tint.w != 0;
|
||||||
|
if (is_visible)
|
||||||
{
|
{
|
||||||
Xform xf = ent->final_local_to_world_xf;
|
Xform xf = ent->final_local_to_world_xf;
|
||||||
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
|
S_Shape shape = S_MulXformShape(ent->final_local_to_world_xf, ent->local_shape);
|
||||||
for (i32 point_idx = 0; point_idx < shape.points_count; ++point_idx)
|
Vec4 color = ent->tint;
|
||||||
{
|
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), 16, V_DrawFlag_Line);
|
||||||
Vec2 *p = &shape.points[point_idx];
|
|
||||||
*p = MulXformV2(xf, *p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec4 color = Color_Red;
|
|
||||||
V_DrawShape(dverts_arena, dvert_idx_arena, shape, LinearFromSrgb(color), 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|||||||
@ -1,15 +1,112 @@
|
|||||||
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail)
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Shape helpers
|
||||||
|
|
||||||
|
void V_DrawPoly(Arena *verts_arena, Arena *idx_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags)
|
||||||
|
{
|
||||||
|
if (flags & V_DrawFlag_Line)
|
||||||
|
{
|
||||||
|
i32 verts_count = points.count;
|
||||||
|
if (verts_count >= 2)
|
||||||
{
|
{
|
||||||
TempArena scratch = BeginScratchNoConflict();
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
|
||||||
Vec2Array draw_points = ZI;
|
|
||||||
if (shape.radius == 0)
|
|
||||||
{
|
{
|
||||||
draw_points.points = shape.points;
|
f32 half_thickness = 1;
|
||||||
draw_points.count = shape.points_count;
|
i32 lines_count = verts_count == 2 ? 1 : verts_count;
|
||||||
|
i32 line_verts_count = lines_count * 4;
|
||||||
|
i32 idx_count = lines_count * 6;
|
||||||
|
i32 idx_offset = ArenaCount(verts_arena, V_DVert);
|
||||||
|
|
||||||
|
/* Push dverts */
|
||||||
|
V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, line_verts_count);
|
||||||
|
for (i32 line_idx = 0; line_idx < lines_count; ++line_idx)
|
||||||
|
{
|
||||||
|
i32 a_idx = line_idx;
|
||||||
|
i32 b_idx = line_idx + 1;
|
||||||
|
if (b_idx >= lines_count)
|
||||||
|
{
|
||||||
|
b_idx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2 a = points.points[a_idx];
|
||||||
|
Vec2 b = points.points[b_idx];
|
||||||
|
|
||||||
|
Vec2 a_to_b = SubVec2(b, a);
|
||||||
|
Vec2 perp = Vec2WithLen(PerpVec2(a_to_b), half_thickness);
|
||||||
|
|
||||||
|
Vec2 p0 = AddVec2(a, perp);
|
||||||
|
Vec2 p1 = SubVec2(a, perp);
|
||||||
|
Vec2 p2 = SubVec2(b, perp);
|
||||||
|
Vec2 p3 = AddVec2(b, perp);
|
||||||
|
|
||||||
|
i32 offset = line_idx * 4;
|
||||||
|
dverts[offset + 0] = (V_DVert) { .pos = p0, .color_lin = color_lin };
|
||||||
|
dverts[offset + 1] = (V_DVert) { .pos = p1, .color_lin = color_lin };
|
||||||
|
dverts[offset + 2] = (V_DVert) { .pos = p2, .color_lin = color_lin };
|
||||||
|
dverts[offset + 3] = (V_DVert) { .pos = p3, .color_lin = color_lin };
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate indices */
|
||||||
|
i32 *indices = PushStructsNoZero(idx_arena, i32, idx_count);
|
||||||
|
for (i32 line_idx = 0; line_idx < lines_count; ++line_idx)
|
||||||
|
{
|
||||||
|
i32 indices_offset = line_idx * 6;
|
||||||
|
i32 vert_idx_offset = idx_offset + (line_idx * 4);
|
||||||
|
indices[indices_offset + 0] = vert_idx_offset + 0;
|
||||||
|
indices[indices_offset + 1] = vert_idx_offset + 1;
|
||||||
|
indices[indices_offset + 2] = vert_idx_offset + 2;
|
||||||
|
indices[indices_offset + 3] = vert_idx_offset + 0;
|
||||||
|
indices[indices_offset + 4] = vert_idx_offset + 2;
|
||||||
|
indices[indices_offset + 5] = vert_idx_offset + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EndScratch(scratch);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
i32 verts_count = points.count;
|
||||||
|
if (verts_count >= 3)
|
||||||
|
{
|
||||||
|
i32 idx_offset = ArenaCount(verts_arena, V_DVert);
|
||||||
|
i32 tris_count = verts_count - 2;
|
||||||
|
i32 idx_count = tris_count * 3;
|
||||||
|
|
||||||
|
/* Push dverts */
|
||||||
|
V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, verts_count);
|
||||||
|
for (i32 point_idx = 0; point_idx < (i32)points.count; ++point_idx)
|
||||||
|
{
|
||||||
|
V_DVert *dvert = &dverts[point_idx];
|
||||||
|
dvert->pos = points.points[point_idx];
|
||||||
|
dvert->color_lin = color_lin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate indices in a fan pattern */
|
||||||
|
i32 *indices = PushStructsNoZero(idx_arena, i32, idx_count);
|
||||||
|
for (i32 i = 0; i < tris_count; ++i)
|
||||||
|
{
|
||||||
|
i32 tri_offset = i * 3;
|
||||||
|
indices[tri_offset + 0] = idx_offset;
|
||||||
|
indices[tri_offset + 1] = idx_offset + i + 1;
|
||||||
|
indices[tri_offset + 2] = idx_offset + i + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags)
|
||||||
|
{
|
||||||
|
if (shape.radius == 0)
|
||||||
|
{
|
||||||
|
Vec2Array draw_points = ZI;
|
||||||
|
draw_points.points = shape.points;
|
||||||
|
draw_points.count = shape.points_count;
|
||||||
|
V_DrawPoly(verts_arena, idx_arena, draw_points, color_lin, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TempArena scratch = BeginScratchNoConflict();
|
||||||
|
{
|
||||||
|
Vec2Array draw_points = ZI;
|
||||||
draw_points.points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
draw_points.points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
||||||
draw_points.count = detail;
|
draw_points.count = detail;
|
||||||
for (i32 i = 0; i < detail; ++i)
|
for (i32 i = 0; i < detail; ++i)
|
||||||
@ -19,33 +116,8 @@ void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color
|
|||||||
Vec2 sp = S_SupportPointFromShape(shape, dir);
|
Vec2 sp = S_SupportPointFromShape(shape, dir);
|
||||||
draw_points.points[i] = sp;
|
draw_points.points[i] = sp;
|
||||||
}
|
}
|
||||||
|
V_DrawPoly(verts_arena, idx_arena, draw_points, color_lin, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 verts_count = draw_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)draw_points.count; ++point_idx)
|
|
||||||
{
|
|
||||||
V_DVert *dvert = &dverts[point_idx];
|
|
||||||
dvert->pos = draw_points.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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EndScratch(scratch);
|
EndScratch(scratch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1 +1,14 @@
|
|||||||
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail);
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Flag types
|
||||||
|
|
||||||
|
Enum(V_DrawFlag)
|
||||||
|
{
|
||||||
|
V_DrawFlag_None = 0,
|
||||||
|
V_DrawFlag_Line = (1 << 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Shape helpers
|
||||||
|
|
||||||
|
void V_DrawPoly(Arena *verts_arena, Arena *idx_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags);
|
||||||
|
void V_DrawShape(Arena *verts_arena, Arena *idx_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user