move UI code to new renderer

This commit is contained in:
Tuomas Katajisto 2026-10-02 21:29:02 +03:00
parent 897fbeea4b
commit 9ebeea8772
12 changed files with 725 additions and 26 deletions

View File

@ -1,4 +1,5 @@
#load "./src/meta/meta.jai";
#load "./src/renderer_sokol/shaders/build.jai";
Iprof :: #import "Iprof"(IMPORT_MODE = .METAPROGRAM);
#import "File_Utilities";
@ -12,6 +13,7 @@ Trueno_Build_Options :: struct {
test_game : bool;
test_exe_engine : bool;
test_exe_game : bool;
renderer : string = "sokol";
}
// Engine tests build against test_game/ so they work without the game/ directory;
@ -25,6 +27,10 @@ build_options_from_args :: (args: []string) -> Trueno_Build_Options {
opts : Trueno_Build_Options;
for arg : args {
if begins_with(arg, "renderer=") {
opts.renderer = slice(arg, 9, arg.count - 9);
continue;
}
if arg == {
case "wasm";
opts.wasm_build = true;
@ -96,11 +102,13 @@ add_trueno_opts_to_compiler_strings :: (trueno_opts : Trueno_Build_Options, w: W
trueno_opts_info := type_info(Trueno_Build_Options);
for trueno_opts_info.members {
if it.type.type != .BOOL continue;
optPtr := (cast(*bool)(*trueno_opts)) + it.offset_in_bytes;
name := tprint("%", it.name);
to_upper_in_place(name);
add_build_string(tprint("FLAG_% :: %;\n", name, bool_to_string(optPtr.*)), w);
}
add_build_string(tprint("RENDERER :: \"%\";\n", trueno_opts.renderer), w);
}
wasm_copy_assets :: () {
@ -245,6 +253,8 @@ wasm_build :: (opts: Build_Options, trueno_opts: Trueno_Build_Options) {
use_test_game := uses_test_game(trueno_opts);
create_pack(use_test_game, ifx use_test_game then "./test_packs" else "./packs");
if trueno_opts.renderer == "sokol" && !compile_sokol_shaders() exit(1);
if trueno_opts.wasm_build {
wasm_build(opt, trueno_opts);
} else {

View File

@ -96,6 +96,7 @@ round_pow2 :: (v: float) -> s32 {
debug_font : *Font;
init :: () {
scene_init();
sfetch_setup(*(sfetch_desc_t.{
max_requests = 128,
num_channels = 2,
@ -272,6 +273,7 @@ frame :: () {
cleanup :: () {
log_info("Cleanup called....");
audio_cleanup();
scene_shutdown();
}
get_window_size :: () -> (s32, s32) {

View File

@ -12,9 +12,8 @@ lint_checks :: (message: *Message) -> bool {
if message.kind != .TYPECHECKED then return true;
code := cast(*Message_Typechecked) message;
lint_ok := true;
lint_ok := lint_sokol_graphics(code);
for code.declarations {
import := it.expression.enclosing_load.enclosing_import;
if import.module_type != .MAIN_PROGRAM then return true;
@ -56,3 +55,39 @@ lint_procedure_name :: (name: string, node: Code_Node) -> bool {
return true;
}
}
lint_sokol_graphics :: (code: *Message_Typechecked) -> bool {
SOKOL_GRAPHICS_MODULES :: string.["gfx", "glue", "gl", "shape", "debugtext", "fontstash"];
is_sokol_graphics :: (path: string) -> bool {
for SOKOL_GRAPHICS_MODULES {
if contains(path, tprint("/sokol-jai/sokol/%/", it)) then return true;
}
return false;
}
ok := true;
for code.all {
load := it.expression.enclosing_load;
if !load || !load.enclosing_import || load.enclosing_import.module_type != .MAIN_PROGRAM then continue;
if contains(load.fully_pathed_filename, "/renderer_sokol/") then continue;
in_scene := ends_with(load.fully_pathed_filename, "/rendering/scene.jai");
for sub: it.subexpressions {
if sub.kind != .IDENT then continue;
decl := (cast(*Code_Ident) sub).resolved_declaration;
if !decl || !decl.enclosing_load then continue;
decl_path := decl.enclosing_load.fully_pathed_filename;
if is_sokol_graphics(decl_path) {
compiler_report(sprint("Linter: % is sokol graphics; only src/renderer_sokol/ may use it\n", decl.name), make_location(sub), .ERROR);
} else if contains(decl_path, "/renderer_sokol/") && !in_scene {
compiler_report(sprint("Linter: % is part of the renderer; only src/rendering/scene.jai may use it\n", decl.name), make_location(sub), .ERROR);
} else {
continue;
}
lint_errors_found += 1;
ok = false;
}
}
return ok;
}

View File

@ -0,0 +1,92 @@
#import,dir "../../modules/sokol-jai/sokol/gfx"(DEBUG = !FLAG_RELEASE_BUILD);
#import,dir "../../modules/sokol-jai/sokol/glue"(DEBUG = !FLAG_RELEASE_BUILD);
#load "shaders/jai/ui.jai";
#load "ui.jai";
renderer_init :: () {
sg_setup(*(sg_desc.{
environment = cast,force(sg_environment) sglue_environment(),
logger = .{ func = slog_func },
}));
white := u8.[255, 255, 255, 255];
renderer.white = make_image(1, 1, white);
ui_init();
}
renderer_shutdown :: () {
sg_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);
}
// 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);
}
renderer_texture_destroy :: (id: u32) {
slot := *renderer.textures[id - 1];
sg_destroy_image(slot.image);
slot.* = .{};
array_add(*renderer.free_textures, xx (id - 1));
}
renderer_render :: (scene: *Scene, width: s32, height: s32) {
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() }));
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;
}
#scope_file
Renderer_Texture :: struct {
image : sg_image;
width : s32;
height : s32;
}
renderer : struct {
textures : [..]Renderer_Texture;
free_textures : [..]s32;
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.data.subimage[0][0] = .{ pixels.data, xx pixels.count };
return sg_make_image(*desc);
}

View File

@ -0,0 +1,22 @@
compile_sokol_shaders :: () -> bool {
dir :: "src/renderer_sokol/shaders";
shdc :: #ifx OS == .MACOS then "sokol-shdc-mac" else "sokol-shdc";
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;
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;
}
}
return true;
}

View File

@ -0,0 +1,422 @@
/*
#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;
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,34 @@
@vs vs_ui
in vec2 position;
in vec2 uv;
in vec4 color0;
layout(binding=0) uniform ui_vs_params {
vec2 screen_size;
};
out vec2 v_uv;
out vec4 v_color;
void main() {
vec2 ndc = position / screen_size * 2.0 - 1.0;
gl_Position = vec4(ndc.x, -ndc.y, 0.0, 1.0);
v_uv = uv;
v_color = color0;
}
@end
@fs fs_ui
in vec2 v_uv;
in vec4 v_color;
out vec4 frag_color;
layout(binding=0) uniform texture2D tex;
layout(binding=0) uniform sampler smp;
void main() {
frag_color = texture(sampler2D(tex, smp), v_uv) * v_color;
}
@end
@program ui vs_ui fs_ui

73
src/renderer_sokol/ui.jai Normal file
View File

@ -0,0 +1,73 @@
ui_init :: () {
shader_desc := ui_shader_desc(sg_query_backend());
desc : sg_pipeline_desc;
desc.shader = sg_make_shader(*shader_desc);
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 }));
}
ui_draw :: (scene: *Scene, w: s32, h: s32) {
if ui.vertices.count == 0 return;
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) }));
bind : sg_bindings;
bind.vertex_buffers[0] = ui.buffer;
bind.samplers[SMP_smp] = ui.sampler;
first : s32;
for scene.ui {
if it.set_scissor {
s := it.scissor;
sg_apply_scissor_rect(s.x, s.y, max(s.w, 0), max(s.h, 0), true);
} else if it.clear_scissor {
sg_apply_scissor_rect(0, 0, w, h, true);
} else if it.vertices.count {
bind.images[IMG_tex] = texture_image(it.texture.id);
sg_apply_bindings(*bind);
sg_draw(first, xx it.vertices.count, 1);
first += xx it.vertices.count;
}
}
}
#scope_file
ui : struct {
pipeline : sg_pipeline;
sampler : sg_sampler;
buffer : sg_buffer;
buffer_size : int;
vertices : [..]Ui_Vertex;
}

View File

@ -7,9 +7,16 @@
#load "debug_draw.jai";
#load "animation.jai";
#if RENDERER == "sokol" {
#load "../renderer_sokol/renderer.jai";
} else {
#assert false "Unknown renderer; build with renderer=sokol.";
}
render :: () {
text_end_frame();
scene_end_frame();
w, h := get_window_size();
scene_end_frame(w, h);
g_debug_line_count = 0;
g_overlay_line_count = 0;
}

View File

@ -1,14 +1,13 @@
// The Scene API. Game, editor and UI code say what to draw through this file;
// how it gets drawn is the renderer's business. The world is persistent: chunks
// are uploaded when loaded or edited. Everything else is submitted every frame
// and dropped by render().
// The new scene API. The idea is that what to draw is defined trough this,
// and the renderer can be nicely separated and tested.
//
// I'm also planning to maybe add a WGPU backend at some point or something.
Trile_Mesh :: struct { id: u32; }
Texture :: struct { id: u32; }
Font_Face :: struct { id: s32; }
View_Id :: struct { index: s32; }
// Grows as each part of the renderer comes back: sky, sun, fog, water, post.
Environment :: struct {
}
@ -24,7 +23,7 @@ Trile_Tint :: enum u8 {
DELETE_PREVIEW;
}
// A billboard with this face direction turns to face the camera.
// This direction means that the billboard should face the camera.
BILLBOARD_FACE_CAMERA :: Vector3.{-100, -100, -100};
Blend_Mode :: enum u8 {
@ -35,19 +34,17 @@ Blend_Mode :: enum u8 {
Particle_Instance :: struct {
position : Vector3;
size : float;
uv_rect : Vector4; // x, y, w, h in the sheet, normalized
uv_rect : Vector4; // x, y, w, h, 0..1
color : Vector4;
}
// Screen-space, in pixels from the top left.
// Pixels from top left.
Ui_Vertex :: struct {
position : Vector2;
uv : Vector2;
color : Vector4;
}
// --- Persistent resources -------------------------------------------------
trile_mesh_create :: (trile: *Trile) -> Trile_Mesh {
scene.trile_mesh_count += 1;
return .{scene.trile_mesh_count};
@ -61,24 +58,22 @@ trile_mesh_destroy :: (mesh: Trile_Mesh) {
// Pixels are RGBA8.
texture_create :: (width: s32, height: s32, pixels: []u8) -> Texture {
scene.texture_count += 1;
return .{scene.texture_count};
return .{renderer_texture_create(width, height, pixels)};
}
texture_update :: (texture: Texture, pixels: []u8) {
renderer_texture_update(texture.id, pixels);
}
texture_destroy :: (texture: Texture) {
renderer_texture_destroy(texture.id);
}
// --- Persistent world -----------------------------------------------------
World_Group :: struct {
mesh : Trile_Mesh;
instances : []Trile_Instance;
}
// Replaces whatever the chunk held before. The groups are copied.
world_set_chunk :: (key: Chunk_Key, groups: []World_Group) {
chunk := find_or_add(*scene.chunks, key);
for chunk.groups array_free(it.instances);
@ -106,8 +101,6 @@ world_clear :: () {
table_reset(*scene.chunks);
}
// --- Per frame ------------------------------------------------------------
add_view :: (view: View) -> View_Id {
array_add(*scene.views, view);
return .{xx (scene.views.count - 1)};
@ -139,8 +132,6 @@ ui_scissor_clear :: () {
array_add(*scene.ui, .{clear_scissor = true});
}
// --- Renderer side: only src/rendering reads these -------------------------
Scene_Chunk :: struct {
groups : [..]World_Group;
}
@ -169,7 +160,6 @@ Scene_Particles :: struct {
particles : []Particle_Instance;
}
// One entry of the UI stream: either a batch of triangles or a scissor change.
Scene_Ui :: struct {
texture : Texture;
vertices : []Ui_Vertex;
@ -178,9 +168,8 @@ Scene_Ui :: struct {
clear_scissor : bool;
}
scene : struct {
Scene :: struct {
trile_mesh_count : u32;
texture_count : u32;
chunks : Table(Chunk_Key, Scene_Chunk, chunk_key_hash, chunk_key_compare);
@ -191,10 +180,23 @@ scene : struct {
ui : [..]Scene_Ui;
}
scene_end_frame :: () {
scene_init :: () {
renderer_init();
}
scene_shutdown :: () {
renderer_shutdown();
}
scene_end_frame :: (width: s32, height: s32) {
renderer_render(*scene, width, height);
array_reset_keeping_memory(*scene.views);
array_reset_keeping_memory(*scene.triles);
array_reset_keeping_memory(*scene.billboards);
array_reset_keeping_memory(*scene.particles);
array_reset_keeping_memory(*scene.ui);
}
#scope_file
scene : Scene;