some tacoma fixes and also particle fixes

This commit is contained in:
Tuomas Katajisto 2026-03-29 16:40:52 +03:00
parent 4d9e175172
commit c67d8253db
15 changed files with 821 additions and 644 deletions

Binary file not shown.

View File

@ -24,4 +24,139 @@ VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure VK_KHR_acceleration_structure
VK_KHR_ray_query VK_KHR_ray_query
BLAS Compaction: 2.1MB -> 0.7MB (1.4MB saved, 66.1% smaller) BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)
_______________
Vulkan Version:
- available: 1.4.309
- requesting: 1.3.0
______________________
Used Instance Layers :
VK_LAYER_KHRONOS_validation
Used Instance Extensions :
____________________
Devices : 1
0: AMD Radeon RX 6950 XT
- Compatible
Compatible physical devices found : 1
Using Device:
- Device Name : AMD Radeon RX 6950 XT
- Vendor : AMD
- Driver Version : 2.0.341
- API Version : 1.4.308
- Device Type : Discrete GPU
________________________
Used Device Extensions :
VK_KHR_deferred_host_operations
VK_KHR_acceleration_structure
VK_KHR_ray_query
BLAS Compaction: 2.4MB -> 0.8MB (1.6MB saved, 66.1% smaller)

Binary file not shown.

View File

@ -32,8 +32,9 @@ Trile_Set :: struct {
} }
World_Trile :: struct { World_Trile :: struct {
index : s32; index : s32;
position : Vector3; position : Vector3;
orientation : s32;
} }
World :: struct { World :: struct {

View File

@ -1,4 +1,4 @@
master_volume 1 master_volume 0.642776
music_volume 0.5 music_volume 0.522385
sfx_volume 1 sfx_volume 1
fullscreen 0 fullscreen 1

View File

@ -41,6 +41,7 @@ Asset_Manager :: struct {
loadedPacks : [..]Loaded_Pack; loadedPacks : [..]Loaded_Pack;
pending_hot_reload : bool; pending_hot_reload : bool;
hot_reload_unpause_pending : bool; hot_reload_unpause_pending : bool;
frames_waited : int;
} }
g_asset_manager : Asset_Manager; g_asset_manager : Asset_Manager;
@ -421,22 +422,27 @@ asset_manager_tick :: () {
} }
if !g_asset_manager.is_fetching && g_asset_manager.fetch_queue.count > 0 { if !g_asset_manager.is_fetching && g_asset_manager.fetch_queue.count > 0 {
req := g_asset_manager.fetch_queue[0]; if g_asset_manager.frames_waited < 3 {
// Ordered remove from front to preserve queue priority. g_asset_manager.frames_waited += 1;
for i: 0..g_asset_manager.fetch_queue.count - 2 { } else {
g_asset_manager.fetch_queue[i] = g_asset_manager.fetch_queue[i + 1]; g_asset_manager.frames_waited = 0;
req := g_asset_manager.fetch_queue[0];
// Ordered remove from front to preserve queue priority.
for i: 0..g_asset_manager.fetch_queue.count - 2 {
g_asset_manager.fetch_queue[i] = g_asset_manager.fetch_queue[i + 1];
}
g_asset_manager.fetch_queue.count -= 1;
g_asset_manager.current_fetch = req;
g_asset_manager.is_fetching = true;
buf_ptr, buf_size := buffer_for_fetch(req.type);
sfetch_send(*(sfetch_request_t.{
path = to_c_string(req.path),
callback = fetch_callback,
buffer = .{ ptr = buf_ptr, size = buf_size },
}));
} }
g_asset_manager.fetch_queue.count -= 1;
g_asset_manager.current_fetch = req;
g_asset_manager.is_fetching = true;
buf_ptr, buf_size := buffer_for_fetch(req.type);
sfetch_send(*(sfetch_request_t.{
path = to_c_string(req.path),
callback = fetch_callback,
buffer = .{ ptr = buf_ptr, size = buf_size },
}));
} }
sfetch_dowork(); sfetch_dowork();

View File

@ -48,11 +48,11 @@ draw_editor_ui :: (theme: *GR.Overall_Theme) {
GR.label(r, tprint("Trueno v%.%", V_MAJOR, V_MINOR), *t_label_left(theme)); GR.label(r, tprint("Trueno v%.%", V_MAJOR, V_MINOR), *t_label_left(theme));
r.x = 100*vw - r.w; r.x = 100*vw - r.w;
if keybind_button(r, "Level studio", .STUDIO_LEVEL, *t_button_selectable(theme, current_editor_view == .Level_Editor)) then current_editor_view = .Level_Editor; if keybind_button(r, "Level studio", .STUDIO_LEVEL, *t_button_selectable(theme, current_editor_view == .Level_Editor)) { clear_particles(); current_editor_view = .Level_Editor; }
r.x -= r.w; r.x -= r.w;
if keybind_button(r, "Trile studio", .STUDIO_TRILE, *t_button_selectable(theme, current_editor_view == .Trile_Editor)) then current_editor_view = .Trile_Editor; if keybind_button(r, "Trile studio", .STUDIO_TRILE, *t_button_selectable(theme, current_editor_view == .Trile_Editor)) { clear_particles(); current_editor_view = .Trile_Editor; }
r.x -= r.w; r.x -= r.w;
if keybind_button(r, "Particle studio", .STUDIO_MATERIAL, *t_button_selectable(theme, current_editor_view == .Particle_Editor)) then current_editor_view = .Particle_Editor; if keybind_button(r, "Particle studio", .STUDIO_MATERIAL, *t_button_selectable(theme, current_editor_view == .Particle_Editor)) { clear_particles(); current_editor_view = .Particle_Editor; }
if current_editor_view == { if current_editor_view == {
case .Trile_Editor; case .Trile_Editor;
@ -94,6 +94,7 @@ tick_editor_ui :: () {
in_editor_view = !in_editor_view; in_editor_view = !in_editor_view;
g_mixer.paused = in_editor_view; g_mixer.paused = in_editor_view;
if !in_editor_view then bypass_postprocess = false; if !in_editor_view then bypass_postprocess = false;
clear_particles();
} }
#if !FLAG_RELEASE_BUILD && OS != .WASM { #if !FLAG_RELEASE_BUILD && OS != .WASM {

View File

@ -495,6 +495,7 @@ remove_trile :: (x: s32, y: s32, z: s32) {
tick_level_editor :: () { tick_level_editor :: () {
#if FLAG_TACOMA_ENABLED { rdm_bake_tick(); } #if FLAG_TACOMA_ENABLED { rdm_bake_tick(); }
tick_level_editor_camera(); tick_level_editor_camera();
tick_particles(cast(float)delta_time);
if is_action_start(Editor_Action.SAVE) then sworld(); if is_action_start(Editor_Action.SAVE) then sworld();
@ -714,9 +715,9 @@ get_trile_at :: (world: *World, wx: s32, wy: s32, wz: s32) -> (name: string, ori
find_emitter_at :: (world: *World, x: s32, y: s32, z: s32) -> (idx: s32, found: bool) { find_emitter_at :: (world: *World, x: s32, y: s32, z: s32) -> (idx: s32, found: bool) {
for inst, i: world.emitter_instances { for inst, i: world.emitter_instances {
ix := cast(s32)inst.position.x; ix := cast(s32)floor(inst.position.x);
iy := cast(s32)inst.position.y; iy := cast(s32)floor(inst.position.y);
iz := cast(s32)inst.position.z; iz := cast(s32)floor(inst.position.z);
if ix == x && iy == y && iz == z then return cast(s32)i, true; if ix == x && iy == y && iz == z then return cast(s32)i, true;
} }
return -1, false; return -1, false;

View File

@ -196,5 +196,5 @@ draw_particle_editor :: () {
} }
tick_particle_editor :: () { tick_particle_editor :: () {
tick_particles(cast(float)delta_time); tick_particles_physics(cast(float)delta_time);
} }

View File

@ -182,7 +182,7 @@ rdm_bake_start :: (world: World, quality: s32, include_water: bool, chunk_keys:
world_trile_idx := cast(s32) world_triles.count; world_trile_idx := cast(s32) world_triles.count;
wx, wy, wz := chunk_local_to_world(chunk.coord, inst.x, inst.y, inst.z); wx, wy, wz := chunk_local_to_world(chunk.coord, inst.x, inst.y, inst.z);
wpos := Vector3.{cast(float) wx, cast(float) wy, cast(float) wz}; wpos := Vector3.{cast(float) wx, cast(float) wy, cast(float) wz};
array_add(*world_triles, Tacoma.World_Trile.{idx, wpos}); array_add(*world_triles, Tacoma.World_Trile.{idx, wpos, cast(s32) inst.orientation});
array_add(*world_trile_roughnesses, roughness_mask); array_add(*world_trile_roughnesses, roughness_mask);
if should_bake { if should_bake {
@ -506,7 +506,7 @@ tacoma_start :: (world: World, include_water: bool) {
for inst: group.instances { for inst: group.instances {
wx, wy, wz := chunk_local_to_world(chunk.coord, inst.x, inst.y, inst.z); wx, wy, wz := chunk_local_to_world(chunk.coord, inst.x, inst.y, inst.z);
array_add(*world_triles, Tacoma.World_Trile.{idx, Vector3.{cast(float) wx, cast(float) wy, cast(float) wz}}); array_add(*world_triles, Tacoma.World_Trile.{idx, Vector3.{cast(float) wx, cast(float) wy, cast(float) wz}, cast(s32) inst.orientation});
} }
} }
} }

View File

@ -100,7 +100,7 @@ init :: () {
logger = .{ func = slog_func }, logger = .{ func = slog_func },
})); }));
asset_manager_init(); asset_manager_init();
Thread.init(*g_mixer.mutex); #if OS != .WASM { Thread.init(*g_mixer.mutex); }
audio_init_thread_context(); audio_init_thread_context();
saudio_setup(*(saudio_desc.{ saudio_setup(*(saudio_desc.{
logger = .{ func = slog_func }, logger = .{ func = slog_func },
@ -108,7 +108,7 @@ init :: () {
})); }));
stm_setup(); stm_setup();
state.dpi_scale = sapp_dpi_scale(); state.dpi_scale = sapp_dpi_scale();
atlas_dim := round_pow2(512.0 * state.dpi_scale); atlas_dim := round_pow2(1024.0 * state.dpi_scale);
fons_context := sfons_create(*(sfons_desc_t.{ fons_context := sfons_create(*(sfons_desc_t.{
width = atlas_dim, width = atlas_dim,
height = atlas_dim, height = atlas_dim,
@ -186,7 +186,7 @@ frame :: () {
add_frame_profiling_point("After asset manager tick"); add_frame_profiling_point("After asset manager tick");
if !mandatory_loads_done() { if !mandatory_loads_done() {
input_per_frame_event_and_flag_update(); print("Mandatory loads not done!!\n");
return; return;
} }
@ -195,6 +195,8 @@ frame :: () {
if init_after_core_done { if init_after_core_done {
fonsClearState(state.fons); fonsClearState(state.fons);
draw_loading_screen(); draw_loading_screen();
tick_ui();
ui_pass();
render(); render();
reset_temporary_storage(); reset_temporary_storage();
} }
@ -251,7 +253,7 @@ frame :: () {
ui_clear_mouse_occluders(); ui_clear_mouse_occluders();
ui_pass(); ui_pass();
add_frame_profiling_point("After UI draw"); add_frame_profiling_point("After UI draw");
prepare_text(debug_font, tprint("frametime: % ms", latest_frametime * 1000)); #if !FLAG_RELEASE_BUILD { prepare_text(debug_font, tprint("frametime: % ms", latest_frametime * 1000)); }
draw_prepared_text(debug_font, 10, 10, .{0.0, 1.0, 0.0, 1.0}); draw_prepared_text(debug_font, 10, 10, .{0.0, 1.0, 0.0, 1.0});
#if !FLAG_RELEASE_BUILD { draw_editor(); } #if !FLAG_RELEASE_BUILD { draw_editor(); }
add_particle_render_tasks(); add_particle_render_tasks();
@ -272,6 +274,7 @@ frame :: () {
} }
cleanup :: () { cleanup :: () {
log_info("Cleanup called....");
audio_cleanup(); audio_cleanup();
sg_shutdown(); sg_shutdown();
} }

View File

@ -45,7 +45,11 @@ MAX_PARTICLES : s32 : 2048;
g_particles : [2048] Particle; g_particles : [2048] Particle;
g_emitter_defs : [..] Particle_Emitter_Config; g_emitter_defs : [..] Particle_Emitter_Config;
tick_particles :: (dt: float) { clear_particles :: () {
for *p: g_particles p.alive = false;
}
tick_particles_physics :: (dt: float) {
for *p: g_particles { for *p: g_particles {
if !p.alive then continue; if !p.alive then continue;
p.age += dt; p.age += dt;
@ -56,7 +60,9 @@ tick_particles :: (dt: float) {
p.velocity.y -= p.gravity * dt; p.velocity.y -= p.gravity * dt;
p.position += p.velocity * dt; p.position += p.velocity * dt;
} }
}
tick_world_emitters :: (dt: float) {
curworld := get_current_world(); curworld := get_current_world();
if !curworld.valid then return; if !curworld.valid then return;
for *inst: curworld.world.emitter_instances { for *inst: curworld.world.emitter_instances {
@ -74,6 +80,11 @@ tick_particles :: (dt: float) {
} }
} }
tick_particles :: (dt: float) {
tick_particles_physics(dt);
tick_world_emitters(dt);
}
tick_emitter_instance :: (inst: *Particle_Emitter_Instance, dt: float) { tick_emitter_instance :: (inst: *Particle_Emitter_Instance, dt: float) {
if !inst.active then return; if !inst.active then return;
if inst.definition == null then return; if inst.definition == null then return;

View File

@ -129,30 +129,34 @@ update_fonts_for_screen :: () {
} }
save_settings :: () { save_settings :: () {
file :: #import "File"; #if OS != .WASM {
builder : String_Builder; file :: #import "File";
append(*builder, tprint("master_volume %\n", g_mixer.config.masterVolume)); builder : String_Builder;
append(*builder, tprint("music_volume %\n", g_mixer.config.musicVolume)); append(*builder, tprint("master_volume %\n", g_mixer.config.masterVolume));
append(*builder, tprint("sfx_volume %\n", g_mixer.config.soundEffectVolume)); append(*builder, tprint("music_volume %\n", g_mixer.config.musicVolume));
append(*builder, tprint("fullscreen %\n", cast(s32) sapp_is_fullscreen())); append(*builder, tprint("sfx_volume %\n", g_mixer.config.soundEffectVolume));
file.write_entire_file(CONFIG_PATH, builder_to_string(*builder,, allocator = temp)); append(*builder, tprint("fullscreen %\n", cast(s32) sapp_is_fullscreen()));
file.write_entire_file(CONFIG_PATH, builder_to_string(*builder,, allocator = temp));
}
} }
load_settings :: () { load_settings :: () {
file :: #import "File"; #if OS != .WASM {
data, ok := file.read_entire_file(CONFIG_PATH,, allocator = temp); file :: #import "File";
if !ok then return; data, ok := file.read_entire_file(CONFIG_PATH,, allocator = temp);
if !ok then return;
text := cast(string) data; text := cast(string) data;
while text.count > 0 { while text.count > 0 {
line := consume_line(*text); line := consume_line(*text);
if line.count == 0 then continue; if line.count == 0 then continue;
key, val := split_first(line, #char " "); key, val := split_first(line, #char " ");
if key == "master_volume" then g_mixer.config.masterVolume = parse_float(val); if key == "master_volume" then g_mixer.config.masterVolume = parse_float(val);
if key == "music_volume" then g_mixer.config.musicVolume = parse_float(val); if key == "music_volume" then g_mixer.config.musicVolume = parse_float(val);
if key == "sfx_volume" then g_mixer.config.soundEffectVolume = parse_float(val); if key == "sfx_volume" then g_mixer.config.soundEffectVolume = parse_float(val);
if key == "fullscreen" { if key == "fullscreen" {
if (parse_int(val) != 0) != sapp_is_fullscreen() then sapp_toggle_fullscreen(); if (parse_int(val) != 0) != sapp_is_fullscreen() then sapp_toggle_fullscreen();
}
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -557,7 +557,8 @@ void main() {
float NdotV_s = max(dot(N, V), 0.0); float NdotV_s = max(dot(N, V), 0.0);
float roughnessBell = 1.0 - 0.7 * sin(roughness * PI); float roughnessBell = 1.0 - 0.7 * sin(roughness * PI);
float grazingSuppress = 1.0 - 0.9 * roughness * sin(roughness * PI) * pow(1.0 - NdotV_s, 2.0); float grazingSuppress = 1.0 - 0.9 * roughness * sin(roughness * PI) * pow(1.0 - NdotV_s, 2.0);
light += indirectSpec * (Frough * envBRDF.x + envBRDF.y) * rdm_spec_scale * roughnessBell * grazingSuppress; float specRoughFade = 1.0 - clamp((roughness - 0.5) / 0.3, 0.0, 1.0);
light += indirectSpec * (Frough * envBRDF.x + envBRDF.y) * rdm_spec_scale * roughnessBell * grazingSuppress * specRoughFade;
// Indirect diffuse (interpolated from neighbor probes) // Indirect diffuse (interpolated from neighbor probes)
vec3 indirectDiff = sample_rdm_diff(N, vpos - hemispherePos, local) * rdm_tint; vec3 indirectDiff = sample_rdm_diff(N, vpos - hemispherePos, local) * rdm_tint;