1586 lines
51 KiB
Plaintext
1586 lines
51 KiB
Plaintext
SHADOWMAP_SIZE :: 1500;
|
||
|
||
Pipeline_Binding :: struct {
|
||
pipeline : sg_pipeline;
|
||
bind : sg_bindings;
|
||
attachments : sg_attachments;
|
||
pass_action : sg_pass_action;
|
||
}
|
||
|
||
g_specular_lut : sg_image;
|
||
g_brdf_lut : sg_image;
|
||
g_rdm_fallback : sg_image; // 1x1 black image used when a chunk has no baked RDM data
|
||
g_rdm_atlas : sg_image; // global RGBA16F atlas holding RDM hemispheres for flagged instances (populated in Steps 5-6)
|
||
g_sh_fallback : sg_image; // 1x1 black 2D image used when a chunk has no SH probe grid
|
||
|
||
g_shadowmap : sg_image;
|
||
g_shadowmap_img : sg_image;
|
||
g_shadowmap_attachments : sg_attachments;
|
||
g_shadowmap_sampler : sg_sampler;
|
||
|
||
g_rendertex : sg_image;
|
||
g_rendertex_depth : sg_image;
|
||
g_rendertex_attachments : sg_attachments;
|
||
|
||
g_gbuf_position : sg_image;
|
||
g_gbuf_normal : sg_image;
|
||
g_gbuf_worldpos : sg_image;
|
||
g_gbuf_depth : sg_image;
|
||
g_gbuf_attachments : sg_attachments;
|
||
|
||
g_ssaobuf : sg_image;
|
||
g_ssao_noise_buf : sg_image;
|
||
g_ssaobuf_depth : sg_image;
|
||
g_ssao_attachments : sg_attachments;
|
||
|
||
g_sh_irradiance : sg_image;
|
||
g_sh_irradiance_attach : sg_attachments;
|
||
|
||
g_postprocess_a : sg_image;
|
||
g_postprocess_b : sg_image;
|
||
g_postprocess_a_depth : sg_image;
|
||
g_postprocess_b_depth : sg_image;
|
||
g_postprocess_attach_a : sg_attachments;
|
||
g_postprocess_attach_b : sg_attachments;
|
||
|
||
g_bloom_tex : sg_image;
|
||
g_bloom_attach : sg_attachments;
|
||
|
||
g_dof_tex : sg_image;
|
||
g_dof_attach : sg_attachments;
|
||
|
||
|
||
gPipelines : struct {
|
||
// G-Buffer generation for SSAO and other effects
|
||
gbuffer: Pipeline_Binding;
|
||
|
||
// Arbitrary triangle rendering for rendering 2D things on the screen.
|
||
// Used for UI rendering.
|
||
arbtri : Pipeline_Binding;
|
||
|
||
// Trixel rendering. Used for Trile editor rendering, in-game triles are rendered from
|
||
// generated meshes.
|
||
trixel : Pipeline_Binding;
|
||
|
||
// Sky rendering.
|
||
sky : Pipeline_Binding;
|
||
|
||
// Renders sets of triles
|
||
trile : Pipeline_Binding;
|
||
|
||
// Per-instance variant for triles flagged with sharp-specular RDM lookup
|
||
trile_rdm : Pipeline_Binding;
|
||
|
||
// Depth-only shadow pass for triles (no lighting/RDM)
|
||
trile_shadow : Pipeline_Binding;
|
||
|
||
// Renders the ground plane. (just water)
|
||
plane : Pipeline_Binding;
|
||
|
||
// Post-processing pipeline
|
||
postprocess : Pipeline_Binding;
|
||
|
||
op : Pipeline_Binding;
|
||
|
||
mix : Pipeline_Binding;
|
||
|
||
bloom : Pipeline_Binding;
|
||
dof: Pipeline_Binding;
|
||
|
||
billboard : Pipeline_Binding;
|
||
|
||
gbuffer_billboard : Pipeline_Binding;
|
||
|
||
particle_additive : Pipeline_Binding;
|
||
particle_alpha : Pipeline_Binding;
|
||
|
||
ssao: Pipeline_Binding;
|
||
|
||
sh_irradiance: Pipeline_Binding;
|
||
|
||
debugline : Pipeline_Binding;
|
||
}
|
||
|
||
create_final_image :: () {
|
||
// @ToDo: Some smarter logic for this.
|
||
w,h := get_render_size();
|
||
|
||
|
||
if g_rendertex.id != INVALID_ID then sg_destroy_image(g_rendertex);
|
||
if g_rendertex_depth.id != INVALID_ID then sg_destroy_image(g_rendertex_depth);
|
||
|
||
img_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
};
|
||
depth_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .DEPTH,
|
||
render_target = true,
|
||
};
|
||
g_rendertex = sg_make_image(*img_desc);
|
||
g_rendertex_depth = sg_make_image(*depth_desc);
|
||
attachmentsDesc : sg_attachments_desc;
|
||
attachmentsDesc = .{
|
||
colors[0].image = g_rendertex,
|
||
depth_stencil.image = g_rendertex_depth,
|
||
};
|
||
sg_destroy_attachments(g_rendertex_attachments);
|
||
g_rendertex_attachments = sg_make_attachments(*attachmentsDesc);
|
||
}
|
||
|
||
create_shadowmap_image :: () {
|
||
w : s32 = SHADOWMAP_SIZE;
|
||
h : s32 = SHADOWMAP_SIZE;
|
||
|
||
if g_shadowmap.id != INVALID_ID then sg_destroy_image(g_shadowmap);
|
||
|
||
depth_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .DEPTH,
|
||
render_target = true,
|
||
};
|
||
img_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
};
|
||
g_shadowmap = sg_make_image(*depth_desc);
|
||
g_shadowmap_img = sg_make_image(*img_desc);
|
||
attachmentsDesc : sg_attachments_desc;
|
||
attachmentsDesc = .{
|
||
colors[0].image = g_shadowmap_img,
|
||
depth_stencil.image = g_shadowmap,
|
||
};
|
||
sg_destroy_attachments(g_shadowmap_attachments);
|
||
g_shadowmap_attachments = sg_make_attachments(*attachmentsDesc);
|
||
}
|
||
|
||
create_pipelines :: () {
|
||
create_gbuffer_images();
|
||
create_gbuffer_pipeline();
|
||
create_arbtri_pipeline();
|
||
create_trixel_pipeline();
|
||
create_trile_pipeline();
|
||
create_trile_rdm_pipeline();
|
||
create_trile_shadow_pipeline();
|
||
create_sky_pipeline();
|
||
create_plane_pipeline();
|
||
create_postprocess_pipeline();
|
||
create_ssao_pipeline();
|
||
create_op_pipeline();
|
||
create_mix_pipeline();
|
||
create_bloom_pipeline();
|
||
create_dof_pipeline();
|
||
create_billboard_pipeline();
|
||
create_gbuffer_billboard_pipeline();
|
||
create_particle_pipeline();
|
||
create_debugline_pipeline();
|
||
|
||
create_shadowmap_image();
|
||
create_final_image();
|
||
create_ssao_images();
|
||
create_sh_irradiance_pipeline();
|
||
create_sh_irradiance_image();
|
||
create_gbuffer_impostors();
|
||
}
|
||
|
||
create_gbuffer_images :: () {
|
||
w,h := get_render_size();
|
||
|
||
if g_gbuf_position.id != INVALID_ID then sg_destroy_image(g_gbuf_position);
|
||
if g_gbuf_normal.id != INVALID_ID then sg_destroy_image(g_gbuf_normal);
|
||
if g_gbuf_worldpos.id != INVALID_ID then sg_destroy_image(g_gbuf_worldpos);
|
||
if g_gbuf_depth.id != INVALID_ID then sg_destroy_image(g_gbuf_depth);
|
||
|
||
img_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
};
|
||
depth_desc := sg_image_desc.{
|
||
width = w,
|
||
height = h,
|
||
pixel_format = .DEPTH,
|
||
render_target = true,
|
||
};
|
||
|
||
g_gbuf_position = sg_make_image(*img_desc);
|
||
g_gbuf_normal = sg_make_image(*img_desc);
|
||
g_gbuf_worldpos = sg_make_image(*img_desc);
|
||
g_gbuf_depth = sg_make_image(*depth_desc);
|
||
|
||
attachmentsDesc : sg_attachments_desc;
|
||
attachmentsDesc = .{
|
||
colors[0].image = g_gbuf_position,
|
||
colors[1].image = g_gbuf_normal,
|
||
colors[2].image = g_gbuf_worldpos,
|
||
depth_stencil.image = g_gbuf_depth,
|
||
};
|
||
sg_destroy_attachments(g_gbuf_attachments);
|
||
g_gbuf_attachments = sg_make_attachments(*attachmentsDesc);
|
||
}
|
||
|
||
TRIXEL_SIZE_HALF : float : 1.0/32.0;
|
||
TRIXEL_SIZE : float : 1.0/16.0;
|
||
|
||
gArbtriMem : [100000*3*9]float;
|
||
|
||
Position_Color :: struct {
|
||
pos: Vector4;
|
||
col: Vector4;
|
||
}
|
||
|
||
create_trixel_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := trixel_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
pipeline.layout.buffers[1].stride = 4*3;
|
||
pipeline.layout.buffers[2].step_func = .PER_INSTANCE;
|
||
|
||
pipeline.layout.attrs[ATTR_trixel_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.layout.attrs[ATTR_trixel_normal] = .{ format = .FLOAT3, buffer_index = 1 };
|
||
pipeline.layout.attrs[ATTR_trixel_inst] = .{ format = .FLOAT4, buffer_index = 2 };
|
||
pipeline.layout.attrs[ATTR_trixel_inst_col] = .{ format = .FLOAT4, buffer_index = 2 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
|
||
};
|
||
|
||
vertices : [24]Vector3 = .[
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, -TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, -TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, TRIXEL_SIZE/2},
|
||
.{-TRIXEL_SIZE/2, TRIXEL_SIZE/2, -TRIXEL_SIZE/2}
|
||
];
|
||
|
||
normals : [24]Vector3 = .[
|
||
.{0.0, 0.0, 1.0},
|
||
.{0.0, 0.0, 1.0},
|
||
.{0.0, 0.0, 1.0},
|
||
.{0.0, 0.0, 1.0},
|
||
.{0.0, 0.0,-1.0},
|
||
.{0.0, 0.0,-1.0},
|
||
.{0.0, 0.0,-1.0},
|
||
.{0.0, 0.0,-1.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0,-1.0, 0.0},
|
||
.{0.0,-1.0, 0.0},
|
||
.{0.0,-1.0, 0.0},
|
||
.{0.0,-1.0, 0.0},
|
||
.{1.0, 0.0, 0.0},
|
||
.{1.0, 0.0, 0.0},
|
||
.{1.0, 0.0, 0.0},
|
||
.{1.0, 0.0, 0.0},
|
||
.{-1.0, 0.0, 0.0},
|
||
.{-1.0, 0.0, 0.0},
|
||
.{-1.0, 0.0, 0.0},
|
||
.{-1.0, 0.0, 0.0}
|
||
];
|
||
|
||
k : u16 = 0;
|
||
i : u16 = 0;
|
||
|
||
indices : [36]u16;
|
||
|
||
while i < 36 {
|
||
indices[i] = 4*k;
|
||
indices[i + 1] = 4*k + 1;
|
||
indices[i + 2] = 4*k + 2;
|
||
indices[i + 3] = 4*k;
|
||
indices[i + 4] = 4*k + 2;
|
||
indices[i + 5] = 4*k + 3;
|
||
k += 1;
|
||
i += 6;
|
||
}
|
||
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.trixel.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 36 * 2 } };
|
||
vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 24 * 3 * 4 } };
|
||
nbuffer := sg_buffer_desc.{ data = .{ ptr = normals.data, size = 24 * 3 * 4 } };
|
||
instance_buffer := sg_buffer_desc.{ usage = .STREAM, size = 4096 * size_of(Position_Color)};
|
||
|
||
gPipelines.trixel.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.trixel.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.trixel.bind.vertex_buffers[1] = sg_make_buffer(*nbuffer);
|
||
gPipelines.trixel.bind.vertex_buffers[2] = sg_make_buffer(*instance_buffer);
|
||
|
||
secondary_instance_buffer := sg_buffer_desc.{ usage = .STREAM, size = 4096 * size_of(Position_Color)};
|
||
trixel_secondary_vbuf = sg_make_buffer(*secondary_instance_buffer);
|
||
}
|
||
|
||
create_gbuffer_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := gbuffer_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
pipeline.layout.buffers[1].stride = 4*3;
|
||
|
||
pipeline.layout.buffers[3].step_func = .PER_INSTANCE;
|
||
|
||
instance_buffer := sg_buffer_desc.{ usage = .STREAM, size = 16 * 4096 * 4 * 4};
|
||
|
||
pipeline.layout.attrs[ATTR_trile_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.layout.attrs[ATTR_trile_normal] = .{ format = .FLOAT3, buffer_index = 1 };
|
||
pipeline.layout.attrs[ATTR_trile_centre] = .{ format = .FLOAT3, buffer_index = 2 };
|
||
pipeline.layout.attrs[ATTR_trile_instance] = .{ format = .FLOAT4, buffer_index = 3 };
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
|
||
color_state_pos := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
color_state_normal := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
|
||
|
||
pipeline.color_count = 3;
|
||
pipeline.colors[0] = color_state_pos;
|
||
pipeline.colors[1] = color_state_normal;
|
||
pipeline.colors[2] = .{ pixel_format = .RGBA16F };
|
||
|
||
gPipelines.gbuffer.pipeline = sg_make_pipeline(*pipeline);
|
||
gPipelines.gbuffer.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
gPipelines.gbuffer.bind.vertex_buffers[3] = sg_make_buffer(*instance_buffer);
|
||
}
|
||
|
||
create_trile_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := trile_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
pipeline.layout.buffers[1].stride = 4*3;
|
||
|
||
pipeline.layout.buffers[3].step_func = .PER_INSTANCE;
|
||
|
||
instance_buffer := sg_buffer_desc.{ usage = .STREAM, size = 16 * 4096 * 4 * 4};
|
||
|
||
pipeline.layout.attrs[ATTR_trile_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.layout.attrs[ATTR_trile_normal] = .{ format = .FLOAT3, buffer_index = 1 };
|
||
pipeline.layout.attrs[ATTR_trile_centre] = .{ format = .FLOAT3, buffer_index = 2 };
|
||
pipeline.layout.attrs[ATTR_trile_instance] = .{ format = .FLOAT4, buffer_index = 3 };
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.trile.pipeline = sg_make_pipeline(*pipeline);
|
||
gPipelines.trile.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
gPipelines.trile.bind.vertex_buffers[3] = sg_make_buffer(*instance_buffer);
|
||
gPipelines.trile.bind.samplers[3] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
}
|
||
|
||
create_trile_rdm_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := trile_rdm_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
pipeline.layout.buffers[1].stride = 4*3;
|
||
pipeline.layout.buffers[3].step_func = .PER_INSTANCE;
|
||
|
||
instance_buffer := sg_buffer_desc.{ usage = .STREAM, size = 16 * 64 };
|
||
|
||
pipeline.layout.attrs[ATTR_trile_rdm_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.layout.attrs[ATTR_trile_rdm_normal] = .{ format = .FLOAT3, buffer_index = 1 };
|
||
pipeline.layout.attrs[ATTR_trile_rdm_centre] = .{ format = .FLOAT3, buffer_index = 2 };
|
||
pipeline.layout.attrs[ATTR_trile_rdm_instance] = .{ format = .FLOAT4, buffer_index = 3 };
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
|
||
},
|
||
};
|
||
|
||
gPipelines.trile_rdm.pipeline = sg_make_pipeline(*pipeline);
|
||
gPipelines.trile_rdm.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
gPipelines.trile_rdm.bind.vertex_buffers[3] = sg_make_buffer(*instance_buffer);
|
||
gPipelines.trile_rdm.bind.samplers[3] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
}
|
||
|
||
create_trile_shadow_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := trile_shadow_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
pipeline.layout.buffers[1].stride = 4*3;
|
||
pipeline.layout.buffers[3].step_func = .PER_INSTANCE;
|
||
// Explicit locations matching layout(location=N) in the shader.
|
||
pipeline.layout.attrs[0] = .{ format = .FLOAT3, buffer_index = 0 }; // position
|
||
pipeline.layout.attrs[1] = .{ format = .FLOAT3, buffer_index = 1 }; // normal (slot match)
|
||
pipeline.layout.attrs[2] = .{ format = .FLOAT3, buffer_index = 2 }; // centre (slot match)
|
||
pipeline.layout.attrs[3] = .{ format = .FLOAT4, buffer_index = 3 }; // instance
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0].pixel_format = .RGBA16F;
|
||
gPipelines.trile_shadow.pipeline = sg_make_pipeline(*pipeline);
|
||
}
|
||
|
||
create_sky_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := sky_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
|
||
pipeline.layout.attrs[ATTR_sky_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
|
||
vertices : [24]Vector3 = .[
|
||
.{-1, -1, 1},
|
||
.{1, -1, 1},
|
||
.{1, 1, 1},
|
||
.{-1, 1, 1},
|
||
.{-1, -1, -1},
|
||
.{-1, 1, -1},
|
||
.{1, 1, -1},
|
||
.{1, -1, -1},
|
||
.{-1, 1, -1},
|
||
.{-1, 1, 1},
|
||
.{1, 1, 1},
|
||
.{1, 1, -1},
|
||
.{-1, -1, -1},
|
||
.{1, -1, -1},
|
||
.{1, -1, 1},
|
||
.{-1, -1, 1},
|
||
.{1, -1, -1},
|
||
.{1, 1, -1},
|
||
.{1, 1, 1},
|
||
.{1, -1, 1},
|
||
.{-1, -1, -1},
|
||
.{-1, -1, 1},
|
||
.{-1, 1, 1},
|
||
.{-1, 1, -1}
|
||
];
|
||
|
||
k : u16 = 0;
|
||
i : u16 = 0;
|
||
|
||
indices : [36]u16;
|
||
|
||
while i < 36 {
|
||
indices[i] = 4*k;
|
||
indices[i + 1] = 4*k + 1;
|
||
indices[i + 2] = 4*k + 2;
|
||
indices[i + 3] = 4*k;
|
||
indices[i + 4] = 4*k + 2;
|
||
indices[i + 5] = 4*k + 3;
|
||
k += 1;
|
||
i += 6;
|
||
}
|
||
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.sky.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 36 * 2 } };
|
||
vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 24 * 3 * 4 } };
|
||
|
||
gPipelines.sky.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.sky.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
}
|
||
|
||
create_plane_pipeline_reflection_images :: () {
|
||
binding := *gPipelines.plane.bind;
|
||
if binding.images[4].id != INVALID_ID then sg_destroy_image(binding.images[4]);
|
||
if binding.images[5].id != INVALID_ID then sg_destroy_image(binding.images[5]);
|
||
if binding.images[0].id != INVALID_ID then sg_destroy_image(binding.images[0]);
|
||
|
||
w, h := get_render_size();
|
||
img_desc := sg_image_desc.{
|
||
width = w/3,
|
||
height = h/3,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
};
|
||
depth_desc := sg_image_desc.{
|
||
width = w/3,
|
||
height = h/3,
|
||
pixel_format = .DEPTH,
|
||
render_target = true,
|
||
};
|
||
binding.images[4] = sg_make_image(*img_desc);
|
||
img_desc.sample_count = 1;
|
||
binding.images[0] = sg_make_image(*img_desc);
|
||
binding.images[5] = sg_make_image(*depth_desc);
|
||
|
||
attachmentsDesc : sg_attachments_desc;
|
||
attachmentsDesc = .{
|
||
colors[0].image = gPipelines.plane.bind.images[0],
|
||
depth_stencil.image = gPipelines.plane.bind.images[5],
|
||
};
|
||
|
||
sg_destroy_attachments(gPipelines.plane.attachments);
|
||
gPipelines.plane.attachments = sg_make_attachments(*attachmentsDesc);
|
||
}
|
||
|
||
create_plane_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := plane_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
|
||
|
||
pipeline.layout.attrs[ATTR_plane_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
vertices: [4]Vector3 = .[
|
||
.{-1.0, 0.0, -1.0},
|
||
.{ 1.0, 0.0, -1.0},
|
||
.{ 1.0, 0.0, 1.0},
|
||
.{-1.0, 0.0, 1.0},
|
||
];
|
||
|
||
indices: [6]u16 = .[
|
||
0, 1, 2,
|
||
0, 2, 3,
|
||
];
|
||
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.plane.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 6 * 2 } };
|
||
vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 4 * 3 * 4 } };
|
||
|
||
gPipelines.plane.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.plane.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
create_plane_pipeline_reflection_images();
|
||
|
||
|
||
|
||
gPipelines.plane.pass_action = .{
|
||
colors[0] = .{ load_action = .CLEAR, clear_value = .{ 0.25, 0.25, 0.25, 1.0 } },
|
||
};
|
||
|
||
gPipelines.plane.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
|
||
g_shadowmap_sampler = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
compare = .LESS,
|
||
}));
|
||
|
||
gPipelines.plane.bind.samplers[1] = g_shadowmap_sampler;
|
||
|
||
gPipelines.plane.bind.samplers[2] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .REPEAT,
|
||
wrap_v = .REPEAT,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
|
||
ground_img_desc := sg_image_desc.{
|
||
width = 1000,
|
||
height = 1000,
|
||
pixel_format = .RGBA8,
|
||
render_target = false,
|
||
sample_count = 1,
|
||
usage = .DYNAMIC,
|
||
};
|
||
}
|
||
|
||
create_arbtri_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := triangle_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_triangle_position] = .{ format = .FLOAT3 };
|
||
pipeline.layout.attrs[ATTR_triangle_color0] = .{ format = .FLOAT4 };
|
||
pipeline.layout.attrs[ATTR_triangle_uv] = .{ format = .FLOAT2 };
|
||
|
||
color_state := sg_color_target_state.{
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.arbtri.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
buffer := sg_buffer_desc.{ usage = .DYNAMIC, size = size_of(type_of(gArbtriMem)) };
|
||
gPipelines.arbtri.bind.vertex_buffers[0] = sg_make_buffer(*buffer);
|
||
gPipelines.arbtri.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
}
|
||
|
||
create_postprocess_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := postprocess_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_postprocess_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_postprocess_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
|
||
color_state := sg_color_target_state.{
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.postprocess.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0), // top-let
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0), // bottom-let
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0), // bottom-right
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0), // top-right
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.postprocess.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.postprocess.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.postprocess.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
gPipelines.postprocess.bind.samplers[1] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
|
||
gPipelines.postprocess.bind.samplers[2] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
|
||
gPipelines.postprocess.bind.samplers[3] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .LINEAR,
|
||
mag_filter = .LINEAR,
|
||
}));
|
||
|
||
}
|
||
|
||
// Takes in a texture, manipulates it and outputs it.
|
||
create_op_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := op_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_op_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_op_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
|
||
color_state := sg_color_target_state.{
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
},
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.op.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0), // top-let
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0), // bottom-let
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0), // bottom-right
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0), // top-right
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.op.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.op.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.op.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
}
|
||
|
||
create_billboard_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := billboard_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
|
||
pipeline.layout.attrs[ATTR_billboard_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
}
|
||
};
|
||
|
||
vertices: [4]Vector3 = .[
|
||
.{ 0.0, 0.0, 0.0},
|
||
.{ 1.0, 0.0, 0.0},
|
||
.{ 1.0, 1.0, 0.0},
|
||
.{ 0.0, 1.0, 0.0},
|
||
];
|
||
|
||
indices: [6]u16 = .[
|
||
0, 1, 2,
|
||
0, 2, 3,
|
||
];
|
||
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.billboard.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 6 * 2 } };
|
||
vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 4 * 3 * 4 } };
|
||
|
||
gPipelines.billboard.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.billboard.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
|
||
gPipelines.billboard.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
}
|
||
|
||
create_gbuffer_billboard_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := gbuffer_billboard_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.buffers[0].stride = 4*3;
|
||
|
||
pipeline.layout.attrs[ATTR_billboard_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
|
||
color_state_pos := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
color_state_normal := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
|
||
|
||
pipeline.color_count = 3;
|
||
pipeline.colors[0] = color_state_pos;
|
||
pipeline.colors[1] = color_state_normal;
|
||
pipeline.colors[2] = .{ pixel_format = .RGBA16F };
|
||
|
||
vertices: [4]Vector3 = .[
|
||
.{ 0.0, 0.0, 0.0},
|
||
.{ 1.0, 0.0, 0.0},
|
||
.{ 1.0, 1.0, 0.0},
|
||
.{ 0.0, 1.0, 0.0},
|
||
];
|
||
|
||
indices: [6]u16 = .[
|
||
0, 1, 2,
|
||
0, 2, 3,
|
||
];
|
||
|
||
gPipelines.gbuffer_billboard.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
ibuffer := sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 6 * 2 } };
|
||
vbuffer := sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 4 * 3 * 4 } };
|
||
|
||
gPipelines.gbuffer_billboard.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.gbuffer_billboard.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
|
||
gPipelines.gbuffer_billboard.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
}
|
||
|
||
// Takes in 2-3 textures, and mixes them.
|
||
create_mix_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := mix_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_mix_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_mix_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
|
||
color_state := sg_color_target_state.{
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
},
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.mix.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0), // top-let
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0), // bottom-let
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0), // bottom-right
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0), // top-right
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.mix.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.mix.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.mix.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
}
|
||
|
||
create_bloom_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := bloom_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_bloom_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_bloom_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth.pixel_format = .NONE;
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = .{ pixel_format = .RGBA16F };
|
||
|
||
gPipelines.bloom.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0),
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0),
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0),
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0),
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.bloom.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.bloom.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.bloom.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
}
|
||
|
||
create_dof_pipeline :: () {
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := dof_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_dof_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_dof_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth.pixel_format = .NONE;
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = .{ pixel_format = .RGBA16F };
|
||
|
||
gPipelines.dof.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0),
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0),
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0),
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0),
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.dof.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.dof.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.dof.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
}
|
||
|
||
create_sh_irradiance_image :: () {
|
||
w, h := get_render_size();
|
||
if g_sh_irradiance.id != INVALID_ID then sg_destroy_image(g_sh_irradiance);
|
||
g_sh_irradiance = sg_make_image(*(sg_image_desc.{
|
||
width = w / 2,
|
||
height = h / 2,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
sample_count = 1,
|
||
}));
|
||
sg_destroy_attachments(g_sh_irradiance_attach);
|
||
g_sh_irradiance_attach = sg_make_attachments(*(sg_attachments_desc.{
|
||
colors[0].image = g_sh_irradiance,
|
||
}));
|
||
}
|
||
|
||
create_sh_irradiance_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := sh_deferred_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.layout.attrs[ATTR_sh_deferred_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_sh_deferred_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth.pixel_format = .NONE;
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = .{ pixel_format = .RGBA16F };
|
||
gPipelines.sh_irradiance.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0),
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0),
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0),
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0),
|
||
];
|
||
quad_indices : [6]u16 = .[ 0, 1, 2, 0, 2, 3 ];
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{ ptr = quad_vertices.data, size = 16 * 4 }};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{ ptr = quad_indices.data, size = 6 * 2 }, type = .INDEXBUFFER };
|
||
gPipelines.sh_irradiance.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.sh_irradiance.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.sh_irradiance.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
}
|
||
|
||
create_ssao_images :: () {
|
||
if g_ssaobuf.id != INVALID_ID then sg_destroy_image(g_ssaobuf);
|
||
if g_ssaobuf_depth.id != INVALID_ID then sg_destroy_image(g_ssaobuf_depth);
|
||
if g_postprocess_a.id != INVALID_ID then sg_destroy_image(g_postprocess_a);
|
||
if g_postprocess_a_depth.id != INVALID_ID then sg_destroy_image(g_postprocess_a_depth);
|
||
if g_postprocess_b.id != INVALID_ID then sg_destroy_image(g_postprocess_b);
|
||
if g_postprocess_b_depth.id != INVALID_ID then sg_destroy_image(g_postprocess_b_depth);
|
||
w,h := get_render_size();
|
||
img_desc := sg_image_desc.{
|
||
width = w/2,
|
||
height = h/2,
|
||
render_target = true,
|
||
pixel_format = .RGBA16F
|
||
};
|
||
img_desc.sample_count = 1;
|
||
g_ssaobuf = sg_make_image(*img_desc);
|
||
img_desc.width *= 2; img_desc.height *= 2;
|
||
g_postprocess_a = sg_make_image(*img_desc);
|
||
g_postprocess_b = sg_make_image(*img_desc);
|
||
img_desc = sg_image_desc.{
|
||
width = w/2,
|
||
height = h/2,
|
||
pixel_format = .DEPTH,
|
||
render_target = true,
|
||
};
|
||
img_desc.sample_count = 1;
|
||
g_ssaobuf_depth = sg_make_image(*img_desc);
|
||
img_desc.width *= 2; img_desc.height *= 2;
|
||
g_postprocess_a_depth = sg_make_image(*img_desc);
|
||
g_postprocess_b_depth = sg_make_image(*img_desc);
|
||
|
||
attachmentsDesc := sg_attachments_desc.{
|
||
colors[0].image = g_ssaobuf,
|
||
depth_stencil.image = g_ssaobuf_depth
|
||
};
|
||
sg_destroy_attachments(g_ssao_attachments);
|
||
g_ssao_attachments = sg_make_attachments(*attachmentsDesc);
|
||
|
||
attachmentsDescA := sg_attachments_desc.{
|
||
colors[0].image = g_postprocess_a,
|
||
depth_stencil.image = g_postprocess_a_depth
|
||
};
|
||
attachmentsDescB := sg_attachments_desc.{
|
||
colors[0].image = g_postprocess_b,
|
||
depth_stencil.image = g_postprocess_b_depth
|
||
};
|
||
sg_destroy_attachments(g_postprocess_attach_a);
|
||
g_postprocess_attach_a = sg_make_attachments(*attachmentsDescA);
|
||
sg_destroy_attachments(g_postprocess_attach_b);
|
||
g_postprocess_attach_b = sg_make_attachments(*attachmentsDescB);
|
||
|
||
if g_bloom_tex.id != INVALID_ID then sg_destroy_image(g_bloom_tex);
|
||
bloom_img_desc := sg_image_desc.{
|
||
width = w/8,
|
||
height = h/8,
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
sample_count = 1,
|
||
};
|
||
g_bloom_tex = sg_make_image(*bloom_img_desc);
|
||
bloom_attach_desc := sg_attachments_desc.{
|
||
colors[0].image = g_bloom_tex,
|
||
};
|
||
sg_destroy_attachments(g_bloom_attach);
|
||
g_bloom_attach = sg_make_attachments(*bloom_attach_desc);
|
||
|
||
if g_dof_tex.id != INVALID_ID then sg_destroy_image(g_dof_tex);
|
||
dof_img_desc := sg_image_desc.{
|
||
width = cast(s32)((cast(float)w)/1.5),
|
||
height = cast(s32)((cast(float)h)/1.5),
|
||
pixel_format = .RGBA16F,
|
||
render_target = true,
|
||
sample_count = 1,
|
||
};
|
||
g_dof_tex = sg_make_image(*dof_img_desc);
|
||
dof_attach_desc := sg_attachments_desc.{
|
||
colors[0].image = g_dof_tex,
|
||
};
|
||
sg_destroy_attachments(g_dof_attach);
|
||
g_dof_attach = sg_make_attachments(*dof_attach_desc);
|
||
}
|
||
|
||
create_ssao_pipeline :: () {
|
||
init_ssao();
|
||
platconf := get_plat_conf();
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := ssao_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
|
||
pipeline.layout.attrs[ATTR_ssao_position] = .{ format = .FLOAT2 };
|
||
pipeline.layout.attrs[ATTR_ssao_uv] = .{ format = .FLOAT2 };
|
||
pipeline.index_type = .UINT16;
|
||
|
||
color_state := sg_color_target_state.{
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA
|
||
},
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
|
||
pipeline.color_count = 1;
|
||
pipeline.depth = .{
|
||
write_enabled = true,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH
|
||
};
|
||
pipeline.colors[0] = color_state;
|
||
|
||
gPipelines.ssao.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
quad_vertices : [16]float = .[
|
||
-1.0, 1.0, 0.0, flip_if_plat(1.0), // top-let
|
||
-1.0, -1.0, 0.0, flip_if_plat(0.0), // bottom-let
|
||
1.0, -1.0, 1.0, flip_if_plat(0.0), // bottom-right
|
||
1.0, 1.0, 1.0, flip_if_plat(1.0), // top-right
|
||
];
|
||
quad_indices : [6]u16 = .[
|
||
0, 1, 2, 0, 2, 3
|
||
];
|
||
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{
|
||
ptr = quad_vertices.data,
|
||
size = 16 * 4
|
||
}};
|
||
ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{
|
||
ptr = quad_indices.data,
|
||
size = 6 * 2
|
||
},
|
||
type = .INDEXBUFFER,
|
||
};
|
||
|
||
gPipelines.ssao.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer);
|
||
gPipelines.ssao.bind.index_buffer = sg_make_buffer(*ibuffer);
|
||
gPipelines.ssao.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .REPEAT,
|
||
wrap_v = .REPEAT,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
|
||
imgdata : sg_image_data;
|
||
imgdata.subimage[0][0] = .{g_ssao_noise.data, cast(u64) (16*4*4)};
|
||
texdesc : sg_image_desc = .{
|
||
render_target = false,
|
||
width = 4,
|
||
height = 4,
|
||
pixel_format = sg_pixel_format.RGBA32F,
|
||
sample_count = 1,
|
||
data = imgdata
|
||
};
|
||
g_ssao_noise_buf = sg_make_image(*texdesc);
|
||
}
|
||
|
||
init_plane_textures :: () {
|
||
gPipelines.plane.bind.images[2] = get_texture_from_pack("core", "utiltex/water_small.png");
|
||
}
|
||
|
||
init_brdf_lut :: () {
|
||
g_brdf_lut = get_texture_from_pack("core", "utiltex/lut.png");
|
||
if g_brdf_lut.id == INVALID_ID {
|
||
// Create a 1x1 fallback so sokol doesn't drop draw calls
|
||
pixels : [4]u8 = .[255, 255, 255, 255];
|
||
imgdata : sg_image_data;
|
||
imgdata.subimage[0][0] = .{ pixels.data, 4 };
|
||
desc := sg_image_desc.{
|
||
width = 1,
|
||
height = 1,
|
||
pixel_format = .RGBA8,
|
||
data = imgdata,
|
||
};
|
||
g_brdf_lut = sg_make_image(*desc);
|
||
}
|
||
|
||
{
|
||
pixels : [4]u8 = .[0, 0, 0, 0];
|
||
imgdata : sg_image_data;
|
||
imgdata.subimage[0][0] = .{ pixels.data, 4 };
|
||
desc := sg_image_desc.{
|
||
width = 1,
|
||
height = 1,
|
||
pixel_format = .RGBA8,
|
||
data = imgdata,
|
||
};
|
||
g_rdm_fallback = sg_make_image(*desc);
|
||
|
||
zero_sh : [4]u16 = .[0, 0, 0, 0];
|
||
sh_imgdata : sg_image_data;
|
||
sh_imgdata.subimage[0][0] = .{ zero_sh.data, size_of(type_of(zero_sh)) };
|
||
sh_desc := sg_image_desc.{
|
||
width = 1,
|
||
height = 1,
|
||
pixel_format = .RGBA16F,
|
||
data = sh_imgdata,
|
||
};
|
||
g_sh_fallback = sg_make_image(*sh_desc);
|
||
|
||
zero_atlas : [4]u16 = .[0, 0, 0, 0];
|
||
atlas_imgdata : sg_image_data;
|
||
atlas_imgdata.subimage[0][0] = .{ zero_atlas.data, size_of(type_of(zero_atlas)) };
|
||
atlas_desc := sg_image_desc.{
|
||
width = 1,
|
||
height = 1,
|
||
pixel_format = .RGBA16F,
|
||
data = atlas_imgdata,
|
||
};
|
||
g_rdm_atlas = sg_make_image(*atlas_desc);
|
||
}
|
||
}
|
||
|
||
g_plane_gbuffer_vertex_buffer : sg_buffer;
|
||
g_plane_gbuffer_normal_buffer : sg_buffer;
|
||
g_plane_gbuffer_center_buffer : sg_buffer;
|
||
g_plane_gbuffer_instance_buffer : sg_buffer;
|
||
|
||
create_gbuffer_impostors :: () {
|
||
plane_vertices: [6]Vector3 = .[
|
||
.{-1.0, 0.0, -1.0},
|
||
.{ 1.0, 0.0, -1.0},
|
||
.{ 1.0, 0.0, 1.0},
|
||
.{-1.0, 0.0, -1.0},
|
||
.{ 1.0, 0.0, 1.0},
|
||
.{-1.0, 0.0, 1.0},
|
||
];
|
||
vbuffer := sg_buffer_desc.{ size = size_of(float) * 18, data = .{
|
||
ptr = plane_vertices.data,
|
||
size = 6 * 3 * 4
|
||
}};
|
||
g_plane_gbuffer_vertex_buffer = sg_make_buffer(*vbuffer);
|
||
|
||
plane_normals: [6]Vector3 = .[
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
];
|
||
nbuffer := sg_buffer_desc.{ size = size_of(float) * 18, data = .{
|
||
ptr = plane_normals.data,
|
||
size = 6 * 3 * 4
|
||
}};
|
||
g_plane_gbuffer_normal_buffer = sg_make_buffer(*nbuffer);
|
||
|
||
plane_centers: [2]Vector3 = .[ // these are useless, just to fill the pipeline requirement.
|
||
.{0.0, 1.0, 0.0},
|
||
.{0.0, 1.0, 0.0},
|
||
];
|
||
cbuffer := sg_buffer_desc.{ size = size_of(float) * 6, data = .{
|
||
ptr = plane_centers.data,
|
||
size = 3 * 2 * 4
|
||
}};
|
||
g_plane_gbuffer_center_buffer = sg_make_buffer(*cbuffer);
|
||
|
||
instances: [1]Vector4 = .[.{0,0,0,0}];
|
||
instance_buffer := sg_buffer_desc.{size = 4 * 4, data = .{
|
||
ptr = instances.data,
|
||
size = 4*4,
|
||
}};
|
||
g_plane_gbuffer_instance_buffer = sg_make_buffer(*instance_buffer);
|
||
|
||
}
|
||
|
||
create_particle_pipeline :: () {
|
||
pipeline: sg_pipeline_desc;
|
||
shader_desc := particle_shader_desc(sg_query_backend());
|
||
shd := sg_make_shader(*shader_desc);
|
||
pipeline.shader = shd;
|
||
|
||
pipeline.layout.buffers[0].stride = 4 * 3;
|
||
pipeline.layout.buffers[1].stride = 4 * 4;
|
||
pipeline.layout.buffers[1].step_func = .PER_INSTANCE;
|
||
pipeline.layout.buffers[2].stride = 4 * 4;
|
||
pipeline.layout.buffers[2].step_func = .PER_INSTANCE;
|
||
pipeline.layout.buffers[3].stride = 4 * 4;
|
||
pipeline.layout.buffers[3].step_func = .PER_INSTANCE;
|
||
|
||
pipeline.layout.attrs[ATTR_particle_position] = .{ format = .FLOAT3, buffer_index = 0 };
|
||
pipeline.layout.attrs[ATTR_particle_inst_pos_size] = .{ format = .FLOAT4, buffer_index = 1 };
|
||
pipeline.layout.attrs[ATTR_particle_inst_uv_rect] = .{ format = .FLOAT4, buffer_index = 2 };
|
||
pipeline.layout.attrs[ATTR_particle_inst_color] = .{ format = .FLOAT4, buffer_index = 3 };
|
||
|
||
pipeline.index_type = .UINT16;
|
||
pipeline.depth = .{
|
||
write_enabled = false,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
pipeline.color_count = 1;
|
||
|
||
pipeline.colors[0] = .{
|
||
pixel_format = .RGBA16F,
|
||
blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE,
|
||
src_factor_alpha = .ONE,
|
||
dst_factor_alpha = .ONE,
|
||
},
|
||
};
|
||
gPipelines.particle_additive.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
pipeline.colors[0].blend = .{
|
||
enabled = true,
|
||
src_factor_rgb = .SRC_ALPHA,
|
||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
|
||
src_factor_alpha = .ONE,
|
||
dst_factor_alpha = .ONE_MINUS_SRC_ALPHA,
|
||
};
|
||
gPipelines.particle_alpha.pipeline = sg_make_pipeline(*pipeline);
|
||
|
||
vertices: [4]Vector3 = .[
|
||
.{ 0.0, 0.0, 0.0 },
|
||
.{ 1.0, 0.0, 0.0 },
|
||
.{ 1.0, 1.0, 0.0 },
|
||
.{ 0.0, 1.0, 0.0 },
|
||
];
|
||
|
||
indices: [6]u16 = .[
|
||
0, 1, 2,
|
||
0, 2, 3,
|
||
];
|
||
|
||
idx_buf := sg_make_buffer(*(sg_buffer_desc.{ type = .INDEXBUFFER, data = .{ ptr = indices.data, size = 6 * 2 } }));
|
||
vtx_buf := sg_make_buffer(*(sg_buffer_desc.{ data = .{ ptr = vertices.data, size = 4 * 3 * 4 } }));
|
||
inst1 := sg_make_buffer(*(sg_buffer_desc.{ size = cast(u64)(MAX_PARTICLES * size_of(Vector4)), usage = .STREAM }));
|
||
inst2 := sg_make_buffer(*(sg_buffer_desc.{ size = cast(u64)(MAX_PARTICLES * size_of(Vector4)), usage = .STREAM }));
|
||
inst3 := sg_make_buffer(*(sg_buffer_desc.{ size = cast(u64)(MAX_PARTICLES * size_of(Vector4)), usage = .STREAM }));
|
||
smp := sg_make_sampler(*(sg_sampler_desc.{
|
||
wrap_u = .CLAMP_TO_EDGE,
|
||
wrap_v = .CLAMP_TO_EDGE,
|
||
min_filter = .NEAREST,
|
||
mag_filter = .NEAREST,
|
||
}));
|
||
|
||
setup_bind :: (bind: *sg_bindings, idx_buf: sg_buffer, vtx_buf: sg_buffer, inst1: sg_buffer, inst2: sg_buffer, inst3: sg_buffer, smp: sg_sampler) {
|
||
bind.index_buffer = idx_buf;
|
||
bind.vertex_buffers[0] = vtx_buf;
|
||
bind.vertex_buffers[1] = inst1;
|
||
bind.vertex_buffers[2] = inst2;
|
||
bind.vertex_buffers[3] = inst3;
|
||
bind.samplers[SMP_particle_spritesmp] = smp;
|
||
}
|
||
setup_bind(*gPipelines.particle_additive.bind, idx_buf, vtx_buf, inst1, inst2, inst3, smp);
|
||
setup_bind(*gPipelines.particle_alpha.bind, idx_buf, vtx_buf, inst1, inst2, inst3, smp);
|
||
}
|
||
|
||
create_debugline_pipeline :: () {
|
||
buf_desc := sg_buffer_desc.{
|
||
size = DEBUG_LINE_MAX * 2 * 7 * size_of(float),
|
||
usage = .DYNAMIC,
|
||
label = "debug_line_verts",
|
||
};
|
||
gPipelines.debugline.bind.vertex_buffers[0] = sg_make_buffer(*buf_desc);
|
||
|
||
pipeline : sg_pipeline_desc;
|
||
shader_desc := debugline_shader_desc(sg_query_backend());
|
||
pipeline.shader = sg_make_shader(*shader_desc);
|
||
pipeline.primitive_type = .LINES;
|
||
pipeline.layout.buffers[0].stride = 28;
|
||
pipeline.layout.attrs[ATTR_debugline_a_pos] = .{ format = .FLOAT3, buffer_index = 0, offset = 0 };
|
||
pipeline.layout.attrs[ATTR_debugline_a_col] = .{ format = .FLOAT4, buffer_index = 0, offset = 12 };
|
||
pipeline.depth = .{
|
||
write_enabled = false,
|
||
compare = .LESS_EQUAL,
|
||
pixel_format = .DEPTH,
|
||
};
|
||
color_state := sg_color_target_state.{
|
||
pixel_format = .RGBA16F,
|
||
};
|
||
pipeline.color_count = 1;
|
||
pipeline.colors[0] = color_state;
|
||
pipeline.label = "debugline_pipeline";
|
||
gPipelines.debugline.pipeline = sg_make_pipeline(*pipeline);
|
||
}
|