port more rendering to the new system
This commit is contained in:
parent
9ebeea8772
commit
ff7787a4e0
@ -1139,7 +1139,7 @@ draw_editor_billboards :: (view: View_Id) {
|
||||
draw_level_editor :: () {
|
||||
curworld := get_current_world();
|
||||
if !curworld.valid then return;
|
||||
view := add_view(.{camera = get_level_editor_camera(), environment = *curworld.world.environment});
|
||||
view := add_view(.{camera = get_level_editor_camera(), environment = world_environment(*curworld.world)});
|
||||
draw_entities(view, *curworld.world);
|
||||
draw_live_particles(view);
|
||||
if show_trile_preview && !trile_preview_disabled {
|
||||
|
||||
@ -61,6 +61,7 @@ draw_material_studio_ui :: (theme: *GR.Overall_Theme) {
|
||||
r.y += r.h;
|
||||
GR.slider(r, *swatch.emittance, 0, 127, 1, *theme.slider_theme);
|
||||
r.y += r.h * 2;
|
||||
swatch_changed(ms_selected);
|
||||
|
||||
r.h = row_h;
|
||||
if GR.button(r, "Save", *theme.button_theme) {
|
||||
@ -73,6 +74,7 @@ draw_material_studio_ui :: (theme: *GR.Overall_Theme) {
|
||||
GR.label(r, "In use, can't delete", *t_label_left(theme));
|
||||
} else if GR.button(r, "Delete", *theme.button_theme) {
|
||||
swatch.* = .{};
|
||||
swatch_changed(ms_selected);
|
||||
ms_selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,7 +386,7 @@ draw_trile_editor :: () {
|
||||
// A trile is drawn in the light of the world it will sit in.
|
||||
environment := New(Environment,, temp);
|
||||
curworld := get_current_world();
|
||||
if curworld.valid environment = *curworld.world.environment;
|
||||
if curworld.valid environment = world_environment(*curworld.world);
|
||||
|
||||
view := add_view(.{camera = get_trile_editor_camera(), environment = environment, draw_world = false});
|
||||
mesh, ok := get_trile_mesh(editor_current_trile.name);
|
||||
|
||||
59
src/renderer_sokol/billboards.jai
Normal file
59
src/renderer_sokol/billboards.jai
Normal file
@ -0,0 +1,59 @@
|
||||
billboards_init :: () {
|
||||
desc := pipeline_desc(billboard_shader_desc(sg_query_backend()), .VIEW, depth_write = true);
|
||||
desc.layout.buffers[0].step_func = .PER_INSTANCE;
|
||||
desc.layout.attrs[ATTR_billboard_center] = .{ format = .FLOAT3 };
|
||||
desc.layout.attrs[ATTR_billboard_size] = .{ format = .FLOAT2 };
|
||||
desc.layout.attrs[ATTR_billboard_uv_rect] = .{ format = .FLOAT4 };
|
||||
desc.layout.attrs[ATTR_billboard_face] = .{ format = .FLOAT3 };
|
||||
billboards.pipeline = sg_make_pipeline(*desc);
|
||||
}
|
||||
|
||||
billboards_upload :: (scene: *Scene) {
|
||||
array_reset_keeping_memory(*billboards.instances);
|
||||
array_reset_keeping_memory(*billboards.batches);
|
||||
|
||||
draws : [..]Keyed(Instance);
|
||||
draws.allocator = temp;
|
||||
for view_index: 0..scene.views.count-1 {
|
||||
array_reset_keeping_memory(*draws);
|
||||
for scene.billboards {
|
||||
if it.view.index != view_index continue;
|
||||
array_add(*draws, .{it.sheet.id, .{it.position, it.size, it.uv_rect, it.face}});
|
||||
}
|
||||
batch_instances(view_index, draws, *billboards.batches, *billboards.instances);
|
||||
}
|
||||
stream_upload(*billboards.stream, billboards.instances);
|
||||
}
|
||||
|
||||
billboards_draw :: (pass: *Pass) {
|
||||
sg_apply_pipeline(billboards.pipeline);
|
||||
apply_uniforms(UB_view_params, *pass.params);
|
||||
|
||||
for billboards.batches {
|
||||
if it.view_index != pass.view_index continue;
|
||||
|
||||
bind : sg_bindings;
|
||||
bind.vertex_buffers[0] = billboards.stream.buffer;
|
||||
bind.vertex_buffer_offsets[0] = it.first * size_of(Instance);
|
||||
bind.images[IMG_sprite] = texture_image(xx it.key);
|
||||
bind.samplers[SMP_sprite_smp] = samplers.nearest_clamp;
|
||||
sg_apply_bindings(*bind);
|
||||
sg_draw(0, 6, it.count);
|
||||
}
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
Instance :: struct {
|
||||
center : Vector3;
|
||||
size : Vector2;
|
||||
uv_rect : Vector4;
|
||||
face : Vector3;
|
||||
}
|
||||
|
||||
billboards : struct {
|
||||
pipeline : sg_pipeline;
|
||||
instances : [..]Instance;
|
||||
batches : [..]Batch;
|
||||
stream : Stream_Buffer;
|
||||
}
|
||||
135
src/renderer_sokol/gpu.jai
Normal file
135
src/renderer_sokol/gpu.jai
Normal file
@ -0,0 +1,135 @@
|
||||
VIEW_COLOR_FORMAT :: sg_pixel_format.RGBA8;
|
||||
VIEW_DEPTH_FORMAT :: sg_pixel_format.DEPTH;
|
||||
|
||||
ALPHA_BLEND :: sg_blend_state.{
|
||||
enabled = true,
|
||||
src_factor_rgb = .SRC_ALPHA,
|
||||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
|
||||
};
|
||||
|
||||
Pipeline_Target :: enum {
|
||||
SCREEN;
|
||||
VIEW;
|
||||
}
|
||||
|
||||
samplers : struct {
|
||||
nearest_clamp : sg_sampler;
|
||||
linear_clamp : sg_sampler;
|
||||
linear_repeat : sg_sampler;
|
||||
}
|
||||
|
||||
samplers_init :: () {
|
||||
samplers.nearest_clamp = sg_make_sampler(*(sg_sampler_desc.{ min_filter = .NEAREST, mag_filter = .NEAREST, wrap_u = .CLAMP_TO_EDGE, wrap_v = .CLAMP_TO_EDGE }));
|
||||
samplers.linear_clamp = sg_make_sampler(*(sg_sampler_desc.{ min_filter = .LINEAR, mag_filter = .LINEAR, wrap_u = .CLAMP_TO_EDGE, wrap_v = .CLAMP_TO_EDGE }));
|
||||
samplers.linear_repeat = sg_make_sampler(*(sg_sampler_desc.{ min_filter = .LINEAR, mag_filter = .LINEAR, wrap_u = .REPEAT, wrap_v = .REPEAT }));
|
||||
}
|
||||
|
||||
// Vertex layout and anything else specific is filled in by the caller.
|
||||
pipeline_desc :: (shader: sg_shader_desc, target: Pipeline_Target, blend := false, depth_write := false) -> sg_pipeline_desc {
|
||||
shader_desc := shader;
|
||||
desc : sg_pipeline_desc;
|
||||
desc.shader = sg_make_shader(*shader_desc);
|
||||
if blend desc.colors[0].blend = ALPHA_BLEND;
|
||||
if target == .VIEW {
|
||||
desc.colors[0].pixel_format = VIEW_COLOR_FORMAT;
|
||||
desc.depth.pixel_format = VIEW_DEPTH_FORMAT;
|
||||
desc.depth.compare = .LESS_EQUAL;
|
||||
desc.depth.write_enabled = depth_write;
|
||||
desc.sample_count = 1;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
|
||||
Pass :: struct {
|
||||
scene : *Scene;
|
||||
view_index : int;
|
||||
view : View;
|
||||
reflection : bool;
|
||||
params : View_Params;
|
||||
}
|
||||
|
||||
make_pass :: (scene: *Scene, view_index: int, reflection: bool) -> Pass {
|
||||
pass := Pass.{ scene = scene, view_index = view_index, view = scene.views[view_index], reflection = reflection };
|
||||
height := ifx pass.view.environment then pass.view.environment.reflection_height else 0;
|
||||
|
||||
camera := pass.view.camera.position;
|
||||
view_proj := scene.view_proj[view_index];
|
||||
pass.params.clip = .[0, 0, 0, 1];
|
||||
if reflection {
|
||||
camera.y = 2 * height - camera.y;
|
||||
view_proj = scene.reflection_view_proj[view_index];
|
||||
pass.params.clip = .[0, 1, 0, -height];
|
||||
}
|
||||
pass.params.view_proj = view_proj.floats;
|
||||
pass.params.camera = .[camera.x, camera.y, camera.z, scene.time];
|
||||
return pass;
|
||||
}
|
||||
|
||||
apply_uniforms :: (slot: s32, params: *$T) {
|
||||
sg_apply_uniforms(slot, *(sg_range.{ params, size_of(T) }));
|
||||
}
|
||||
|
||||
Slots :: struct (T: Type) {
|
||||
items : [..]T;
|
||||
free : [..]u32;
|
||||
}
|
||||
|
||||
// Ids start at 1 so that 0 can mean none.
|
||||
slot_add :: (slots: *Slots($T)) -> u32, *T {
|
||||
if slots.free.count {
|
||||
id := pop(*slots.free);
|
||||
return id, *slots.items[id - 1];
|
||||
}
|
||||
item := array_add(*slots.items);
|
||||
return xx slots.items.count, item;
|
||||
}
|
||||
|
||||
slot_get :: (slots: *Slots($T), id: u32) -> *T {
|
||||
if id == 0 || id > slots.items.count return null;
|
||||
return *slots.items[id - 1];
|
||||
}
|
||||
|
||||
slot_remove :: (slots: *Slots($T), id: u32) {
|
||||
slots.items[id - 1] = .{};
|
||||
array_add(*slots.free, id);
|
||||
}
|
||||
|
||||
Stream_Buffer :: struct {
|
||||
buffer : sg_buffer;
|
||||
size : int;
|
||||
}
|
||||
|
||||
stream_upload :: (stream: *Stream_Buffer, data: []$T) {
|
||||
if data.count == 0 return;
|
||||
size := data.count * size_of(T);
|
||||
if size > stream.size {
|
||||
if stream.size sg_destroy_buffer(stream.buffer);
|
||||
stream.size = max(size, stream.size * 2);
|
||||
stream.buffer = sg_make_buffer(*(sg_buffer_desc.{ size = xx stream.size, usage = .STREAM }));
|
||||
}
|
||||
sg_update_buffer(stream.buffer, *(sg_range.{ data.data, xx size }));
|
||||
}
|
||||
|
||||
Keyed :: struct (Instance: Type) {
|
||||
key : s64;
|
||||
instance : Instance;
|
||||
}
|
||||
|
||||
Batch :: struct {
|
||||
view_index : s32;
|
||||
key : s64;
|
||||
first : s32;
|
||||
count : s32;
|
||||
}
|
||||
|
||||
// Sorts the view's draws by key and appends one batch per run of equal keys.
|
||||
batch_instances :: (view_index: int, draws: []Keyed($I), batches: *[..]Batch, instances: *[..]I) {
|
||||
quick_sort(draws, (a: Keyed(I), b: Keyed(I)) -> s64 { return a.key - b.key; });
|
||||
for draws {
|
||||
if it_index == 0 || draws[it_index - 1].key != it.key {
|
||||
array_add(batches, .{view_index = xx view_index, key = it.key, first = xx instances.count});
|
||||
}
|
||||
array_add(instances, it.instance);
|
||||
batches.*[batches.count - 1].count += 1;
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,16 @@
|
||||
#import,dir "../../modules/sokol-jai/sokol/gfx"(DEBUG = !FLAG_RELEASE_BUILD);
|
||||
#import,dir "../../modules/sokol-jai/sokol/glue"(DEBUG = !FLAG_RELEASE_BUILD);
|
||||
#import "Sort";
|
||||
|
||||
#load "shaders/jai/ui.jai";
|
||||
#load "shaders/jai/shaders.jai";
|
||||
#load "gpu.jai";
|
||||
#load "ui.jai";
|
||||
#load "triles.jai";
|
||||
#load "views.jai";
|
||||
#load "water.jai";
|
||||
#load "billboards.jai";
|
||||
|
||||
renderer_init :: () {
|
||||
renderer_init :: (orientations: [ORIENTATION_COUNT]Matrix3) {
|
||||
sg_setup(*(sg_desc.{
|
||||
environment = cast,force(sg_environment) sglue_environment(),
|
||||
logger = .{ func = slog_func },
|
||||
@ -13,7 +19,12 @@ renderer_init :: () {
|
||||
white := u8.[255, 255, 255, 255];
|
||||
renderer.white = make_image(1, 1, white);
|
||||
|
||||
samplers_init();
|
||||
ui_init();
|
||||
triles_init(orientations);
|
||||
views_init();
|
||||
water_init();
|
||||
billboards_init();
|
||||
}
|
||||
|
||||
renderer_shutdown :: () {
|
||||
@ -21,50 +32,55 @@ renderer_shutdown :: () {
|
||||
}
|
||||
|
||||
renderer_texture_create :: (width: s32, height: s32, pixels: []u8) -> u32 {
|
||||
slot : *Renderer_Texture;
|
||||
index : int;
|
||||
if renderer.free_textures.count {
|
||||
index = pop(*renderer.free_textures);
|
||||
slot = *renderer.textures[index];
|
||||
} else {
|
||||
index = renderer.textures.count;
|
||||
slot = array_add(*renderer.textures);
|
||||
}
|
||||
slot.width = width;
|
||||
slot.height = height;
|
||||
slot.image = make_image(width, height, pixels);
|
||||
return xx (index + 1);
|
||||
id, texture := slot_add(*renderer.textures);
|
||||
texture.width = width;
|
||||
texture.height = height;
|
||||
texture.image = make_image(width, height, pixels);
|
||||
return id;
|
||||
}
|
||||
|
||||
// Immutable images are recreated rather than updated, so a texture can be
|
||||
// updated any number of times in a frame.
|
||||
renderer_texture_update :: (id: u32, pixels: []u8) {
|
||||
slot := *renderer.textures[id - 1];
|
||||
sg_destroy_image(slot.image);
|
||||
slot.image = make_image(slot.width, slot.height, pixels);
|
||||
texture := slot_get(*renderer.textures, id);
|
||||
sg_destroy_image(texture.image);
|
||||
texture.image = make_image(texture.width, texture.height, pixels);
|
||||
}
|
||||
|
||||
renderer_texture_destroy :: (id: u32) {
|
||||
slot := *renderer.textures[id - 1];
|
||||
sg_destroy_image(slot.image);
|
||||
slot.* = .{};
|
||||
array_add(*renderer.free_textures, xx (id - 1));
|
||||
sg_destroy_image(slot_get(*renderer.textures, id).image);
|
||||
slot_remove(*renderer.textures, id);
|
||||
}
|
||||
|
||||
renderer_render :: (scene: *Scene, width: s32, height: s32) {
|
||||
triles_upload(scene);
|
||||
billboards_upload(scene);
|
||||
ui_upload(scene);
|
||||
|
||||
pass_action : sg_pass_action;
|
||||
pass_action.colors[0] = .{ load_action = .CLEAR, clear_value = .{0, 0, 0, 1} };
|
||||
sg_begin_pass(*(sg_pass.{ action = pass_action, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
for view, view_index: scene.views {
|
||||
for reflection: bool.[true, false] {
|
||||
pass := make_pass(scene, view_index, reflection);
|
||||
view_begin_pass(view_index, width, height, reflection);
|
||||
triles_draw(*pass);
|
||||
billboards_draw(*pass);
|
||||
water_draw(*pass);
|
||||
sg_end_pass();
|
||||
}
|
||||
}
|
||||
|
||||
action : sg_pass_action;
|
||||
action.colors[0] = .{ load_action = .CLEAR, clear_value = .{0, 0, 0, 1} };
|
||||
sg_begin_pass(*(sg_pass.{ action = action, swapchain = cast,force(sg_swapchain) sglue_swapchain() }));
|
||||
for scene.views view_composite(it_index);
|
||||
ui_draw(scene, width, height);
|
||||
sg_end_pass();
|
||||
sg_commit();
|
||||
}
|
||||
|
||||
texture_image :: (id: u32) -> sg_image {
|
||||
if id == 0 return renderer.white;
|
||||
return renderer.textures[id - 1].image;
|
||||
texture := slot_get(*renderer.textures, id);
|
||||
if !texture || !texture.image.id return renderer.white;
|
||||
return texture.image;
|
||||
}
|
||||
|
||||
#scope_file
|
||||
@ -76,17 +92,12 @@ Renderer_Texture :: struct {
|
||||
}
|
||||
|
||||
renderer : struct {
|
||||
textures : [..]Renderer_Texture;
|
||||
free_textures : [..]s32;
|
||||
white : sg_image;
|
||||
textures : Slots(Renderer_Texture);
|
||||
white : sg_image;
|
||||
}
|
||||
|
||||
make_image :: (width: s32, height: s32, pixels: []u8) -> sg_image {
|
||||
desc := sg_image_desc.{
|
||||
width = width,
|
||||
height = height,
|
||||
pixel_format = .RGBA8,
|
||||
};
|
||||
desc := sg_image_desc.{ width = width, height = height, pixel_format = .RGBA8 };
|
||||
desc.data.subimage[0][0] = .{ pixels.data, xx pixels.count };
|
||||
return sg_make_image(*desc);
|
||||
}
|
||||
|
||||
43
src/renderer_sokol/shaders/billboard.glsl
Normal file
43
src/renderer_sokol/shaders/billboard.glsl
Normal file
@ -0,0 +1,43 @@
|
||||
@vs vs_billboard
|
||||
@include_block view
|
||||
@include_block quad
|
||||
|
||||
in vec3 center; // bottom middle
|
||||
in vec2 size;
|
||||
in vec4 uv_rect;
|
||||
in vec3 face;
|
||||
|
||||
out float v_clip;
|
||||
out vec2 v_uv;
|
||||
|
||||
void main() {
|
||||
vec2 c = quad_corner(gl_VertexIndex);
|
||||
vec3 look = face;
|
||||
if (face.x < -10.0) look = vec3(center.x - camera.x, 0.0, center.z - camera.z);
|
||||
if (dot(look.xz, look.xz) < 0.0001) look = vec3(0.0, 0.0, 1.0);
|
||||
vec3 right = normalize(cross(vec3(0.0, 1.0, 0.0), look));
|
||||
|
||||
vec3 world = center + right * ((c.x - 0.5) * size.x) + vec3(0.0, c.y * size.y, 0.0);
|
||||
gl_Position = view_proj * vec4(world, 1.0);
|
||||
v_clip = dot(vec4(world, 1.0), clip);
|
||||
v_uv = vec2(uv_rect.x + c.x * uv_rect.z, uv_rect.y + (1.0 - c.y) * uv_rect.w);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs_billboard
|
||||
in float v_clip;
|
||||
in vec2 v_uv;
|
||||
out vec4 frag_color;
|
||||
|
||||
layout(binding=0) uniform texture2D sprite;
|
||||
layout(binding=0) uniform sampler sprite_smp;
|
||||
|
||||
void main() {
|
||||
if (v_clip < 0.0) discard;
|
||||
vec4 sampled = texture(sampler2D(sprite, sprite_smp), v_uv);
|
||||
if (sampled.a < 0.01) discard;
|
||||
frag_color = vec4(sampled.rgb, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@program billboard vs_billboard fs_billboard
|
||||
@ -1,22 +1,23 @@
|
||||
compile_sokol_shaders :: () -> bool {
|
||||
dir :: "src/renderer_sokol/shaders";
|
||||
shdc :: #ifx OS == .MACOS then "sokol-shdc-mac" else "sokol-shdc";
|
||||
dir :: "src/renderer_sokol/shaders";
|
||||
input :: "src/renderer_sokol/shaders/shaders.glsl";
|
||||
output :: "src/renderer_sokol/shaders/jai/shaders.jai";
|
||||
shdc :: #ifx OS == .MACOS then "src/renderer_sokol/shaders/sokol-shdc-mac" else "src/renderer_sokol/shaders/sokol-shdc";
|
||||
|
||||
out_time, _, out_exists := file_modtime_and_size(output);
|
||||
stale := !out_exists;
|
||||
for file_list(dir) {
|
||||
if !ends_with(it, ".glsl") continue;
|
||||
name := path_strip_extension(path_filename(it));
|
||||
out := tprint("%/jai/%.jai", dir, name);
|
||||
|
||||
src_time := file_modtime_and_size(it);
|
||||
out_time, _, out_exists := file_modtime_and_size(out);
|
||||
if out_exists && compare_apollo_times(out_time, src_time) >= 0 continue;
|
||||
if compare_apollo_times(src_time, out_time) > 0 stale = true;
|
||||
}
|
||||
if !stale return true;
|
||||
|
||||
result, output, error := run_command(tprint("%/%", dir, shdc), "-i", it, "-o", out,
|
||||
"-l", "glsl430:glsl300es:metal_macos", "-f", "sokol_jai", capture_and_return_output = true);
|
||||
if result.exit_code != 0 {
|
||||
log_error("sokol-shdc failed on %:\n%%", it, output, error);
|
||||
return false;
|
||||
}
|
||||
result, out, error := run_command(shdc, "-i", input, "-o", output,
|
||||
"-l", "glsl430:glsl300es:metal_macos", "-f", "sokol_jai", capture_and_return_output = true);
|
||||
if result.exit_code != 0 {
|
||||
log_error("sokol-shdc failed:\n%%", out, error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
14
src/renderer_sokol/shaders/common.glsl
Normal file
14
src/renderer_sokol/shaders/common.glsl
Normal file
@ -0,0 +1,14 @@
|
||||
@block view
|
||||
layout(binding=0) uniform view_params {
|
||||
mat4 view_proj;
|
||||
vec4 camera; // xyz = position, w = time
|
||||
vec4 clip; // plane; geometry on its negative side is dropped
|
||||
};
|
||||
@end
|
||||
|
||||
@block quad
|
||||
vec2 quad_corner(int vertex_index) {
|
||||
const vec2 corners[6] = vec2[6](vec2(0, 0), vec2(1, 0), vec2(1, 1), vec2(0, 0), vec2(1, 1), vec2(0, 1));
|
||||
return corners[vertex_index];
|
||||
}
|
||||
@end
|
||||
27
src/renderer_sokol/shaders/composite.glsl
Normal file
27
src/renderer_sokol/shaders/composite.glsl
Normal file
@ -0,0 +1,27 @@
|
||||
@vs vs_composite
|
||||
layout(binding=0) uniform composite_vs_params {
|
||||
float flip_y;
|
||||
};
|
||||
|
||||
out vec2 v_uv;
|
||||
|
||||
void main() {
|
||||
vec2 p = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
v_uv = vec2(p.x, mix(p.y, 1.0 - p.y, flip_y));
|
||||
gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs_composite
|
||||
in vec2 v_uv;
|
||||
out vec4 frag_color;
|
||||
|
||||
layout(binding=0) uniform texture2D view_color;
|
||||
layout(binding=0) uniform sampler composite_smp;
|
||||
|
||||
void main() {
|
||||
frag_color = texture(sampler2D(view_color, composite_smp), v_uv);
|
||||
}
|
||||
@end
|
||||
|
||||
@program composite vs_composite fs_composite
|
||||
3204
src/renderer_sokol/shaders/jai/shaders.jai
Normal file
3204
src/renderer_sokol/shaders/jai/shaders.jai
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,422 +0,0 @@
|
||||
/*
|
||||
#version:1# (machine generated, don't edit!)
|
||||
|
||||
Generated by sokol-shdc (https://github.com/floooh/sokol-tools)
|
||||
|
||||
Cmdline:
|
||||
sokol-shdc -i src/renderer_sokol/shaders/ui.glsl -o src/renderer_sokol/shaders/jai/ui.jai -l glsl430:glsl300es:metal_macos -f sokol_jai
|
||||
|
||||
Overview:
|
||||
=========
|
||||
Shader program: 'ui':
|
||||
Get shader desc: ui_shader_desc(sg_query_backend())
|
||||
Vertex Shader: vs_ui
|
||||
Fragment Shader: fs_ui
|
||||
Attributes:
|
||||
ATTR_ui_position => 0
|
||||
ATTR_ui_uv => 1
|
||||
ATTR_ui_color0 => 2
|
||||
Bindings:
|
||||
Uniform block 'ui_vs_params':
|
||||
Jai struct: Ui_Vs_Params
|
||||
Bind slot: UB_ui_vs_params => 0
|
||||
Image 'tex':
|
||||
Image type: ._2D
|
||||
Sample type: .FLOAT
|
||||
Multisampled: false
|
||||
Bind slot: IMG_tex => 0
|
||||
Sampler 'smp':
|
||||
Type: .FILTERING
|
||||
Bind slot: SMP_smp => 0
|
||||
*/
|
||||
ATTR_ui_position :: 0;
|
||||
ATTR_ui_uv :: 1;
|
||||
ATTR_ui_color0 :: 2;
|
||||
UB_ui_vs_params :: 0;
|
||||
IMG_tex :: 0;
|
||||
SMP_smp :: 0;
|
||||
Ui_Vs_Params :: struct {
|
||||
screen_size: [2]float;
|
||||
_: [8]u8;
|
||||
};
|
||||
/*
|
||||
#version 430
|
||||
|
||||
uniform vec4 ui_vs_params[1];
|
||||
layout(location = 0) in vec2 position;
|
||||
layout(location = 0) out vec2 v_uv;
|
||||
layout(location = 1) in vec2 uv;
|
||||
layout(location = 1) out vec4 v_color;
|
||||
layout(location = 2) in vec4 color0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 _26 = ((position / ui_vs_params[0].xy) * 2.0) - vec2(1.0);
|
||||
gl_Position = vec4(_26.x, -_26.y, 0.0, 1.0);
|
||||
v_uv = uv;
|
||||
v_color = color0;
|
||||
}
|
||||
|
||||
*/
|
||||
vs_ui_source_glsl430 := u8.[
|
||||
0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x75,0x6e,
|
||||
0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x75,0x69,0x5f,0x76,0x73,
|
||||
0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,0x6c,0x61,0x79,0x6f,
|
||||
0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,
|
||||
0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,
|
||||
0x6e,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,
|
||||
0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,
|
||||
0x20,0x76,0x5f,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,
|
||||
0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x69,0x6e,0x20,0x76,
|
||||
0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,
|
||||
0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x6f,0x75,0x74,
|
||||
0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,
|
||||
0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,
|
||||
0x20,0x32,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,
|
||||
0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,
|
||||
0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x36,0x20,
|
||||
0x3d,0x20,0x28,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x2f,0x20,0x75,
|
||||
0x69,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,
|
||||
0x79,0x29,0x20,0x2a,0x20,0x32,0x2e,0x30,0x29,0x20,0x2d,0x20,0x76,0x65,0x63,0x32,
|
||||
0x28,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,
|
||||
0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,
|
||||
0x36,0x2e,0x78,0x2c,0x20,0x2d,0x5f,0x32,0x36,0x2e,0x79,0x2c,0x20,0x30,0x2e,0x30,
|
||||
0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x5f,0x75,0x76,
|
||||
0x20,0x3d,0x20,0x75,0x76,0x3b,0x0a,0x20,0x20,0x20,0x20,0x76,0x5f,0x63,0x6f,0x6c,
|
||||
0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,
|
||||
0x00,
|
||||
];
|
||||
/*
|
||||
#version 430
|
||||
|
||||
layout(binding = 16) uniform sampler2D tex_smp;
|
||||
|
||||
layout(location = 0) out vec4 frag_color;
|
||||
layout(location = 0) in vec2 v_uv;
|
||||
layout(location = 1) in vec4 v_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = texture(tex_smp, v_uv) * v_color;
|
||||
}
|
||||
|
||||
*/
|
||||
fs_ui_source_glsl430 := u8.[
|
||||
0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x6c,0x61,
|
||||
0x79,0x6f,0x75,0x74,0x28,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x20,0x3d,0x20,0x31,
|
||||
0x36,0x29,0x20,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x73,0x61,0x6d,0x70,0x6c,
|
||||
0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x5f,0x73,0x6d,0x70,0x3b,0x0a,0x0a,0x6c,
|
||||
0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,
|
||||
0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,
|
||||
0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,
|
||||
0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,
|
||||
0x20,0x76,0x65,0x63,0x32,0x20,0x76,0x5f,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f,
|
||||
0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,
|
||||
0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,
|
||||
0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,
|
||||
0x0a,0x20,0x20,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,
|
||||
0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x5f,0x73,0x6d,
|
||||
0x70,0x2c,0x20,0x76,0x5f,0x75,0x76,0x29,0x20,0x2a,0x20,0x76,0x5f,0x63,0x6f,0x6c,
|
||||
0x6f,0x72,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
||||
];
|
||||
/*
|
||||
#version 300 es
|
||||
|
||||
uniform vec4 ui_vs_params[1];
|
||||
layout(location = 0) in vec2 position;
|
||||
out vec2 v_uv;
|
||||
layout(location = 1) in vec2 uv;
|
||||
out vec4 v_color;
|
||||
layout(location = 2) in vec4 color0;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 _26 = ((position / ui_vs_params[0].xy) * 2.0) - vec2(1.0);
|
||||
gl_Position = vec4(_26.x, -_26.y, 0.0, 1.0);
|
||||
v_uv = uv;
|
||||
v_color = color0;
|
||||
}
|
||||
|
||||
*/
|
||||
vs_ui_source_glsl300es := u8.[
|
||||
0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a,
|
||||
0x0a,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x75,0x69,
|
||||
0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x31,0x5d,0x3b,0x0a,0x6c,
|
||||
0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,
|
||||
0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,
|
||||
0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32,0x20,0x76,
|
||||
0x5f,0x75,0x76,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,
|
||||
0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,
|
||||
0x32,0x20,0x75,0x76,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x76,
|
||||
0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,
|
||||
0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x32,0x29,0x20,0x69,0x6e,0x20,
|
||||
0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x0a,0x76,0x6f,
|
||||
0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,
|
||||
0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x36,0x20,0x3d,0x20,0x28,0x28,0x70,0x6f,0x73,
|
||||
0x69,0x74,0x69,0x6f,0x6e,0x20,0x2f,0x20,0x75,0x69,0x5f,0x76,0x73,0x5f,0x70,0x61,
|
||||
0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2e,0x78,0x79,0x29,0x20,0x2a,0x20,0x32,0x2e,
|
||||
0x30,0x29,0x20,0x2d,0x20,0x76,0x65,0x63,0x32,0x28,0x31,0x2e,0x30,0x29,0x3b,0x0a,
|
||||
0x20,0x20,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,
|
||||
0x3d,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x32,0x36,0x2e,0x78,0x2c,0x20,0x2d,0x5f,
|
||||
0x32,0x36,0x2e,0x79,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,
|
||||
0x0a,0x20,0x20,0x20,0x20,0x76,0x5f,0x75,0x76,0x20,0x3d,0x20,0x75,0x76,0x3b,0x0a,
|
||||
0x20,0x20,0x20,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,
|
||||
0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
||||
];
|
||||
/*
|
||||
#version 300 es
|
||||
precision mediump float;
|
||||
precision highp int;
|
||||
|
||||
uniform highp sampler2D tex_smp;
|
||||
|
||||
layout(location = 0) out highp vec4 frag_color;
|
||||
in highp vec2 v_uv;
|
||||
in highp vec4 v_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
frag_color = texture(tex_smp, v_uv) * v_color;
|
||||
}
|
||||
|
||||
*/
|
||||
fs_ui_source_glsl300es := u8.[
|
||||
0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a,
|
||||
0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,0x6d,0x65,0x64,0x69,0x75,0x6d,
|
||||
0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x3b,0x0a,0x70,0x72,0x65,0x63,0x69,0x73,0x69,
|
||||
0x6f,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x69,0x6e,0x74,0x3b,0x0a,0x0a,0x75,
|
||||
0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x73,0x61,0x6d,
|
||||
0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x74,0x65,0x78,0x5f,0x73,0x6d,0x70,0x3b,0x0a,
|
||||
0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,
|
||||
0x20,0x3d,0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x68,0x69,0x67,0x68,0x70,0x20,
|
||||
0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,
|
||||
0x0a,0x69,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x76,
|
||||
0x5f,0x75,0x76,0x3b,0x0a,0x69,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,
|
||||
0x63,0x34,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,
|
||||
0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
|
||||
0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x74,0x65,0x78,0x74,
|
||||
0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x5f,0x73,0x6d,0x70,0x2c,0x20,0x76,0x5f,0x75,
|
||||
0x76,0x29,0x20,0x2a,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x7d,0x0a,
|
||||
0x0a,0x00,
|
||||
];
|
||||
/*
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct ui_vs_params
|
||||
{
|
||||
float2 screen_size;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
float4 v_color [[user(locn1)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float2 position [[attribute(0)]];
|
||||
float2 uv [[attribute(1)]];
|
||||
float4 color0 [[attribute(2)]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(main0_in in [[stage_in]], constant ui_vs_params& _15 [[buffer(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 _26 = ((in.position / _15.screen_size) * 2.0) - float2(1.0);
|
||||
out.gl_Position = float4(_26.x, -_26.y, 0.0, 1.0);
|
||||
out.v_uv = in.uv;
|
||||
out.v_color = in.color0;
|
||||
return out;
|
||||
}
|
||||
|
||||
*/
|
||||
vs_ui_source_metal_macos := u8.[
|
||||
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
|
||||
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
|
||||
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
|
||||
0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
|
||||
0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x75,
|
||||
0x69,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,
|
||||
0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x73,0x63,0x72,0x65,0x65,0x6e,0x5f,
|
||||
0x73,0x69,0x7a,0x65,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,
|
||||
0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,
|
||||
0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x76,0x5f,0x75,0x76,0x20,0x5b,0x5b,0x75,
|
||||
0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,
|
||||
0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,
|
||||
0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,
|
||||
0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x6c,0x5f,
|
||||
0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,0x73,0x69,0x74,
|
||||
0x69,0x6f,0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,
|
||||
0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,
|
||||
0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
|
||||
0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x30,0x29,0x5d,
|
||||
0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,
|
||||
0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x31,0x29,0x5d,
|
||||
0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x63,0x6f,
|
||||
0x6c,0x6f,0x72,0x30,0x20,0x5b,0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,
|
||||
0x28,0x32,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65,
|
||||
0x78,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,
|
||||
0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,
|
||||
0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,0x20,0x63,0x6f,0x6e,0x73,
|
||||
0x74,0x61,0x6e,0x74,0x20,0x75,0x69,0x5f,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,
|
||||
0x73,0x26,0x20,0x5f,0x31,0x35,0x20,0x5b,0x5b,0x62,0x75,0x66,0x66,0x65,0x72,0x28,
|
||||
0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,
|
||||
0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,
|
||||
0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x5f,0x32,0x36,0x20,0x3d,
|
||||
0x20,0x28,0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x2f,
|
||||
0x20,0x5f,0x31,0x35,0x2e,0x73,0x63,0x72,0x65,0x65,0x6e,0x5f,0x73,0x69,0x7a,0x65,
|
||||
0x29,0x20,0x2a,0x20,0x32,0x2e,0x30,0x29,0x20,0x2d,0x20,0x66,0x6c,0x6f,0x61,0x74,
|
||||
0x32,0x28,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,
|
||||
0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x66,0x6c,
|
||||
0x6f,0x61,0x74,0x34,0x28,0x5f,0x32,0x36,0x2e,0x78,0x2c,0x20,0x2d,0x5f,0x32,0x36,
|
||||
0x2e,0x79,0x2c,0x20,0x30,0x2e,0x30,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,
|
||||
0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x76,0x5f,0x75,0x76,0x20,0x3d,0x20,0x69,0x6e,
|
||||
0x2e,0x75,0x76,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x76,0x5f,0x63,
|
||||
0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c,0x6f,0x72,0x30,
|
||||
0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,
|
||||
0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
||||
];
|
||||
/*
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 frag_color [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
float4 v_color [[user(locn1)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.frag_color = tex.sample(smp, in.v_uv) * in.v_color;
|
||||
return out;
|
||||
}
|
||||
|
||||
*/
|
||||
fs_ui_source_metal_macos := u8.[
|
||||
0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f,
|
||||
0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,
|
||||
0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a,
|
||||
0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20,
|
||||
0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,
|
||||
0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,
|
||||
0x6c,0x6f,0x61,0x74,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,
|
||||
0x20,0x5b,0x5b,0x63,0x6f,0x6c,0x6f,0x72,0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,
|
||||
0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,
|
||||
0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,
|
||||
0x76,0x5f,0x75,0x76,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,
|
||||
0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,
|
||||
0x20,0x76,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28,
|
||||
0x6c,0x6f,0x63,0x6e,0x31,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x66,0x72,
|
||||
0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,
|
||||
0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20,
|
||||
0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c,
|
||||
0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74,
|
||||
0x3e,0x20,0x74,0x65,0x78,0x20,0x5b,0x5b,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,
|
||||
0x30,0x29,0x5d,0x5d,0x2c,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x20,0x73,0x6d,
|
||||
0x70,0x20,0x5b,0x5b,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x28,0x30,0x29,0x5d,0x5d,
|
||||
0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,
|
||||
0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a,0x20,0x20,0x20,0x20,
|
||||
0x6f,0x75,0x74,0x2e,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,
|
||||
0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28,0x73,0x6d,0x70,0x2c,
|
||||
0x20,0x69,0x6e,0x2e,0x76,0x5f,0x75,0x76,0x29,0x20,0x2a,0x20,0x69,0x6e,0x2e,0x76,
|
||||
0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,
|
||||
0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
|
||||
];
|
||||
ui_shader_desc :: (backend: sg_backend) -> sg_shader_desc {
|
||||
desc: sg_shader_desc;
|
||||
desc.label = "ui_shader";
|
||||
if backend == {
|
||||
case .GLCORE;
|
||||
desc.vertex_func.source = xx *vs_ui_source_glsl430;
|
||||
desc.vertex_func.entry = "main";
|
||||
desc.fragment_func.source = xx *fs_ui_source_glsl430;
|
||||
desc.fragment_func.entry = "main";
|
||||
desc.attrs[0].base_type = .FLOAT;
|
||||
desc.attrs[0].glsl_name = "position";
|
||||
desc.attrs[1].base_type = .FLOAT;
|
||||
desc.attrs[1].glsl_name = "uv";
|
||||
desc.attrs[2].base_type = .FLOAT;
|
||||
desc.attrs[2].glsl_name = "color0";
|
||||
desc.uniform_blocks[0].stage = .VERTEX;
|
||||
desc.uniform_blocks[0].layout = .STD140;
|
||||
desc.uniform_blocks[0].size = 16;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].type = .FLOAT4;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].array_count = 1;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].glsl_name = "ui_vs_params";
|
||||
desc.images[0].stage = .FRAGMENT;
|
||||
desc.images[0].multisampled = false;
|
||||
desc.images[0].image_type = ._2D;
|
||||
desc.images[0].sample_type = .FLOAT;
|
||||
desc.samplers[0].stage = .FRAGMENT;
|
||||
desc.samplers[0].sampler_type = .FILTERING;
|
||||
desc.image_sampler_pairs[0].stage = .FRAGMENT;
|
||||
desc.image_sampler_pairs[0].image_slot = 0;
|
||||
desc.image_sampler_pairs[0].sampler_slot = 0;
|
||||
desc.image_sampler_pairs[0].glsl_name = "tex_smp";
|
||||
case .GLES3;
|
||||
desc.vertex_func.source = xx *vs_ui_source_glsl300es;
|
||||
desc.vertex_func.entry = "main";
|
||||
desc.fragment_func.source = xx *fs_ui_source_glsl300es;
|
||||
desc.fragment_func.entry = "main";
|
||||
desc.attrs[0].base_type = .FLOAT;
|
||||
desc.attrs[0].glsl_name = "position";
|
||||
desc.attrs[1].base_type = .FLOAT;
|
||||
desc.attrs[1].glsl_name = "uv";
|
||||
desc.attrs[2].base_type = .FLOAT;
|
||||
desc.attrs[2].glsl_name = "color0";
|
||||
desc.uniform_blocks[0].stage = .VERTEX;
|
||||
desc.uniform_blocks[0].layout = .STD140;
|
||||
desc.uniform_blocks[0].size = 16;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].type = .FLOAT4;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].array_count = 1;
|
||||
desc.uniform_blocks[0].glsl_uniforms[0].glsl_name = "ui_vs_params";
|
||||
desc.images[0].stage = .FRAGMENT;
|
||||
desc.images[0].multisampled = false;
|
||||
desc.images[0].image_type = ._2D;
|
||||
desc.images[0].sample_type = .FLOAT;
|
||||
desc.samplers[0].stage = .FRAGMENT;
|
||||
desc.samplers[0].sampler_type = .FILTERING;
|
||||
desc.image_sampler_pairs[0].stage = .FRAGMENT;
|
||||
desc.image_sampler_pairs[0].image_slot = 0;
|
||||
desc.image_sampler_pairs[0].sampler_slot = 0;
|
||||
desc.image_sampler_pairs[0].glsl_name = "tex_smp";
|
||||
case .METAL_MACOS;
|
||||
desc.vertex_func.source = xx *vs_ui_source_metal_macos;
|
||||
desc.vertex_func.entry = "main0";
|
||||
desc.fragment_func.source = xx *fs_ui_source_metal_macos;
|
||||
desc.fragment_func.entry = "main0";
|
||||
desc.attrs[0].base_type = .FLOAT;
|
||||
desc.attrs[1].base_type = .FLOAT;
|
||||
desc.attrs[2].base_type = .FLOAT;
|
||||
desc.uniform_blocks[0].stage = .VERTEX;
|
||||
desc.uniform_blocks[0].layout = .STD140;
|
||||
desc.uniform_blocks[0].size = 16;
|
||||
desc.uniform_blocks[0].msl_buffer_n = 0;
|
||||
desc.images[0].stage = .FRAGMENT;
|
||||
desc.images[0].multisampled = false;
|
||||
desc.images[0].image_type = ._2D;
|
||||
desc.images[0].sample_type = .FLOAT;
|
||||
desc.images[0].msl_texture_n = 0;
|
||||
desc.samplers[0].stage = .FRAGMENT;
|
||||
desc.samplers[0].sampler_type = .FILTERING;
|
||||
desc.samplers[0].msl_sampler_n = 0;
|
||||
desc.image_sampler_pairs[0].stage = .FRAGMENT;
|
||||
desc.image_sampler_pairs[0].image_slot = 0;
|
||||
desc.image_sampler_pairs[0].sampler_slot = 0;
|
||||
}
|
||||
return desc;
|
||||
}
|
||||
6
src/renderer_sokol/shaders/shaders.glsl
Normal file
6
src/renderer_sokol/shaders/shaders.glsl
Normal file
@ -0,0 +1,6 @@
|
||||
@include common.glsl
|
||||
@include ui.glsl
|
||||
@include composite.glsl
|
||||
@include trile.glsl
|
||||
@include water.glsl
|
||||
@include billboard.glsl
|
||||
48
src/renderer_sokol/shaders/trile.glsl
Normal file
48
src/renderer_sokol/shaders/trile.glsl
Normal file
@ -0,0 +1,48 @@
|
||||
@vs vs_trile
|
||||
@include_block view
|
||||
|
||||
layout(binding=1) uniform trile_params {
|
||||
vec4 orientations[72];
|
||||
};
|
||||
|
||||
in vec3 position;
|
||||
in float swatch;
|
||||
in vec4 instance; // xyz = position, w = orientation
|
||||
in float tint;
|
||||
|
||||
out float v_clip;
|
||||
out float v_swatch;
|
||||
out float v_tint;
|
||||
|
||||
void main() {
|
||||
int ori = int(instance.w + 0.5) * 3;
|
||||
vec3 p = position - 0.5;
|
||||
vec3 world = vec3(dot(orientations[ori].xyz, p),
|
||||
dot(orientations[ori + 1].xyz, p),
|
||||
dot(orientations[ori + 2].xyz, p)) + 0.5 + instance.xyz;
|
||||
gl_Position = view_proj * vec4(world, 1.0);
|
||||
v_clip = dot(vec4(world, 1.0), clip);
|
||||
v_swatch = swatch;
|
||||
v_tint = tint;
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs_trile
|
||||
in float v_clip;
|
||||
in float v_swatch;
|
||||
in float v_tint;
|
||||
out vec4 frag_color;
|
||||
|
||||
layout(binding=0) uniform texture2D palette;
|
||||
layout(binding=0) uniform sampler palette_smp;
|
||||
|
||||
void main() {
|
||||
if (v_clip < 0.0) discard;
|
||||
vec3 albedo = texelFetch(sampler2D(palette, palette_smp), ivec2(int(v_swatch + 0.5), 0), 0).rgb;
|
||||
if (v_tint > 1.5) albedo = mix(albedo, vec3(1.0, 0.2, 0.2), 0.5);
|
||||
else if (v_tint > 0.5) albedo = mix(albedo, vec3(0.2, 1.0, 0.2), 0.5);
|
||||
frag_color = vec4(albedo, 1.0);
|
||||
}
|
||||
@end
|
||||
|
||||
@program trile vs_trile fs_trile
|
||||
64
src/renderer_sokol/shaders/water.glsl
Normal file
64
src/renderer_sokol/shaders/water.glsl
Normal file
@ -0,0 +1,64 @@
|
||||
@vs vs_water
|
||||
@include_block view
|
||||
@include_block quad
|
||||
|
||||
layout(binding=1) uniform water_vs_params {
|
||||
float height;
|
||||
float half_size;
|
||||
};
|
||||
|
||||
out vec3 v_to_camera;
|
||||
out vec4 v_normal_uv;
|
||||
|
||||
void main() {
|
||||
vec2 xz = camera.xz + (quad_corner(gl_VertexIndex) * 2.0 - 1.0) * half_size;
|
||||
vec3 world = vec3(xz.x, height, xz.y);
|
||||
gl_Position = view_proj * vec4(world, 1.0);
|
||||
|
||||
vec2 flow = camera.w * vec2(-0.005, -0.012);
|
||||
v_normal_uv = vec4(xz * 0.4 + flow * 1.5, xz * 0.1 + flow * 1.7);
|
||||
v_to_camera = camera.xyz - world;
|
||||
}
|
||||
@end
|
||||
|
||||
@fs fs_water
|
||||
in vec3 v_to_camera;
|
||||
in vec4 v_normal_uv;
|
||||
out vec4 frag_color;
|
||||
|
||||
layout(binding=2) uniform water_fs_params {
|
||||
vec3 color;
|
||||
float surface;
|
||||
float reflectivity;
|
||||
float distortion;
|
||||
};
|
||||
|
||||
layout(binding=0) uniform texture2D reflection;
|
||||
layout(binding=1) uniform texture2D normals;
|
||||
layout(binding=0) uniform sampler reflection_smp;
|
||||
layout(binding=1) uniform sampler normals_smp;
|
||||
|
||||
void main() {
|
||||
if (surface < 0.5) {
|
||||
frag_color = vec4(color, 1.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec3 n1 = texture(sampler2D(normals, normals_smp), v_normal_uv.xy).xzy * 2.0 - 1.0;
|
||||
vec3 n2 = texture(sampler2D(normals, normals_smp), v_normal_uv.zw).xzy * 2.0 - 1.0;
|
||||
vec3 normal = normalize(n1 + n2);
|
||||
|
||||
float facing = max(dot(normalize(v_to_camera), normal), 0.0);
|
||||
float fresnel = min(1.0, 0.02 + 0.98 * pow(1.0 - facing, 5.0) + 0.45);
|
||||
|
||||
vec2 uv = gl_FragCoord.xy / vec2(textureSize(sampler2D(reflection, reflection_smp), 0));
|
||||
uv.y = 1.0 - uv.y;
|
||||
vec3 reflected = texture(sampler2D(reflection, reflection_smp), uv + normal.xz * distortion).rgb;
|
||||
|
||||
vec3 surface_color = mix(color, reflected, mix(fresnel, 1.0, reflectivity));
|
||||
float alpha = mix(mix(0.3, 0.5, fresnel), 1.0, reflectivity);
|
||||
frag_color = vec4(surface_color, alpha);
|
||||
}
|
||||
@end
|
||||
|
||||
@program water vs_water fs_water
|
||||
133
src/renderer_sokol/triles.jai
Normal file
133
src/renderer_sokol/triles.jai
Normal file
@ -0,0 +1,133 @@
|
||||
triles_init :: (orientations: [ORIENTATION_COUNT]Matrix3) {
|
||||
desc := pipeline_desc(trile_shader_desc(sg_query_backend()), .VIEW, depth_write = true);
|
||||
desc.layout.buffers[1].step_func = .PER_INSTANCE;
|
||||
desc.layout.attrs[ATTR_trile_position] = .{ format = .FLOAT3 };
|
||||
desc.layout.attrs[ATTR_trile_swatch] = .{ format = .FLOAT };
|
||||
desc.layout.attrs[ATTR_trile_instance] = .{ format = .FLOAT4, buffer_index = 1 };
|
||||
desc.layout.attrs[ATTR_trile_tint] = .{ format = .FLOAT, buffer_index = 1 };
|
||||
desc.cull_mode = .BACK;
|
||||
desc.face_winding = .CCW;
|
||||
triles.pipeline = sg_make_pipeline(*desc);
|
||||
|
||||
for orientations {
|
||||
for r: 0..2 for c: 0..2 triles.params.orientations[it_index * 3 + r][c] = it.coef[r][c];
|
||||
}
|
||||
triles.palette_dirty = true;
|
||||
}
|
||||
|
||||
renderer_trile_mesh_create :: (vertices: []Trile_Vertex) -> u32 {
|
||||
id, mesh := slot_add(*triles.meshes);
|
||||
make_mesh(mesh, vertices);
|
||||
return id;
|
||||
}
|
||||
|
||||
renderer_trile_mesh_update :: (id: u32, vertices: []Trile_Vertex) {
|
||||
mesh := slot_get(*triles.meshes, id);
|
||||
free_mesh(mesh);
|
||||
make_mesh(mesh, vertices);
|
||||
}
|
||||
|
||||
renderer_trile_mesh_destroy :: (id: u32) {
|
||||
free_mesh(slot_get(*triles.meshes, id));
|
||||
slot_remove(*triles.meshes, id);
|
||||
}
|
||||
|
||||
renderer_swatch_set :: (id: u8, color: [3]u8, roughness: u8, metallic: u8, emittance: u8) {
|
||||
for 0..2 triles.palette[id][it] = color[it];
|
||||
triles.palette[id][3] = 255;
|
||||
triles.palette_dirty = true;
|
||||
}
|
||||
|
||||
triles_upload :: (scene: *Scene) {
|
||||
if triles.palette_dirty {
|
||||
triles.palette_dirty = false;
|
||||
if triles.palette_image.id sg_destroy_image(triles.palette_image);
|
||||
desc := sg_image_desc.{ width = 256, height = 1, pixel_format = .RGBA8 };
|
||||
desc.data.subimage[0][0] = .{ triles.palette.data, size_of(type_of(triles.palette)) };
|
||||
triles.palette_image = sg_make_image(*desc);
|
||||
}
|
||||
|
||||
array_reset_keeping_memory(*triles.instances);
|
||||
array_reset_keeping_memory(*triles.batches);
|
||||
|
||||
draws : [..]Keyed(Instance);
|
||||
draws.allocator = temp;
|
||||
for view, view_index: scene.views {
|
||||
array_reset_keeping_memory(*draws);
|
||||
if view.draw_world {
|
||||
for chunk: scene.chunks for group: chunk.groups for group.instances {
|
||||
position := chunk.origin + Vector3.{xx it.x, xx it.y, xx it.z};
|
||||
array_add(*draws, .{group.mesh.id, .{position, xx it.orientation, 0}});
|
||||
}
|
||||
}
|
||||
for scene.triles {
|
||||
if it.view.index != view_index continue;
|
||||
preview : s64 = ifx it.tint != .NONE then PREVIEW_KEY else 0;
|
||||
array_add(*draws, .{preview | it.mesh.id, .{it.position, xx it.orientation, xx it.tint}});
|
||||
}
|
||||
batch_instances(view_index, draws, *triles.batches, *triles.instances);
|
||||
}
|
||||
stream_upload(*triles.stream, triles.instances);
|
||||
}
|
||||
|
||||
triles_draw :: (pass: *Pass) {
|
||||
sg_apply_pipeline(triles.pipeline);
|
||||
apply_uniforms(UB_view_params, *pass.params);
|
||||
apply_uniforms(UB_trile_params, *triles.params);
|
||||
|
||||
for triles.batches {
|
||||
if it.view_index != pass.view_index || (pass.reflection && it.key & PREVIEW_KEY) continue;
|
||||
mesh := slot_get(*triles.meshes, xx (it.key & ~PREVIEW_KEY));
|
||||
if !mesh || mesh.vertex_count == 0 continue;
|
||||
|
||||
bind : sg_bindings;
|
||||
bind.vertex_buffers[0] = mesh.vertices;
|
||||
bind.vertex_buffers[1] = triles.stream.buffer;
|
||||
bind.vertex_buffer_offsets[1] = it.first * size_of(Instance);
|
||||
bind.images[IMG_palette] = triles.palette_image;
|
||||
bind.samplers[SMP_palette_smp] = samplers.nearest_clamp;
|
||||
sg_apply_bindings(*bind);
|
||||
sg_draw(0, mesh.vertex_count, it.count);
|
||||
}
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
Mesh :: struct {
|
||||
vertices : sg_buffer;
|
||||
vertex_count : s32;
|
||||
}
|
||||
|
||||
Instance :: struct {
|
||||
position : Vector3;
|
||||
orientation : float;
|
||||
tint : float;
|
||||
}
|
||||
|
||||
PREVIEW_KEY :: 1 << 32;
|
||||
|
||||
triles : struct {
|
||||
pipeline : sg_pipeline;
|
||||
params : Trile_Params;
|
||||
meshes : Slots(Mesh);
|
||||
|
||||
palette : [256][4]u8;
|
||||
palette_image : sg_image;
|
||||
palette_dirty : bool;
|
||||
|
||||
instances : [..]Instance;
|
||||
batches : [..]Batch;
|
||||
stream : Stream_Buffer;
|
||||
}
|
||||
|
||||
make_mesh :: (mesh: *Mesh, vertices: []Trile_Vertex) {
|
||||
mesh.vertex_count = xx vertices.count;
|
||||
if vertices.count {
|
||||
mesh.vertices = sg_make_buffer(*(sg_buffer_desc.{ data = .{ vertices.data, xx (vertices.count * size_of(Trile_Vertex)) } }));
|
||||
}
|
||||
}
|
||||
|
||||
free_mesh :: (mesh: *Mesh) {
|
||||
if mesh.vertex_count sg_destroy_buffer(mesh.vertices);
|
||||
mesh.* = .{};
|
||||
}
|
||||
@ -1,38 +1,15 @@
|
||||
ui_init :: () {
|
||||
shader_desc := ui_shader_desc(sg_query_backend());
|
||||
|
||||
desc : sg_pipeline_desc;
|
||||
desc.shader = sg_make_shader(*shader_desc);
|
||||
desc := pipeline_desc(ui_shader_desc(sg_query_backend()), .SCREEN, blend = true);
|
||||
desc.layout.attrs[ATTR_ui_position] = .{ format = .FLOAT2 };
|
||||
desc.layout.attrs[ATTR_ui_uv] = .{ format = .FLOAT2 };
|
||||
desc.layout.attrs[ATTR_ui_color0] = .{ format = .FLOAT4 };
|
||||
desc.colors[0].blend = .{
|
||||
enabled = true,
|
||||
src_factor_rgb = .SRC_ALPHA,
|
||||
dst_factor_rgb = .ONE_MINUS_SRC_ALPHA,
|
||||
};
|
||||
ui.pipeline = sg_make_pipeline(*desc);
|
||||
|
||||
ui.sampler = sg_make_sampler(*(sg_sampler_desc.{
|
||||
wrap_u = .CLAMP_TO_EDGE,
|
||||
wrap_v = .CLAMP_TO_EDGE,
|
||||
min_filter = .NEAREST,
|
||||
mag_filter = .NEAREST,
|
||||
}));
|
||||
}
|
||||
|
||||
ui_upload :: (scene: *Scene) {
|
||||
array_reset_keeping_memory(*ui.vertices);
|
||||
for scene.ui array_add(*ui.vertices, ..it.vertices);
|
||||
if ui.vertices.count == 0 return;
|
||||
|
||||
size := ui.vertices.count * size_of(Ui_Vertex);
|
||||
if size > ui.buffer_size {
|
||||
if ui.buffer_size sg_destroy_buffer(ui.buffer);
|
||||
ui.buffer_size = max(size, ui.buffer_size * 2);
|
||||
ui.buffer = sg_make_buffer(*(sg_buffer_desc.{ size = xx ui.buffer_size, usage = .STREAM }));
|
||||
}
|
||||
sg_update_buffer(ui.buffer, *(sg_range.{ ui.vertices.data, xx size }));
|
||||
stream_upload(*ui.stream, ui.vertices);
|
||||
}
|
||||
|
||||
ui_draw :: (scene: *Scene, w: s32, h: s32) {
|
||||
@ -40,11 +17,11 @@ ui_draw :: (scene: *Scene, w: s32, h: s32) {
|
||||
|
||||
sg_apply_pipeline(ui.pipeline);
|
||||
params := Ui_Vs_Params.{ screen_size = .[xx w, xx h] };
|
||||
sg_apply_uniforms(UB_ui_vs_params, *(sg_range.{ *params, size_of(Ui_Vs_Params) }));
|
||||
apply_uniforms(UB_ui_vs_params, *params);
|
||||
|
||||
bind : sg_bindings;
|
||||
bind.vertex_buffers[0] = ui.buffer;
|
||||
bind.samplers[SMP_smp] = ui.sampler;
|
||||
bind.vertex_buffers[0] = ui.stream.buffer;
|
||||
bind.samplers[SMP_smp] = samplers.nearest_clamp;
|
||||
|
||||
first : s32;
|
||||
for scene.ui {
|
||||
@ -66,8 +43,6 @@ ui_draw :: (scene: *Scene, w: s32, h: s32) {
|
||||
|
||||
ui : struct {
|
||||
pipeline : sg_pipeline;
|
||||
sampler : sg_sampler;
|
||||
buffer : sg_buffer;
|
||||
buffer_size : int;
|
||||
stream : Stream_Buffer;
|
||||
vertices : [..]Ui_Vertex;
|
||||
}
|
||||
|
||||
72
src/renderer_sokol/views.jai
Normal file
72
src/renderer_sokol/views.jai
Normal file
@ -0,0 +1,72 @@
|
||||
views_init :: () {
|
||||
desc := pipeline_desc(composite_shader_desc(sg_query_backend()), .SCREEN);
|
||||
views.composite = sg_make_pipeline(*desc);
|
||||
}
|
||||
|
||||
view_begin_pass :: (index: int, width: s32, height: s32, reflection: bool) {
|
||||
if width != views.width || height != views.height {
|
||||
for views.targets {
|
||||
destroy_target(it.main);
|
||||
destroy_target(it.reflection);
|
||||
}
|
||||
array_reset_keeping_memory(*views.targets);
|
||||
views.width = width;
|
||||
views.height = height;
|
||||
}
|
||||
while views.targets.count <= index array_add(*views.targets, .{make_target(width, height), make_target(width, height)});
|
||||
targets := views.targets[index];
|
||||
|
||||
action : sg_pass_action;
|
||||
action.colors[0] = .{ load_action = .CLEAR, clear_value = .{0, 0, 0, 1} };
|
||||
action.depth = .{ load_action = .CLEAR, clear_value = 1 };
|
||||
target := ifx reflection then targets.reflection else targets.main;
|
||||
sg_begin_pass(*(sg_pass.{ action = action, attachments = target.attachments }));
|
||||
}
|
||||
|
||||
view_reflection_image :: (index: int) -> sg_image {
|
||||
return views.targets[index].reflection.color;
|
||||
}
|
||||
|
||||
view_composite :: (index: int) {
|
||||
sg_apply_pipeline(views.composite);
|
||||
params := Composite_Vs_Params.{ flip_y = ifx sg_query_features().origin_top_left then 1.0 else 0.0 };
|
||||
apply_uniforms(UB_composite_vs_params, *params);
|
||||
|
||||
bind : sg_bindings;
|
||||
bind.images[IMG_view_color] = views.targets[index].main.color;
|
||||
bind.samplers[SMP_composite_smp] = samplers.nearest_clamp;
|
||||
sg_apply_bindings(*bind);
|
||||
sg_draw(0, 3, 1);
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
View_Target :: struct {
|
||||
color : sg_image;
|
||||
depth : sg_image;
|
||||
attachments : sg_attachments;
|
||||
}
|
||||
|
||||
views : struct {
|
||||
composite : sg_pipeline;
|
||||
targets : [..]struct { main, reflection: View_Target; };
|
||||
width : s32;
|
||||
height : s32;
|
||||
}
|
||||
|
||||
make_target :: (width: s32, height: s32) -> View_Target {
|
||||
t : View_Target;
|
||||
t.color = sg_make_image(*(sg_image_desc.{ render_target = true, width = width, height = height, pixel_format = VIEW_COLOR_FORMAT, sample_count = 1 }));
|
||||
t.depth = sg_make_image(*(sg_image_desc.{ render_target = true, width = width, height = height, pixel_format = VIEW_DEPTH_FORMAT, sample_count = 1 }));
|
||||
desc : sg_attachments_desc;
|
||||
desc.colors[0].image = t.color;
|
||||
desc.depth_stencil.image = t.depth;
|
||||
t.attachments = sg_make_attachments(*desc);
|
||||
return t;
|
||||
}
|
||||
|
||||
destroy_target :: (t: View_Target) {
|
||||
sg_destroy_attachments(t.attachments);
|
||||
sg_destroy_image(t.color);
|
||||
sg_destroy_image(t.depth);
|
||||
}
|
||||
42
src/renderer_sokol/water.jai
Normal file
42
src/renderer_sokol/water.jai
Normal file
@ -0,0 +1,42 @@
|
||||
WATER_HALF_SIZE :: 1000.0;
|
||||
|
||||
water_init :: () {
|
||||
desc := pipeline_desc(water_shader_desc(sg_query_backend()), .VIEW, blend = true);
|
||||
water.pipeline = sg_make_pipeline(*desc);
|
||||
}
|
||||
|
||||
water_draw :: (pass: *Pass) {
|
||||
env := pass.view.environment;
|
||||
if pass.reflection || !pass.view.draw_world || !env || !env.water return;
|
||||
|
||||
sg_apply_pipeline(water.pipeline);
|
||||
apply_uniforms(UB_view_params, *pass.params);
|
||||
|
||||
bind : sg_bindings;
|
||||
bind.images[IMG_reflection] = view_reflection_image(pass.view_index);
|
||||
bind.images[IMG_normals] = texture_image(env.water_normals.id);
|
||||
bind.samplers[SMP_reflection_smp] = samplers.linear_clamp;
|
||||
bind.samplers[SMP_normals_smp] = samplers.linear_repeat;
|
||||
sg_apply_bindings(*bind);
|
||||
|
||||
draw_plane :: (height: float, color: Vector3, surface: bool) #expand {
|
||||
vs := Water_Vs_Params.{ height = height, half_size = WATER_HALF_SIZE };
|
||||
fs := Water_Fs_Params.{
|
||||
color = color.component,
|
||||
surface = xx surface,
|
||||
reflectivity = env.water_reflectivity,
|
||||
distortion = env.water_distortion,
|
||||
};
|
||||
apply_uniforms(UB_water_vs_params, *vs);
|
||||
apply_uniforms(UB_water_fs_params, *fs);
|
||||
sg_draw(0, 6, 1);
|
||||
}
|
||||
draw_plane(0, env.deep_color, false);
|
||||
draw_plane(env.reflection_height, env.water_color, true);
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
water : struct {
|
||||
pipeline : sg_pipeline;
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
// scene.jai and text.jai.
|
||||
|
||||
#load "scene.jai";
|
||||
#load "trile_mesher.jai";
|
||||
#load "text.jai";
|
||||
#load "camera.jai";
|
||||
#load "debug_draw.jai";
|
||||
@ -16,7 +17,7 @@
|
||||
render :: () {
|
||||
text_end_frame();
|
||||
w, h := get_window_size();
|
||||
scene_end_frame(w, h);
|
||||
scene_end_frame(w, h, xx get_time());
|
||||
g_debug_line_count = 0;
|
||||
g_overlay_line_count = 0;
|
||||
}
|
||||
|
||||
@ -9,6 +9,13 @@ Font_Face :: struct { id: s32; }
|
||||
View_Id :: struct { index: s32; }
|
||||
|
||||
Environment :: struct {
|
||||
reflection_height : float;
|
||||
water : bool;
|
||||
water_color : Vector3 = .{1, 1, 1};
|
||||
deep_color : Vector3 = .{1, 1, 1};
|
||||
water_reflectivity : float;
|
||||
water_distortion : float = 0.007;
|
||||
water_normals : Texture;
|
||||
}
|
||||
|
||||
View :: struct {
|
||||
@ -46,14 +53,19 @@ Ui_Vertex :: struct {
|
||||
}
|
||||
|
||||
trile_mesh_create :: (trile: *Trile) -> Trile_Mesh {
|
||||
scene.trile_mesh_count += 1;
|
||||
return .{scene.trile_mesh_count};
|
||||
return .{renderer_trile_mesh_create(mesh_trile(trile))};
|
||||
}
|
||||
|
||||
trile_mesh_update :: (mesh: Trile_Mesh, trile: *Trile) {
|
||||
renderer_trile_mesh_update(mesh.id, mesh_trile(trile));
|
||||
}
|
||||
|
||||
trile_mesh_destroy :: (mesh: Trile_Mesh) {
|
||||
renderer_trile_mesh_destroy(mesh.id);
|
||||
}
|
||||
|
||||
swatch_set :: (id: u8, color: [3]u8, roughness: u8, metallic: u8, emittance: u8) {
|
||||
renderer_swatch_set(id, color, roughness, metallic, emittance);
|
||||
}
|
||||
|
||||
// Pixels are RGBA8.
|
||||
@ -74,8 +86,9 @@ World_Group :: struct {
|
||||
instances : []Trile_Instance;
|
||||
}
|
||||
|
||||
world_set_chunk :: (key: Chunk_Key, groups: []World_Group) {
|
||||
world_set_chunk :: (key: Chunk_Key, origin: Vector3, groups: []World_Group) {
|
||||
chunk := find_or_add(*scene.chunks, key);
|
||||
chunk.origin = origin;
|
||||
for chunk.groups array_free(it.instances);
|
||||
array_reset_keeping_memory(*chunk.groups);
|
||||
for groups {
|
||||
@ -103,6 +116,13 @@ world_clear :: () {
|
||||
|
||||
add_view :: (view: View) -> View_Id {
|
||||
array_add(*scene.views, view);
|
||||
camera := view.camera;
|
||||
array_add(*scene.view_proj, create_viewproj(*camera));
|
||||
|
||||
height := ifx view.environment then view.environment.reflection_height else 0;
|
||||
camera.position.y = 2 * height - camera.position.y;
|
||||
camera.target.y = 2 * height - camera.target.y;
|
||||
array_add(*scene.reflection_view_proj, create_viewproj(*camera));
|
||||
return .{xx (scene.views.count - 1)};
|
||||
}
|
||||
|
||||
@ -133,6 +153,7 @@ ui_scissor_clear :: () {
|
||||
}
|
||||
|
||||
Scene_Chunk :: struct {
|
||||
origin : Vector3;
|
||||
groups : [..]World_Group;
|
||||
}
|
||||
|
||||
@ -168,12 +189,18 @@ Scene_Ui :: struct {
|
||||
clear_scissor : bool;
|
||||
}
|
||||
|
||||
Scene :: struct {
|
||||
trile_mesh_count : u32;
|
||||
Trile_Vertex :: struct {
|
||||
position : Vector3;
|
||||
swatch : float;
|
||||
}
|
||||
|
||||
Scene :: struct {
|
||||
chunks : Table(Chunk_Key, Scene_Chunk, chunk_key_hash, chunk_key_compare);
|
||||
|
||||
views : [..]View;
|
||||
view_proj : [..]Matrix4;
|
||||
reflection_view_proj : [..]Matrix4;
|
||||
time : float;
|
||||
triles : [..]Scene_Trile;
|
||||
billboards : [..]Scene_Billboard;
|
||||
particles : [..]Scene_Particles;
|
||||
@ -181,16 +208,24 @@ Scene :: struct {
|
||||
}
|
||||
|
||||
scene_init :: () {
|
||||
renderer_init();
|
||||
orientations : [ORIENTATION_COUNT]Matrix3;
|
||||
for *orientations {
|
||||
m := orientation_matrix(xx it_index).m;
|
||||
for r: 0..2 for c: 0..2 it.coef[r][c] = xx m[r][c];
|
||||
}
|
||||
renderer_init(orientations);
|
||||
}
|
||||
|
||||
scene_shutdown :: () {
|
||||
renderer_shutdown();
|
||||
}
|
||||
|
||||
scene_end_frame :: (width: s32, height: s32) {
|
||||
scene_end_frame :: (width: s32, height: s32, time: float) {
|
||||
scene.time = time;
|
||||
renderer_render(*scene, width, height);
|
||||
array_reset_keeping_memory(*scene.views);
|
||||
array_reset_keeping_memory(*scene.view_proj);
|
||||
array_reset_keeping_memory(*scene.reflection_view_proj);
|
||||
array_reset_keeping_memory(*scene.triles);
|
||||
array_reset_keeping_memory(*scene.billboards);
|
||||
array_reset_keeping_memory(*scene.particles);
|
||||
|
||||
57
src/rendering/trile_mesher.jai
Normal file
57
src/rendering/trile_mesher.jai
Normal file
@ -0,0 +1,57 @@
|
||||
mesh_trile :: (trile: *Trile) -> []Trile_Vertex {
|
||||
vertices : [..]Trile_Vertex;
|
||||
vertices.allocator = temp;
|
||||
|
||||
for axis: 0..2 for sign: s32.[1, -1] {
|
||||
u_axis := (axis + 1) % 3;
|
||||
v_axis := (axis + 2) % 3;
|
||||
for depth: 0..15 {
|
||||
mask : [16][16]u8;
|
||||
for u: 0..15 for v: 0..15 {
|
||||
c : [3]s32;
|
||||
c[axis] = xx depth; c[u_axis] = xx u; c[v_axis] = xx v;
|
||||
swatch := trixel(trile, c);
|
||||
c[axis] += sign;
|
||||
if trixel(trile, c) == 0 mask[u][v] = swatch;
|
||||
}
|
||||
|
||||
for u0: 0..15 for v0: 0..15 {
|
||||
swatch := mask[u0][v0];
|
||||
if !swatch continue;
|
||||
v1 := v0 + 1;
|
||||
while v1 < 16 && mask[u0][v1] == swatch v1 += 1;
|
||||
u1 := u0 + 1;
|
||||
while u1 < 16 && row_matches(*mask, u1, v0, v1, swatch) u1 += 1;
|
||||
for u: u0..u1-1 for v: v0..v1-1 mask[u][v] = 0;
|
||||
|
||||
plane := cast(float)(depth + ifx sign > 0 then 1 else 0);
|
||||
corner :: (axis: int, u_axis: int, v_axis: int, plane: float, u: int, v: int) -> Vector3 #expand {
|
||||
p : Vector3;
|
||||
p.component[axis] = plane * TRIXEL_SIZE;
|
||||
p.component[u_axis] = u * TRIXEL_SIZE;
|
||||
p.component[v_axis] = v * TRIXEL_SIZE;
|
||||
return p;
|
||||
}
|
||||
p0 := corner(axis, u_axis, v_axis, plane, u0, v0);
|
||||
p1 := corner(axis, u_axis, v_axis, plane, u1, v0);
|
||||
p2 := corner(axis, u_axis, v_axis, plane, u1, v1);
|
||||
p3 := corner(axis, u_axis, v_axis, plane, u0, v1);
|
||||
if sign < 0 p1, p3 = p3, p1;
|
||||
for Vector3.[p0, p1, p2, p0, p2, p3] array_add(*vertices, .{it, xx swatch});
|
||||
}
|
||||
}
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
#scope_file
|
||||
|
||||
row_matches :: (mask: *[16][16]u8, u: int, v0: int, v1: int, swatch: u8) -> bool {
|
||||
for v: v0..v1-1 if mask.*[u][v] != swatch return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
trixel :: (trile: *Trile, c: [3]s32) -> u8 {
|
||||
for c if it < 0 || it > 15 return 0;
|
||||
return trile.trixels[c[0]][c[1]][c[2]];
|
||||
}
|
||||
@ -158,12 +158,18 @@ swatch_add :: (name: string, color: [3]u8, roughness: u8 = 4, metallic: u8 = 0,
|
||||
for 1..MAX_SWATCHES-1 {
|
||||
if g_swatches[it].used continue;
|
||||
g_swatches[it] = .{used = true, name = copy_string(name), color = color, roughness = roughness, metallic = metallic, emittance = emittance};
|
||||
swatch_changed(xx it);
|
||||
return cast(u8) it, true;
|
||||
}
|
||||
log_error("All % swatches are in use", MAX_SWATCHES - 1);
|
||||
return 0, false;
|
||||
}
|
||||
|
||||
swatch_changed :: (id: u8) {
|
||||
s := g_swatches[id];
|
||||
swatch_set(id, s.color, s.roughness, s.metallic, s.emittance);
|
||||
}
|
||||
|
||||
swatch_color :: (id: u8) -> Vector3 {
|
||||
c := g_swatches[id].color;
|
||||
return .{c[0] / 255.0, c[1] / 255.0, c[2] / 255.0};
|
||||
@ -212,6 +218,7 @@ lswatches :: () {
|
||||
if it.id < 1 || it.id >= MAX_SWATCHES continue;
|
||||
g_swatches[it.id] = .{used = true, name = sprint("%", it.name), color = it.color, roughness = it.roughness, metallic = it.metallic, emittance = it.emittance};
|
||||
}
|
||||
for 0..MAX_SWATCHES-1 swatch_changed(xx it);
|
||||
} @Command
|
||||
|
||||
Palette_Entry :: struct {
|
||||
|
||||
@ -251,7 +251,8 @@ upload_chunk :: (chunk: *Chunk) {
|
||||
mesh, ok := get_trile_mesh(it.trile_name);
|
||||
if ok array_add(*groups, .{mesh, it.instances});
|
||||
}
|
||||
world_set_chunk(chunk.coord, groups);
|
||||
origin := Vector3.{xx (chunk.coord.x * CHUNK_SIZE), xx (chunk.coord.y * CHUNK_SIZE), xx (chunk.coord.z * CHUNK_SIZE)};
|
||||
world_set_chunk(chunk.coord, origin, groups);
|
||||
}
|
||||
|
||||
get_note_locations :: (note : string) -> []Vector3 {
|
||||
@ -720,6 +721,19 @@ World_Config :: struct {
|
||||
|
||||
INDOOR_REFLECTION_PLANE :: 1.0;
|
||||
|
||||
world_environment :: (world: *World) -> *Environment {
|
||||
env := *world.environment;
|
||||
conf := *world.conf;
|
||||
env.reflection_height = effective_plane_height(conf);
|
||||
env.water = !conf.indoor;
|
||||
env.water_color = conf.waterColor;
|
||||
env.deep_color = conf.deepColor;
|
||||
env.water_reflectivity = conf.waterReflectivity;
|
||||
env.water_distortion = conf.waterDistortion;
|
||||
env.water_normals = get_texture_from_pack("core", "utiltex/water_small.png");
|
||||
return env;
|
||||
}
|
||||
|
||||
// The planar reflection height: the water surface outdoors, the floor indoors.
|
||||
effective_plane_height :: (wc: *World_Config) -> float {
|
||||
if wc.indoor return INDOOR_REFLECTION_PLANE;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user