get render task queue system working for triles

This commit is contained in:
Tuomas Katajisto 2025-10-07 21:27:13 +03:00
parent 0a123efc55
commit e236410fd0
6 changed files with 124 additions and 74 deletions

View File

@ -333,48 +333,13 @@ tick_level_editor :: () {
}
}
draw_world_triles :: (cam: *Camera, world: *World) {
mvp := create_viewproj(cam);
vs_params : Trile_Vs_Params;
vs_params.mvp = mvp.floats;
vs_params.camera = cam.position.component;
sg_apply_pipeline(gPipelines.trile.pipeline);
world_conf : Trile_World_Config;
world_config_to_shader_type(*world.conf, *world_conf);
draw_world_triles :: (world: *World) {
for world.positions {
// @ToDo: This fucking sucks. We are appending 4096 Vector4s to the
// instance buffer per trile type in level even if there is only one
// trile of that type. Should be an easy fix, fix at the latest when
// making a reusable version of trile rendering.
positions : [4096]Vector4;
trilegfx := get_trile_gfx(it.trileName);
idx : s32 = 0;
for pos : it.positions {
positions[idx] = pos;
idx += 1;
}
offset := sg_append_buffer(gPipelines.trile.bind.vertex_buffers[3], *(sg_range.{
ptr = positions.data,
size = size_of(type_of(positions)),
}));
bindings : sg_bindings;
bindings.vertex_buffers[0] = trilegfx.vertex_buffer;
bindings.vertex_buffers[1] = trilegfx.normal_buffer;
bindings.vertex_buffers[2] = trilegfx.centre_buffer;
bindings.vertex_buffers[3] = gPipelines.trile.bind.vertex_buffers[3];
bindings.vertex_buffer_offsets[3] = offset;
bindings.samplers[0] = gPipelines.trile.bind.samplers[0];
bindings.images[0] = trilegfx.trixel_colors;
sg_apply_bindings(*bindings);
sg_apply_uniforms(UB_trile_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params))}));
sg_apply_uniforms(UB_trile_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
sg_draw(0, cast(s32) trilegfx.vertex_count, idx);
triletask := Rendering_Task_Trile.{};
triletask.trile = it.trileName;
triletask.positions = it.positions;
triletask.worldConf = *world.conf;
add_rendering_task(triletask);
}
}
@ -385,7 +350,7 @@ draw_level_editor :: () {
add_rendering_task(skytask);
groundtask := Rendering_Task_Ground.{type = .GROUND, world = *world};
add_rendering_task(groundtask);
// draw_world_triles(*cam, *world);
draw_world_triles(*world);
}
draw_level_editor_ui :: (theme: *GR.Overall_Theme) {

27
src/meta/hacks.jai Normal file
View File

@ -0,0 +1,27 @@
// This function is causing issues and I don't want to deal with it.
remove_getrect_custom_cursor :: (message: *Message, w: *Workspace) {
if message.kind == {
case .TYPECHECKED;
tc_message := cast(*Message_Typechecked) message;
for tc : tc_message.procedure_bodies {
body := tc.expression;
assert(body.block != null);
if body.header.name == "pointer_end_frame" && !endframe_modified {
print("Found and killed %\n", body.header.name);
new_statements : [..] *Code_Node;
body.block.statements = new_statements;
compiler_modify_procedure(message.workspace, body);
endframe_modified = true;
}
if body.header.name == "getrect_set_pointer_image" && !pointerimage_modified {
print("Found and killed %\n", body.header.name);
new_statements : [..] *Code_Node;
body.block.statements = new_statements;
compiler_modify_procedure(message.workspace, body);
pointerimage_modified = true;
}
}
}
}

View File

@ -1,39 +1,13 @@
#load "ascii.jai";
#load "pack.jai";
#load "lint.jai";
#load "hacks.jai";
#load "console_commands.jai";
#load "shaderload.jai";
endframe_modified := false;
pointerimage_modified := false;
// This function is causing issues and I don't want to deal with it.
remove_getrect_custom_cursor :: (message: *Message, w: *Workspace) {
if message.kind == {
case .TYPECHECKED;
tc_message := cast(*Message_Typechecked) message;
for tc : tc_message.procedure_bodies {
body := tc.expression;
assert(body.block != null);
if body.header.name == "pointer_end_frame" && !endframe_modified {
print("Found and killed %\n", body.header.name);
new_statements : [..] *Code_Node;
body.block.statements = new_statements;
compiler_modify_procedure(message.workspace, body);
endframe_modified = true;
}
if body.header.name == "getrect_set_pointer_image" && !pointerimage_modified {
print("Found and killed %\n", body.header.name);
new_statements : [..] *Code_Node;
body.block.statements = new_statements;
compiler_modify_procedure(message.workspace, body);
pointerimage_modified = true;
}
}
}
}
custom_message_handler :: (message: *Message, w: *Workspace) {
lint_checks(message);

View File

@ -16,6 +16,8 @@ Render_Command_Type :: enum {
SET_CAMERA;
DRAW_GROUND;
GENERATE_GROUND;
ADD_TRILE_POSITIONS;
DRAW_TRILE_POSITIONS;
}
Render_Command :: struct {
@ -24,21 +26,39 @@ Render_Command :: struct {
Render_Command_Sky :: struct {
#as using c : Render_Command;
c.type = .DRAW_SKY;
worldConfig : *World_Config;
}
Render_Command_Add_Trile_Positions :: struct {
#as using c : Render_Command;
c.type = .ADD_TRILE_POSITIONS;
positions : []Vector4;
}
Render_Command_Draw_Trile_Positions :: struct {
#as using c : Render_Command;
c.type = .DRAW_TRILE_POSITIONS;
trile : string;
amount : s32;
conf : *World_Config;
}
Render_Command_Draw_Ground :: struct {
#as using c : Render_Command;
c.type = .DRAW_GROUND;
worldConfig : *World_Config;
}
Render_Command_Generate_Ground_Texture :: struct {
#as using c : Render_Command;
c.type = .GENERATE_GROUND;
world : *World;
}
Render_Command_Set_Camera :: struct {
#as using c : Render_Command;
c.type = .SET_CAMERA;
camera: Camera;
}

View File

@ -1,7 +1,16 @@
camera: Camera;
trile_offsets : [..]s32;
current_trile_offset_index : s32 = 0;
backend_handle_command :: (cmd: *Render_Command) {
if cmd.type == {
case .ADD_TRILE_POSITIONS;
add_command := cast(*Render_Command_Add_Trile_Positions)cmd;
backend_add_trile_positions(add_command.positions);
case .DRAW_TRILE_POSITIONS;
draw_command := cast(*Render_Command_Draw_Trile_Positions)cmd;
backend_draw_trile_positions(draw_command.trile, draw_command.amount, draw_command.conf);
case .DRAW_SKY;
sky_command := cast(*Render_Command_Sky)cmd;
backend_draw_sky(sky_command.worldConfig);
@ -18,6 +27,43 @@ backend_handle_command :: (cmd: *Render_Command) {
}
}
backend_add_trile_positions :: (positions : []Vector4) {
offset := sg_append_buffer(gPipelines.trile.bind.vertex_buffers[3], *(sg_range.{
ptr = positions.data,
size = size_of(Vector4) * cast(u64)positions.count,
}));
array_add(*trile_offsets, offset);
}
backend_draw_trile_positions :: (trile : string, amount : s32, worldConf: *World_Config) {
mvp := create_viewproj(*camera);
vs_params : Trile_Vs_Params;
vs_params.mvp = mvp.floats;
vs_params.camera = camera.position.component;
sg_apply_pipeline(gPipelines.trile.pipeline);
world_conf : Trile_World_Config;
world_config_to_shader_type(worldConf, *world_conf);
offset := trile_offsets[current_trile_offset_index];
current_trile_offset_index += 1;
trilegfx := get_trile_gfx(trile);
bindings : sg_bindings;
bindings.vertex_buffers[0] = trilegfx.vertex_buffer;
bindings.vertex_buffers[1] = trilegfx.normal_buffer;
bindings.vertex_buffers[2] = trilegfx.centre_buffer;
bindings.vertex_buffers[3] = gPipelines.trile.bind.vertex_buffers[3];
bindings.vertex_buffer_offsets[3] = offset;
bindings.samplers[0] = gPipelines.trile.bind.samplers[0];
bindings.images[0] = trilegfx.trixel_colors;
sg_apply_bindings(*bindings);
sg_apply_uniforms(UB_trile_vs_params, *(sg_range.{ ptr = *vs_params, size = size_of(type_of(vs_params))}));
sg_apply_uniforms(UB_trile_world_config, *(sg_range.{ptr = *world_conf, size = size_of(type_of(world_conf))}));
sg_draw(0, cast(s32) trilegfx.vertex_count, amount);
}
backend_draw_sky :: (wc: *World_Config) {
mvp := create_viewproj(*camera);
vs_params : Sky_Vs_Params;
@ -60,18 +106,21 @@ backend_process_command_buckets :: () {
backend_handle_command(it);
}
current_trile_offset_index = 0; // This is not optimal, but it is nice and simple.
// 2. Reflection pass
sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = gPipelines.plane.attachments}));
for render_command_buckets.reflection {
backend_handle_command(it);
}
sg_end_pass();
current_trile_offset_index = 0; // This is not optimal, but it is nice and simple.
// 3. Main pass
sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
for render_command_buckets.main {
backend_handle_command(it);
}
current_trile_offset_index = 0; // This is not optimal, but it is nice and simple.
// 3.2 Draw the UI. @ToDo: This should probably happen after post processing once we have that.
// Also, it's kind of stupid that this has it's own command system. It should be moved to using the
// same backend commands we are using for other rendering.
@ -91,4 +140,5 @@ backend_process_command_buckets :: () {
array_reset_keeping_memory(*render_command_buckets.reflection);
array_reset_keeping_memory(*render_command_buckets.main);
array_reset_keeping_memory(*render_command_buckets.ui);
array_reset_keeping_memory(*trile_offsets);
}

View File

@ -31,6 +31,14 @@ Rendering_Task_Ground :: struct {
world : *World;
}
Rendering_Task_Trile :: struct {
#as using t : Rendering_Task;
t.type = .TRILE;
trile : string;
positions : []Vector4;
worldConf : *World_Config;
}
Rendering_Task_Set_Camera :: struct {
#as using t : Rendering_Task;
camera : Camera;
@ -51,28 +59,34 @@ rendering_tasklist : [..]*Rendering_Task;
tasks_to_commands :: () {
for rendering_tasklist {
if it.type == {
case .TRILE;
trileTask := (cast(*Rendering_Task_Trile)it);
addPositionsCmd := New(Render_Command_Add_Trile_Positions,, temp);
addPositionsCmd.positions = trileTask.positions;
array_add(*render_command_buckets.setup, addPositionsCmd);
drawPositionsCmd := New(Render_Command_Draw_Trile_Positions,, temp);
drawPositionsCmd.trile = trileTask.trile;
drawPositionsCmd.amount = cast(s32)trileTask.positions.count;
drawPositionsCmd.conf = trileTask.worldConf;
array_add(*render_command_buckets.reflection, drawPositionsCmd);
array_add(*render_command_buckets.main, drawPositionsCmd);
case .SKY;
command := New(Render_Command_Sky,, temp);
command.type = .DRAW_SKY;
command.worldConfig = (cast(*Rendering_Task_Sky)it).worldConfig;
array_add(*render_command_buckets.reflection, command);
array_add(*render_command_buckets.main, command);
case .GROUND;
commandDrawGround := New(Render_Command_Draw_Ground,, temp);
commandDrawGround.type = .DRAW_GROUND;
commandDrawGround.worldConfig = *(cast(*Rendering_Task_Ground)it).world.conf;
commandGenGround := New(Render_Command_Generate_Ground_Texture,, temp);
commandGenGround.type = .GENERATE_GROUND;
commandGenGround.world = (cast(*Rendering_Task_Ground)it).world;
array_add(*render_command_buckets.setup, commandGenGround);
array_add(*render_command_buckets.main, commandDrawGround);
case .SET_CAMERA;
command := New(Render_Command_Set_Camera,, temp);
command.type = .SET_CAMERA;
command.camera = (cast(*Rendering_Task_Set_Camera)it).camera;
array_add(*render_command_buckets.main, command);
commandReflected := New(Render_Command_Set_Camera,, temp);
commandReflected.type = .SET_CAMERA;
commandReflected.camera = (cast(*Rendering_Task_Set_Camera)it).camera;
commandReflected.camera.target *= Vector3.{1, -1, 1};
commandReflected.camera.position *= Vector3.{1, -1, 1};