draw layer refactor
This commit is contained in:
parent
3d863022fb
commit
2d953cca9b
@ -245,7 +245,7 @@ void P_AppStartup(String args_str)
|
||||
S_StartupReceipt sprite_sr = sprite_startup();
|
||||
M_StartupReceipt mixer_sr = mixer_startup();
|
||||
SND_StartupReceipt sound_sr = sound_startup(&asset_cache_sr);
|
||||
D_StartupReceipt draw_sr = draw_startup(&font_sr);
|
||||
D_StartupReceipt draw_sr = D_Startup(&font_sr);
|
||||
SimStartupReceipt sim_sr = sim_startup();
|
||||
|
||||
/* Interface systems */
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
Struct(Vec2) {
|
||||
f32 x, y;
|
||||
};
|
||||
#define VEC2(x, y) CppCompatInitListType(Vec2) { (x), (y) }
|
||||
|
||||
Struct(Vec2Array) {
|
||||
Vec2 *points;
|
||||
@ -21,6 +22,7 @@ Struct(Vec2Array) {
|
||||
Struct(Vec3) {
|
||||
f32 x, y, z;
|
||||
};
|
||||
#define VEC3(x, y, z) CppCompatInitListType(Vec3) { (x), (y), (z) }
|
||||
|
||||
Struct(Vec3Array) {
|
||||
Vec3 *points;
|
||||
@ -33,6 +35,7 @@ Struct(Vec3Array) {
|
||||
Struct(Vec4) {
|
||||
f32 x, y, z, w;
|
||||
};
|
||||
#define VEC4(x, y, z, w) ((Vec4) { (x), (y), (z), (w) })
|
||||
|
||||
Struct(Vec4Array) {
|
||||
Vec4 *points;
|
||||
@ -45,6 +48,7 @@ Struct(Vec4Array) {
|
||||
Struct(Vec2I32) {
|
||||
i32 x, y;
|
||||
};
|
||||
#define VEC2I32(x, y) CppCompatInitListType(Vec2I32) { (x), (y) }
|
||||
|
||||
////////////////////////////////
|
||||
//~ Integer vector3 types
|
||||
@ -52,6 +56,7 @@ Struct(Vec2I32) {
|
||||
Struct(Vec3I32) {
|
||||
i32 x, y, z;
|
||||
};
|
||||
#define VEC3I32(x, y, z) CppCompatInitListType(Vec3I32) { (x), (y), (z) }
|
||||
|
||||
////////////////////////////////
|
||||
//~ Xform types
|
||||
@ -245,7 +250,6 @@ i64 LerpI64(i64 val0, i64 val1, f64 t);
|
||||
////////////////////////////////
|
||||
//~ Vec2 operations
|
||||
|
||||
#define VEC2(x, y) CppCompatInitListType(Vec2) { (x), (y) }
|
||||
#define Vec2FromVec2I32(v) VEC2((v).x, (v).y)
|
||||
|
||||
b32 IsVec2Zero(Vec2 a);
|
||||
@ -300,30 +304,14 @@ Vec2 ClosestPointFromRay(Vec2 ray_pos, Vec2 ray_dir_norm, Vec2 p);
|
||||
Vec2 LerpVec2(Vec2 val0, Vec2 val1, f32 t);
|
||||
Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Vec3 operations
|
||||
|
||||
#define VEC3(x, y, z) ((Vec3) { (x), (y), (z) })
|
||||
|
||||
////////////////////////////////
|
||||
//~ Vec4 operations
|
||||
|
||||
#define VEC4(x, y, z, w) ((Vec4) { (x), (y), (z), (w) })
|
||||
|
||||
////////////////////////////////
|
||||
//~ Vec2I32 Operations
|
||||
|
||||
#define VEC2I32(x, y) CppCompatInitListType(Vec2I32) { (x), (y) }
|
||||
b32 EqVec2I32(Vec2I32 a, Vec2I32 b);
|
||||
Vec2I32 NegVec2I32(Vec2I32 a);
|
||||
Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b);
|
||||
Vec2I32 SubVec2I32(Vec2I32 a, Vec2I32 b);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Vec3I32 operations
|
||||
|
||||
#define VEC3I32(x, y, z) CppCompatInitListType(Vec3I32) { (x), (y), (z) }
|
||||
|
||||
////////////////////////////////
|
||||
//~ Xform operations
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ CLD_Shape CLD_ShapeFromQuad(Quad quad)
|
||||
////////////////////////////////
|
||||
//~ Menkowski support point
|
||||
|
||||
CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore)
|
||||
CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore)
|
||||
{
|
||||
Vec2 *points = shape->points;
|
||||
u32 count = shape->count;
|
||||
@ -37,7 +37,8 @@ CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec
|
||||
dir = RotateVec2(dir, -RotationFromXform(xf));
|
||||
dir = MulVec2Vec2(dir, ScaleFromXform(xf));
|
||||
|
||||
if (count == 1) {
|
||||
if (count == 1)
|
||||
{
|
||||
/* Skip 'ignore' on single point colliders */
|
||||
ignore = -1;
|
||||
}
|
||||
@ -45,20 +46,24 @@ CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec
|
||||
Vec2 furthest = ZI;
|
||||
u32 furthest_index = 0;
|
||||
f32 furthest_dot = -F32Infinity;
|
||||
for (u32 i = 0; i < count; ++i) {
|
||||
if ((i32)i == ignore) {
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
{
|
||||
if ((i32)i == ignore)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Vec2 p = points[i];
|
||||
f32 dot = DotVec2(dir, p);
|
||||
if (dot > furthest_dot) {
|
||||
if (dot > furthest_dot)
|
||||
{
|
||||
furthest = p;
|
||||
furthest_dot = dot;
|
||||
furthest_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (radius > 0.0) {
|
||||
if (radius > 0.0)
|
||||
{
|
||||
dir = Vec2WithLen(dir, radius);
|
||||
furthest = AddVec2(furthest, dir);
|
||||
}
|
||||
@ -73,7 +78,7 @@ CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec
|
||||
|
||||
CLD_SupportPoint CLD_SupportPointFromDir(CLD_Shape *shape, Xform xf, Vec2 dir)
|
||||
{
|
||||
return CLD_SupportPointFromDirInternal(shape, xf, dir, -1);
|
||||
return CLD_SupportPointFromDirEx(shape, xf, dir, -1);
|
||||
}
|
||||
|
||||
CLD_MenkowskiPoint CLD_MenkowskiPointFromDir(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir)
|
||||
@ -151,15 +156,19 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
Vec2 removed_a = ZI;
|
||||
Vec2 removed_b = ZI;
|
||||
u32 num_removed = 0;
|
||||
for (;;) {
|
||||
if (s.len == 1) {
|
||||
for (;;)
|
||||
{
|
||||
if (s.len == 1)
|
||||
{
|
||||
//- Find second point in simplex
|
||||
/* Second point is support point towards origin */
|
||||
dir = NegVec2(s.a.p);
|
||||
|
||||
CLD_DBGSTEP;
|
||||
m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
/* Check that new point is far enough away from existing point */
|
||||
if (Vec2LenSq(SubVec2(m.p, s.a.p)) < min_unique_pt_dist_sq) {
|
||||
if (Vec2LenSq(SubVec2(m.p, s.a.p)) < min_unique_pt_dist_sq)
|
||||
{
|
||||
overlapping = 0;
|
||||
break;
|
||||
}
|
||||
@ -172,6 +181,7 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
}
|
||||
|
||||
{
|
||||
//- Find third point in simplex
|
||||
CLD_DBGSTEP;
|
||||
m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
/* Check that new point is far enough away from existing points */
|
||||
@ -182,7 +192,8 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
(Vec2LenSq(SubVec2(m.p, removed_a)) < min_unique_pt_dist_sq) ||
|
||||
(num_removed >= 2 && Vec2LenSq(SubVec2(m.p, removed_b)) < min_unique_pt_dist_sq))
|
||||
) ||
|
||||
AbsF32(WedgeVec2(SubVec2(s.b.p, s.a.p), SubVec2(m.p, s.a.p))) < min_unique_pt_dist_sq) {
|
||||
AbsF32(WedgeVec2(SubVec2(s.b.p, s.a.p), SubVec2(m.p, s.a.p))) < min_unique_pt_dist_sq)
|
||||
{
|
||||
overlapping = 0;
|
||||
break;
|
||||
}
|
||||
@ -193,14 +204,15 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
|
||||
if ((AbsF32(WedgeVec2(SubVec2(s.b.p, s.a.p), NegVec2(s.a.p))) <= min_unique_pt_dist_sq) ||
|
||||
(AbsF32(WedgeVec2(SubVec2(s.c.p, s.b.p), NegVec2(s.b.p))) <= min_unique_pt_dist_sq) ||
|
||||
(AbsF32(WedgeVec2(SubVec2(s.c.p, s.a.p), NegVec2(s.a.p))) <= min_unique_pt_dist_sq)) {
|
||||
(AbsF32(WedgeVec2(SubVec2(s.c.p, s.a.p), NegVec2(s.a.p))) <= min_unique_pt_dist_sq))
|
||||
{
|
||||
/* Simplex lies on origin */
|
||||
overlapping = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine region of the simplex in which the origin lies */
|
||||
//- Determine region of the simplex in which the origin lies
|
||||
CLD_DBGSTEP;
|
||||
Vec2 vab = SubVec2(s.b.p, s.a.p);
|
||||
Vec2 vac = SubVec2(s.c.p, s.a.p);
|
||||
@ -218,48 +230,61 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
f32 vac_dot = DotVec2(vac, NegVec2(s.a.p)) / Vec2LenSq(vac);
|
||||
f32 vbc_dot = DotVec2(vbc, NegVec2(s.b.p)) / Vec2LenSq(vbc);
|
||||
|
||||
if (rab_dot >= 0 && vab_dot >= 0 && vab_dot <= 1) {
|
||||
/* Region ab, remove c */
|
||||
if (rab_dot >= 0 && vab_dot >= 0 && vab_dot <= 1)
|
||||
{
|
||||
//- Region ab, remove c
|
||||
num_removed = 1;
|
||||
removed_a = s.c.p;
|
||||
s.len = 2;
|
||||
dir = rab_dir; /* Next third point is in direction of region ab */
|
||||
} else if (rac_dot >= 0 && vac_dot >= 0 && vac_dot <= 1) {
|
||||
/* Region ac, remove b */
|
||||
}
|
||||
else if (rac_dot >= 0 && vac_dot >= 0 && vac_dot <= 1)
|
||||
{
|
||||
//- Region ac, remove b
|
||||
num_removed = 1;
|
||||
removed_a = s.b.p;
|
||||
s.len = 2;
|
||||
s.b = s.c;
|
||||
dir = rac_dir; /* Next third point is in direction of region ac */
|
||||
} else if (rbc_dot >= 0 && vbc_dot >= 0 && vbc_dot <= 1) {
|
||||
/* Region bc, remove a */
|
||||
}
|
||||
else if (rbc_dot >= 0 && vbc_dot >= 0 && vbc_dot <= 1)
|
||||
{
|
||||
//- Region bc, remove a
|
||||
num_removed = 1;
|
||||
removed_a = s.a.p;
|
||||
s.len = 2;
|
||||
s.a = s.b;
|
||||
s.b = s.c;
|
||||
dir = rbc_dir; /* Next third point is in direction of region bc */
|
||||
} else if (vab_dot <= 0 && vac_dot <= 0) {
|
||||
/* Region a, remove bc */
|
||||
}
|
||||
else if (vab_dot <= 0 && vac_dot <= 0)
|
||||
{
|
||||
//- Region a, remove bc
|
||||
num_removed = 2;
|
||||
removed_a = s.b.p;
|
||||
removed_b = s.c.p;
|
||||
s.len = 1;
|
||||
} else if (vab_dot >= 1 && vbc_dot <= 0) {
|
||||
/* Region b, remove ac */
|
||||
}
|
||||
else if (vab_dot >= 1 && vbc_dot <= 0)
|
||||
{
|
||||
//- Region b, remove ac
|
||||
num_removed = 2;
|
||||
removed_a = s.a.p;
|
||||
removed_b = s.c.p;
|
||||
s.len = 1;
|
||||
s.a = s.b;
|
||||
} else if (vac_dot >= 1 && vbc_dot >= 1) {
|
||||
/* Region c, remove ab */
|
||||
}
|
||||
else if (vac_dot >= 1 && vbc_dot >= 1)
|
||||
{
|
||||
//- Region c, remove ab
|
||||
num_removed = 2;
|
||||
removed_a = s.a.p;
|
||||
removed_b = s.b.p;
|
||||
s.len = 1;
|
||||
s.a = s.c;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No region, must be in simplex */
|
||||
overlapping = 1;
|
||||
break;
|
||||
@ -267,7 +292,7 @@ CLD_GjkData CLD_GjkDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
}
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
abort:
|
||||
abort :
|
||||
#endif
|
||||
|
||||
CLD_GjkData result = {
|
||||
@ -302,7 +327,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
|
||||
CLD_MenkowskiPoint *proto = 0;
|
||||
u32 proto_count = 0;
|
||||
if (gjk_result.overlapping) {
|
||||
if (gjk_result.overlapping)
|
||||
{
|
||||
CLD_MenkowskiSimplex s = gjk_result.simplex;
|
||||
proto = PushDry(scratch.arena, CLD_MenkowskiPoint);
|
||||
{
|
||||
@ -317,7 +343,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
i32 winding = WindingFromVec2(SubVec2(s.c.p, s.a.p), SubVec2(s.b.p, s.a.p));
|
||||
|
||||
u32 epa_iterations = 0;
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
++epa_iterations;
|
||||
|
||||
/* Find dir from origin to closest edge */
|
||||
@ -326,7 +353,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
CLD_MenkowskiPoint closest_a = ZI;
|
||||
CLD_MenkowskiPoint closest_b = ZI;
|
||||
u32 closest_b_index = 0;
|
||||
for (u32 i = 0; i < proto_count; ++i) {
|
||||
for (u32 i = 0; i < proto_count; ++i)
|
||||
{
|
||||
u32 a_index = i;
|
||||
u32 b_index = (i < proto_count - 1) ? (i + 1) : 0;
|
||||
CLD_MenkowskiPoint a = proto[a_index];
|
||||
@ -339,7 +367,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
Vec2 proj = AddVec2(a.p, MulVec2(vab, proj_ratio));
|
||||
|
||||
f32 proj_len_sq = Vec2LenSq(proj);
|
||||
if (proj_len_sq < closest_len_sq - min_unique_pt_dist_sq) {
|
||||
if (proj_len_sq < closest_len_sq - min_unique_pt_dist_sq)
|
||||
{
|
||||
closest_a = a;
|
||||
closest_b = b;
|
||||
closest_b_index = b_index;
|
||||
@ -378,16 +407,20 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
|
||||
f32 dot = DotVec2(vab, vam) / Vec2LenSq(vab);
|
||||
|
||||
if (dot >= -validity_epsilon && dot <= 1 - validity_epsilon && (WedgeVec2(vab, vam) * -winding) >= -validity_epsilon) {
|
||||
if (dot >= -validity_epsilon && dot <= 1 - validity_epsilon && (WedgeVec2(vab, vam) * -winding) >= -validity_epsilon)
|
||||
{
|
||||
/* New point is not between edge */
|
||||
valid = 0;
|
||||
} else if (Vec2LenSq(vam) < min_unique_pt_dist_sq || Vec2LenSq(vbm) < min_unique_pt_dist_sq) {
|
||||
}
|
||||
else if (Vec2LenSq(vam) < min_unique_pt_dist_sq || Vec2LenSq(vbm) < min_unique_pt_dist_sq)
|
||||
{
|
||||
/* New point is too close to existing */
|
||||
valid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid || epa_iterations >= max_iterations) {
|
||||
if (!valid || epa_iterations >= max_iterations)
|
||||
{
|
||||
normal = NormVec2(dir);
|
||||
closest_feature.a = closest_a;
|
||||
closest_feature.b = closest_b;
|
||||
@ -401,7 +434,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
++proto_count;
|
||||
|
||||
/* Shift points in prototype to make room */
|
||||
for (u32 i = proto_count - 1; i > closest_b_index; --i) {
|
||||
for (u32 i = proto_count - 1; i > closest_b_index; --i)
|
||||
{
|
||||
u32 shift_from = (i > 0) ? i - 1 : proto_count - 1;
|
||||
u32 shift_to = i;
|
||||
proto[shift_to] = proto[shift_from];
|
||||
@ -410,7 +444,9 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
/* Insert new point into prototype */
|
||||
proto[closest_b_index] = m;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = NormVec2(gjk_result.final_dir);
|
||||
closest_feature.len = gjk_result.simplex.len;
|
||||
closest_feature.a = gjk_result.simplex.a;
|
||||
@ -418,7 +454,7 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
}
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
abort:
|
||||
abort :
|
||||
#endif
|
||||
|
||||
CLD_EpaData result = {
|
||||
@ -429,7 +465,8 @@ CLD_EpaData CLD_EpaDataFromShapes(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf
|
||||
#if COLLIDER_DEBUG
|
||||
result.dbg_step = dbg_step;
|
||||
u32 len = MinU32(proto_count, countof(result.prototype.points));
|
||||
for (u32 i = 0; i < len; ++i) {
|
||||
for (u32 i = 0; i < len; ++i)
|
||||
{
|
||||
result.prototype.points[i] = proto[i].p;
|
||||
}
|
||||
result.prototype.len = len;
|
||||
@ -538,31 +575,40 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
CLD_DBGSTEP;
|
||||
|
||||
/* Determine collision */
|
||||
if (gjk_result.overlapping) {
|
||||
colliding = 1;
|
||||
} else {
|
||||
CLD_MenkowskiFeature f = epa_result.closest_feature;
|
||||
/* Shapes not overlapping, determine if distance between shapes within tolerance */
|
||||
if (f.len == 1) {
|
||||
Vec2 p = NegVec2(f.a.p);
|
||||
if (Vec2LenSq(p) <= (tolerance * tolerance)) {
|
||||
if (gjk_result.overlapping)
|
||||
{
|
||||
colliding = 1;
|
||||
}
|
||||
} else {
|
||||
else
|
||||
{
|
||||
CLD_MenkowskiFeature f = epa_result.closest_feature;
|
||||
/* Shapes not overlapping, determine if distance between shapes within tolerance */
|
||||
if (f.len == 1)
|
||||
{
|
||||
Vec2 p = NegVec2(f.a.p);
|
||||
if (Vec2LenSq(p) <= (tolerance * tolerance))
|
||||
{
|
||||
colliding = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Project origin to determine if distance is within tolerance. */
|
||||
Assert(f.len == 2);
|
||||
Vec2 vab = SubVec2(f.b.p, f.a.p);
|
||||
Vec2 vao = NegVec2(f.a.p);
|
||||
f32 ratio = ClampF32(DotVec2(vab, vao) / DotVec2(vab, vab), 0, 1);
|
||||
Vec2 p = AddVec2(f.a.p, MulVec2(vab, ratio));
|
||||
if (Vec2LenSq(p) <= (tolerance * tolerance)) {
|
||||
if (Vec2LenSq(p) <= (tolerance * tolerance))
|
||||
{
|
||||
colliding = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clip to determine final points */
|
||||
if (colliding) {
|
||||
if (colliding)
|
||||
{
|
||||
/* Max vertices must be < 16 to fit in 4 bit ids */
|
||||
StaticAssert(countof(shape0->points) <= 16);
|
||||
|
||||
@ -577,24 +623,35 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
CLD_SupportPoint b0 = f.b.s0;
|
||||
CLD_SupportPoint b1 = f.b.s1;
|
||||
/* FIXME: Manually account for shapes w/ 1 & 2 points */
|
||||
if (f.len == 2) {
|
||||
if (a0.i == b0.i) {
|
||||
if (shape0->count > 1) {
|
||||
b0 = CLD_SupportPointFromDirInternal(shape0, xf0, normal, b0.i);
|
||||
} else {
|
||||
if (f.len == 2)
|
||||
{
|
||||
if (a0.i == b0.i)
|
||||
{
|
||||
if (shape0->count > 1)
|
||||
{
|
||||
b0 = CLD_SupportPointFromDirEx(shape0, xf0, normal, b0.i);
|
||||
}
|
||||
else
|
||||
{
|
||||
collapse0 = 1;
|
||||
b0 = a0;
|
||||
}
|
||||
}
|
||||
if (a1.i == b1.i) {
|
||||
if (shape1->count > 1) {
|
||||
b1 = CLD_SupportPointFromDirInternal(shape1, xf1, NegVec2(normal), b1.i);
|
||||
} else {
|
||||
if (a1.i == b1.i)
|
||||
{
|
||||
if (shape1->count > 1)
|
||||
{
|
||||
b1 = CLD_SupportPointFromDirEx(shape1, xf1, NegVec2(normal), b1.i);
|
||||
}
|
||||
else
|
||||
{
|
||||
collapse1 = 1;
|
||||
b1 = a1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
collapse0 = 1;
|
||||
collapse1 = 1;
|
||||
b0 = a0;
|
||||
@ -607,13 +664,15 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
Vec2 vab1_norm = NormVec2(vab1);
|
||||
|
||||
/* Swap points based on normal direction for consistent clipping */
|
||||
if (WedgeVec2(normal, vab0) < 0) {
|
||||
if (WedgeVec2(normal, vab0) < 0)
|
||||
{
|
||||
CLD_SupportPoint tmp = a0;
|
||||
a0 = b0;
|
||||
b0 = tmp;
|
||||
vab0 = NegVec2(vab0);
|
||||
}
|
||||
if (WedgeVec2(normal, vab1) < 0) {
|
||||
if (WedgeVec2(normal, vab1) < 0)
|
||||
{
|
||||
CLD_SupportPoint tmp = a1;
|
||||
a1 = b1;
|
||||
b1 = tmp;
|
||||
@ -626,18 +685,26 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
collapse1 = collapse1 || AbsF32(WedgeVec2(normal, vab1_norm)) < collapse_epsilon;
|
||||
|
||||
/* Collapse lines into deepest point */
|
||||
if (collapse0) {
|
||||
if (DotVec2(normal, vab0) > 0) {
|
||||
if (collapse0)
|
||||
{
|
||||
if (DotVec2(normal, vab0) > 0)
|
||||
{
|
||||
a0 = b0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Remove this (debugging) */
|
||||
b0 = a0;
|
||||
}
|
||||
}
|
||||
if (collapse1) {
|
||||
if (DotVec2(normal, vab1) < 0) {
|
||||
if (collapse1)
|
||||
{
|
||||
if (DotVec2(normal, vab1) < 0)
|
||||
{
|
||||
a1 = b1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: Remove this (debugging) */
|
||||
b1 = a1;
|
||||
}
|
||||
@ -649,7 +716,8 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
Vec2 b_midpoint = ZI;
|
||||
b32 ignore_a = 1;
|
||||
b32 ignore_b = 1;
|
||||
if (!collapse0 && !collapse1) {
|
||||
if (!collapse0 && !collapse1)
|
||||
{
|
||||
/* Clip line to line */
|
||||
CLD_ClippedLine clip_result = CLD_ClipLineToLine(a0.p, b0.p, a1.p, b1.p, normal);
|
||||
Vec2 a0_clipped = clip_result.a0_clipped;
|
||||
@ -666,10 +734,14 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
ignore_a = 0;
|
||||
ignore_b = 0;
|
||||
Vec2 vfin = SubVec2(b_midpoint, a_midpoint);
|
||||
if (Vec2LenSq(vfin) < (0.005 * 0.005)) {
|
||||
if (a_sep > b_sep) {
|
||||
if (Vec2LenSq(vfin) < (0.005 * 0.005))
|
||||
{
|
||||
if (a_sep > b_sep)
|
||||
{
|
||||
ignore_a = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ignore_b = 1;
|
||||
}
|
||||
}
|
||||
@ -677,15 +749,19 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
result.a1_clipped = a1_clipped;
|
||||
result.b0_clipped = b0_clipped;
|
||||
result.b1_clipped = b1_clipped;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Vec2 p0 = a0.p;
|
||||
Vec2 p1 = a1.p;
|
||||
/* TODO: Choose ID based on closest clipped point */
|
||||
if (collapse1 && !collapse0) {
|
||||
if (collapse1 && !collapse0)
|
||||
{
|
||||
/* Project a1 onto vab0 */
|
||||
p0 = CLD_ClipPointToLine(a0.p, b0.p, a1.p, normal);
|
||||
}
|
||||
if (collapse0 && !collapse1) {
|
||||
if (collapse0 && !collapse1)
|
||||
{
|
||||
/* Project a0 onto vab1 */
|
||||
p1 = CLD_ClipPointToLine(a1.p, b1.p, a0.p, normal);
|
||||
}
|
||||
@ -701,13 +777,15 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
}
|
||||
|
||||
/* Insert points */
|
||||
if (!ignore_a && a_sep < tolerance) {
|
||||
if (!ignore_a && a_sep < tolerance)
|
||||
{
|
||||
CLD_CollisionPoint *point = &points[num_points++];
|
||||
point->id = a0.i | (a1.i << 4);
|
||||
point->separation = a_sep;
|
||||
point->point = a_midpoint;
|
||||
}
|
||||
if (!ignore_b && b_sep < tolerance) {
|
||||
if (!ignore_b && b_sep < tolerance)
|
||||
{
|
||||
CLD_CollisionPoint *point = &points[num_points++];
|
||||
point->id = b0.i | (b1.i << 4);
|
||||
point->separation = b_sep;
|
||||
@ -723,7 +801,7 @@ CLD_CollisionData CLD_CollisionDataFromShapes(CLD_Shape *shape0, CLD_Shape *shap
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
result.solved = 1;
|
||||
abort:
|
||||
abort:
|
||||
result.simplex = gjk_result.simplex;
|
||||
result.prototype.len = epa_result.prototype.len;
|
||||
CopyBytes(result.prototype.points, epa_result.prototype.points, sizeof(result.prototype.points[0]) * result.prototype.len);
|
||||
@ -783,11 +861,14 @@ CLD_ClosestPointData CLD_ClosestPointDataFromShapes(CLD_Shape *shape0, CLD_Shape
|
||||
|
||||
colliding = gjk_result.overlapping;
|
||||
CLD_MenkowskiFeature f = epa_result.closest_feature;
|
||||
if (f.len == 1) {
|
||||
if (f.len == 1)
|
||||
{
|
||||
p0 = f.a.s0.p;
|
||||
p1 = f.a.s1.p;
|
||||
colliding = gjk_result.overlapping || Vec2LenSq(NegVec2(f.a.p)) <= (tolerance * tolerance);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert(f.len == 2);
|
||||
/* FIXME: Winding order dependent? */
|
||||
f32 ratio;
|
||||
@ -810,10 +891,10 @@ CLD_ClosestPointData CLD_ClosestPointDataFromShapes(CLD_Shape *shape0, CLD_Shape
|
||||
|
||||
#if COLLIDER_DEBUG
|
||||
result.solved = 1;
|
||||
abort:
|
||||
abort:
|
||||
result.simplex = gjk_result.simplex;
|
||||
result.prototype.len = epa_result.prototype.len;
|
||||
CopyBytes(result.prototype.points, epa_result.prototype.points, sizeof(result.prototype.points[0]) *result.prototype.len);
|
||||
CopyBytes(result.prototype.points, epa_result.prototype.points, sizeof(result.prototype.points[0]) * result.prototype.len);
|
||||
result.simplex = gjk_result.simplex;
|
||||
#endif
|
||||
result.p0 = p0;
|
||||
@ -841,7 +922,8 @@ f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, X
|
||||
Vec2 dir_neg;
|
||||
{
|
||||
CLD_ClosestPointData closest_points = CLD_ClosestPointDataFromShapes(c0, c1, xf0_t0, xf1_t0);
|
||||
if (closest_points.colliding) {
|
||||
if (closest_points.colliding)
|
||||
{
|
||||
/* Shapes are penetrating at t=0 */
|
||||
return 0;
|
||||
}
|
||||
@ -855,20 +937,25 @@ f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, X
|
||||
Vec2 p0 = CLD_SupportPointFromDir(c0, xf0_t1, dir).p;
|
||||
Vec2 p1 = CLD_SupportPointFromDir(c1, xf1_t1, dir_neg).p;
|
||||
t1_sep = DotVec2(dir, SubVec2(p1, p0));
|
||||
if (t1_sep > 0) {
|
||||
if (t1_sep > 0)
|
||||
{
|
||||
/* Shapes are not penetrating at t=1 */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
u32 iteration = 0;
|
||||
while (AbsF32(t_sep) > tolerance && iteration < max_iterations) {
|
||||
while (AbsF32(t_sep) > tolerance && iteration < max_iterations)
|
||||
{
|
||||
/* Use mix of bisection & 0 position method to find root
|
||||
* (as described in https://box2d.org/files/ErinCatto_ContinuousCollision_GDC2013.pdf) */
|
||||
if (iteration & 1) {
|
||||
if (iteration & 1)
|
||||
{
|
||||
/* Bisect */
|
||||
t = (t1 + t0) / 2.0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* False position (fastest for linear case) */
|
||||
f32 m = (t1_sep - t0_sep) / (t1 - t0);
|
||||
t = (-t1_sep / m) + t1;
|
||||
@ -882,10 +969,13 @@ f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, X
|
||||
t_sep = DotVec2(dir, SubVec2(p1, p0));
|
||||
|
||||
/* Update bracket */
|
||||
if (t_sep > 0) {
|
||||
if (t_sep > 0)
|
||||
{
|
||||
t0 = t;
|
||||
t0_sep = t_sep;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = t;
|
||||
t1_sep = t_sep;
|
||||
}
|
||||
@ -903,11 +993,13 @@ f32 CLD_TimeOfImpact(CLD_Shape *c0, CLD_Shape *c1, Xform xf0_t0, Xform xf1_t0, X
|
||||
Vec2Array CLD_Menkowski(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, u32 detail)
|
||||
{
|
||||
Vec2Array result = { .points = PushDry(arena, Vec2) };
|
||||
for (u64 i = 0; i < detail; ++i) {
|
||||
for (u64 i = 0; i < detail; ++i)
|
||||
{
|
||||
f32 angle = ((f32)i / detail) * (2 * Pi);
|
||||
Vec2 dir = Vec2FromAngle(angle);
|
||||
CLD_MenkowskiPoint m = CLD_MenkowskiPointFromDir(shape0, shape1, xf0, xf1, dir);
|
||||
if (result.count == 0 || !EqVec2(m.p, result.points[result.count - 1])) {
|
||||
if (result.count == 0 || !EqVec2(m.p, result.points[result.count - 1]))
|
||||
{
|
||||
*PushStructNoZero(arena, Vec2) = m.p;
|
||||
++result.count;
|
||||
}
|
||||
@ -924,9 +1016,11 @@ Vec2Array CLD_PointCloud(Arena *arena, CLD_Shape *shape0, CLD_Shape *shape1, Xfo
|
||||
Vec2 *points1 = shape1->points;
|
||||
u32 count0 = shape0->count;
|
||||
u32 count1 = shape1->count;
|
||||
for (u64 i = 0; i < count0; ++i) {
|
||||
for (u64 i = 0; i < count0; ++i)
|
||||
{
|
||||
Vec2 p0 = MulXformV2(xf0, points0[i]);
|
||||
for (u64 j = 0; j < count1; ++j) {
|
||||
for (u64 j = 0; j < count1; ++j)
|
||||
{
|
||||
Vec2 p1 = MulXformV2(xf1, points1[j]);
|
||||
*PushStructNoZero(arena, Vec2) = SubVec2(p0, p1);
|
||||
++result.count;
|
||||
@ -954,14 +1048,17 @@ b32 CLD_GjkBoolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||
/* Second point is support point towards origin */
|
||||
dir = NegVec2(s.a);
|
||||
p = CLD_MenkowskiPointFromDir(shape0, shape1, dir);
|
||||
if (DotVec2(dir, p) >= 0) {
|
||||
if (DotVec2(dir, p) >= 0)
|
||||
{
|
||||
s.b = s.a;
|
||||
s.a = p;
|
||||
for (;;) {
|
||||
for (;;)
|
||||
{
|
||||
/* Third point is support point in direction of line normal towards origin */
|
||||
dir = PerpVec2TowardsDir(SubVec2(s.b, s.a), NegVec2(s.a));
|
||||
p = CLD_MenkowskiPointFromDir(shape0, shape1, dir);
|
||||
if (DotVec2(dir, p) < 0) {
|
||||
if (DotVec2(dir, p) < 0)
|
||||
{
|
||||
/* New point did not cross origin, collision impossible */
|
||||
break;
|
||||
}
|
||||
@ -975,15 +1072,21 @@ b32 CLD_GjkBoolean(CLD_Shape *shape0, CLD_Shape *shape1)
|
||||
Vec2 a_to_origin = NegVec2(s.a);
|
||||
|
||||
dir = PerpVec2TowardsDir(vab, NegVec2(vac)); /* Normal of ab pointing away from c */
|
||||
if (DotVec2(dir, a_to_origin) >= 0) {
|
||||
if (DotVec2(dir, a_to_origin) >= 0)
|
||||
{
|
||||
/* Point is in region ab, remove c from simplex (will happen automatically next iteration) */
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Point is not in region ab */
|
||||
dir = PerpVec2TowardsDir(vac, NegVec2(vab)); /* Normal of ac pointing away from b */
|
||||
if (DotVec2(dir, a_to_origin) >= 0) {
|
||||
if (DotVec2(dir, a_to_origin) >= 0)
|
||||
{
|
||||
/* Point is in region ac, remove b from simplex */
|
||||
s.b = s.c;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Point is in simplex */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -82,7 +82,8 @@ Struct(CLD_ClosestPointData)
|
||||
////////////////////////////////
|
||||
//~ Clipping types
|
||||
|
||||
Struct(CLD_ClippedLine) {
|
||||
Struct(CLD_ClippedLine)
|
||||
{
|
||||
Vec2 a0_clipped, b0_clipped;
|
||||
Vec2 a1_clipped, b1_clipped;
|
||||
};
|
||||
@ -158,7 +159,7 @@ CLD_Shape CLD_ShapeFromQuad(Quad quad);
|
||||
////////////////////////////////
|
||||
//~ Menkowski operations
|
||||
|
||||
CLD_SupportPoint CLD_SupportPointFromDirInternal(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore);
|
||||
CLD_SupportPoint CLD_SupportPointFromDirEx(CLD_Shape *shape, Xform xf, Vec2 dir, i32 ignore);
|
||||
CLD_SupportPoint CLD_SupportPointFromDir(CLD_Shape *shape, Xform xf, Vec2 dir);
|
||||
CLD_MenkowskiPoint CLD_MenkowskiPointFromDir(CLD_Shape *shape0, CLD_Shape *shape1, Xform xf0, Xform xf1, Vec2 dir);
|
||||
|
||||
|
||||
@ -1,25 +1,22 @@
|
||||
Global struct {
|
||||
G_Resource *solid_white_texture;
|
||||
} G = ZI, DebugAlias(G, G_draw);
|
||||
D_SharedState D_shared_state = ZI;
|
||||
|
||||
/* ========================== *
|
||||
* Startup
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Startup
|
||||
|
||||
D_StartupReceipt draw_startup(F_StartupReceipt *font_sr)
|
||||
D_StartupReceipt D_Startup(F_StartupReceipt *font_sr)
|
||||
{
|
||||
__prof;
|
||||
D_SharedState *g = &D_shared_state;
|
||||
(UNUSED)font_sr;
|
||||
u32 pixel_white = 0xFFFFFFFF;
|
||||
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(1, 1), &pixel_white);
|
||||
g->solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, VEC2I32(1, 1), &pixel_white);
|
||||
return (D_StartupReceipt) { 0 };
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Material
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Material
|
||||
|
||||
void draw_material(G_RenderSig *sig, D_MaterialParams params)
|
||||
void D_DrawMaterial(G_RenderSig *sig, D_MaterialParams params)
|
||||
{
|
||||
G_RenderCmdDesc cmd = ZI;
|
||||
cmd.kind = GP_RENDER_CMD_KIND_DRAW_MATERIAL;
|
||||
@ -32,11 +29,10 @@ void draw_material(G_RenderSig *sig, D_MaterialParams params)
|
||||
gp_push_render_cmd(sig, &cmd);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Fill shapes
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Solid shapes
|
||||
|
||||
void draw_poly_ex(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color)
|
||||
void D_DrawPolyEx(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color)
|
||||
{
|
||||
G_RenderCmdDesc cmd = ZI;
|
||||
cmd.kind = GP_RENDER_CMD_KIND_DRAW_UI_SHAPE;
|
||||
@ -47,38 +43,40 @@ void draw_poly_ex(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 c
|
||||
}
|
||||
|
||||
/* Draws a filled polygon using triangles in a fan pattern */
|
||||
void draw_poly(G_RenderSig *sig, Vec2Array vertices, u32 color)
|
||||
void D_DrawPoly(G_RenderSig *sig, Vec2Array vertices, u32 color)
|
||||
{
|
||||
if (vertices.count >= 3) {
|
||||
if (vertices.count >= 3)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
u32 num_tris = vertices.count - 2;
|
||||
u32 num_indices = num_tris * 3;
|
||||
|
||||
/* Generate indices in a fan pattern */
|
||||
G_Indices indices = {
|
||||
.count = num_indices,
|
||||
.indices = PushStructsNoZero(scratch.arena, u32, num_indices)
|
||||
};
|
||||
for (u32 i = 0; i < num_tris; ++i) {
|
||||
G_Indices indices = ZI;
|
||||
indices.count = num_indices;
|
||||
indices.indices = PushStructsNoZero(scratch.arena, u32, num_indices);
|
||||
for (u32 i = 0; i < num_tris; ++i)
|
||||
{
|
||||
u32 tri_offset = i * 3;
|
||||
indices.indices[tri_offset + 0] = 0;
|
||||
indices.indices[tri_offset + 1] = (i + 1);
|
||||
indices.indices[tri_offset + 2] = (i + 2);
|
||||
}
|
||||
|
||||
draw_poly_ex(sig, vertices, indices, color);
|
||||
D_DrawPolyEx(sig, vertices, indices, color);
|
||||
|
||||
EndScratch(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail)
|
||||
void D_DrawCircle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
Vec2 *points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
||||
for (u32 i = 0; i < detail; ++i) {
|
||||
for (u32 i = 0; i < detail; ++i)
|
||||
{
|
||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||
Vec2 p = VEC2(
|
||||
radius * CosF32(angle),
|
||||
@ -91,12 +89,12 @@ void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail)
|
||||
.points = points,
|
||||
.count = detail
|
||||
};
|
||||
draw_poly(sig, vertices, color);
|
||||
D_DrawPoly(sig, vertices, color);
|
||||
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
void draw_quad(G_RenderSig *sig, Quad quad, u32 color)
|
||||
void D_DrawQuad(G_RenderSig *sig, Quad quad, u32 color)
|
||||
{
|
||||
LocalPersist u32 indices_array[6] = {
|
||||
0, 1, 2,
|
||||
@ -104,62 +102,66 @@ void draw_quad(G_RenderSig *sig, Quad quad, u32 color)
|
||||
};
|
||||
Vec2Array vertices = { .count = 4, .points = quad.e };
|
||||
G_Indices indices = { .count = 6, .indices = indices_array };
|
||||
draw_poly_ex(sig, vertices, indices, color);
|
||||
D_DrawPolyEx(sig, vertices, indices, color);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Line shapes
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Line shapes
|
||||
|
||||
void draw_gradient_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color)
|
||||
void D_DrawLineGradient(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color)
|
||||
{
|
||||
#if 0
|
||||
D_SharedState *g = &D_shared_state;
|
||||
Quad quad = QuadFromLine(start, end, thickness);
|
||||
draw_material(sig, DRAW_MATERIAL_PARAMS(.texture = G.solid_white_texture, .tint0 = start_color, .tint1 = end_color, .quad = quad));
|
||||
D_DrawMaterial(sig, D_MATERIALPARAMS(.texture = g->solid_white_texture, .tint0 = start_color, .tint1 = end_color, .quad = quad));
|
||||
#else
|
||||
/* Placeholder */
|
||||
(UNUSED)end_color;
|
||||
Quad quad = QuadFromLine(start, end, thickness);
|
||||
draw_quad(sig, quad, start_color);
|
||||
D_DrawQuad(sig, quad, start_color);
|
||||
#endif
|
||||
}
|
||||
|
||||
void draw_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color)
|
||||
void D_DrawLine(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color)
|
||||
{
|
||||
Quad quad = QuadFromLine(start, end, thickness);
|
||||
draw_quad(sig, quad, color);
|
||||
D_DrawQuad(sig, quad, color);
|
||||
}
|
||||
|
||||
void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color)
|
||||
void D_DrawRay(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color)
|
||||
{
|
||||
Quad quad = QuadFromRay(pos, rel, thickness);
|
||||
draw_quad(sig, quad, color);
|
||||
D_DrawQuad(sig, quad, color);
|
||||
}
|
||||
|
||||
void draw_poly_line(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color)
|
||||
void D_DrawPolyLine(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color)
|
||||
{
|
||||
if (points.count >= 2) {
|
||||
for (u64 i = 1; i < points.count; ++i) {
|
||||
if (points.count >= 2)
|
||||
{
|
||||
for (u64 i = 1; i < points.count; ++i)
|
||||
{
|
||||
Vec2 p1 = points.points[i - 1];
|
||||
Vec2 p2 = points.points[i];
|
||||
Quad q = QuadFromLine(p1, p2, thickness);
|
||||
draw_quad(sig, q, color);
|
||||
D_DrawQuad(sig, q, color);
|
||||
}
|
||||
if (loop && points.count > 2) {
|
||||
if (loop && points.count > 2)
|
||||
{
|
||||
Vec2 p1 = points.points[points.count - 1];
|
||||
Vec2 p2 = points.points[0];
|
||||
Quad q = QuadFromLine(p1, p2, thickness);
|
||||
draw_quad(sig, q, color);
|
||||
D_DrawQuad(sig, q, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
||||
void D_DrawCircleLine(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
|
||||
Vec2 *points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
||||
for (u32 i = 0; i < detail; ++i) {
|
||||
for (u32 i = 0; i < detail; ++i)
|
||||
{
|
||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||
Vec2 p = VEC2(
|
||||
radius * CosF32(angle),
|
||||
@ -172,19 +174,19 @@ void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32
|
||||
.points = points,
|
||||
.count = detail
|
||||
};
|
||||
draw_poly_line(sig, a, 1, thickness, color);
|
||||
D_DrawPolyLine(sig, a, 1, thickness, color);
|
||||
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
|
||||
void D_DrawQuadLine(G_RenderSig *sig, Quad quad, f32 thickness, u32 color)
|
||||
{
|
||||
Vec2 points[] = { quad.p0, quad.p1, quad.p2, quad.p3 };
|
||||
Vec2Array a = { .points = points, .count = countof(points) };
|
||||
draw_poly_line(sig, a, 1, thickness, color);
|
||||
D_DrawPolyLine(sig, a, 1, thickness, color);
|
||||
}
|
||||
|
||||
void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color)
|
||||
void D_DrawArrowLine(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color)
|
||||
{
|
||||
const f32 head_width_ratio = 0.5f; /* Width of arrowhead relative to its length */
|
||||
|
||||
@ -208,48 +210,52 @@ void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32
|
||||
.points = head_points,
|
||||
.count = countof(head_points)
|
||||
};
|
||||
draw_poly(sig, head_points_v2_array, color);
|
||||
D_DrawPoly(sig, head_points_v2_array, color);
|
||||
|
||||
Quad line_quad = QuadFromLine(start, head_start, thickness);
|
||||
draw_quad(sig, line_quad, color);
|
||||
D_DrawQuad(sig, line_quad, color);
|
||||
}
|
||||
|
||||
void draw_arrow_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color)
|
||||
void D_DrawArrowRay(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color)
|
||||
{
|
||||
Vec2 end = AddVec2(pos, rel);
|
||||
draw_arrow_line(sig, pos, end, thickness, arrowhead_height, color);
|
||||
D_DrawArrowLine(sig, pos, end, thickness, arrowhead_height, color);
|
||||
}
|
||||
|
||||
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail)
|
||||
void D_DrawColliderLine(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail)
|
||||
{
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
Vec2Array poly = ZI;
|
||||
if (shape.radius == 0) {
|
||||
if (shape.radius == 0)
|
||||
{
|
||||
poly.count = shape.count;
|
||||
poly.points = PushStructsNoZero(scratch.arena, Vec2, shape.count);
|
||||
for (u32 i = 0; i < shape.count; ++i) {
|
||||
for (u32 i = 0; i < shape.count; ++i)
|
||||
{
|
||||
Vec2 p = MulXformV2(shape_xf, shape.points[i]);
|
||||
poly.points[i] = p;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
poly.count = detail;
|
||||
poly.points = PushStructsNoZero(scratch.arena, Vec2, detail);
|
||||
for (u32 i = 0; i < detail; ++i) {
|
||||
for (u32 i = 0; i < detail; ++i)
|
||||
{
|
||||
f32 angle = ((f32)i / (f32)detail) * Tau;
|
||||
Vec2 dir = VEC2(CosF32(angle), SinF32(angle));
|
||||
Vec2 p = CLD_SupportPointFromDir(&shape, shape_xf, dir).p;
|
||||
poly.points[i] = p;
|
||||
}
|
||||
}
|
||||
draw_poly_line(sig, poly, 1, thickness, color);
|
||||
D_DrawPolyLine(sig, poly, 1, thickness, color);
|
||||
EndScratch(scratch);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Grid
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Grid
|
||||
|
||||
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset)
|
||||
void D_DrawGrid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset)
|
||||
{
|
||||
i32 grid_id = 0;
|
||||
{
|
||||
@ -274,11 +280,10 @@ void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 lin
|
||||
gp_push_render_cmd(sig, &cmd);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* UI
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Ui
|
||||
|
||||
void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params)
|
||||
void D_DrawUiRect(G_RenderSig *sig, D_UiRectParams params)
|
||||
{
|
||||
G_RenderCmdDesc cmd = ZI;
|
||||
cmd.kind = GP_RENDER_CMD_KIND_DRAW_UI_RECT;
|
||||
@ -289,9 +294,8 @@ void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params)
|
||||
gp_push_render_cmd(sig, &cmd);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Text
|
||||
* ========================== */
|
||||
////////////////////////////////
|
||||
//~ Text
|
||||
|
||||
/* Returns the rect of the text area */
|
||||
Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
@ -302,55 +306,46 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
f32 inv_font_image_height = 1.0 / (f32)params.font->image_height;
|
||||
f32 line_spacing = params.font->point_size * 1.5f * params.scale;
|
||||
|
||||
/* ========================== *
|
||||
* Build line glyphs
|
||||
* ========================== */
|
||||
|
||||
struct drawable_glyph {
|
||||
f32 off_x;
|
||||
f32 off_y;
|
||||
f32 width;
|
||||
f32 height;
|
||||
f32 advance;
|
||||
ClipRect clip;
|
||||
};
|
||||
|
||||
struct drawable_line {
|
||||
f32 line_width;
|
||||
u32 num_glyphs;
|
||||
struct drawable_glyph *glyphs;
|
||||
struct drawable_line *next;
|
||||
};
|
||||
//- Build line glyphs
|
||||
|
||||
u64 num_lines = 0;
|
||||
f32 widest_line = 0;
|
||||
|
||||
struct drawable_line *first_line = 0;
|
||||
struct drawable_line *last_line = 0;
|
||||
D_TextLine *first_line = 0;
|
||||
D_TextLine *last_line = 0;
|
||||
f32 first_line_top_offset = 0;
|
||||
f32 last_line_bottom_offset = 0;
|
||||
|
||||
if (params.str.len > 0) {
|
||||
if (params.str.len > 0)
|
||||
{
|
||||
b32 string_done = 0;
|
||||
CodepointIter iter = BeginCodepointIter(params.str);
|
||||
while (!string_done) {
|
||||
while (!string_done)
|
||||
{
|
||||
f32 line_width = 0;
|
||||
f32 top_offset = 0;
|
||||
f32 bottom_offset = 0;
|
||||
u64 num_line_glyphs = 0;
|
||||
struct drawable_glyph *line_glyphs = PushDry(scratch.arena, struct drawable_glyph);
|
||||
D_TextGlyph *line_glyphs = PushDry(scratch.arena, D_TextGlyph);
|
||||
|
||||
b32 line_done = 0;
|
||||
while (!line_done) {
|
||||
while (!line_done)
|
||||
{
|
||||
string_done = !AdvanceCodepointIter(&iter);
|
||||
if (string_done) {
|
||||
if (string_done)
|
||||
{
|
||||
line_done = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 codepoint = iter.codepoint;
|
||||
if (codepoint == '\n') {
|
||||
if (codepoint == '\n')
|
||||
{
|
||||
line_done = 1;
|
||||
} else {
|
||||
struct drawable_glyph *tg = PushStruct(scratch.arena, struct drawable_glyph);
|
||||
}
|
||||
else
|
||||
{
|
||||
D_TextGlyph *tg = PushStruct(scratch.arena, D_TextGlyph);
|
||||
++num_line_glyphs;
|
||||
F_Glyph *glyph = font_get_glyph(params.font, codepoint);
|
||||
tg->off_x = glyph->off_x * params.scale;
|
||||
@ -378,13 +373,16 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
|
||||
/* Line ended */
|
||||
/* TODO: Only create nodes for non-empty lines. Embed line number in the node. */
|
||||
struct drawable_line *node = PushStruct(scratch.arena, struct drawable_line);
|
||||
D_TextLine *node = PushStruct(scratch.arena, D_TextLine);
|
||||
node->line_width = line_width;
|
||||
node->num_glyphs = num_line_glyphs;
|
||||
node->glyphs = line_glyphs;
|
||||
if (last_line) {
|
||||
if (last_line)
|
||||
{
|
||||
last_line->next = node;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
first_line = node;
|
||||
first_line_top_offset = top_offset;
|
||||
}
|
||||
@ -396,9 +394,7 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
EndCodepointIter(&iter);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Determine text bounds
|
||||
* ========================== */
|
||||
//- Determine text bounds
|
||||
|
||||
Rect bounds = ZI;
|
||||
bounds.x = params.pos.x;
|
||||
@ -407,7 +403,8 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
bounds.height = num_lines * line_spacing + first_line_top_offset + last_line_bottom_offset;
|
||||
|
||||
/* Offset bounds X */
|
||||
switch (params.offset_x) {
|
||||
switch (params.offset_x)
|
||||
{
|
||||
case DRAW_TEXT_OFFSET_X_LEFT: break;
|
||||
case DRAW_TEXT_OFFSET_X_CENTER:
|
||||
{
|
||||
@ -420,7 +417,8 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
}
|
||||
|
||||
/* Offset bounds Y */
|
||||
switch (params.offset_y) {
|
||||
switch (params.offset_y)
|
||||
{
|
||||
case DRAW_TEXT_OFFSET_Y_TOP: break;
|
||||
case DRAW_TEXT_OFFSET_Y_CENTER:
|
||||
{
|
||||
@ -428,23 +426,24 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
} break;
|
||||
case DRAW_TEXT_OFFSET_Y_BOTTOM:
|
||||
{
|
||||
if (last_line) {
|
||||
if (last_line)
|
||||
{
|
||||
bounds.y -= bounds.height + last_line_bottom_offset;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Draw lines
|
||||
* ========================== */
|
||||
//- Draw lines
|
||||
|
||||
u64 line_number = 0;
|
||||
for (struct drawable_line *line = first_line; line; line = line->next) {
|
||||
for (D_TextLine *line = first_line; line; line = line->next)
|
||||
{
|
||||
Vec2 draw_pos = bounds.pos;
|
||||
draw_pos.y += line_number * line_spacing - first_line_top_offset;
|
||||
|
||||
/* Alignment */
|
||||
switch (params.alignment) {
|
||||
switch (params.alignment)
|
||||
{
|
||||
case DRAW_TEXT_ALIGNMENT_LEFT: break;
|
||||
case DRAW_TEXT_ALIGNMENT_CENTER:
|
||||
{
|
||||
@ -456,13 +455,14 @@ Rect draw_text(G_RenderSig *sig, D_TextParams params)
|
||||
} break;
|
||||
}
|
||||
|
||||
/* Draw glyphs */
|
||||
for (u64 i = 0; i < line->num_glyphs; ++i) {
|
||||
struct drawable_glyph *tg = &line->glyphs[i];
|
||||
/* Draw glyphs in line */
|
||||
for (u64 i = 0; i < line->num_glyphs; ++i)
|
||||
{
|
||||
D_TextGlyph *tg = &line->glyphs[i];
|
||||
Vec2 pos = VEC2(draw_pos.x + tg->off_x, draw_pos.y + tg->off_y);
|
||||
Vec2 size = VEC2(tg->width, tg->height);
|
||||
Xform xf = XformFromRect(RectFromVec2(pos, size));
|
||||
draw_ui_rect(sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = params.font->texture, .tint = params.color, .clip = tg->clip));
|
||||
D_DrawUiRect(sig, D_UIRECTPARAMS(.xf = xf, .texture = params.font->texture, .tint = params.color, .clip = tg->clip));
|
||||
draw_pos.x += tg->advance;
|
||||
|
||||
}
|
||||
|
||||
@ -1,17 +1,8 @@
|
||||
Struct(D_StartupReceipt) { i32 _; };
|
||||
D_StartupReceipt draw_startup(F_StartupReceipt *font_sr);
|
||||
////////////////////////////////
|
||||
//~ Material types
|
||||
|
||||
/* ========================== *
|
||||
* Material
|
||||
* ========================== */
|
||||
|
||||
#define DRAW_MATERIAL_PARAMS(...) ((D_MaterialParams) { \
|
||||
.tint = ColorWhite, \
|
||||
.clip = AllClipped, \
|
||||
__VA_ARGS__ \
|
||||
})
|
||||
|
||||
Struct(D_MaterialParams) {
|
||||
Struct(D_MaterialParams)
|
||||
{
|
||||
Xform xf;
|
||||
G_Resource *texture;
|
||||
ClipRect clip;
|
||||
@ -19,83 +10,34 @@ Struct(D_MaterialParams) {
|
||||
b32 is_light;
|
||||
Vec3 light_emittance;
|
||||
};
|
||||
|
||||
void draw_material(G_RenderSig *sig, D_MaterialParams params);
|
||||
|
||||
/* ========================== *
|
||||
* Fill shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_poly_ex(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color);
|
||||
|
||||
void draw_poly(G_RenderSig *sig, Vec2Array points, u32 color);
|
||||
|
||||
void draw_circle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail);
|
||||
|
||||
void draw_quad(G_RenderSig *sig, Quad quad, u32 color);
|
||||
|
||||
/* ========================== *
|
||||
* Line shapes
|
||||
* ========================== */
|
||||
|
||||
void draw_gradient_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color);
|
||||
|
||||
void draw_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color);
|
||||
|
||||
void draw_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color);
|
||||
|
||||
void draw_poly_line(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color);
|
||||
|
||||
void draw_circle_line(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
||||
|
||||
void draw_quad_line(G_RenderSig *sig, Quad quad, f32 thickness, u32 color);
|
||||
|
||||
void draw_arrow_line(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color);
|
||||
|
||||
void draw_arrow_ray(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color);
|
||||
|
||||
void draw_collider_line(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail);
|
||||
|
||||
/* ========================== *
|
||||
* Grid
|
||||
* ========================== */
|
||||
|
||||
void draw_grid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset);
|
||||
|
||||
/* ========================== *
|
||||
* UI
|
||||
* ========================== */
|
||||
|
||||
#define DRAW_UI_RECT_PARAMS(...) ((D_UiRectParams) { \
|
||||
#define D_MATERIALPARAMS(...) ((D_MaterialParams) { \
|
||||
.tint = ColorWhite, \
|
||||
.clip = AllClipped, \
|
||||
__VA_ARGS__ \
|
||||
})
|
||||
|
||||
Struct(D_UiRectParams) {
|
||||
////////////////////////////////
|
||||
//~ Ui types
|
||||
|
||||
Struct(D_UiRectParams)
|
||||
{
|
||||
Xform xf;
|
||||
G_Resource *texture;
|
||||
ClipRect clip;
|
||||
u32 tint;
|
||||
};
|
||||
|
||||
void draw_ui_rect(G_RenderSig *sig, D_UiRectParams params);
|
||||
|
||||
/* ========================== *
|
||||
* Text
|
||||
* ========================== */
|
||||
|
||||
#define DRAW_TEXT_PARAMS(...) ((D_TextParams) { \
|
||||
.scale = 1.0, \
|
||||
.alignment = DRAW_TEXT_ALIGNMENT_LEFT, \
|
||||
.offset_x = DRAW_TEXT_OFFSET_X_LEFT, \
|
||||
.offset_y = DRAW_TEXT_OFFSET_Y_TOP, \
|
||||
.color = ColorWhite, \
|
||||
#define D_UIRECTPARAMS(...) ((D_UiRectParams) { \
|
||||
.tint = ColorWhite, \
|
||||
.clip = AllClipped, \
|
||||
__VA_ARGS__ \
|
||||
})
|
||||
|
||||
////////////////////////////////
|
||||
//~ Text types
|
||||
|
||||
/* How is text aligned within its area */
|
||||
typedef i32 D_TextAlignment; enum {
|
||||
typedef i32 D_TextAlignment; enum
|
||||
{
|
||||
DRAW_TEXT_ALIGNMENT_LEFT, /* Default */
|
||||
DRAW_TEXT_ALIGNMENT_CENTER,
|
||||
DRAW_TEXT_ALIGNMENT_RIGHT
|
||||
@ -104,19 +46,40 @@ typedef i32 D_TextAlignment; enum {
|
||||
/* How does the specified text position relate to the text area.
|
||||
* E.g. BOTTOM & RIGHT means the bottom-right of the text area will snap to
|
||||
* the specified position. */
|
||||
typedef i32 D_TextOffsetX; enum {
|
||||
typedef i32 D_TextOffsetX; enum
|
||||
{
|
||||
DRAW_TEXT_OFFSET_X_LEFT, /* Default */
|
||||
DRAW_TEXT_OFFSET_X_CENTER,
|
||||
DRAW_TEXT_OFFSET_X_RIGHT
|
||||
};
|
||||
|
||||
typedef i32 D_TextOffsetY; enum {
|
||||
typedef i32 D_TextOffsetY; enum
|
||||
{
|
||||
DRAW_TEXT_OFFSET_Y_TOP, /* Default */
|
||||
DRAW_TEXT_OFFSET_Y_CENTER,
|
||||
DRAW_TEXT_OFFSET_Y_BOTTOM
|
||||
};
|
||||
|
||||
Struct(D_TextParams) {
|
||||
Struct(D_TextGlyph)
|
||||
{
|
||||
f32 off_x;
|
||||
f32 off_y;
|
||||
f32 width;
|
||||
f32 height;
|
||||
f32 advance;
|
||||
ClipRect clip;
|
||||
};
|
||||
|
||||
Struct(D_TextLine)
|
||||
{
|
||||
f32 line_width;
|
||||
u32 num_glyphs;
|
||||
D_TextGlyph *glyphs;
|
||||
D_TextLine *next;
|
||||
};
|
||||
|
||||
Struct(D_TextParams)
|
||||
{
|
||||
F_Font *font;
|
||||
Vec2 pos;
|
||||
f32 scale;
|
||||
@ -126,5 +89,68 @@ Struct(D_TextParams) {
|
||||
D_TextOffsetY offset_y;
|
||||
String str;
|
||||
};
|
||||
#define D_TEXTPARAMS(...) ((D_TextParams) { \
|
||||
.scale = 1.0, \
|
||||
.alignment = DRAW_TEXT_ALIGNMENT_LEFT, \
|
||||
.offset_x = DRAW_TEXT_OFFSET_X_LEFT, \
|
||||
.offset_y = DRAW_TEXT_OFFSET_Y_TOP, \
|
||||
.color = ColorWhite, \
|
||||
__VA_ARGS__ \
|
||||
})
|
||||
|
||||
////////////////////////////////
|
||||
//~ Shared state
|
||||
|
||||
Struct(D_SharedState)
|
||||
{
|
||||
G_Resource *solid_white_texture;
|
||||
};
|
||||
|
||||
extern D_SharedState D_shared_state;
|
||||
|
||||
////////////////////////////////
|
||||
//~ Startup
|
||||
|
||||
Struct(D_StartupReceipt) { i32 _; };
|
||||
D_StartupReceipt D_Startup(F_StartupReceipt *font_sr);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Material operations
|
||||
|
||||
void D_DrawMaterial(G_RenderSig *sig, D_MaterialParams params);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Solid shape operations
|
||||
|
||||
void D_DrawPolyEx(G_RenderSig *sig, Vec2Array vertices, G_Indices indices, u32 color);
|
||||
void D_DrawPoly(G_RenderSig *sig, Vec2Array points, u32 color);
|
||||
void D_DrawCircle(G_RenderSig *sig, Vec2 pos, f32 radius, u32 color, u32 detail);
|
||||
void D_DrawQuad(G_RenderSig *sig, Quad quad, u32 color);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Line shape operations
|
||||
|
||||
void D_DrawLineGradient(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 start_color, u32 end_color);
|
||||
void D_DrawLine(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, u32 color);
|
||||
void D_DrawRay(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, u32 color);
|
||||
void D_DrawPolyLine(G_RenderSig *sig, Vec2Array points, b32 loop, f32 thickness, u32 color);
|
||||
void D_DrawCircleLine(G_RenderSig *sig, Vec2 pos, f32 radius, f32 thickness, u32 color, u32 detail);
|
||||
void D_DrawQuadLine(G_RenderSig *sig, Quad quad, f32 thickness, u32 color);
|
||||
void D_DrawArrowLine(G_RenderSig *sig, Vec2 start, Vec2 end, f32 thickness, f32 arrowhead_height, u32 color);
|
||||
void D_DrawArrowRay(G_RenderSig *sig, Vec2 pos, Vec2 rel, f32 thickness, f32 arrowhead_height, u32 color);
|
||||
void D_DrawColliderLine(G_RenderSig *sig, CLD_Shape shape, Xform shape_xf, f32 thickness, u32 color, u32 detail);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Grid operations
|
||||
|
||||
void D_DrawGrid(G_RenderSig *sig, Xform xf, u32 bg0_color, u32 bg1_color, u32 line_color, u32 x_color, u32 y_color, f32 thickness, f32 spacing, Vec2 offset);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Ui operations
|
||||
|
||||
void D_DrawUiRect(G_RenderSig *sig, D_UiRectParams params);
|
||||
|
||||
////////////////////////////////
|
||||
//~ Text operations
|
||||
|
||||
Rect draw_text(G_RenderSig *sig, D_TextParams params);
|
||||
|
||||
@ -266,13 +266,13 @@ internal void debug_draw_xform(Xform xf, u32 color_x, u32 color_y)
|
||||
x_ray = MulVec2(x_ray, ray_scale);
|
||||
y_ray = MulVec2(y_ray, ray_scale);
|
||||
|
||||
draw_arrow_ray(G.render_sig, pos, x_ray, thickness, arrowhead_len, color_x);
|
||||
draw_arrow_ray(G.render_sig, pos, y_ray, thickness, arrowhead_len, color_y);
|
||||
D_DrawArrowRay(G.render_sig, pos, x_ray, thickness, arrowhead_len, color_x);
|
||||
D_DrawArrowRay(G.render_sig, pos, y_ray, thickness, arrowhead_len, color_y);
|
||||
|
||||
//u32 color_quad = Rgba32F(0, 1, 1, 0.3);
|
||||
//Quad quad = QuadFromRect(RectFromScalar(0, 0, 1, -1));
|
||||
//quad = MulXformQuad(xf, ScaleQuad(quad, 0.075f));
|
||||
//draw_quad(G.render_sig, quad, color);
|
||||
//D_DrawQuad(G.render_sig, quad, color);
|
||||
}
|
||||
|
||||
internal void debug_draw_movement(Ent *ent)
|
||||
@ -289,7 +289,7 @@ internal void debug_draw_movement(Ent *ent)
|
||||
Vec2 vel_ray = MulXformBasisV2(G.world_to_ui_xf, velocity);
|
||||
|
||||
if (Vec2Len(vel_ray) > 0.00001) {
|
||||
draw_arrow_ray(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||
D_DrawArrowRay(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -461,7 +461,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
||||
if (log->level <= level) {
|
||||
/* Draw background */
|
||||
u32 color = colors[log->level][log->color_index];
|
||||
draw_quad(G.render_sig, QuadFromRect(log->bounds), Alpha32F(color, opacity));
|
||||
D_DrawQuad(G.render_sig, QuadFromRect(log->bounds), Alpha32F(color, opacity));
|
||||
|
||||
/* Draw text */
|
||||
String text = log->msg;
|
||||
@ -477,7 +477,7 @@ internal void draw_debug_console(i32 level, b32 minimized)
|
||||
FmtString(text));
|
||||
}
|
||||
|
||||
D_TextParams params = DRAW_TEXT_PARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = Alpha32F(ColorWhite, opacity), .str = text);
|
||||
D_TextParams params = D_TEXTPARAMS(.font = font, .pos = draw_pos, .offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM, .color = Alpha32F(ColorWhite, opacity), .str = text);
|
||||
Rect bounds = draw_text(G.render_sig, params);
|
||||
|
||||
Rect draw_bounds = bounds;
|
||||
@ -1031,7 +1031,7 @@ internal void user_update(P_Window *window)
|
||||
Vec2 size = InvertXformBasisMulV2(G.world_to_render_xf, G.render_size);
|
||||
u32 color0 = Rgba32F(0.17f, 0.17f, 0.17f, 1.f);
|
||||
u32 color1 = Rgba32F(0.15f, 0.15f, 0.15f, 1.f);
|
||||
draw_grid(G.render_sig, XformFromRect(RectFromVec2(pos, size)), color0, color1, Rgba32(0x3f, 0x3f, 0x3f, 0xFF), ColorRed, ColorGreen, thickness, spacing, offset);
|
||||
D_DrawGrid(G.render_sig, XformFromRect(RectFromVec2(pos, size)), color0, color1, Rgba32(0x3f, 0x3f, 0x3f, 0xFF), ColorRed, ColorGreen, thickness, spacing, offset);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1215,9 +1215,9 @@ internal void user_update(P_Window *window)
|
||||
u32 color_end = Rgba32F(1, 0.8, 0.4, opacity_b);
|
||||
|
||||
if (opacity_b > 0.99f) {
|
||||
draw_circle(G.render_sig, b, thickness / 2, color_end, 20);
|
||||
D_DrawCircle(G.render_sig, b, thickness / 2, color_end, 20);
|
||||
}
|
||||
draw_gradient_line(G.render_sig, a, b, thickness, color_start, color_end);
|
||||
D_DrawLineGradient(G.render_sig, a, b, thickness, color_start, color_end);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1232,8 +1232,8 @@ internal void user_update(P_Window *window)
|
||||
Vec3 emittance = ent->sprite_emittance;
|
||||
u32 tint = ent->sprite_tint;
|
||||
S_SheetFrame frame = sprite_sheet_get_frame(sheet, ent->animation_frame);
|
||||
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = sprite_xform, .texture = texture->gp_texture, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance);
|
||||
draw_material(G.render_sig, params);
|
||||
D_MaterialParams params = D_MATERIALPARAMS(.xf = sprite_xform, .texture = texture->gp_texture, .tint = tint, .clip = frame.clip, .is_light = is_light, .light_emittance = emittance);
|
||||
D_DrawMaterial(G.render_sig, params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1254,8 +1254,8 @@ internal void user_update(P_Window *window)
|
||||
Vec2I32 world_tile_index = sim_world_tile_index_from_local_tile_index(chunk_index, local_tile_index);
|
||||
Vec2 pos = sim_pos_from_world_tile_index(world_tile_index);
|
||||
Xform tile_xf = XformFromRect(RectFromVec2(pos, VEC2(tile_size, tile_size)));
|
||||
D_MaterialParams params = DRAW_MATERIAL_PARAMS(.xf = tile_xf, .texture = tile_texture->gp_texture, .is_light = 1, .light_emittance = VEC3(0, 0, 0));
|
||||
draw_material(G.render_sig, params);
|
||||
D_MaterialParams params = D_MATERIALPARAMS(.xf = tile_xf, .texture = tile_texture->gp_texture, .is_light = 1, .light_emittance = VEC3(0, 0, 0));
|
||||
D_DrawMaterial(G.render_sig, params);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1284,7 +1284,7 @@ internal void user_update(P_Window *window)
|
||||
u32 color = Rgba32F(1, 0, 1, 0.5);
|
||||
Quad quad = QuadFromAabb(aabb);
|
||||
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||
draw_quad_line(G.render_sig, quad, thickness, color);
|
||||
D_DrawQuadLine(G.render_sig, quad, thickness, color);
|
||||
}
|
||||
|
||||
/* Draw focus arrow */
|
||||
@ -1295,7 +1295,7 @@ internal void user_update(P_Window *window)
|
||||
start = MulXformV2(G.world_to_ui_xf, start);
|
||||
Vec2 end = AddVec2(xf.og, ent->control.focus);
|
||||
end = MulXformV2(G.world_to_ui_xf, end);
|
||||
draw_arrow_line(G.render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5));
|
||||
D_DrawArrowLine(G.render_sig, start, end, 3, 10, Rgba32F(1, 1, 1, 0.5));
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1321,16 +1321,16 @@ internal void user_update(P_Window *window)
|
||||
Quad quad = QuadFromRect(slice.rect);
|
||||
quad = MulXformQuad(sprite_xform, quad);
|
||||
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||
draw_quad_line(G.render_sig, quad, 2, quad_color);
|
||||
D_DrawQuadLine(G.render_sig, quad, 2, quad_color);
|
||||
}
|
||||
|
||||
draw_circle(G.render_sig, center, 3, point_color, 20);
|
||||
D_DrawCircle(G.render_sig, center, 3, point_color, 20);
|
||||
|
||||
if (slice.has_ray) {
|
||||
Vec2 ray = MulXformBasisV2(sprite_xform, slice.dir);
|
||||
ray = MulXformBasisV2(G.world_to_ui_xf, ray);
|
||||
ray = Vec2WithLen(ray, 25);
|
||||
draw_arrow_ray(G.render_sig, center, ray, 2, 10, ray_color);
|
||||
D_DrawArrowRay(G.render_sig, center, ray, 2, 10, ray_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1347,7 +1347,7 @@ internal void user_update(P_Window *window)
|
||||
f32 radius = 3;
|
||||
Vec2 point = MulXformV2(e1_xf, ent->weld_joint_data.point_local_e1);
|
||||
point = MulXformV2(G.world_to_ui_xf, point);
|
||||
draw_circle(G.render_sig, point, radius, color, 10);
|
||||
D_DrawCircle(G.render_sig, point, radius, color, 10);
|
||||
|
||||
DEBUGBREAKABLE;
|
||||
}
|
||||
@ -1362,8 +1362,8 @@ internal void user_update(P_Window *window)
|
||||
Vec2 point_end = G.world_cursor;
|
||||
point_start = MulXformV2(G.world_to_ui_xf, point_start);
|
||||
point_end = MulXformV2(G.world_to_ui_xf, point_end);
|
||||
draw_arrow_line(G.render_sig, point_start, point_end, 3, 10, color);
|
||||
draw_circle(G.render_sig, point_start, 4, color, 10);
|
||||
D_DrawArrowLine(G.render_sig, point_start, point_end, 3, 10, color);
|
||||
D_DrawCircle(G.render_sig, point_start, 4, color, 10);
|
||||
}
|
||||
|
||||
/* Draw collider */
|
||||
@ -1375,13 +1375,13 @@ internal void user_update(P_Window *window)
|
||||
/* Draw collider using support points */
|
||||
u32 detail = 32;
|
||||
Xform collider_draw_xf = MulXform(G.world_to_ui_xf, xf);
|
||||
draw_collider_line(G.render_sig, collider, collider_draw_xf, thickness, color, detail);
|
||||
D_DrawColliderLine(G.render_sig, collider, collider_draw_xf, thickness, color, detail);
|
||||
}
|
||||
{
|
||||
/* Draw collider shape points */
|
||||
for (u32 i = 0; i < collider.count; ++i) {
|
||||
Vec2 p = MulXformV2(MulXform(G.world_to_ui_xf, xf), collider.points[i]);
|
||||
draw_circle(G.render_sig, p, 3, ColorBlue, 10);
|
||||
D_DrawCircle(G.render_sig, p, 3, ColorBlue, 10);
|
||||
}
|
||||
}
|
||||
if (collider.count == 1 && collider.radius > 0) {
|
||||
@ -1390,14 +1390,14 @@ internal void user_update(P_Window *window)
|
||||
Vec2 end = CLD_SupportPointFromDir(&collider, xf, NegVec2(xf.by)).p;
|
||||
start = MulXformV2(G.world_to_ui_xf, start);
|
||||
end = MulXformV2(G.world_to_ui_xf, end);
|
||||
draw_line(G.render_sig, start, end, thickness, color);
|
||||
D_DrawLine(G.render_sig, start, end, thickness, color);
|
||||
}
|
||||
#if 0
|
||||
/* Draw support point at focus dir */
|
||||
{
|
||||
Vec2 p = collider_support_point(&collider, xf, ent->control.focus);
|
||||
p = MulXformV2(G.world_to_ui_xf, p);
|
||||
draw_circle(G.render_sig, p, 3, ColorRed, 10);
|
||||
D_DrawCircle(G.render_sig, p, 3, ColorRed, 10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1421,7 +1421,7 @@ internal void user_update(P_Window *window)
|
||||
|
||||
/* Draw point */
|
||||
{
|
||||
draw_circle(G.render_sig, MulXformV2(G.world_to_ui_xf, dbg_pt), radius, color, 10);
|
||||
D_DrawCircle(G.render_sig, MulXformV2(G.world_to_ui_xf, dbg_pt), radius, color, 10);
|
||||
}
|
||||
|
||||
/* Draw normal */
|
||||
@ -1431,7 +1431,7 @@ internal void user_update(P_Window *window)
|
||||
f32 arrow_height = 5;
|
||||
Vec2 start = MulXformV2(G.world_to_ui_xf, dbg_pt);
|
||||
Vec2 end = MulXformV2(G.world_to_ui_xf, AddVec2(dbg_pt, MulVec2(NormVec2(data->normal), len)));
|
||||
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrow_height, color);
|
||||
D_DrawArrowLine(G.render_sig, start, end, arrow_thickness, arrow_height, color);
|
||||
}
|
||||
#if 0
|
||||
/* Draw contact info */
|
||||
@ -1489,8 +1489,8 @@ internal void user_update(P_Window *window)
|
||||
u32 color = Rgba32F(1, 1, 0, 0.5);
|
||||
Vec2 a = MulXformV2(G.world_to_ui_xf, data->closest0);
|
||||
Vec2 b = MulXformV2(G.world_to_ui_xf, data->closest1);
|
||||
draw_circle(G.render_sig, a, radius, color, 10);
|
||||
draw_circle(G.render_sig, b, radius, color, 10);
|
||||
D_DrawCircle(G.render_sig, a, radius, color, 10);
|
||||
D_DrawCircle(G.render_sig, b, radius, color, 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1507,28 +1507,28 @@ internal void user_update(P_Window *window)
|
||||
{
|
||||
Vec2 a = MulXformV2(G.world_to_ui_xf, collision_reuslt.a0);
|
||||
Vec2 b = MulXformV2(G.world_to_ui_xf, collision_reuslt.b0);
|
||||
draw_line(G.render_sig, a, b, thickness, color_line);
|
||||
draw_circle(G.render_sig, a, radius, color_a, 10);
|
||||
draw_circle(G.render_sig, b, radius, color_b, 10);
|
||||
D_DrawLine(G.render_sig, a, b, thickness, color_line);
|
||||
D_DrawCircle(G.render_sig, a, radius, color_a, 10);
|
||||
D_DrawCircle(G.render_sig, b, radius, color_b, 10);
|
||||
|
||||
Vec2 a_clipped = MulXformV2(G.world_to_ui_xf, collision_reuslt.a0_clipped);
|
||||
Vec2 b_clipped = MulXformV2(G.world_to_ui_xf, collision_reuslt.b0_clipped);
|
||||
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||
D_DrawLine(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||
D_DrawCircle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||
D_DrawCircle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||
}
|
||||
{
|
||||
Vec2 a = MulXformV2(G.world_to_ui_xf, collision_reuslt.a1);
|
||||
Vec2 b = MulXformV2(G.world_to_ui_xf, collision_reuslt.b1);
|
||||
draw_line(G.render_sig, a, b, thickness, color_line);
|
||||
draw_circle(G.render_sig, a, radius, color_a, 10);
|
||||
draw_circle(G.render_sig, b, radius, color_b, 10);
|
||||
D_DrawLine(G.render_sig, a, b, thickness, color_line);
|
||||
D_DrawCircle(G.render_sig, a, radius, color_a, 10);
|
||||
D_DrawCircle(G.render_sig, b, radius, color_b, 10);
|
||||
|
||||
Vec2 a_clipped = MulXformV2(G.world_to_ui_xf, collision_reuslt.a1_clipped);
|
||||
Vec2 b_clipped = MulXformV2(G.world_to_ui_xf, collision_reuslt.b1_clipped);
|
||||
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||
draw_circle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||
D_DrawLine(G.render_sig, a_clipped, b_clipped, thickness, color_line_clipped);
|
||||
D_DrawCircle(G.render_sig, a_clipped, radius, color_a_clipped, 10);
|
||||
D_DrawCircle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1585,8 +1585,8 @@ internal void user_update(P_Window *window)
|
||||
Vec2Array m = CLD_Menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
||||
//draw_poly(G.render_sig, m, color);
|
||||
D_DrawPolyLine(G.render_sig, m, 1, thickness, color);
|
||||
//D_DrawPoly(G.render_sig, m, color);
|
||||
}
|
||||
|
||||
/* Draw CLD_PointCloud */
|
||||
@ -1598,7 +1598,7 @@ internal void user_update(P_Window *window)
|
||||
|
||||
for (u64 i = 0; i < m.count; ++i) {
|
||||
Vec2 p = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||
draw_circle(G.render_sig, p, radius, color, 10);
|
||||
D_DrawCircle(G.render_sig, p, radius, color, 10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1612,8 +1612,8 @@ internal void user_update(P_Window *window)
|
||||
.count = collision_reuslt.prototype.len
|
||||
};
|
||||
for (u64 i = 0; i < m.count; ++i) m.points[i] = MulXformV2(G.world_to_ui_xf, m.points[i]);
|
||||
draw_poly_line(G.render_sig, m, 1, thickness, color);
|
||||
for (u64 i = 0; i < m.count; ++i) draw_circle(G.render_sig, m.points[i], 10, color, 10);
|
||||
D_DrawPolyLine(G.render_sig, m, 1, thickness, color);
|
||||
for (u64 i = 0; i < m.count; ++i) D_DrawCircle(G.render_sig, m.points[i], 10, color, 10);
|
||||
}
|
||||
|
||||
/* Draw simplex */
|
||||
@ -1631,18 +1631,18 @@ internal void user_update(P_Window *window)
|
||||
|
||||
if (simplex.len >= 1) {
|
||||
u32 color = simplex.len == 1 ? color_first : (simplex.len == 2 ? color_second : color_third);
|
||||
draw_circle(G.render_sig, simplex_array.points[0], thickness * 3, color, 10);
|
||||
D_DrawCircle(G.render_sig, simplex_array.points[0], thickness * 3, color, 10);
|
||||
}
|
||||
if (simplex.len >= 2) {
|
||||
u32 color = simplex.len == 2 ? color_first : color_second;
|
||||
draw_circle(G.render_sig, simplex_array.points[1], thickness * 3, color, 10);
|
||||
D_DrawCircle(G.render_sig, simplex_array.points[1], thickness * 3, color, 10);
|
||||
}
|
||||
if (simplex.len >= 3) {
|
||||
u32 color = color_first;
|
||||
draw_circle(G.render_sig, simplex_array.points[2], thickness * 3, color, 10);
|
||||
D_DrawCircle(G.render_sig, simplex_array.points[2], thickness * 3, color, 10);
|
||||
}
|
||||
if (simplex.len >= 2) {
|
||||
draw_poly_line(G.render_sig, simplex_array, simplex.len > 2, thickness, line_color);
|
||||
D_DrawPolyLine(G.render_sig, simplex_array, simplex.len > 2, thickness, line_color);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1654,7 +1654,7 @@ internal void user_update(P_Window *window)
|
||||
f32 arrowhead_height = 10;
|
||||
Vec2 start = MulXformV2(G.world_to_ui_xf, VEC2(0, 0));
|
||||
Vec2 end = MulXformV2(G.world_to_ui_xf, MulVec2(NormVec2(collision_reuslt.normal), len));
|
||||
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrowhead_height, color);
|
||||
D_DrawArrowLine(G.render_sig, start, end, arrow_thickness, arrowhead_height, color);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1669,7 +1669,7 @@ internal void user_update(P_Window *window)
|
||||
|
||||
Vec2 start = MulXformV2(G.world_to_ui_xf, xf.og);
|
||||
Vec2 end = MulXformV2(G.world_to_ui_xf, parent_xf.og);
|
||||
draw_arrow_line(G.render_sig, start, end, thickness, arrow_height, color);
|
||||
D_DrawArrowLine(G.render_sig, start, end, thickness, arrow_height, color);
|
||||
}
|
||||
|
||||
/* Draw camera rect */
|
||||
@ -1681,7 +1681,7 @@ internal void user_update(P_Window *window)
|
||||
Quad quad = MulXformQuad(quad_xf, CenteredUnitSquareQuad);
|
||||
quad = MulXformQuad(G.world_to_ui_xf, quad);
|
||||
|
||||
draw_quad_line(G.render_sig, quad, thickness, color);
|
||||
D_DrawQuadLine(G.render_sig, quad, thickness, color);
|
||||
}
|
||||
|
||||
EndTempArena(temp);
|
||||
@ -1697,7 +1697,7 @@ internal void user_update(P_Window *window)
|
||||
S_Texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
|
||||
Vec2 size = VEC2(t->width, t->height);
|
||||
Xform xf = XformFromTrs(TRS(.t = crosshair_pos, .s = size));
|
||||
draw_ui_rect(G.render_sig, DRAW_UI_RECT_PARAMS(.xf = xf, .texture = t->gp_texture));
|
||||
D_DrawUiRect(G.render_sig, D_UIRECTPARAMS(.xf = xf, .texture = t->gp_texture));
|
||||
}
|
||||
|
||||
/* FIXME: Enable this */
|
||||
@ -1909,7 +1909,7 @@ internal void user_update(P_Window *window)
|
||||
String dbg_text = ZI;
|
||||
dbg_text.text = PushDry(temp.arena, u8);
|
||||
dbg_text.len += get_ent_debug_text(temp.arena, ent).len;
|
||||
draw_text(G.render_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = dbg_text));
|
||||
draw_text(G.render_sig, D_TEXTPARAMS(.font = font, .pos = pos, .str = dbg_text));
|
||||
|
||||
EndTempArena(temp);
|
||||
}
|
||||
@ -2029,7 +2029,7 @@ internal void user_update(P_Window *window)
|
||||
|
||||
Vec2 pos = VEC2(10, G.ui_size.y);
|
||||
D_TextOffsetY offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM;
|
||||
draw_text(G.render_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = ColorWhite));
|
||||
draw_text(G.render_sig, D_TEXTPARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = ColorWhite));
|
||||
EndTempArena(temp);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user