render texture testing

This commit is contained in:
jacob 2025-07-23 10:58:41 -05:00
parent cebb0dae46
commit 5fb52441d4
8 changed files with 265 additions and 150 deletions

View File

@ -81,7 +81,6 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
{ {
struct ps_output output; struct ps_output output;
float4 albedo = input.vs.tint_lin; float4 albedo = input.vs.tint_lin;
float4 emittance = input.vs.emittance_lin;
/* Texture */ /* Texture */
if (input.vs.tex_nurid >= 0) { if (input.vs.tex_nurid >= 0) {
@ -120,6 +119,8 @@ SH_ENTRY(ROOTSIG) struct ps_output ps(struct ps_input input)
albedo = linear_from_srgb32(color_srgb); albedo = linear_from_srgb32(color_srgb);
} }
float4 emittance = input.vs.emittance_lin * albedo.a;
output.SV_Target0 = albedo; output.SV_Target0 = albedo;
output.SV_Target1 = emittance; output.SV_Target1 = emittance;
return output; return output;

View File

@ -25,7 +25,7 @@ struct cs_input {
* Lighting * Lighting
* ========================== */ * ========================== */
#define SAMPLES 1 #define SAMPLES 64
#define MARCHES 16 #define MARCHES 16
#define AMBIENT float3(0, 0, 0) #define AMBIENT float3(0, 0, 0)
@ -34,13 +34,8 @@ float rand_angle(uint2 pos, uint ray_index) {
int3 noise_coord = int3(1, 1, 1); int3 noise_coord = int3(1, 1, 1);
noise_coord += int3(pos.xy, ray_index); noise_coord += int3(pos.xy, ray_index);
// noise_coord.xy += g_constants.frame_index;
// noise_coord.xyz += g_constants.frame_seed.xyz; // noise_coord.xyz += g_constants.frame_seed.xyz;
// noise_coord.xyz += g_constants.frame_seed.xyz; noise_coord.xy -= g_constants.camera_offset;
// noise_coord.z *= g_constants.frame_seed.w;
// noise_coord.xy
uint noise = noise_tex[noise_coord % uint3(SH_BLUE_NOISE_TEX_WIDTH, SH_BLUE_NOISE_TEX_HEIGHT, SH_BLUE_NOISE_TEX_DEPTH)]; uint noise = noise_tex[noise_coord % uint3(SH_BLUE_NOISE_TEX_WIDTH, SH_BLUE_NOISE_TEX_HEIGHT, SH_BLUE_NOISE_TEX_DEPTH)];
return ((float)noise / (float)0xFFFF) * TAU; return ((float)noise / (float)0xFFFF) * TAU;

View File

@ -84,6 +84,6 @@
/* TODO: Move these to user-configurable settings */ /* TODO: Move these to user-configurable settings */
#define VSYNC 1 #define VSYNC !RTC
#define AUDIO_ENABLED 0 #define AUDIO_ENABLED 0
#define FPS_LIMIT 300 #define FPS_LIMIT 300

View File

@ -104,9 +104,9 @@ struct gp_render_cmd_desc {
}; };
struct gp_render_params { struct gp_render_params {
struct v2i32 draw_target_size; struct v2i32 ui_size;
struct rect draw_target_viewport; struct v2i32 render_size;
struct xform draw_target_view; struct xform world_to_render_xf;
}; };
struct gp_render_sig *gp_render_sig_alloc(void); struct gp_render_sig *gp_render_sig_alloc(void);

View File

@ -2793,7 +2793,7 @@ struct render_sig {
struct dx12_resource *emittance_flood_target; struct dx12_resource *emittance_flood_target;
struct dx12_resource *shade_read; struct dx12_resource *shade_read;
struct dx12_resource *shade_target; struct dx12_resource *shade_target;
struct dx12_resource *final_target; struct dx12_resource *ui_target;
}; };
struct material_instance_desc { struct material_instance_desc {
@ -2951,12 +2951,15 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
struct render_sig *sig = (struct render_sig *)render_sig; struct render_sig *sig = (struct render_sig *)render_sig;
++sig->frame_index; ++sig->frame_index;
struct v2i32 final_target_size = params.draw_target_size; struct v2i32 ui_size = V2I32(max_i32(params.ui_size.x, 1), max_i32(params.ui_size.y, 1));
final_target_size.x = max_i32(final_target_size.x, 1); struct v2i32 render_size = V2I32(max_i32(params.render_size.x, 1), max_i32(params.render_size.y, 1));
final_target_size.y = max_i32(final_target_size.y, 1); struct xform world_to_render_xf = params.world_to_render_xf;
struct rect ui_viewport = RECT_FROM_V2(V2(0, 0), V2(ui_size.x, ui_size.y));
struct rect render_viewport = RECT_FROM_V2(V2(0, 0), V2(render_size.x, render_size.y));
/* Release buffers if size changed */ /* Release buffers if size changed */
if (sig->final_target && !v2i32_eq(final_target_size, sig->final_target->texture_size)) { if (sig->ui_target && !v2i32_eq(ui_size, sig->ui_target->texture_size)) {
__profn("Release sig resources"); __profn("Release sig resources");
fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->albedo, FENCED_RELEASE_KIND_RESOURCE);
fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->emittance, FENCED_RELEASE_KIND_RESOURCE);
@ -2964,20 +2967,20 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
fenced_release(sig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->emittance_flood_target, FENCED_RELEASE_KIND_RESOURCE);
fenced_release(sig->shade_read, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->shade_read, FENCED_RELEASE_KIND_RESOURCE);
fenced_release(sig->shade_target, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->shade_target, FENCED_RELEASE_KIND_RESOURCE);
fenced_release(sig->final_target, FENCED_RELEASE_KIND_RESOURCE); fenced_release(sig->ui_target, FENCED_RELEASE_KIND_RESOURCE);
sig->final_target = 0; sig->ui_target = 0;
} }
/* Allocate buffers */ /* Allocate buffers */
if (!sig->final_target) { if (!sig->ui_target) {
__profn("Allocate sig resources"); __profn("Allocate sig resources");
sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); sig->albedo = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET);
sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); sig->emittance = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_RENDER_TARGET);
sig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); sig->emittance_flood_read = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
sig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); sig->emittance_flood_target = gbuff_alloc(DXGI_FORMAT_R16G16_UINT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
sig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); sig->shade_read = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
sig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, final_target_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); sig->shade_target = gbuff_alloc(DXGI_FORMAT_R16G16B16A16_FLOAT, render_size, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);
sig->final_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, final_target_size, D3D12_RESOURCE_STATE_RENDER_TARGET); sig->ui_target = gbuff_alloc(DXGI_FORMAT_R8G8B8A8_UNORM, ui_size, D3D12_RESOURCE_STATE_RENDER_TARGET);
} }
struct sprite_scope *sprite_scope = sprite_scope_begin(); struct sprite_scope *sprite_scope = sprite_scope_begin();
@ -2993,9 +2996,9 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
{ {
__profn("Run render"); __profn("Run render");
__profnc_dx12(cl->cq->prof, cl->cl, "Run render", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Run render", RGB32_F(0.5, 0.2, 0.2));
struct mat4x4 world_vp_matrix = calculate_vp(params.draw_target_view, params.draw_target_viewport.width, params.draw_target_viewport.height); struct mat4x4 world_to_render_vp_matrix = calculate_vp(world_to_render_xf, render_viewport.width, render_viewport.height);
struct mat4x4 blit_vp_matrix = calculate_vp(XFORM_TRS(.t = v2_mul(V2(final_target_size.x, final_target_size.y), 0.5), .s = V2(final_target_size.x, final_target_size.y)), params.draw_target_viewport.width, params.draw_target_viewport.height); struct mat4x4 blit_vp_matrix = calculate_vp(XFORM_TRS(.t = v2_mul(V2(ui_size.x, ui_size.y), 0.5), .s = V2(ui_size.x, ui_size.y)), ui_viewport.width, ui_viewport.height);
struct mat4x4 ui_vp_matrix = calculate_vp(XFORM_IDENT, params.draw_target_viewport.width, params.draw_target_viewport.height); struct mat4x4 ui_vp_matrix = calculate_vp(XFORM_IDENT, ui_viewport.width, ui_viewport.height);
/* Upload dummmy vert & index buffer */ /* Upload dummmy vert & index buffer */
/* TODO: Make these static */ /* TODO: Make these static */
@ -3127,14 +3130,14 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, material_pipeline->rootsig);
/* Set Rasterizer State */ /* Set Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport); D3D12_VIEWPORT viewport = viewport_from_rect(render_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport); D3D12_RECT scissor = scissor_from_rect(render_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
/* Set constants */ /* Set constants */
struct sh_material_constants constants = ZI; struct sh_material_constants constants = ZI;
constants.projection = sh_float4x4_from_mat4x4(world_vp_matrix); constants.projection = sh_float4x4_from_mat4x4(world_to_render_vp_matrix);
/* Set parameters */ /* Set parameters */
command_list_set_graphics_root_constant(cl, &constants, sizeof(constants)); command_list_set_graphics_root_constant(cl, &constants, sizeof(constants));
@ -3200,8 +3203,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index); constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
constants.read_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->uav_descriptor->index); constants.read_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->uav_descriptor->index);
constants.target_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_target->uav_descriptor->index); constants.target_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_target->uav_descriptor->index);
constants.tex_width = sh_uint_from_u32(final_target_size.x); constants.tex_width = sh_uint_from_u32(render_size.x);
constants.tex_height = sh_uint_from_u32(final_target_size.y); constants.tex_height = sh_uint_from_u32(render_size.y);
/* Set parameters */ /* Set parameters */
command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); command_list_set_compute_root_constant(cl, &constants, sizeof(constants));
@ -3209,7 +3212,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 2, descriptor_heap->start_gpu_handle);
/* Dispatch */ /* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1); ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1);
/* Swap buffers */ /* Swap buffers */
struct dx12_resource *swp = sig->emittance_flood_read; struct dx12_resource *swp = sig->emittance_flood_read;
@ -3218,7 +3221,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
/* Update step */ /* Update step */
if (step_length == -1) { if (step_length == -1) {
step_length = max_i32(final_target_size.x, final_target_size.y) / 2; step_length = max_i32(render_size.x, render_size.y) / 2;
} else { } else {
step_length /= 2; step_length /= 2;
} }
@ -3269,14 +3272,14 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
(u32)rand_u64_from_state(&sig->rand), (u32)rand_u64_from_state(&sig->rand),
(u32)rand_u64_from_state(&sig->rand)); (u32)rand_u64_from_state(&sig->rand));
constants.frame_index = sh_uint_from_u32(sig->frame_index); constants.frame_index = sh_uint_from_u32(sig->frame_index);
constants.camera_offset = sh_float2_from_v2(params.draw_target_view.og); constants.camera_offset = sh_float2_from_v2(world_to_render_xf.og);
constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index); constants.albedo_tex_urid = sh_uint_from_u32(sig->albedo->srv_descriptor->index);
constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index); constants.emittance_tex_urid = sh_uint_from_u32(sig->emittance->srv_descriptor->index);
constants.emittance_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->srv_descriptor->index); constants.emittance_flood_tex_urid = sh_uint_from_u32(sig->emittance_flood_read->srv_descriptor->index);
constants.read_tex_urid = sh_uint_from_u32(sig->shade_read->uav_descriptor->index); constants.read_tex_urid = sh_uint_from_u32(sig->shade_read->uav_descriptor->index);
constants.target_tex_urid = sh_uint_from_u32(sig->shade_target->uav_descriptor->index); constants.target_tex_urid = sh_uint_from_u32(sig->shade_target->uav_descriptor->index);
constants.tex_width = sh_uint_from_u32(final_target_size.x); constants.tex_width = sh_uint_from_u32(render_size.x);
constants.tex_height = sh_uint_from_u32(final_target_size.y); constants.tex_height = sh_uint_from_u32(render_size.y);
/* Set parameters */ /* Set parameters */
command_list_set_compute_root_constant(cl, &constants, sizeof(constants)); command_list_set_compute_root_constant(cl, &constants, sizeof(constants));
@ -3286,7 +3289,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 4, descriptor_heap->start_gpu_handle); ID3D12GraphicsCommandList_SetComputeRootDescriptorTable(cl->cl, 4, descriptor_heap->start_gpu_handle);
/* Dispatch */ /* Dispatch */
ID3D12GraphicsCommandList_Dispatch(cl->cl, (final_target_size.x + 7) / 8, (final_target_size.y + 7) / 8, 1); ID3D12GraphicsCommandList_Dispatch(cl->cl, (render_size.x + 7) / 8, (render_size.y + 7) / 8, 1);
/* Swap */ /* Swap */
struct dx12_resource *swp = sig->shade_read; struct dx12_resource *swp = sig->shade_read;
@ -3301,17 +3304,17 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
struct dx12_resource_barrier_desc barriers[] = { struct dx12_resource_barrier_desc barriers[] = {
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS }, { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->shade_read, D3D12_RESOURCE_STATE_UNORDERED_ACCESS },
{ D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->shade_read, 0 }, { D3D12_RESOURCE_BARRIER_TYPE_UAV, sig->shade_read, 0 },
{ D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->final_target, D3D12_RESOURCE_STATE_RENDER_TARGET } { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, sig->ui_target, D3D12_RESOURCE_STATE_RENDER_TARGET }
}; };
dx12_resource_barriers(cl->cl, countof(barriers), barriers); dx12_resource_barriers(cl->cl, countof(barriers), barriers);
ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &sig->final_target->rtv_descriptor->handle, 0, 0); ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &sig->ui_target->rtv_descriptor->handle, 0, 0);
} }
/* Clear */ /* Clear */
{ {
__profn("Clear final target"); __profn("Clear ui target");
__profnc_dx12(cl->cq->prof, cl->cl, "Clear final target", RGB32_F(0.5, 0.2, 0.2)); __profnc_dx12(cl->cq->prof, cl->cl, "Clear ui target", RGB32_F(0.5, 0.2, 0.2));
f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f };
ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->final_target->rtv_descriptor->handle, clear_color, 0, 0); ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, sig->ui_target->rtv_descriptor->handle, clear_color, 0, 0);
} }
} }
@ -3325,8 +3328,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, blit_pipeline->rootsig);
/* Set Rasterizer State */ /* Set Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport); D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport); D3D12_RECT scissor = scissor_from_rect(ui_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
@ -3361,8 +3364,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, ui_pipeline->rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, ui_pipeline->rootsig);
/* Set Rasterizer State */ /* Set Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport); D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport); D3D12_RECT scissor = scissor_from_rect(ui_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
@ -3395,8 +3398,8 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, shape_pipeline->rootsig); ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, shape_pipeline->rootsig);
/* Set Rasterizer State */ /* Set Rasterizer State */
D3D12_VIEWPORT viewport = viewport_from_rect(params.draw_target_viewport); D3D12_VIEWPORT viewport = viewport_from_rect(ui_viewport);
D3D12_RECT scissor = scissor_from_rect(params.draw_target_viewport); D3D12_RECT scissor = scissor_from_rect(ui_viewport);
ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport); ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &viewport);
ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor); ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &scissor);
@ -3424,7 +3427,7 @@ struct gp_resource *gp_run_render(struct gp_render_sig *render_sig, struct gp_re
render_sig_reset(sig); render_sig_reset(sig);
scratch_end(scratch); scratch_end(scratch);
return (struct gp_resource *)sig->final_target; return (struct gp_resource *)sig->ui_target;
} }
/* ========================== * /* ========================== *

View File

@ -162,6 +162,17 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
e->friction = 0; e->friction = 0;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
e->sprite_emittance = V3(1, 1, 1);
//e->control_force = 500; //e->control_force = 500;
e->control_force = 1200; e->control_force = 1200;
e->control_force_max_speed = 7; e->control_force_max_speed = 7;
@ -183,6 +194,9 @@ INTERNAL struct sim_ent *test_spawn_employee(struct sim_ent *parent)
struct sim_ent *e = test_spawn_chucker(employee); struct sim_ent *e = test_spawn_chucker(employee);
employee->equipped = e->id; employee->equipped = e->id;
sim_ent_enable_prop(e, SEPROP_LIGHT_TEST);
e->sprite_emittance = V3(1, 1, 1);
} }
return employee; return employee;

View File

@ -3165,7 +3165,7 @@ void sys_message_box(enum sys_message_box_kind kind, struct string message)
} break; } break;
} }
logf_info("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message)); logf_debug("Showing message box kind %F with text \"%F\"", FMT_SINT(kind), FMT_STR(message));
MessageBoxExW(0, message_wstr, title, mbox_type, 0); MessageBoxExW(0, message_wstr, title, mbox_type, 0);
scratch_end(scratch); scratch_end(scratch);

View File

@ -70,8 +70,6 @@ GLOBAL struct {
/* Gpu resources */ /* Gpu resources */
struct gp_render_sig *render_sig; struct gp_render_sig *render_sig;
struct xform world_to_user_xf;
struct bind_state bind_states[USER_BIND_KIND_COUNT]; struct bind_state bind_states[USER_BIND_KIND_COUNT];
/* Debug camera */ /* Debug camera */
@ -126,12 +124,19 @@ GLOBAL struct {
i64 real_time_ns; i64 real_time_ns;
/* Per-frame */ /* Per-frame */
struct v2 screen_size; struct v2 screen_size;
struct v2 screen_cursor; struct v2 screen_cursor;
struct v2 user_screen_offset;
struct v2 user_size; struct xform world_to_ui_xf;
struct v2 user_center; struct xform world_to_render_xf;
struct v2 user_cursor;
struct v2 ui_screen_offset;
struct v2 ui_size;
struct v2 ui_cursor;
struct v2 render_size;
struct v2 world_cursor; struct v2 world_cursor;
struct v2 focus_send; struct v2 focus_send;
} G = ZI, DEBUG_ALIAS(G, G_user); } G = ZI, DEBUG_ALIAS(G, G_user);
@ -236,7 +241,8 @@ struct user_startup_receipt user_startup(struct font_startup_receipt *font_sr,
G.local_to_user_client = sim_client_alloc(G.local_to_user_client_store); G.local_to_user_client = sim_client_alloc(G.local_to_user_client_store);
/* GPU handles */ /* GPU handles */
G.world_to_user_xf = XFORM_IDENT; G.world_to_ui_xf = XFORM_IDENT;
G.world_to_render_xf = XFORM_IDENT;
G.render_sig = gp_render_sig_alloc(); G.render_sig = gp_render_sig_alloc();
G.console_logs_arena = arena_alloc(GIBI(64)); G.console_logs_arena = arena_alloc(GIBI(64));
@ -273,9 +279,9 @@ INTERNAL void debug_draw_xform(struct xform xf, u32 color_x, u32 color_y)
f32 thickness = 2.f; f32 thickness = 2.f;
f32 arrowhead_len = 15.f; f32 arrowhead_len = 15.f;
struct v2 pos = xform_mul_v2(G.world_to_user_xf, xf.og); struct v2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
struct v2 x_ray = xform_basis_mul_v2(G.world_to_user_xf, xform_get_right(xf)); struct v2 x_ray = xform_basis_mul_v2(G.world_to_ui_xf, xform_get_right(xf));
struct v2 y_ray = xform_basis_mul_v2(G.world_to_user_xf, xform_get_up(xf)); struct v2 y_ray = xform_basis_mul_v2(G.world_to_ui_xf, xform_get_up(xf));
f32 ray_scale = 1; f32 ray_scale = 1;
x_ray = v2_mul(x_ray, ray_scale); x_ray = v2_mul(x_ray, ray_scale);
@ -300,8 +306,8 @@ INTERNAL void debug_draw_movement(struct sim_ent *ent)
struct xform xf = sim_ent_get_xform(ent); struct xform xf = sim_ent_get_xform(ent);
struct v2 velocity = ent->linear_velocity; struct v2 velocity = ent->linear_velocity;
struct v2 pos = xform_mul_v2(G.world_to_user_xf, xf.og); struct v2 pos = xform_mul_v2(G.world_to_ui_xf, xf.og);
struct v2 vel_ray = xform_basis_mul_v2(G.world_to_user_xf, velocity); struct v2 vel_ray = xform_basis_mul_v2(G.world_to_ui_xf, velocity);
if (v2_len(vel_ray) > 0.00001) { if (v2_len(vel_ray) > 0.00001) {
draw_arrow_ray(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel); draw_arrow_ray(G.render_sig, pos, vel_ray, thickness, arrow_len, color_vel);
@ -729,10 +735,10 @@ INTERNAL void user_update(struct sys_window *window)
b32 pressed = event->kind == SYS_EVENT_KIND_BUTTON_DOWN; b32 pressed = event->kind == SYS_EVENT_KIND_BUTTON_DOWN;
#if 0 #if 0
b32 out_of_bounds = button >= SYS_BTN_M1 && button <= SYS_BTN_M5 && b32 out_of_bounds = button >= SYS_BTN_M1 && button <= SYS_BTN_M5 &&
(G.user_cursor.x < 0 || (G.ui_cursor.x < 0 ||
G.user_cursor.y < 0 || G.ui_cursor.y < 0 ||
G.user_cursor.x > G.user_size.x || G.ui_cursor.x > G.ui_size.x ||
G.user_cursor.y > G.user_size.y); G.ui_cursor.y > G.ui_size.y);
#else #else
b32 out_of_bounds = 0; b32 out_of_bounds = 0;
#endif #endif
@ -878,9 +884,18 @@ INTERNAL void user_update(struct sys_window *window)
* ========================== */ * ========================== */
/* Calculate ui dimensions */ /* Calculate ui dimensions */
DEBUGBREAKABLE;
/* FIXME:
* At 180p & 360p, objects increment in uniform but grid does not.
* At 270p, grid increments in uniform but objects do not */
//G.render_size = V2(320, 180);
//G.render_size = V2(480, 270);
G.render_size = V2(640, 360);
//G.render_size = V2(2560, 1440);
if (G.debug_camera) { if (G.debug_camera) {
G.user_size = G.screen_size; G.ui_size = G.screen_size;
G.user_screen_offset = V2(0, 0); G.ui_screen_offset = V2(0, 0);
} else { } else {
/* Determine ui size by camera & window dimensions */ /* Determine ui size by camera & window dimensions */
f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT); f32 aspect_ratio = (f32)(DEFAULT_CAMERA_WIDTH / DEFAULT_CAMERA_HEIGHT);
@ -898,27 +913,26 @@ INTERNAL void user_update(struct sys_window *window)
} else { } else {
height = math_ceil(width / aspect_ratio); height = math_ceil(width / aspect_ratio);
} }
G.user_size = V2(width, height); G.ui_size = V2(width, height);
/* Center ui in window */ /* Center ui in window */
f32 x = 0; f32 x = 0;
f32 y = 0; f32 y = 0;
x = math_round(G.screen_size.x / 2 - width / 2); x = math_round(G.screen_size.x / 2 - width / 2);
y = math_round(G.screen_size.y / 2 - height / 2); y = math_round(G.screen_size.y / 2 - height / 2);
G.user_screen_offset = V2(x, y); G.ui_screen_offset = V2(x, y);
} }
G.user_center = v2_mul(G.user_size, 0.5); G.ui_cursor = v2_sub(G.screen_cursor, G.ui_screen_offset);
G.user_cursor = v2_sub(G.screen_cursor, G.user_screen_offset);
/* ========================== * /* ========================== *
* Update view from camera * Update view from camera
* ========================== */ * ========================== */
if (G.debug_camera) { if (G.debug_camera) {
G.world_to_user_xf = xform_basis_with_rotation_world(G.world_to_user_xf, 0); G.world_to_ui_xf = xform_basis_with_rotation_world(G.world_to_ui_xf, 0);
struct v2 world_cursor = xform_invert_mul_v2(G.world_to_user_xf, G.user_cursor); struct v2 world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
/* Pan view */ /* Pan view */
if (G.bind_states[USER_BIND_KIND_PAN].is_held) { if (G.bind_states[USER_BIND_KIND_PAN].is_held) {
@ -927,8 +941,8 @@ INTERNAL void user_update(struct sys_window *window)
G.debug_camera_panning = 1; G.debug_camera_panning = 1;
} }
struct v2 offset = v2_neg(v2_sub(G.debug_camera_pan_start, world_cursor)); struct v2 offset = v2_neg(v2_sub(G.debug_camera_pan_start, world_cursor));
G.world_to_user_xf = xform_translated(G.world_to_user_xf, offset); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, offset);
world_cursor = xform_invert_mul_v2(G.world_to_user_xf, G.user_cursor); world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
G.debug_camera_pan_start = world_cursor; G.debug_camera_pan_start = world_cursor;
} else { } else {
G.debug_camera_panning = 0; G.debug_camera_panning = 0;
@ -940,9 +954,9 @@ INTERNAL void user_update(struct sys_window *window)
/* Zoom to cursor */ /* Zoom to cursor */
f32 zoom_rate = 2; f32 zoom_rate = 2;
f32 zoom = math_pow(zoom_rate, input_zooms); f32 zoom = math_pow(zoom_rate, input_zooms);
G.world_to_user_xf = xform_translated(G.world_to_user_xf, world_cursor); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, world_cursor);
G.world_to_user_xf = xform_scaled(G.world_to_user_xf, V2(zoom, zoom)); G.world_to_ui_xf = xform_scaled(G.world_to_ui_xf, V2(zoom, zoom));
G.world_to_user_xf = xform_translated(G.world_to_user_xf, v2_neg(world_cursor)); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(world_cursor));
} }
} else { } else {
struct xform xf = sim_ent_get_xform(local_camera); struct xform xf = sim_ent_get_xform(local_camera);
@ -951,7 +965,7 @@ INTERNAL void user_update(struct sys_window *window)
f32 rot = xform_get_rotation(xf); f32 rot = xform_get_rotation(xf);
/* Scale view into viewport based on camera size */ /* Scale view into viewport based on camera size */
struct v2 size = G.user_size; struct v2 size = G.ui_size;
{ {
struct xform quad_xf = xform_mul(xf, local_camera->camera_quad_xform); struct xform quad_xf = xform_mul(xf, local_camera->camera_quad_xform);
struct v2 camera_size = xform_get_scale(quad_xf); struct v2 camera_size = xform_get_scale(quad_xf);
@ -961,16 +975,104 @@ INTERNAL void user_update(struct sys_window *window)
} }
f32 scale_ui = min_f32(size.x, size.y); f32 scale_ui = min_f32(size.x, size.y);
struct trs trs = TRS(.t = v2_sub(G.user_center, center), .r = rot, .s = V2(scale_ui, scale_ui)); struct v2 ui_center = v2_mul(G.ui_size, 0.5);
struct trs trs = TRS(.t = v2_sub(ui_center, center), .r = rot, .s = V2(scale_ui, scale_ui));
struct v2 pivot = center; struct v2 pivot = center;
G.world_to_user_xf = XFORM_IDENT; G.world_to_ui_xf = XFORM_IDENT;
G.world_to_user_xf = xform_translated(G.world_to_user_xf, pivot); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, pivot);
G.world_to_user_xf = xform_translated(G.world_to_user_xf, trs.t); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, trs.t);
G.world_to_user_xf = xform_rotated(G.world_to_user_xf, trs.r); G.world_to_ui_xf = xform_rotated(G.world_to_ui_xf, trs.r);
G.world_to_user_xf = xform_scaled(G.world_to_user_xf, trs.s); G.world_to_ui_xf = xform_scaled(G.world_to_ui_xf, trs.s);
G.world_to_user_xf = xform_translated(G.world_to_user_xf, v2_neg(pivot)); G.world_to_ui_xf = xform_translated(G.world_to_ui_xf, v2_neg(pivot));
} }
G.world_cursor = xform_invert_mul_v2(G.world_to_user_xf, G.user_cursor);
DEBUGBREAKABLE;
if (G.debug_camera) {
G.world_to_render_xf = xform_basis_with_rotation_world(G.world_to_render_xf, 0);
struct v2 world_cursor = xform_invert_mul_v2(G.world_to_render_xf, G.ui_cursor);
/* Pan view */
if (G.bind_states[USER_BIND_KIND_PAN].is_held) {
if (!G.debug_camera_panning) {
G.debug_camera_pan_start = world_cursor;
G.debug_camera_panning = 1;
}
struct v2 offset = v2_neg(v2_sub(G.debug_camera_pan_start, world_cursor));
G.world_to_render_xf = xform_translated(G.world_to_render_xf, offset);
world_cursor = xform_invert_mul_v2(G.world_to_render_xf, G.ui_cursor);
G.debug_camera_pan_start = world_cursor;
} else {
G.debug_camera_panning = 0;
}
/* Zoom view */
i32 input_zooms = G.bind_states[USER_BIND_KIND_ZOOM_IN].num_presses - G.bind_states[USER_BIND_KIND_ZOOM_OUT].num_presses;
if (input_zooms != 0) {
/* Zoom to cursor */
f32 zoom_rate = 2;
f32 zoom = math_pow(zoom_rate, input_zooms);
G.world_to_render_xf = xform_translated(G.world_to_render_xf, world_cursor);
G.world_to_render_xf = xform_scaled(G.world_to_render_xf, V2(zoom, zoom));
G.world_to_render_xf = xform_translated(G.world_to_render_xf, v2_neg(world_cursor));
}
} else {
struct xform xf = sim_ent_get_xform(local_camera);
struct v2 center = xf.og;
f32 rot = xform_get_rotation(xf);
/* Scale view into viewport based on camera size */
struct v2 size = G.render_size;
{
struct xform quad_xf = xform_mul(xf, local_camera->camera_quad_xform);
struct v2 camera_size = xform_get_scale(quad_xf);
if (!v2_is_zero(camera_size)) {
size = v2_div_v2(size, camera_size);
}
}
f32 scale_render = min_f32(size.x, size.y);
struct v2 render_center = v2_mul(G.render_size, 0.5);
struct trs trs = TRS(.t = v2_sub(render_center, center), .r = rot, .s = V2(scale_render, scale_render));
struct v2 pivot = center;
G.world_to_render_xf = XFORM_IDENT;
G.world_to_render_xf = xform_translated(G.world_to_render_xf, pivot);
G.world_to_render_xf = xform_translated(G.world_to_render_xf, trs.t);
G.world_to_render_xf = xform_rotated(G.world_to_render_xf, trs.r);
G.world_to_render_xf = xform_scaled(G.world_to_render_xf, trs.s);
G.world_to_render_xf = xform_translated(G.world_to_render_xf, v2_neg(pivot));
}
/* ========================== *
* Update cursor
* ========================== */
G.world_cursor = xform_invert_mul_v2(G.world_to_ui_xf, G.ui_cursor);
/* ========================== * /* ========================== *
* Update listener from view * Update listener from view
@ -978,8 +1080,9 @@ INTERNAL void user_update(struct sys_window *window)
{ {
struct v2 up = V2(0, -1); struct v2 up = V2(0, -1);
struct v2 listener_pos = xform_invert_mul_v2(G.world_to_user_xf, G.user_center); struct v2 ui_center = v2_mul(G.ui_size, 0.5f);
struct v2 listener_dir = v2_norm(xform_basis_invert_mul_v2(G.world_to_user_xf, up)); struct v2 listener_pos = xform_invert_mul_v2(G.world_to_ui_xf, ui_center);
struct v2 listener_dir = v2_norm(xform_basis_invert_mul_v2(G.world_to_ui_xf, up));
mixer_set_listener(listener_pos, listener_dir); mixer_set_listener(listener_pos, listener_dir);
} }
@ -988,13 +1091,13 @@ INTERNAL void user_update(struct sys_window *window)
* ========================== */ * ========================== */
{ {
f32 thickness = 2; f32 thickness = 1;
struct v2 offset = v2_neg(xform_mul_v2(G.world_to_user_xf, V2(0, 0))); struct v2 offset = v2_neg(xform_mul_v2(G.world_to_render_xf, V2(0, 0)));
f32 spacing = xform_get_scale(G.world_to_user_xf).x; f32 spacing = xform_get_scale(G.world_to_render_xf).x;
struct v2 pos = xform_invert_mul_v2(G.world_to_user_xf, V2(0, 0)); struct v2 pos = xform_invert_mul_v2(G.world_to_render_xf, V2(0, 0));
struct v2 size = xform_basis_invert_mul_v2(G.world_to_user_xf, G.user_size); struct v2 size = xform_basis_invert_mul_v2(G.world_to_render_xf, G.render_size);
u32 color0 = RGBA32_F(0.17f, 0.17f, 0.17f, 1.f); u32 color0 = RGBA32_F(0.17f, 0.17f, 0.17f, 1.f);
u32 color1 = RGBA32_F(0.15f, 0.15f, 0.15f, 1.f); u32 color1 = RGBA32_F(0.15f, 0.15f, 0.15f, 1.f);
draw_grid(G.render_sig, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset); draw_grid(G.render_sig, xform_from_rect(RECT_FROM_V2(pos, size)), color0, color1, RGBA32(0x3f, 0x3f, 0x3f, 0xFF), COLOR_RED, COLOR_GREEN, thickness, spacing, offset);
@ -1246,7 +1349,7 @@ INTERNAL void user_update(struct sys_window *window)
f32 thickness = 1; f32 thickness = 1;
u32 color = RGBA32_F(1, 0, 1, 0.5); u32 color = RGBA32_F(1, 0, 1, 0.5);
struct quad quad = quad_from_aabb(aabb); struct quad quad = quad_from_aabb(aabb);
quad = xform_mul_quad(G.world_to_user_xf, quad); quad = xform_mul_quad(G.world_to_ui_xf, quad);
draw_quad_line(G.render_sig, quad, thickness, color); draw_quad_line(G.render_sig, quad, thickness, color);
} }
@ -1255,9 +1358,9 @@ INTERNAL void user_update(struct sys_window *window)
struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite); struct sprite_sheet *sheet = sprite_sheet_from_tag_async(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame); struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, LIT("attach.wep"), ent->animation_frame);
struct v2 start = xform_mul_v2(sprite_xform, slice.center); struct v2 start = xform_mul_v2(sprite_xform, slice.center);
start = xform_mul_v2(G.world_to_user_xf, start); start = xform_mul_v2(G.world_to_ui_xf, start);
struct v2 end = v2_add(xf.og, ent->control.focus); struct v2 end = v2_add(xf.og, ent->control.focus);
end = xform_mul_v2(G.world_to_user_xf, end); end = xform_mul_v2(G.world_to_ui_xf, end);
draw_arrow_line(G.render_sig, start, end, 3, 10, RGBA32_F(1, 1, 1, 0.5)); draw_arrow_line(G.render_sig, start, end, 3, 10, RGBA32_F(1, 1, 1, 0.5));
} }
@ -1278,12 +1381,12 @@ INTERNAL void user_update(struct sys_window *window)
struct sprite_sheet_slice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j]; struct sprite_sheet_slice slice = group->frame_slices[(ent->animation_frame * group->per_frame_count) + j];
struct v2 center = xform_mul_v2(sprite_xform, slice.center); struct v2 center = xform_mul_v2(sprite_xform, slice.center);
center = xform_mul_v2(G.world_to_user_xf, center); center = xform_mul_v2(G.world_to_ui_xf, center);
if (!slice.has_ray) { if (!slice.has_ray) {
struct quad quad = quad_from_rect(slice.rect); struct quad quad = quad_from_rect(slice.rect);
quad = xform_mul_quad(sprite_xform, quad); quad = xform_mul_quad(sprite_xform, quad);
quad = xform_mul_quad(G.world_to_user_xf, quad); quad = xform_mul_quad(G.world_to_ui_xf, quad);
draw_quad_line(G.render_sig, quad, 2, quad_color); draw_quad_line(G.render_sig, quad, 2, quad_color);
} }
@ -1291,7 +1394,7 @@ INTERNAL void user_update(struct sys_window *window)
if (slice.has_ray) { if (slice.has_ray) {
struct v2 ray = xform_basis_mul_v2(sprite_xform, slice.dir); struct v2 ray = xform_basis_mul_v2(sprite_xform, slice.dir);
ray = xform_basis_mul_v2(G.world_to_user_xf, ray); ray = xform_basis_mul_v2(G.world_to_ui_xf, ray);
ray = v2_with_len(ray, 25); ray = v2_with_len(ray, 25);
draw_arrow_ray(G.render_sig, center, ray, 2, 10, ray_color); draw_arrow_ray(G.render_sig, center, ray, 2, 10, ray_color);
} }
@ -1309,7 +1412,7 @@ INTERNAL void user_update(struct sys_window *window)
u32 color = COLOR_YELLOW; u32 color = COLOR_YELLOW;
f32 radius = 3; f32 radius = 3;
struct v2 point = xform_mul_v2(e1_xf, ent->weld_joint_data.point_local_e1); struct v2 point = xform_mul_v2(e1_xf, ent->weld_joint_data.point_local_e1);
point = xform_mul_v2(G.world_to_user_xf, point); point = xform_mul_v2(G.world_to_ui_xf, point);
draw_circle(G.render_sig, point, radius, color, 10); draw_circle(G.render_sig, point, radius, color, 10);
DEBUGBREAKABLE; DEBUGBREAKABLE;
@ -1323,8 +1426,8 @@ INTERNAL void user_update(struct sys_window *window)
u32 color = COLOR_WHITE; u32 color = COLOR_WHITE;
struct v2 point_start = xform_mul_v2(target_xf, ent->mouse_joint_data.point_local_start); struct v2 point_start = xform_mul_v2(target_xf, ent->mouse_joint_data.point_local_start);
struct v2 point_end = G.world_cursor; struct v2 point_end = G.world_cursor;
point_start = xform_mul_v2(G.world_to_user_xf, point_start); point_start = xform_mul_v2(G.world_to_ui_xf, point_start);
point_end = xform_mul_v2(G.world_to_user_xf, point_end); point_end = xform_mul_v2(G.world_to_ui_xf, point_end);
draw_arrow_line(G.render_sig, point_start, point_end, 3, 10, color); draw_arrow_line(G.render_sig, point_start, point_end, 3, 10, color);
draw_circle(G.render_sig, point_start, 4, color, 10); draw_circle(G.render_sig, point_start, 4, color, 10);
} }
@ -1337,13 +1440,13 @@ INTERNAL void user_update(struct sys_window *window)
{ {
/* Draw collider using support points */ /* Draw collider using support points */
u32 detail = 32; u32 detail = 32;
struct xform collider_draw_xf = xform_mul(G.world_to_user_xf, xf); struct xform collider_draw_xf = xform_mul(G.world_to_ui_xf, xf);
draw_collider_line(G.render_sig, collider, collider_draw_xf, thickness, color, detail); draw_collider_line(G.render_sig, collider, collider_draw_xf, thickness, color, detail);
} }
{ {
/* Draw collider shape points */ /* Draw collider shape points */
for (u32 i = 0; i < collider.count; ++i) { for (u32 i = 0; i < collider.count; ++i) {
struct v2 p = xform_mul_v2(xform_mul(G.world_to_user_xf, xf), collider.points[i]); struct v2 p = xform_mul_v2(xform_mul(G.world_to_ui_xf, xf), collider.points[i]);
draw_circle(G.render_sig, p, 3, COLOR_BLUE, 10); draw_circle(G.render_sig, p, 3, COLOR_BLUE, 10);
} }
} }
@ -1351,15 +1454,15 @@ INTERNAL void user_update(struct sys_window *window)
/* Draw upwards line for circle */ /* Draw upwards line for circle */
struct v2 start = xf.og; struct v2 start = xf.og;
struct v2 end = collider_get_support_point(&collider, xf, v2_neg(xf.by)).p; struct v2 end = collider_get_support_point(&collider, xf, v2_neg(xf.by)).p;
start = xform_mul_v2(G.world_to_user_xf, start); start = xform_mul_v2(G.world_to_ui_xf, start);
end = xform_mul_v2(G.world_to_user_xf, end); end = xform_mul_v2(G.world_to_ui_xf, end);
draw_line(G.render_sig, start, end, thickness, color); draw_line(G.render_sig, start, end, thickness, color);
} }
#if 0 #if 0
/* Draw support point at focus dir */ /* Draw support point at focus dir */
{ {
struct v2 p = collider_support_point(&collider, xf, ent->control.focus); struct v2 p = collider_support_point(&collider, xf, ent->control.focus);
p = xform_mul_v2(G.world_to_user_xf, p); p = xform_mul_v2(G.world_to_ui_xf, p);
draw_circle(G.render_sig, p, 3, COLOR_RED, 10); draw_circle(G.render_sig, p, 3, COLOR_RED, 10);
} }
#endif #endif
@ -1384,7 +1487,7 @@ INTERNAL void user_update(struct sys_window *window)
/* Draw point */ /* Draw point */
{ {
draw_circle(G.render_sig, xform_mul_v2(G.world_to_user_xf, dbg_pt), radius, color, 10); draw_circle(G.render_sig, xform_mul_v2(G.world_to_ui_xf, dbg_pt), radius, color, 10);
} }
/* Draw normal */ /* Draw normal */
@ -1392,8 +1495,8 @@ INTERNAL void user_update(struct sys_window *window)
f32 len = 0.1f; f32 len = 0.1f;
f32 arrow_thickness = 2; f32 arrow_thickness = 2;
f32 arrow_height = 5; f32 arrow_height = 5;
struct v2 start = xform_mul_v2(G.world_to_user_xf, dbg_pt); struct v2 start = xform_mul_v2(G.world_to_ui_xf, dbg_pt);
struct v2 end = xform_mul_v2(G.world_to_user_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len))); struct v2 end = xform_mul_v2(G.world_to_ui_xf, v2_add(dbg_pt, v2_mul(v2_norm(data->normal), len)));
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrow_height, color); draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrow_height, color);
} }
#if 0 #if 0
@ -1424,7 +1527,7 @@ INTERNAL void user_update(struct sys_window *window)
FMT_UINT(data->num_points)); FMT_UINT(data->num_points));
draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, dbg_pt)), V2(0, offset_px)), text); draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, dbg_pt)), V2(0, offset_px)), text);
} }
} }
#endif #endif
@ -1450,8 +1553,8 @@ INTERNAL void user_update(struct sys_window *window)
{ {
f32 radius = 4; f32 radius = 4;
u32 color = RGBA32_F(1, 1, 0, 0.5); u32 color = RGBA32_F(1, 1, 0, 0.5);
struct v2 a = xform_mul_v2(G.world_to_user_xf, data->closest0); struct v2 a = xform_mul_v2(G.world_to_ui_xf, data->closest0);
struct v2 b = xform_mul_v2(G.world_to_user_xf, data->closest1); struct v2 b = xform_mul_v2(G.world_to_ui_xf, data->closest1);
draw_circle(G.render_sig, a, radius, color, 10); draw_circle(G.render_sig, a, radius, color, 10);
draw_circle(G.render_sig, b, radius, color, 10); draw_circle(G.render_sig, b, radius, color, 10);
} }
@ -1468,27 +1571,27 @@ INTERNAL void user_update(struct sys_window *window)
u32 color_a_clipped = RGBA32_F(1, 0, 0, 1); u32 color_a_clipped = RGBA32_F(1, 0, 0, 1);
u32 color_b_clipped = RGBA32_F(0, 1, 0, 1); u32 color_b_clipped = RGBA32_F(0, 1, 0, 1);
{ {
struct v2 a = xform_mul_v2(G.world_to_user_xf, collider_res.a0); struct v2 a = xform_mul_v2(G.world_to_ui_xf, collider_res.a0);
struct v2 b = xform_mul_v2(G.world_to_user_xf, collider_res.b0); struct v2 b = xform_mul_v2(G.world_to_ui_xf, collider_res.b0);
draw_line(G.render_sig, a, b, thickness, color_line); 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, a, radius, color_a, 10);
draw_circle(G.render_sig, b, radius, color_b, 10); draw_circle(G.render_sig, b, radius, color_b, 10);
struct v2 a_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.a0_clipped); struct v2 a_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.a0_clipped);
struct v2 b_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.b0_clipped); struct v2 b_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.b0_clipped);
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_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, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10); draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
} }
{ {
struct v2 a = xform_mul_v2(G.world_to_user_xf, collider_res.a1); struct v2 a = xform_mul_v2(G.world_to_ui_xf, collider_res.a1);
struct v2 b = xform_mul_v2(G.world_to_user_xf, collider_res.b1); struct v2 b = xform_mul_v2(G.world_to_ui_xf, collider_res.b1);
draw_line(G.render_sig, a, b, thickness, color_line); 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, a, radius, color_a, 10);
draw_circle(G.render_sig, b, radius, color_b, 10); draw_circle(G.render_sig, b, radius, color_b, 10);
struct v2 a_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.a1_clipped); struct v2 a_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.a1_clipped);
struct v2 b_clipped = xform_mul_v2(G.world_to_user_xf, collider_res.b1_clipped); struct v2 b_clipped = xform_mul_v2(G.world_to_ui_xf, collider_res.b1_clipped);
draw_line(G.render_sig, a_clipped, b_clipped, thickness, color_line_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, a_clipped, radius, color_a_clipped, 10);
draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10); draw_circle(G.render_sig, b_clipped, radius, color_b_clipped, 10);
@ -1532,7 +1635,7 @@ INTERNAL void user_update(struct sys_window *window)
FMT_FLOAT_P(xform_get_rotation(e1_xf), 24)); FMT_FLOAT_P(xform_get_rotation(e1_xf), 24));
draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_user_xf, V2(0, 0))), V2(0, offset_px)), text); draw_text(G.render_sig, disp_font, v2_add(v2_round(xform_mul_v2(G.world_to_ui_xf, V2(0, 0))), V2(0, offset_px)), text);
} }
} }
#endif #endif
@ -1547,7 +1650,7 @@ INTERNAL void user_update(struct sys_window *window)
struct v2_array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail); struct v2_array m = menkowski(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf, detail);
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_user_xf, m.points[i]); for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
draw_poly_line(G.render_sig, m, 1, thickness, color); draw_poly_line(G.render_sig, m, 1, thickness, color);
//draw_poly(G.render_sig, m, color); //draw_poly(G.render_sig, m, color);
} }
@ -1560,7 +1663,7 @@ INTERNAL void user_update(struct sys_window *window)
struct v2_array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf); struct v2_array m = cloud(temp.arena, &e0_collider, &e1_collider, e0_xf, e1_xf);
for (u64 i = 0; i < m.count; ++i) { for (u64 i = 0; i < m.count; ++i) {
struct v2 p = xform_mul_v2(G.world_to_user_xf, m.points[i]); struct v2 p = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
draw_circle(G.render_sig, p, radius, color, 10); draw_circle(G.render_sig, p, radius, color, 10);
} }
} }
@ -1574,7 +1677,7 @@ INTERNAL void user_update(struct sys_window *window)
.points = collider_res.prototype.points, .points = collider_res.prototype.points,
.count = collider_res.prototype.len .count = collider_res.prototype.len
}; };
for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_user_xf, m.points[i]); for (u64 i = 0; i < m.count; ++i) m.points[i] = xform_mul_v2(G.world_to_ui_xf, m.points[i]);
draw_poly_line(G.render_sig, m, 1, thickness, color); 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); for (u64 i = 0; i < m.count; ++i) draw_circle(G.render_sig, m.points[i], 10, color, 10);
} }
@ -1589,7 +1692,7 @@ INTERNAL void user_update(struct sys_window *window)
struct collider_menkowski_simplex simplex = collider_res.simplex; struct collider_menkowski_simplex simplex = collider_res.simplex;
struct v2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p }; struct v2 simplex_points[] = { simplex.a.p, simplex.b.p, simplex.c.p };
for (u64 i = 0; i < countof(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_to_user_xf, simplex_points[i]); for (u64 i = 0; i < countof(simplex_points); ++i) simplex_points[i] = xform_mul_v2(G.world_to_ui_xf, simplex_points[i]);
struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points }; struct v2_array simplex_array = { .count = simplex.len, .points = simplex_points };
if (simplex.len >= 1) { if (simplex.len >= 1) {
@ -1615,8 +1718,8 @@ INTERNAL void user_update(struct sys_window *window)
f32 len = 0.1f; f32 len = 0.1f;
f32 arrow_thickness = 4; f32 arrow_thickness = 4;
f32 arrowhead_height = 10; f32 arrowhead_height = 10;
struct v2 start = xform_mul_v2(G.world_to_user_xf, V2(0, 0)); struct v2 start = xform_mul_v2(G.world_to_ui_xf, V2(0, 0));
struct v2 end = xform_mul_v2(G.world_to_user_xf, v2_mul(v2_norm(collider_res.normal), len)); struct v2 end = xform_mul_v2(G.world_to_ui_xf, v2_mul(v2_norm(collider_res.normal), len));
draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrowhead_height, color); draw_arrow_line(G.render_sig, start, end, arrow_thickness, arrowhead_height, color);
} }
} }
@ -1630,8 +1733,8 @@ INTERNAL void user_update(struct sys_window *window)
f32 thickness = 2; f32 thickness = 2;
f32 arrow_height = 15; f32 arrow_height = 15;
struct v2 start = xform_mul_v2(G.world_to_user_xf, xf.og); struct v2 start = xform_mul_v2(G.world_to_ui_xf, xf.og);
struct v2 end = xform_mul_v2(G.world_to_user_xf, parent_xf.og); struct v2 end = xform_mul_v2(G.world_to_ui_xf, parent_xf.og);
draw_arrow_line(G.render_sig, start, end, thickness, arrow_height, color); draw_arrow_line(G.render_sig, start, end, thickness, arrow_height, color);
} }
@ -1642,7 +1745,7 @@ INTERNAL void user_update(struct sys_window *window)
struct xform quad_xf = xform_mul(xf, ent->camera_quad_xform); struct xform quad_xf = xform_mul(xf, ent->camera_quad_xform);
struct quad quad = xform_mul_quad(quad_xf, QUAD_UNIT_SQUARE_CENTERED); struct quad quad = xform_mul_quad(quad_xf, QUAD_UNIT_SQUARE_CENTERED);
quad = xform_mul_quad(G.world_to_user_xf, quad); quad = xform_mul_quad(G.world_to_ui_xf, quad);
draw_quad_line(G.render_sig, quad, thickness, color); draw_quad_line(G.render_sig, quad, thickness, color);
} }
@ -1655,7 +1758,7 @@ INTERNAL void user_update(struct sys_window *window)
/* Draw crosshair or show cursor */ /* Draw crosshair or show cursor */
if (!G.debug_camera) { if (!G.debug_camera) {
__profn("Draw crosshair"); __profn("Draw crosshair");
struct v2 crosshair_pos = G.user_cursor; struct v2 crosshair_pos = G.ui_cursor;
struct sprite_tag crosshair = sprite_tag_from_path(LIT("sprite/crosshair.ase")); struct sprite_tag crosshair = sprite_tag_from_path(LIT("sprite/crosshair.ase"));
struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair); struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, crosshair);
struct v2 size = V2(t->width, t->height); struct v2 size = V2(t->width, t->height);
@ -1673,7 +1776,7 @@ INTERNAL void user_update(struct sys_window *window)
} else { } else {
struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(LIT("sprite/crosshair.ase"))); struct sprite_texture *t = sprite_texture_from_tag_async(sprite_frame_scope, sprite_tag_from_path(LIT("sprite/crosshair.ase")));
struct v2 size = V2(t->width, t->height); struct v2 size = V2(t->width, t->height);
struct rect cursor_clip = RECT_FROM_V2(G.user_screen_offset, G.user_size); struct rect cursor_clip = RECT_FROM_V2(G.ui_screen_offset, G.ui_size);
cursor_clip.pos = v2_add(cursor_clip.pos, v2_mul(size, 0.5f)); cursor_clip.pos = v2_add(cursor_clip.pos, v2_mul(size, 0.5f));
cursor_clip.pos = v2_add(cursor_clip.pos, V2(1, 1)); cursor_clip.pos = v2_add(cursor_clip.pos, V2(1, 1));
cursor_clip.size = v2_sub(cursor_clip.size, size); cursor_clip.size = v2_sub(cursor_clip.size, size);
@ -1732,7 +1835,7 @@ INTERNAL void user_update(struct sys_window *window)
} }
} }
input_move_dir = xform_basis_invert_mul_v2(G.world_to_user_xf, input_move_dir); /* Make move dir relative to world view */ input_move_dir = xform_basis_invert_mul_v2(G.world_to_ui_xf, input_move_dir); /* Make move dir relative to world view */
input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed); input_move_dir = v2_mul(v2_norm(input_move_dir), move_speed);
} }
@ -1864,7 +1967,7 @@ INTERNAL void user_update(struct sys_window *window)
if (G.debug_draw && hovered_ent->valid) { if (G.debug_draw && hovered_ent->valid) {
struct sim_ent *ent = hovered_ent; struct sim_ent *ent = hovered_ent;
struct v2 pos = v2_add(G.user_cursor, V2(15, 15)); struct v2 pos = v2_add(G.ui_cursor, V2(15, 15));
struct font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f); struct font *font = font_load_async(LIT("font/fixedsys.ttf"), 12.0f);
if (font) { if (font) {
struct arena_temp temp = arena_temp_begin(scratch.arena); struct arena_temp temp = arena_temp_begin(scratch.arena);
@ -1990,7 +2093,7 @@ INTERNAL void user_update(struct sys_window *window)
//draw_text(G.render_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved))); //draw_text(G.render_sig, font, pos, string_format(temp.arena, LIT("blended world entities: %F/%F"), FMT_UINT(G.ss_blended->num_ents_allocated), FMT_UINT(G.ss_blended->num_ents_reserved)));
//draw_text(G.render_sig, font, pos, text); //draw_text(G.render_sig, font, pos, text);
struct v2 pos = V2(10, G.user_size.y); struct v2 pos = V2(10, G.ui_size.y);
enum draw_text_offset_y offset_y = DRAW_TEXT_OFFSET_Y_BOTTOM; enum draw_text_offset_y 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 = COLOR_WHITE)); draw_text(G.render_sig, DRAW_TEXT_PARAMS(.font = font, .pos = pos, .str = text, .offset_y = offset_y, .color = COLOR_WHITE));
arena_temp_end(temp); arena_temp_end(temp);
@ -2015,23 +2118,22 @@ INTERNAL void user_update(struct sys_window *window)
{ {
__profn("Render"); __profn("Render");
struct v2i32 world_resolution = v2_round_to_int(G.render_size);
struct rect user_viewport = RECT_FROM_V2(V2(0, 0), G.user_size); struct v2i32 user_resolution = v2_round_to_int(G.ui_size);
struct v2i32 user_resolution = v2_round_to_int(user_viewport.size);
struct v2i32 backbuffer_resolution = v2_round_to_int(G.screen_size); struct v2i32 backbuffer_resolution = v2_round_to_int(G.screen_size);
/* Draw world to user texture */ /* Draw world to user texture */
struct gp_resource *render_texture = 0; struct gp_resource *render_texture = 0;
{ {
struct gp_render_params params = ZI; struct gp_render_params params = ZI;
params.draw_target_size = user_resolution; params.ui_size = user_resolution;
params.draw_target_viewport = user_viewport; params.render_size = world_resolution;
params.draw_target_view = G.world_to_user_xf; params.world_to_render_xf = G.world_to_render_xf;
render_texture = gp_run_render(G.render_sig, params); render_texture = gp_run_render(G.render_sig, params);
} }
/* Present */ /* Present */
gp_present(G.swapchain, backbuffer_resolution, render_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.user_size), VSYNC); gp_present(G.swapchain, backbuffer_resolution, render_texture, XFORM_TRS(.t = v2_mul(G.screen_size, 0.5), .s = G.ui_size), VSYNC);
} }
/* ========================== * /* ========================== *