trueno/src/rendering/arbtri.jai

142 lines
3.7 KiB
Plaintext

Arb_Tri :: struct {
pos : [3]Vector3;
col : [3]Vector4;
uv : [3]Vector2;
}
Arb_Draw_Command_Type :: enum {
INVALID;
DRAW_TEXT;
FLUSH_TRI;
SET_TEXTURE;
PREPARE_TEXT;
FONT_BOUNDARY;
QUAD_OCCLUDER;
REMOVE_TEXTURE;
SET_SCISSOR;
REMOVE_SCISSOR;
}
Arb_Draw_Command :: struct {
type : Arb_Draw_Command_Type = .INVALID;
// for triangles
tri_offset : int = 0;
tri_count : int = 0;
texture : *Ui_Texture;
// for text
layer: s32 = 0;
scissor: Ui_Rect;
}
Arb_Tri_State :: struct {
active : bool = false;
trilist : [..]Arb_Tri;
command_list : [..]Arb_Draw_Command;
latest_flush : int = 0;
}
arbTriState : Arb_Tri_State;
init_arb_state :: () {
gPipelines.arbtri.bind.images[0] = default_texture.tex;
array_reset_keeping_memory(*arbTriState.trilist);
array_reset_keeping_memory(*arbTriState.command_list);
arbTriState.active = true;
arbTriState.latest_flush = 0;
}
arb_tri_command_add :: (command: Arb_Draw_Command) {
if !arbTriState.active {
init_arb_state();
}
array_add(*arbTriState.command_list, command);
}
arb_tri_add :: (tri: Arb_Tri) {
if !arbTriState.active {
init_arb_state();
}
array_add(*arbTriState.trilist, tri);
}
transform_to_screen_x :: (coord: float) -> float {
w, h := get_window_size();
return (coord / cast(float) w) * 2.0 - 1.0;
}
transform_to_screen_y :: (coord: float) -> float {
w, h := get_window_size();
return (coord / cast(float) h) * 2.0 - 1.0;
}
arb_tri_flush :: () {
if !arbTriState.active {
return;
}
arbTriState.active = false;
for tri, i : arbTriState.trilist {
bgn := i * 3 * 9;
for 0..2 {
gArbtriMem[bgn + it * 9 + 0] = transform_to_screen_x(tri.pos[it].x);
gArbtriMem[bgn + it * 9 + 1] = transform_to_screen_y(tri.pos[it].y) * -1.0;
gArbtriMem[bgn + it * 9 + 2] = 0;
gArbtriMem[bgn + it * 9 + 3] = tri.col[it].x;
gArbtriMem[bgn + it * 9 + 4] = tri.col[it].y;
gArbtriMem[bgn + it * 9 + 5] = tri.col[it].z;
gArbtriMem[bgn + it * 9 + 6] = tri.col[it].w;
gArbtriMem[bgn + it * 9 + 7] = tri.uv[it].x;
gArbtriMem[bgn + it * 9 + 8] = tri.uv[it].y;
}
}
sg_update_buffer(gPipelines.arbtri.bind.vertex_buffers[0], *(sg_range.{ ptr = gArbtriMem.data, size = size_of(type_of(gArbtriMem)) }));
flush_arb_commands();
}
debug_arb_flush : bool : false;
layer : s32 = 0;
flush_arb_commands :: () {
sfons_flush(state.fons); // All the text has been drawn, now flush it to the atlas.
layer = 0;
if debug_arb_flush then print(" --- !BEGIN FLUSH! ---- \n");
for arbTriState.command_list {
if debug_arb_flush then print("[command] %\n", it.type);
if it.type == {
case .SET_TEXTURE;
gPipelines.arbtri.bind.images[0] = it.texture.tex;
gCurrentTexture = it.texture;
case .REMOVE_TEXTURE;
gCurrentTexture = null;
case .FLUSH_TRI;
sg_apply_pipeline(gPipelines.arbtri.pipeline);
sg_apply_bindings(*gPipelines.arbtri.bind);
sg_draw(xx (it.tri_offset * 3), xx (it.tri_count * 3), 1);
case .PREPARE_TEXT;
case .SET_SCISSOR;
s := it.scissor;
w,h := get_window_size();
sgl_viewport(0,0,w,h,true);
sg_apply_scissor_rect(s.x, s.y, s.w, s.h, true);
case .REMOVE_SCISSOR;
w,h := get_window_size();
sg_apply_scissor_rect(0, 0, w, w, true);
case .DRAW_TEXT;
sgl_draw_layer(it.layer);
}
}
}