2023-06-17 17:00:55 +00:00
|
|
|
inline b32 AreEqual(render_handle A, render_handle B)
|
|
|
|
{
|
|
|
|
b32 Result = false;
|
|
|
|
if((A.U64[0] == B.U64[0]) && (A.U64[1] == B.U64[1]) &&
|
|
|
|
(A.U64[2] == B.U64[2]) && (A.U64[3] == B.U64[3]))
|
|
|
|
{
|
|
|
|
Result = true;
|
|
|
|
}
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
inline v2_s32 GetTextureDim(render_handle Handle)
|
2023-06-17 17:00:55 +00:00
|
|
|
{
|
2023-06-21 16:59:36 +00:00
|
|
|
v2_s32 Result = V2S32(Handle.U32[2], Handle.U32[3]);
|
2023-06-17 17:00:55 +00:00
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline render_handle EmptyRenderHandle(void)
|
|
|
|
{
|
|
|
|
render_handle Result = {};
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define PushCommand(Group, type) (type *)PushCommand_(Group, Render_Command_##type, sizeof(type))
|
|
|
|
static void *PushCommand_(render_group *Group, render_command_type Type, u64 Size)
|
|
|
|
{
|
|
|
|
void *Result = 0;
|
|
|
|
|
|
|
|
vn_render_commands *Commands = Group->Commands;
|
|
|
|
|
|
|
|
u64 TotalSize = Size + sizeof(render_command_header);
|
|
|
|
|
|
|
|
u8 *PushBufferEnd = Commands->PushBufferBase + Commands->MaxPushBufferSize;
|
|
|
|
if((Commands->PushBufferAt + TotalSize) <= PushBufferEnd)
|
|
|
|
{
|
|
|
|
render_command_header *Header = (render_command_header *)Commands->PushBufferAt;
|
|
|
|
Header->Type = Type;
|
|
|
|
|
|
|
|
Commands->PushBufferAt += sizeof(*Header);
|
|
|
|
|
|
|
|
Group->CurrentCommand = Header;
|
|
|
|
|
|
|
|
Result = Commands->PushBufferAt;
|
|
|
|
Commands->PushBufferAt += Size;
|
2023-06-21 16:59:36 +00:00
|
|
|
Fill(Result, 0, Size);
|
2023-06-17 17:00:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
InvalidCodepath;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline render_group BeginRenderGroup(vn_render_commands *Commands)
|
|
|
|
{
|
|
|
|
render_group Group = {};
|
|
|
|
Group.Commands = Commands;
|
|
|
|
Group.ClipStack[0].Max = Commands->RenderDim;
|
|
|
|
return(Group);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PushClear(render_group *Group, v3 Color)
|
|
|
|
{
|
|
|
|
render_command_clear *Command = PushCommand(Group, render_command_clear);
|
|
|
|
Command->Color = Color;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline s32 GetTextureIndexForCommand(render_command_quads *Command, render_handle Handle)
|
|
|
|
{
|
|
|
|
s32 Result = -1;
|
|
|
|
|
|
|
|
for(s32 TextureIndex = 0;
|
|
|
|
TextureIndex < MAX_BOUND_TEXTURES;
|
|
|
|
++TextureIndex)
|
|
|
|
{
|
|
|
|
if(AreEqual(Command->Textures[TextureIndex], EmptyRenderHandle()))
|
|
|
|
{
|
|
|
|
Assert(Command->TexturesUsed == TextureIndex);
|
|
|
|
|
|
|
|
Command->Textures[TextureIndex] = Handle;
|
|
|
|
++Command->TexturesUsed;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(AreEqual(Command->Textures[TextureIndex], Handle))
|
|
|
|
{
|
|
|
|
Result = TextureIndex;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline u32 PackV4ToU32(v4 V)
|
|
|
|
{
|
|
|
|
u32 Result =
|
|
|
|
((u8)(Clamp01(V.x)*255.0)<<24) |
|
|
|
|
((u8)(Clamp01(V.y)*255.0)<<16) |
|
|
|
|
((u8)(Clamp01(V.z)*255.0)<<8) |
|
|
|
|
((u8)(Clamp01(V.w)*255.0)<<0);
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PushTexturedQuad(render_group *Group,
|
|
|
|
v2 P, v2 Dim,
|
|
|
|
v2 SourceP, v2 SourceDim,
|
|
|
|
v4 Color00, v4 Color10, v4 Color01, v4 Color11,
|
|
|
|
r32 CornerRadius, r32 EdgeSoftness, r32 BorderThickness,
|
|
|
|
render_handle Texture)
|
|
|
|
{
|
|
|
|
vn_render_commands *Commands = Group->Commands;
|
|
|
|
|
|
|
|
render_command_quads *Command = (render_command_quads *)(Group->CurrentCommand + 1);
|
|
|
|
s32 TextureIndex;
|
|
|
|
if(!(Group->CurrentCommand && Group->CurrentCommand->Type == Render_Command_render_command_quads &&
|
|
|
|
(TextureIndex = GetTextureIndexForCommand(Command, Texture)) != -1))
|
|
|
|
{
|
|
|
|
Command = PushCommand(Group, render_command_quads);
|
|
|
|
Command->QuadBufferIndex = Commands->QuadIndexCount;
|
|
|
|
TextureIndex = GetTextureIndexForCommand(Command, Texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
range2_r32 Clip = Group->ClipStack[Group->ClipStackUsed];
|
|
|
|
range2_r32 Dest = Range2R32(P, P + Dim);
|
|
|
|
|
|
|
|
v2 DestMin = Max(Dest.Min, Clip.Min);
|
|
|
|
v2 DestMax = Min(Dest.Max, Clip.Max);
|
|
|
|
|
2023-06-27 14:14:28 +00:00
|
|
|
if(InRange(Clip, P) || InRange(Clip, P + Dim))
|
2023-06-17 17:00:55 +00:00
|
|
|
{
|
|
|
|
v2 HalfSize = Dim*0.5;
|
|
|
|
|
|
|
|
v2 P00 = V2(DestMin.x, DestMin.y);
|
|
|
|
v2 P01 = V2(DestMin.x, DestMax.y);
|
|
|
|
v2 P10 = V2(DestMax.x, DestMin.y);
|
|
|
|
v2 P11 = V2(DestMax.x, DestMax.y);
|
|
|
|
v2 Center = P + HalfSize;
|
|
|
|
|
|
|
|
u32 Width = Texture.U32[2];
|
|
|
|
u32 Height = Texture.U32[3];
|
|
|
|
|
|
|
|
SourceP.x /= Width;
|
|
|
|
SourceP.y /= Height;
|
|
|
|
SourceDim.x /= Width;
|
|
|
|
SourceDim.y /= Height;
|
|
|
|
|
|
|
|
v2 Source00 = SourceP;
|
|
|
|
v2 Source01 = SourceP + V2(0, SourceDim.y);
|
|
|
|
v2 Source10 = SourceP + V2(SourceDim.x, 0);
|
|
|
|
v2 Source11 = SourceP + SourceDim;
|
|
|
|
|
|
|
|
s32 BaseVertex = Commands->QuadVertexCount;
|
|
|
|
|
|
|
|
quad_vertex *Vertex = Commands->QuadVertexBase + Commands->QuadVertexCount++;
|
|
|
|
Vertex->P = P00;
|
|
|
|
Vertex->SourceP = Source00;
|
|
|
|
Vertex->TextureIndex = TextureIndex;
|
|
|
|
Vertex->Color = PackV4ToU32(Color00);
|
|
|
|
Vertex->ToCenter = Center - P00;
|
|
|
|
Vertex->HalfSize = HalfSize;
|
|
|
|
Vertex->CornerRadius = CornerRadius;
|
|
|
|
Vertex->EdgeSoftness = EdgeSoftness;
|
|
|
|
Vertex->BorderThickness = BorderThickness;
|
|
|
|
|
|
|
|
Vertex = Commands->QuadVertexBase + Commands->QuadVertexCount++;
|
|
|
|
Vertex->P = P10;
|
|
|
|
Vertex->SourceP = Source10;
|
|
|
|
Vertex->TextureIndex = TextureIndex;
|
|
|
|
Vertex->Color = PackV4ToU32(Color10);
|
|
|
|
Vertex->ToCenter = Center - P10;
|
|
|
|
Vertex->HalfSize = HalfSize;
|
|
|
|
Vertex->CornerRadius = CornerRadius;
|
|
|
|
Vertex->EdgeSoftness = EdgeSoftness;
|
|
|
|
Vertex->BorderThickness = BorderThickness;
|
|
|
|
|
|
|
|
Vertex = Commands->QuadVertexBase + Commands->QuadVertexCount++;
|
|
|
|
Vertex->P = P01;
|
|
|
|
Vertex->SourceP = Source01;
|
|
|
|
Vertex->TextureIndex = TextureIndex;
|
|
|
|
Vertex->Color = PackV4ToU32(Color01);
|
|
|
|
Vertex->ToCenter = Center - P01;
|
|
|
|
Vertex->HalfSize = HalfSize;
|
|
|
|
Vertex->CornerRadius = CornerRadius;
|
|
|
|
Vertex->EdgeSoftness = EdgeSoftness;
|
|
|
|
Vertex->BorderThickness = BorderThickness;
|
|
|
|
|
|
|
|
Vertex = Commands->QuadVertexBase + Commands->QuadVertexCount++;
|
|
|
|
Vertex->P = P11;
|
|
|
|
Vertex->SourceP = Source11;
|
|
|
|
Vertex->TextureIndex = TextureIndex;
|
|
|
|
Vertex->Color = PackV4ToU32(Color11);
|
|
|
|
Vertex->ToCenter = Center - P11;
|
|
|
|
Vertex->HalfSize = HalfSize;
|
|
|
|
Vertex->CornerRadius = CornerRadius;
|
|
|
|
Vertex->EdgeSoftness = EdgeSoftness;
|
|
|
|
Vertex->BorderThickness = BorderThickness;
|
|
|
|
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 0;
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 3;
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 1;
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 0;
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 2;
|
|
|
|
Commands->QuadIndexBase[Commands->QuadIndexCount++] = BaseVertex + 3;
|
|
|
|
|
|
|
|
++Command->QuadCount;
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int BreakMe = 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PushQuad(render_group *Group, v2 P, v2 Dim,
|
|
|
|
v4 Color00, v4 Color01, v4 Color10, v4 Color11,
|
|
|
|
r32 CornerRadius, r32 EdgeSoftness, r32 BorderThickness)
|
|
|
|
{
|
|
|
|
PushTexturedQuad(Group, P, Dim, V2(0, 0), V2(0, 0), Color00, Color01, Color10, Color11,
|
|
|
|
CornerRadius, EdgeSoftness, BorderThickness, Group->Commands->WhiteTexture);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PushQuad(render_group *Group, v2 P, v2 Dim,
|
|
|
|
v4 Color,
|
|
|
|
r32 CornerRadius, r32 EdgeSoftness, r32 BorderThickness)
|
|
|
|
{
|
|
|
|
PushTexturedQuad(Group, P, Dim, V2(0, 0), V2(0, 0), Color, Color, Color, Color,
|
|
|
|
CornerRadius, EdgeSoftness, BorderThickness, Group->Commands->WhiteTexture);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PushClip(render_group *Group, range2_r32 Clip)
|
|
|
|
{
|
|
|
|
Assert(Group->ClipStackUsed + 1 < ArrayCount(Group->ClipStack));
|
|
|
|
|
|
|
|
Group->ClipStack[++Group->ClipStackUsed] = Clip;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void PopClip(render_group *Group)
|
|
|
|
{
|
|
|
|
Assert(Group->ClipStackUsed > 0);
|
|
|
|
|
|
|
|
Group->ClipStack[--Group->ClipStackUsed];
|
|
|
|
}
|