Merge remote-tracking branch 'origin/gles3'

main
commit 741ceb14f5

2
.gitignore vendored

@ -109,3 +109,5 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
emsdk/

@ -15,6 +15,7 @@ copy marketing_page\favicon.ico %OUTPUT_FOLDER%\favicon.ico
emcc ^
-sEXPORTED_FUNCTIONS=_main,_end_text_input,_stop_controlling_input,_start_controlling_input,_read_from_save_data,_dump_save_data,_is_receiving_text_input^
-sEXPORTED_RUNTIME_METHODS=ccall,cwrap^
-s USE_WEBGL2=1^
-s INITIAL_MEMORY=62914560^
-s ALLOW_MEMORY_GROWTH -s TOTAL_STACK=15728640^
%FLAGS%^

240
main.c

@ -26,8 +26,8 @@
#if defined(__EMSCRIPTEN__)
#define WEB
#define SOKOL_GLES2
#define SAMPLE_COUNT 1 // bumping this back to 4 is troublesome for web, because there's a mismatch in sample counts. Perhaps we must upgrade to gles3, in doing so, we should upgrade to the newest sokol gfx.
#define SOKOL_GLES3
#define SAMPLE_COUNT 4
#endif
#define DRWAV_ASSERT game_assert
@ -58,11 +58,7 @@ __declspec(dllexport) uint32_t AmdPowerXpressRequestHighPerformance = 0x00000001
#pragma warning(push)
#pragma warning(disable : 4191) // unsafe function calling
#ifdef WEB
# ifndef GL_EXT_PROTOTYPES
# define GL_GLEXT_PROTOTYPES
# endif
# include <GLES2/gl2.h>
# include <GLES2/gl2ext.h>
# include <GLES3/gl3.h>
# undef glGetError
# define glGetError() (GL_NO_ERROR)
#endif
@ -843,18 +839,15 @@ sg_image load_image(MD_String8 path)
{
.width = png_width,
.height = png_height,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_LINEAR,
.pixel_format = sapp_sgcontext().color_format,
.num_mipmaps = 1,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
.mag_filter = SG_FILTER_LINEAR,
.data.subimage[0][0] =
{
.ptr = pixels,
.size = (size_t)(png_width * png_height * num_channels),
}
});
loaded->image = to_return;
MD_ReleaseScratch(scratch);
return to_return;
@ -1233,14 +1226,6 @@ Armature load_armature(MD_Arena *arena, MD_String8 binary_file, MD_String8 armat
.width = to_return.bones_texture_width,
.height = to_return.bones_texture_height,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_NEAREST,
.mag_filter = SG_FILTER_NEAREST,
// for webgl NPOT texures https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
.wrap_w = SG_WRAP_CLAMP_TO_EDGE,
.usage = SG_USAGE_STREAM,
});
@ -2662,26 +2647,34 @@ Shadow_State init_shadow_state();
static struct
{
sg_pass_action clear_everything_pass_action;
sg_pass_action threedee_msaa_pass_action;
sg_pass_action clear_depth_buffer_pass_action;
sg_pipeline twodee_pip;
sg_bindings bind;
sg_pipeline threedee_pip;
sg_pipeline threedee_alpha_blended_pip;
sg_pipeline armature_pip;
sg_bindings threedee_bind;
sg_image outline_pass_image;
sg_image outline_pass_resolve_image;
sg_pass outline_pass;
sg_pipeline outline_mesh_pip;
sg_pipeline outline_armature_pip;
sg_pass threedee_pass; // is a pass so I can do post processing in a shader
sg_image threedee_pass_image;
sg_image threedee_pass_resolve_image;
sg_image threedee_pass_depth_image;
sg_pipeline twodee_outline_pip;
sg_pipeline twodee_colorcorrect_pip;
sg_sampler sampler_linear;
sg_sampler sampler_linear_border;
sg_sampler sampler_nearest;
Shadow_State shadows;
} state;
@ -2696,7 +2689,9 @@ void create_screenspace_gfx_state()
MAYBE_DESTROY(state.threedee_pass, sg_destroy_pass);
MAYBE_DESTROY(state.outline_pass_image, sg_destroy_image);
MAYBE_DESTROY(state.outline_pass_resolve_image, sg_destroy_image);
MAYBE_DESTROY(state.threedee_pass_image, sg_destroy_image);
MAYBE_DESTROY(state.threedee_pass_resolve_image, sg_destroy_image);
MAYBE_DESTROY(state.threedee_pass_depth_image, sg_destroy_image);
#undef MAYBE_DESTROY
@ -2766,35 +2761,41 @@ void create_screenspace_gfx_state()
.render_target = true,
.width = sapp_width(),
.height = sapp_height(),
.pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_BORDER,
.wrap_v = SG_WRAP_CLAMP_TO_BORDER,
.border_color = SG_BORDERCOLOR_OPAQUE_WHITE,
.sample_count = SAMPLE_COUNT,
.pixel_format = sapp_sgcontext().color_format,
.label = "outline-pass-render-target",
};
desc.sample_count = SAMPLE_COUNT;
state.outline_pass_image = sg_make_image(&desc);
desc.sample_count = 1;
state.outline_pass_resolve_image = sg_make_image(&desc);
state.outline_pass = sg_make_pass(&(sg_pass_desc){
.color_attachments[0].image = state.outline_pass_image,
.resolve_attachments[0].image = state.outline_pass_resolve_image,
.depth_stencil_attachment = {
0
},
.label = "outline-pass",
});
desc.sample_count = SAMPLE_COUNT;
desc.sample_count = 1;
desc.label = "threedee-pass-render-target";
desc.sample_count = SAMPLE_COUNT;
state.threedee_pass_image = sg_make_image(&desc);
desc.label = "threedee-pass-resolve-render-target";
desc.sample_count = 1;
state.threedee_pass_resolve_image = sg_make_image(&desc);
desc.label = "threedee-pass-depth-render-target";
desc.pixel_format = sapp_depth_format();
desc.pixel_format = SG_PIXELFORMAT_DEPTH;
desc.sample_count = SAMPLE_COUNT;
state.threedee_pass_depth_image = sg_make_image(&desc);
state.threedee_pass = sg_make_pass(&(sg_pass_desc){
.color_attachments[0].image = state.threedee_pass_image,
.resolve_attachments[0].image = state.threedee_pass_resolve_image,
.depth_stencil_attachment = (sg_pass_attachment_desc){
.image = state.threedee_pass_depth_image,
.mip_level = 0,
@ -3014,8 +3015,8 @@ Color blendalpha(Color c, float alpha)
// in pixels
Vec2 img_size(sg_image img)
{
sg_image_info info = sg_query_image_info(img);
return V2((float)info.width, (float)info.height);
sg_image_desc desc = sg_query_image_desc(img);
return V2((float)desc.width, (float)desc.height);
}
#ifdef DEVTOOLS
@ -3137,8 +3138,6 @@ LoadedFont load_font(MD_Arena *arena, MD_String8 font_filepath, float font_size)
.width = font_bitmap_width,
.height = font_bitmap_width,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.data.subimage[0][0] =
{
.ptr = font_bitmap_rgba,
@ -3215,6 +3214,7 @@ void init(void)
sg_setup(&(sg_desc) {
.context = sapp_sgcontext(),
.buffer_pool_size = 512,
.logger.func = slog_func,
});
stm_setup();
saudio_setup(&(saudio_desc) {
@ -3375,29 +3375,38 @@ void init(void)
assert(desc);
shd = sg_make_shader(desc);
state.threedee_pip = sg_make_pipeline(&(sg_pipeline_desc){
.shader = shd,
.layout = {.attrs = {
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
}},
.depth = {
.pixel_format = sapp_depth_format(),
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.colors[0].blend = (sg_blend_state){
{
sg_pipeline_desc threedee_pip_desc = {
.shader = shd,
.layout = {.attrs = {
[ATTR_threedee_vs_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
}},
.depth = {
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.alpha_to_coverage_enabled = true,
.sample_count = SAMPLE_COUNT,
.colors[0].blend.enabled = false,
.label = "threedee",
};
state.threedee_pip = sg_make_pipeline(&threedee_pip_desc);
threedee_pip_desc.depth.write_enabled = false;
threedee_pip_desc.alpha_to_coverage_enabled = false;
threedee_pip_desc.colors[0].blend = (sg_blend_state){
// allow transparency
.enabled = true,
.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_rgb = SG_BLENDOP_ADD,
.src_factor_alpha = SG_BLENDFACTOR_ONE,
.src_factor_alpha = SG_BLENDFACTOR_SRC_ALPHA,
.dst_factor_alpha = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA,
.op_alpha = SG_BLENDOP_ADD,
},
.label = "threedee",
});
state.threedee_alpha_blended_pip = sg_make_pipeline(&threedee_pip_desc);
}
desc = threedee_armature_shader_desc(sg_query_backend());
assert(desc);
@ -3407,10 +3416,11 @@ void init(void)
{
.shader = shd,
.depth = {
.pixel_format = sapp_depth_format(),
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true
},
.sample_count = SAMPLE_COUNT,
.layout = {
.attrs =
{
@ -3434,11 +3444,45 @@ void init(void)
state.clear_depth_buffer_pass_action = (sg_pass_action)
{
.colors[0] = { .action = SG_ACTION_LOAD },
.depth = { .action = SG_ACTION_CLEAR, .value = 1.0f },
.colors[0] = { .load_action = SG_LOADACTION_LOAD },
.depth = { .load_action = SG_LOADACTION_CLEAR, .clear_value = 1.0f },
};
state.clear_everything_pass_action = state.clear_depth_buffer_pass_action;
state.clear_everything_pass_action.colors[0] = (sg_color_attachment_action){ .action = SG_ACTION_CLEAR, .value = { clearcol.r, clearcol.g, clearcol.b, 1.0f } };
state.clear_everything_pass_action.colors[0] = (sg_color_attachment_action){ .load_action = SG_LOADACTION_CLEAR, .clear_value = { clearcol.r, clearcol.g, clearcol.b, 1.0f } };
state.threedee_msaa_pass_action = state.clear_everything_pass_action;
state.threedee_msaa_pass_action.colors[0].load_action = SG_LOADACTION_CLEAR;
state.threedee_msaa_pass_action.colors[0].store_action = SG_STOREACTION_DONTCARE;
state.sampler_linear = sg_make_sampler(&(sg_sampler_desc) {
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
// .mipmap_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
// .max_anisotropy = 16,
.label = "sampler-linear",
});
state.sampler_linear_border = sg_make_sampler(&(sg_sampler_desc) {
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_BORDER,
.wrap_v = SG_WRAP_CLAMP_TO_BORDER,
.border_color = SG_BORDERCOLOR_OPAQUE_WHITE,
.label = "sampler-linear-border",
});
state.sampler_nearest = sg_make_sampler(&(sg_sampler_desc) {
.min_filter = SG_FILTER_NEAREST,
.mag_filter = SG_FILTER_NEAREST,
// for webgl NPOT texures https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL
.wrap_u = SG_WRAP_CLAMP_TO_EDGE,
.wrap_v = SG_WRAP_CLAMP_TO_EDGE,
.wrap_w = SG_WRAP_CLAMP_TO_EDGE,
.label = "sampler-nearest",
});
}
Vec2 screen_size()
@ -3729,9 +3773,16 @@ void flush_quad_batch()
state.bind.vertex_buffer_offsets[0] = sg_append_buffer(state.bind.vertex_buffers[0], &(sg_range) { cur_batch_data, cur_batch_data_index*sizeof(*cur_batch_data) });
state.bind.fs_images[SLOT_threedee_twodee_tex] = cur_batch_image;
state.bind.fs.images[SLOT_threedee_twodee_tex] = cur_batch_image; // NOTE that this might get FUCKED if a custom pipeline is provided with more/less texture slots!!!
state.bind.fs.samplers[SLOT_threedee_fs_twodee_smp] = state.sampler_linear; // NOTE that this might get FUCKED if a custom pipeline is provided with more/less sampler slots!!!
sg_apply_bindings(&state.bind);
cur_batch_params.tex_size = img_size(cur_batch_image);
cur_batch_params.screen_size = screen_size();
#if defined(SOKOL_GLCORE33) || defined(SOKOL_GLES3)
cur_batch_params.flip_and_swap_rgb = 0;
#else
cur_batch_params.flip_and_swap_rgb = 1;
#endif
sg_apply_uniforms(SG_SHADERSTAGE_FS, SLOT_threedee_twodee_fs_params, &SG_RANGE(cur_batch_params));
cur_batch_params.tex_size = V2(0,0); // unsure if setting the tex_size to something nonzero fucks up the batching so I'm just resetting it back here
assert(cur_batch_data_index % FLOATS_PER_VERTEX == 0);
@ -4840,8 +4891,8 @@ Shadow_State init_shadow_state() {
shadows.pass_action = (sg_pass_action) {
.colors[0] = {
.action = SG_ACTION_CLEAR,
.value = { 1.0f, 1.0f, 1.0f, 1.0f }
.load_action = SG_LOADACTION_CLEAR,
.clear_value = { 1.0f, 1.0f, 1.0f, 1.0f }
}
};
@ -4851,18 +4902,14 @@ Shadow_State init_shadow_state() {
be pertinent to just dig into sokol and add the functionality we want later,
but as a first pass, we will just do as the romans do. I.e. have both a colour
and depth component. - Canada Day 2023.
TODO: with GLES3, depth only rendering passes are now supported
*/
sg_image_desc img_desc = {
.render_target = true,
.width = SHADOW_MAP_DIMENSION,
.height = SHADOW_MAP_DIMENSION,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wrap_u = SG_WRAP_CLAMP_TO_BORDER,
.wrap_v = SG_WRAP_CLAMP_TO_BORDER,
.border_color = SG_BORDERCOLOR_OPAQUE_WHITE,
.sample_count = SAMPLE_COUNT,
.pixel_format = sapp_sgcontext().color_format,
.sample_count = 1,
.label = "shadow-map-color-image"
};
shadows.color_img = sg_make_image(&img_desc);
@ -4886,13 +4933,13 @@ Shadow_State init_shadow_state() {
.shader = sg_make_shader(threedee_mesh_shadow_mapping_shader_desc(sg_query_backend())),
// Cull front faces in the shadow map pass
// .cull_mode = SG_CULLMODE_BACK,
.sample_count = SAMPLE_COUNT,
.sample_count = 1,
.depth = {
.pixel_format = SG_PIXELFORMAT_DEPTH,
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true,
},
.colors[0].pixel_format = SG_PIXELFORMAT_RGBA8,
.colors[0].pixel_format = sapp_sgcontext().color_format,
.label = "shadow-map-pipeline"
};
@ -4900,7 +4947,7 @@ Shadow_State init_shadow_state() {
desc.label = "armature-shadow-map-pipeline";
desc.shader = sg_make_shader(threedee_armature_shadow_mapping_shader_desc(sg_query_backend()));
sg_vertex_attr_desc skeleton_vertex_attrs[] = {
sg_vertex_attr_state skeleton_vertex_attrs[] = {
[ATTR_threedee_vs_skeleton_pos_in].format = SG_VERTEXFORMAT_FLOAT3,
[ATTR_threedee_vs_skeleton_uv_in].format = SG_VERTEXFORMAT_FLOAT2,
[ATTR_threedee_vs_skeleton_indices_in].format = SG_VERTEXFORMAT_USHORT4N,
@ -5100,12 +5147,22 @@ void actually_draw_thing(DrawnThing *it, Mat4 light_space_matrix, bool for_outli
{
if(for_outline)
sg_apply_pipeline(state.outline_mesh_pip);
else if (it->alpha_blend)
sg_apply_pipeline(state.threedee_alpha_blended_pip);
else
sg_apply_pipeline(state.threedee_pip);
sg_bindings bindings = {0};
bindings.fs_images[SLOT_threedee_tex] = it->mesh->image;
if(!for_outline)
bindings.fs_images[SLOT_threedee_shadow_map] = state.shadows.color_img;
bindings.fs.images[SLOT_threedee_tex] = it->mesh->image;
if(for_outline)
{
bindings.fs.samplers[SLOT_threedee_fs_outline_smp] = state.sampler_linear;
}
else
{
bindings.fs.images[SLOT_threedee_shadow_map] = state.shadows.color_img;
bindings.fs.samplers[SLOT_threedee_fs_shadow_smp] = state.sampler_linear_border;
bindings.fs.samplers[SLOT_threedee_fs_smp] = state.sampler_linear;
}
bindings.vertex_buffers[0] = it->mesh->loaded_buffer;
sg_apply_bindings(&bindings);
@ -5131,10 +5188,19 @@ void actually_draw_thing(DrawnThing *it, Mat4 light_space_matrix, bool for_outli
else
sg_apply_pipeline(state.armature_pip);
sg_bindings bindings = {0};
bindings.vs_images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.fs_images[SLOT_threedee_tex] = it->armature->image;
if(!for_outline)
bindings.fs_images[SLOT_threedee_shadow_map] = state.shadows.color_img;
bindings.vs.images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.vs.samplers[SLOT_threedee_vs_skeleton_smp] = state.sampler_nearest;
bindings.fs.images[SLOT_threedee_tex] = it->armature->image;
if(for_outline)
{
bindings.fs.samplers[SLOT_threedee_fs_outline_smp] = state.sampler_linear;
}
else
{
bindings.fs.images[SLOT_threedee_shadow_map] = state.shadows.color_img;
bindings.fs.samplers[SLOT_threedee_fs_shadow_smp] = state.sampler_linear_border;
bindings.fs.samplers[SLOT_threedee_fs_smp] = state.sampler_linear;
}
bindings.vertex_buffers[0] = it->armature->loaded_buffer;
sg_apply_bindings(&bindings);
@ -5278,7 +5344,8 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
if(it->mesh)
{
sg_bindings bindings = {0};
bindings.fs_images[SLOT_threedee_tex] = it->mesh->image;
bindings.fs.images[SLOT_threedee_tex] = it->mesh->image;
bindings.fs.samplers[SLOT_threedee_fs_shadow_mapping_smp] = state.sampler_linear;
bindings.vertex_buffers[0] = it->mesh->loaded_buffer;
sg_apply_bindings(&bindings);
@ -5303,8 +5370,10 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
if(it->armature)
{
sg_bindings bindings = {0};
bindings.vs_images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.fs_images[SLOT_threedee_tex] = it->armature->image;
bindings.vs.images[SLOT_threedee_bones_tex] = it->armature->bones_texture;
bindings.vs.samplers[SLOT_threedee_vs_skeleton_smp] = state.sampler_nearest;
bindings.fs.images[SLOT_threedee_tex] = it->armature->image;
bindings.fs.samplers[SLOT_threedee_fs_shadow_mapping_smp] = state.sampler_linear;
bindings.vertex_buffers[0] = it->armature->loaded_buffer;
sg_apply_bindings(&bindings);
@ -5330,8 +5399,8 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
{
sg_begin_pass(state.outline_pass, &(sg_pass_action) {
.colors[0] = {
.action = SG_ACTION_CLEAR,
.value = { 0.0f, 0.0f, 0.0f, 0.0f },
.load_action = SG_LOADACTION_CLEAR,
.clear_value = { 0.0f, 0.0f, 0.0f, 0.0f },
}
});
@ -5348,7 +5417,7 @@ void flush_all_drawn_things(Vec3 light_dir, Vec3 cam_pos, Vec3 cam_facing, Vec3
// actually draw, IMPORTANT after this drawn_this_frame is zeroed out!
{
sg_begin_pass(state.threedee_pass, &state.clear_everything_pass_action);
sg_begin_pass(state.threedee_pass, &state.threedee_msaa_pass_action);
// draw meshes
SLICE_ITER(DrawnThing, drawn_this_frame)
@ -5689,8 +5758,8 @@ void frame(void)
flush_all_drawn_things(light_dir, cam_pos, facing, right);
// draw the 3d render
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.threedee_pass_image), WHITE, .layer = LAYER_WORLD, .custom_pipeline = state.twodee_colorcorrect_pip });
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.outline_pass_image), WHITE, .custom_pipeline = state.twodee_outline_pip, .layer = LAYER_UI});
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.threedee_pass_resolve_image), WHITE, .layer = LAYER_WORLD, .custom_pipeline = state.twodee_colorcorrect_pip });
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y), screen_size()), IMG(state.outline_pass_resolve_image), WHITE, .custom_pipeline = state.twodee_outline_pip, .layer = LAYER_UI});
// 2d drawing TODO move this to when the drawing is flushed.
sg_begin_default_pass(&state.clear_depth_buffer_pass_action, sapp_width(), sapp_height());
@ -7031,7 +7100,7 @@ ISANERROR("Don't know how to do this stuff on this platform.")
{
Vec2 depth_size = V2(200.0f, 200.0f);
draw_quad((DrawParams){quad_at(V2(screen_size().x - depth_size.x, screen_size().y), depth_size), IMG(state.shadows.color_img), WHITE, .layer = LAYER_UI_FG});
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y/2.0f), MulV2F(screen_size(), 0.1f)), IMG(state.outline_pass_image), WHITE, .layer = LAYER_UI_FG});
draw_quad((DrawParams){quad_at(V2(0.0, screen_size().y/2.0f), MulV2F(screen_size(), 0.1f)), IMG(state.outline_pass_resolve_image), WHITE, .layer = LAYER_UI_FG});
Vec3 view_cam_pos = MulM4V4(InvGeneralM4(view), V4(0,0,0,1)).xyz;
//if(view_cam_pos.y >= 4.900f) // causes nan if not true... not good...
@ -7134,6 +7203,7 @@ ISANERROR("Don't know how to do this stuff on this platform.")
Vec2 *points = d.quad.points;
threedee_twodee_fs_params_t params = {
.tint = d.tint,
.time = (float)fmod(elapsed_time, 100),
};
params.alpha_clip_threshold = d.alpha_clip_threshold;
if (d.do_clipping)
@ -7192,10 +7262,10 @@ ISANERROR("Don't know how to do this stuff on this platform.")
};
// convert to uv space
sg_image_info info = sg_query_image_info(d.image);
sg_image_desc desc = sg_query_image_desc(d.image);
for (int i = 0; i < 4; i++)
{
tex_coords[i] = DivV2(tex_coords[i], V2((float)info.width, (float)info.height));
tex_coords[i] = DivV2(tex_coords[i], V2((float)desc.width, (float)desc.height));
}
for (int i = 0; i < 4; i++)
{
@ -7563,13 +7633,13 @@ sapp_desc sokol_main(int argc, char* argv[])
.frame_cb = frame,
.cleanup_cb = cleanup,
.event_cb = event,
.sample_count = SAMPLE_COUNT,
.sample_count = 1,
.width = 800,
.height = 600,
//.gl_force_gles2 = true, not sure why this was here in example, look into
.window_title = "Dante's Cowboy",
.win32_console_attach = true,
.win32_console_create = true,
.icon.sokol_default = true,
.logger.func = slog_func,
};
}

@ -9,7 +9,7 @@ if exist gen\ (
)
@REM shaders
thirdparty\sokol-shdc.exe --input threedee.glsl --output gen\threedee.glsl.h --slang glsl100:hlsl5:metal_macos:glsl330 || goto :error
thirdparty\sokol-shdc.exe --input threedee.glsl --output gen\threedee.glsl.h --slang glsl300es:hlsl5:glsl330 || goto :error
@REM metadesk codegen
cl /nologo /diagnostics:caret /Ithirdparty /W3 /Zi /WX codegen.c || goto :error

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -118,7 +118,6 @@ SOKOL_API_IMPL sg_context_desc sapp_sgcontext(void) {
desc.color_format = (sg_pixel_format) sapp_color_format();
desc.depth_format = (sg_pixel_format) sapp_depth_format();
desc.sample_count = sapp_sample_count();
desc.gl.force_gles2 = sapp_gles2();
desc.metal.device = sapp_metal_get_device();
desc.metal.renderpass_descriptor_cb = sapp_metal_get_renderpass_descriptor;
desc.metal.drawable_cb = sapp_metal_get_drawable;

@ -82,7 +82,8 @@ uniform skeleton_vs_params {
vec2 bones_tex_size;
};
uniform sampler2D bones_tex;
uniform texture2D bones_tex;
uniform sampler vs_skeleton_smp;
float decode_normalized_float32(vec4 v)
{
@ -110,7 +111,7 @@ void main() {
{
for(int col = 0; col < 4; col++)
{
bone_mat[col][row] = decode_normalized_float32(texture(bones_tex, vec2((0.5 + col*4 + row)/bones_tex_size.x, y_coord)));
bone_mat[col][row] = decode_normalized_float32(texture(sampler2D(bones_tex, vs_skeleton_smp), vec2((0.5 + col*4 + row)/bones_tex_size.x, y_coord)));
}
}
@ -172,8 +173,10 @@ void main() {
@fs fs
uniform sampler2D tex;
uniform sampler2D shadow_map;
uniform texture2D tex;
uniform texture2D shadow_map;
uniform sampler fs_smp;
uniform samplerShadow fs_shadow_smp;
uniform fs_params {
int shadow_map_dimension;
@ -193,7 +196,7 @@ float decodeDepth(vec4 rgba) {
return dot(rgba, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/16581375.0));
}
float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth, float n_dot_l) {
float do_shadow_sample(texture2D shadowMap, vec2 uv, float scene_depth, float n_dot_l) {
{
//WebGL does not support GL_CLAMP_TO_BORDER, or border colors at all it seems, so we have to check explicitly.
//This will probably slow down other versions which do support texture borders, but the current system does
@ -201,7 +204,7 @@ float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth, float n_
if (uv.x < 0.0 || uv.x > 1.0 || uv.y < 0.0 || uv.y > 1.0)
return 1.0;
}
float map_depth = decodeDepth(texture(shadowMap, uv));
float map_depth = decodeDepth(texture(sampler2D(shadowMap, fs_shadow_smp), uv));
// float bias = max(0.03f * (1.0f - n_dot_l), 0.005f);
// bias = clamp(bias, 0.0, 0.01);
@ -216,7 +219,7 @@ float do_shadow_sample(sampler2D shadowMap, vec2 uv, float scene_depth, float n_
}
float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, int texture_height, float scene_depth_light_space, float n_dot_l) {
float bilinear_shadow_sample(texture2D shadowMap, vec2 uv, int texture_width, int texture_height, float scene_depth_light_space, float n_dot_l) {
vec2 texture_dim = vec2(float(texture_width), float(texture_height));
vec2 texel_dim = vec2(1.0 / float(texture_width ), 1.0 / float(texture_height));
@ -244,7 +247,7 @@ float bilinear_shadow_sample(sampler2D shadowMap, vec2 uv, int texture_width, in
return result;
}
float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_position, float n_dot_l) {
float calculate_shadow_factor(texture2D shadowMap, vec4 light_space_fragment_position, float n_dot_l) {
float shadow = 1.0;
vec3 projected_coords = light_space_fragment_position.xyz / light_space_fragment_position.w;
@ -275,7 +278,7 @@ float calculate_shadow_factor(sampler2D shadowMap, vec4 light_space_fragment_pos
}
void main() {
vec4 col = texture(tex, uv);
vec4 col = texture(sampler2D(tex, fs_smp), uv);
bool alpha_blend = bool(alpha_blend_int);
@ -292,11 +295,6 @@ void main() {
//col.rgb = vec3(desertness, 0, 0);
if(col.a < 0.1 && !alpha_blend)
{
discard;
}
else
{
vec3 normal = normalize(cross(dFdx(world_space_frag_pos.xyz), dFdy(world_space_frag_pos.xyz)));
@ -307,23 +305,21 @@ void main() {
float lighting_factor = shadow_factor * n_dot_l;
lighting_factor = lighting_factor * 0.5 + 0.5;
if(alpha_blend)
if (!alpha_blend)
{
frag_color = vec4(col.rgb*lighting_factor, col.a);
float _Cutoff = 0.75; // Change this! it is tuned for existing bushes and TreeLayer leaves 2023-08-23
col.a = (col.a - _Cutoff) / max(fwidth(col.a), 0.0001) + 0.5;
}
else
{
frag_color = vec4(col.rgb*lighting_factor, 1.0);
}
//frag_color = vec4(col.rgb, 1.0);
frag_color = vec4(col.rgb*lighting_factor, col.a);
}
}
@end
@fs fs_shadow_mapping
uniform sampler2D tex;
uniform texture2D tex;
uniform sampler fs_shadow_mapping_smp;
in vec3 pos;
in vec2 uv;
@ -341,7 +337,7 @@ vec4 encodeDepth(float v) {
}
void main() {
vec4 col = texture(tex, uv);
vec4 col = texture(sampler2D(tex, fs_shadow_mapping_smp), uv);
if(col.a < 0.5)
{
discard;
@ -366,7 +362,9 @@ void main() {
@end
@fs fs_twodee
uniform sampler2D twodee_tex;
uniform texture2D twodee_tex;
uniform sampler fs_twodee_smp;
uniform twodee_fs_params {
vec4 tint;
@ -375,8 +373,12 @@ uniform twodee_fs_params {
vec2 clip_lr;
float alpha_clip_threshold;
float time;
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -387,7 +389,10 @@ out vec4 frag_color;
void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
frag_color = texture(twodee_tex, uv) * tint;
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
frag_color = texture(sampler2D(twodee_tex, fs_twodee_smp), real_uv) * tint;
if (flip_and_swap_rgb > 0) frag_color.rgb = frag_color.bgr;
if(frag_color.a <= alpha_clip_threshold)
{
discard;
@ -397,7 +402,9 @@ void main() {
@end
@fs fs_twodee_outline
uniform sampler2D twodee_tex;
uniform texture2D twodee_tex;
uniform sampler fs_twodee_outline_smp;
uniform twodee_fs_params {
vec4 tint;
@ -406,8 +413,12 @@ uniform twodee_fs_params {
vec2 clip_lr;
float alpha_clip_threshold;
float time;
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -418,31 +429,45 @@ out vec4 frag_color;
void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
float left = texture(twodee_tex, uv + vec2(-1, 0)/tex_size).a;
float right = texture(twodee_tex, uv + vec2(1, 0)/tex_size).a;
float up = texture(twodee_tex, uv + vec2(0, 1)/tex_size).a;
float down = texture(twodee_tex, uv + vec2(0, -1)/tex_size).a;
if(
false
|| left > 0.1 && right < 0.1
|| left < 0.1 && right > 0.1
|| up < 0.1 && down > 0.1
|| up > 0.1 && down < 0.1
)
{
frag_color = vec4(1.0);
}
else
{
frag_color = vec4(0.0);
}
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
// 5-tap tent filter: centre, left, right, up, down
float c = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv).a;
float l = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(-1, 0)/tex_size).a;
float r = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(+1, 0)/tex_size).a;
float u = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(0, +1)/tex_size).a;
float d = texture(sampler2D(twodee_tex, fs_twodee_outline_smp), real_uv + vec2(0, -1)/tex_size).a;
// if centre pixel is ~1, it is inside a shape.
// if centre pixel is ~0, it is outside a shape.
// if it is in the middle, it is near an MSAA-resolved edge.
// we parallel-compute the inside AND outside glows, and then lerp using c.
float lerp_t = c;
// buffer is linear-space to be ACES-corrected later, but MSAA happens in gamma space;
// I want a gamma-space blend; so I cheaply do pow(x, 2) by computing x*x.
c *= c; l *= l; r *= r; u *= u; d *= d;
float accum_o = (c + l + r + u + d);
float accum_i = 5 - (c + l + r + u + d);
accum_o = 0.3 * accum_o;
accum_i = 0.3 * accum_i;
accum_o = clamp(accum_o, 0, 1);
accum_i = clamp(accum_i, 0, 1);
accum_o = sqrt(accum_o); // cheap gamma-undo
accum_i = sqrt(accum_i); // cheap gamma-undo
float accum = mix(accum_o, accum_i, lerp_t);
frag_color = vec4(1, 1, 1, accum);
}
@end
@fs fs_twodee_color_correction
uniform sampler2D twodee_tex;
uniform texture2D twodee_tex;
uniform sampler fs_twodee_color_correction_smp;
uniform twodee_fs_params {
vec4 tint;
@ -451,8 +476,12 @@ uniform twodee_fs_params {
vec2 clip_lr;
float alpha_clip_threshold;
float time;
vec2 tex_size;
vec2 screen_size;
float flip_and_swap_rgb;
};
in vec2 uv;
@ -473,10 +502,32 @@ void main() {
// clip space is from [-1,1] [left, right]of screen on X, and [-1,1] [bottom, top] of screen on Y
if(pos.x < clip_ul.x || pos.x > clip_lr.x || pos.y < clip_lr.y || pos.y > clip_ul.y) discard;
vec4 col = texture(twodee_tex, uv);
vec2 real_uv = uv;
if (flip_and_swap_rgb > 0) real_uv.y = 1 - real_uv.y;
vec4 col = texture(sampler2D(twodee_tex, fs_twodee_color_correction_smp), real_uv);
if (flip_and_swap_rgb > 0) col.rgb = col.bgr;
col.rgb = acesFilm(col.rgb);
// Film grain
vec2 grain_uv = gl_FragCoord.xy / screen_size.xy;
float x = grain_uv.x * grain_uv.y * time * 24 + 100.0;
vec3 noise = vec3(mod((mod(x, 13.0) + 1.0) * (mod(x, 123.0) + 1.0), 0.01)) * 100.0;
col.rgb += (noise - 0.5) * 0.05;
col.rgb *= 0.95;
// Hard-clip contrast levels
float min = 11; float max = 204;
col.rgb -= min/255;
col.rgb *= 255/(max-min);
// Vignette
col.rgb *= clamp(1.5 - length(gl_FragCoord.xy / screen_size.xy - vec2(0.5)), 0, 1);
// Cross-process
float cross_process_strength = 0.5;
col.rg *= (col.rg * ((-cross_process_strength) * col.rg + (-1.5 * (-cross_process_strength))) + (0.5 * (-cross_process_strength) + 1));
col.b *= (col.b * ((+cross_process_strength) * col.b + (-1.5 * (+cross_process_strength))) + (0.5 * (+cross_process_strength) + 1));
col.rgb = clamp(col.rgb, 0, 1);
frag_color = col;
}
@end
@ -484,7 +535,8 @@ void main() {
@fs fs_outline
uniform sampler2D tex;
uniform texture2D tex;
uniform sampler fs_outline_smp;
in vec3 pos;
in vec2 uv;
@ -495,7 +547,7 @@ in vec4 world_space_frag_pos;
out vec4 frag_color;
void main() {
vec4 col = texture(tex, uv);
vec4 col = texture(sampler2D(tex, fs_outline_smp), uv);
if(col.a < 0.5)
{
discard;

Loading…
Cancel
Save