Automatic texture batching + sprite rendering

This commit is contained in:
Peaceultime 2025-06-23 00:15:01 +02:00
parent b02b2b02d5
commit e8516827e1
15 changed files with 758 additions and 4704 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
app.* app.*
.vscode/c_cpp_properties.json

View File

@ -21,6 +21,7 @@
"includePath": [ "includePath": [
"${workspaceFolder}/../sokol", "${workspaceFolder}/../sokol",
"${workspaceFolder}/../sokol_gp", "${workspaceFolder}/../sokol_gp",
"${workspaceFolder}/../cimgui",
"${workspaceFolder}/../flecs/distr" "${workspaceFolder}/../flecs/distr"
], ],
"defines": [ "defines": [
@ -29,7 +30,7 @@
"_UNICODE" "_UNICODE"
], ],
"windowsSdkVersion": "10.0.22621.0", "windowsSdkVersion": "10.0.22621.0",
"compilerPath": "C:\\Users\\c.pons\\Documents\\Perso\\Git\\emsdk\\upstream\\emscripten\\emcc.bat", "compilerPath": "D:\\UserDefaults\\Desktop\\Dev\\Git\\emsdk\\upstream\\emscripten\\emcc.bat",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++17", "cppStandard": "c++17",
"intelliSenseMode": "windows-clang-x64", "intelliSenseMode": "windows-clang-x64",
@ -46,7 +47,6 @@
"-sUSE_WEBGL2", "-sUSE_WEBGL2",
"-sASSERTIONS", "-sASSERTIONS",
"-sWASM_BIGINT", "-sWASM_BIGINT",
"-pthread",
"-sFILESYSTEM=0", "-sFILESYSTEM=0",
"-sALLOW_MEMORY_GROWTH=1", "-sALLOW_MEMORY_GROWTH=1",
"-sSTACK_SIZE=1mb", "-sSTACK_SIZE=1mb",

View File

@ -22,6 +22,12 @@
"syslog.h": "c", "syslog.h": "c",
"base.h": "c", "base.h": "c",
"stdarg.h": "c", "stdarg.h": "c",
"rand.h": "c" "rand.h": "c",
"sokol_gfx_imgui.h": "c",
"cimgui.h": "c",
"sokol_imgui.h": "c",
"typeinfo": "c",
"api.h": "c",
"sprite.h": "c"
} }
} }

View File

@ -1 +1,20 @@
emcc -O3 src/main.c -o app.html -sUSE_WEBGL2 -sWASM_BIGINT -sALLOW_MEMORY_GROWTH -pthread -I../sokol -I../sokol_gp -I../flecs/distr --shell-file=shell.html -sFILESYSTEM=0 emcc -O3 src/main.c -o app.html -sUSE_WEBGPU -sWASM_BIGINT -sALLOW_MEMORY_GROWTH -I../sokol -I../sokol_gp -I../cimgui -msimd128 -flto --llvm-lto 1 --shell-file=shell.html -sFILESYSTEM=0
emcc -O3 src/main.c \
../cimgui/cimgui.cpp \
../cimgui/imgui.cpp \
../cimgui/imgui_draw.cpp \
../cimgui/imgui_tables.cpp \
../cimgui/imgui_widgets.cpp \
-o app.html \
-sUSE_WEBGPU \
-sWASM_BIGINT \
-sALLOW_MEMORY_GROWTH \
-I../sokol \
-I../sokol_gp \
-I../cimgui \
-I../flecs/distr \
-msimd128 \
-flto \
--shell-file=shell.html \
-sFILESYSTEM=0

View File

@ -1,2 +1,19 @@
xxd -i src/shaders/sprite.wgsl src/generated/sprite.h xxd -i src/shaders/sprite.wgsl src/generated/sprite.h
emcc src/main.c -o app.html -sUSE_WEBGPU -sASSERTIONS -sWASM_BIGINT -sALLOW_MEMORY_GROWTH -pthread -I../sokol -I../sokol_gp -I../flecs/distr --shell-file=shell.html -sFILESYSTEM=0 -g emcc src/main.c \
../cimgui/cimgui.cpp \
../cimgui/imgui.cpp \
../cimgui/imgui_draw.cpp \
../cimgui/imgui_tables.cpp \
../cimgui/imgui_widgets.cpp \
-o app.html \
-sUSE_WEBGPU \
-sASSERTIONS \
-sWASM_BIGINT \
-sALLOW_MEMORY_GROWTH \
-I../sokol \
-I../sokol_gp \
-I../cimgui \
-I../flecs/distr \
-msimd128 \
--shell-file=shell.html \
-sFILESYSTEM=0

27
src/api.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef API_DEFINITION
#define API_DEFINITION
#define SOKOL_IMPL
#define SOKOL_WGPU
#include "cimgui.h"
#include "sokol_gfx.h"
#include "sokol_app.h"
#include "sokol_glue.h"
#include "sokol_log.h"
#include "util/sokol_memtrack.h"
#include "util/sokol_imgui.h"
#include "math.h"
#include "rand.h"
#include "util.h"
#include "sprite.h"
#include "generated/sprite.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#endif

View File

@ -1,427 +0,0 @@
#pragma once
/*
#version:1# (machine generated, don't edit!)
Generated by sokol-shdc (https://github.com/floooh/sokol-tools)
Cmdline:
sokol-shdc --slang=wgsl -i src/shaders/base.glsl -o src/generated/base.h --ifdef
Overview:
=========
Shader program: 'base':
Get shader desc: base_shader_desc(sg_query_backend());
Vertex Shader: vs
Fragment Shader: fs
Attributes:
ATTR_base_in_quad => 0
Bindings:
Uniform block 'vs_uniform':
C struct: vs_uniform_t
Bind slot: UB_vs_uniform => 0
Uniform block 'fs_uniform':
C struct: fs_uniform_t
Bind slot: UB_fs_uniform => 1
Storage buffer 'vs_ssbo':
C struct: cell_t
Bind slot: SBUF_vs_ssbo => 0
Readonly: true
*/
#if !defined(SOKOL_GFX_INCLUDED)
#error "Please include sokol_gfx.h before base.h"
#endif
#if !defined(SOKOL_SHDC_ALIGN)
#if defined(_MSC_VER)
#define SOKOL_SHDC_ALIGN(a) __declspec(align(a))
#else
#define SOKOL_SHDC_ALIGN(a) __attribute__((aligned(a)))
#endif
#endif
#define ATTR_base_in_quad (0)
#define UB_vs_uniform (0)
#define UB_fs_uniform (1)
#define SBUF_vs_ssbo (0)
#pragma pack(push,1)
SOKOL_SHDC_ALIGN(16) typedef struct vs_uniform_t {
float radius;
uint8_t _pad_4[12];
} vs_uniform_t;
#pragma pack(pop)
#pragma pack(push,1)
SOKOL_SHDC_ALIGN(16) typedef struct fs_uniform_t {
float radius;
uint8_t _pad_4[12];
} fs_uniform_t;
#pragma pack(pop)
#pragma pack(push,1)
SOKOL_SHDC_ALIGN(8) typedef struct cell_t {
float pos[2];
} cell_t;
#pragma pack(pop)
/*
diagnostic(off, derivative_uniformity);
struct cell {
/_ @offset(0) _/
pos : vec2f,
}
alias RTArr = array<cell>;
struct vs_ssbo {
/_ @offset(0) _/
cells : RTArr,
}
struct vs_uniform {
/_ @offset(0) _/
radius : f32,
}
var<private> x_centroid : vec2f;
@group(1) @binding(32) var<storage, read> x_51 : vs_ssbo;
var<private> gl_InstanceIndex : i32;
var<private> x_color : vec3f;
var<private> x_quad : vec2f;
@group(0) @binding(0) var<uniform> x_66 : vs_uniform;
var<private> in_quad : vec2f;
var<private> gl_Position : vec4f;
fn color_i1_(i : ptr<function, i32>) -> vec3f {
var r : f32;
var g : f32;
var b : f32;
let x_16 : i32 = *(i);
r = (f32(((x_16 >> bitcast<u32>(0i)) & 255i)) / 255.0f);
let x_25 : i32 = *(i);
g = (f32(((x_25 >> bitcast<u32>(8i)) & 255i)) / 255.0f);
let x_32 : i32 = *(i);
b = (f32(((x_32 >> bitcast<u32>(16i)) & 255i)) / 255.0f);
let x_38 : f32 = r;
let x_39 : f32 = g;
let x_40 : f32 = b;
return vec3f(x_38, x_39, x_40);
}
fn main_1() {
var param : i32;
let x_54 : i32 = gl_InstanceIndex;
let x_57 : vec2f = x_51.cells[x_54].pos;
x_centroid = x_57;
let x_61 : i32 = gl_InstanceIndex;
param = x_61;
let x_62 : vec3f = color_i1_(&(param));
x_color = x_62;
let x_69 : f32 = x_66.radius;
let x_72 : vec2f = in_quad;
let x_74 : vec2f = x_centroid;
x_quad = ((x_72 * x_69) + x_74);
let x_83 : vec2f = x_quad;
gl_Position = vec4f(x_83.x, x_83.y, 0.0f, 1.0f);
return;
}
struct main_out {
@location(2)
x_centroid_1 : vec2f,
@location(3) @interpolate(flat)
x_color_1 : vec3f,
@location(1)
x_quad_1 : vec2f,
@builtin(position)
gl_Position : vec4f,
}
@vertex
fn main(@builtin(instance_index) gl_InstanceIndex_param : u32, @location(0) in_quad_param : vec2f) -> main_out {
gl_InstanceIndex = bitcast<i32>(gl_InstanceIndex_param);
in_quad = in_quad_param;
main_1();
return main_out(x_centroid, x_color, x_quad, gl_Position);
}
*/
#if defined(SOKOL_WGPU)
static const uint8_t vs_source_wgsl[1944] = {
0x64,0x69,0x61,0x67,0x6e,0x6f,0x73,0x74,0x69,0x63,0x28,0x6f,0x66,0x66,0x2c,0x20,
0x64,0x65,0x72,0x69,0x76,0x61,0x74,0x69,0x76,0x65,0x5f,0x75,0x6e,0x69,0x66,0x6f,
0x72,0x6d,0x69,0x74,0x79,0x29,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
0x63,0x65,0x6c,0x6c,0x20,0x7b,0x0a,0x20,0x20,0x2f,0x2a,0x20,0x40,0x6f,0x66,0x66,
0x73,0x65,0x74,0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,0x20,0x20,0x70,0x6f,0x73,0x20,
0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x0a,0x7d,0x0a,0x0a,0x61,0x6c,0x69,0x61,
0x73,0x20,0x52,0x54,0x41,0x72,0x72,0x20,0x3d,0x20,0x61,0x72,0x72,0x61,0x79,0x3c,
0x63,0x65,0x6c,0x6c,0x3e,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x76,
0x73,0x5f,0x73,0x73,0x62,0x6f,0x20,0x7b,0x0a,0x20,0x20,0x2f,0x2a,0x20,0x40,0x6f,
0x66,0x66,0x73,0x65,0x74,0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,0x20,0x20,0x63,0x65,
0x6c,0x6c,0x73,0x20,0x3a,0x20,0x52,0x54,0x41,0x72,0x72,0x2c,0x0a,0x7d,0x0a,0x0a,
0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x76,0x73,0x5f,0x75,0x6e,0x69,0x66,0x6f,0x72,
0x6d,0x20,0x7b,0x0a,0x20,0x20,0x2f,0x2a,0x20,0x40,0x6f,0x66,0x66,0x73,0x65,0x74,
0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,0x20,0x20,0x72,0x61,0x64,0x69,0x75,0x73,0x20,
0x3a,0x20,0x66,0x33,0x32,0x2c,0x0a,0x7d,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,
0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,
0x64,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x3b,0x0a,0x0a,0x40,0x67,0x72,0x6f,
0x75,0x70,0x28,0x31,0x29,0x20,0x40,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x28,0x33,
0x32,0x29,0x20,0x76,0x61,0x72,0x3c,0x73,0x74,0x6f,0x72,0x61,0x67,0x65,0x2c,0x20,
0x72,0x65,0x61,0x64,0x3e,0x20,0x78,0x5f,0x35,0x31,0x20,0x3a,0x20,0x76,0x73,0x5f,
0x73,0x73,0x62,0x6f,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,
0x74,0x65,0x3e,0x20,0x67,0x6c,0x5f,0x49,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x49,
0x6e,0x64,0x65,0x78,0x20,0x3a,0x20,0x69,0x33,0x32,0x3b,0x0a,0x0a,0x76,0x61,0x72,
0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x78,0x5f,0x63,0x6f,0x6c,0x6f,
0x72,0x20,0x3a,0x20,0x76,0x65,0x63,0x33,0x66,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,
0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x78,0x5f,0x71,0x75,0x61,0x64,0x20,
0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x3b,0x0a,0x0a,0x40,0x67,0x72,0x6f,0x75,0x70,
0x28,0x30,0x29,0x20,0x40,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x28,0x30,0x29,0x20,
0x76,0x61,0x72,0x3c,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x3e,0x20,0x78,0x5f,0x36,
0x36,0x20,0x3a,0x20,0x76,0x73,0x5f,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x3b,0x0a,
0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x69,0x6e,
0x5f,0x71,0x75,0x61,0x64,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x3b,0x0a,0x0a,
0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x67,0x6c,0x5f,
0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,
0x3b,0x0a,0x0a,0x66,0x6e,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x69,0x31,0x5f,0x28,
0x69,0x20,0x3a,0x20,0x70,0x74,0x72,0x3c,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,
0x2c,0x20,0x69,0x33,0x32,0x3e,0x29,0x20,0x2d,0x3e,0x20,0x76,0x65,0x63,0x33,0x66,
0x20,0x7b,0x0a,0x20,0x20,0x76,0x61,0x72,0x20,0x72,0x20,0x3a,0x20,0x66,0x33,0x32,
0x3b,0x0a,0x20,0x20,0x76,0x61,0x72,0x20,0x67,0x20,0x3a,0x20,0x66,0x33,0x32,0x3b,
0x0a,0x20,0x20,0x76,0x61,0x72,0x20,0x62,0x20,0x3a,0x20,0x66,0x33,0x32,0x3b,0x0a,
0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x31,0x36,0x20,0x3a,0x20,0x69,0x33,0x32,
0x20,0x3d,0x20,0x2a,0x28,0x69,0x29,0x3b,0x0a,0x20,0x20,0x72,0x20,0x3d,0x20,0x28,
0x66,0x33,0x32,0x28,0x28,0x28,0x78,0x5f,0x31,0x36,0x20,0x3e,0x3e,0x20,0x62,0x69,
0x74,0x63,0x61,0x73,0x74,0x3c,0x75,0x33,0x32,0x3e,0x28,0x30,0x69,0x29,0x29,0x20,
0x26,0x20,0x32,0x35,0x35,0x69,0x29,0x29,0x20,0x2f,0x20,0x32,0x35,0x35,0x2e,0x30,
0x66,0x29,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,0x35,0x20,0x3a,
0x20,0x69,0x33,0x32,0x20,0x3d,0x20,0x2a,0x28,0x69,0x29,0x3b,0x0a,0x20,0x20,0x67,
0x20,0x3d,0x20,0x28,0x66,0x33,0x32,0x28,0x28,0x28,0x78,0x5f,0x32,0x35,0x20,0x3e,
0x3e,0x20,0x62,0x69,0x74,0x63,0x61,0x73,0x74,0x3c,0x75,0x33,0x32,0x3e,0x28,0x38,
0x69,0x29,0x29,0x20,0x26,0x20,0x32,0x35,0x35,0x69,0x29,0x29,0x20,0x2f,0x20,0x32,
0x35,0x35,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,
0x33,0x32,0x20,0x3a,0x20,0x69,0x33,0x32,0x20,0x3d,0x20,0x2a,0x28,0x69,0x29,0x3b,
0x0a,0x20,0x20,0x62,0x20,0x3d,0x20,0x28,0x66,0x33,0x32,0x28,0x28,0x28,0x78,0x5f,
0x33,0x32,0x20,0x3e,0x3e,0x20,0x62,0x69,0x74,0x63,0x61,0x73,0x74,0x3c,0x75,0x33,
0x32,0x3e,0x28,0x31,0x36,0x69,0x29,0x29,0x20,0x26,0x20,0x32,0x35,0x35,0x69,0x29,
0x29,0x20,0x2f,0x20,0x32,0x35,0x35,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x20,0x20,0x6c,
0x65,0x74,0x20,0x78,0x5f,0x33,0x38,0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,
0x72,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x33,0x39,0x20,0x3a,0x20,
0x66,0x33,0x32,0x20,0x3d,0x20,0x67,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,
0x5f,0x34,0x30,0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,0x62,0x3b,0x0a,0x20,
0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x76,0x65,0x63,0x33,0x66,0x28,0x78,0x5f,
0x33,0x38,0x2c,0x20,0x78,0x5f,0x33,0x39,0x2c,0x20,0x78,0x5f,0x34,0x30,0x29,0x3b,
0x0a,0x7d,0x0a,0x0a,0x66,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,0x20,
0x7b,0x0a,0x20,0x20,0x76,0x61,0x72,0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,
0x69,0x33,0x32,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x35,0x34,0x20,
0x3a,0x20,0x69,0x33,0x32,0x20,0x3d,0x20,0x67,0x6c,0x5f,0x49,0x6e,0x73,0x74,0x61,
0x6e,0x63,0x65,0x49,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,
0x78,0x5f,0x35,0x37,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,0x78,
0x5f,0x35,0x31,0x2e,0x63,0x65,0x6c,0x6c,0x73,0x5b,0x78,0x5f,0x35,0x34,0x5d,0x2e,
0x70,0x6f,0x73,0x3b,0x0a,0x20,0x20,0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,
0x64,0x20,0x3d,0x20,0x78,0x5f,0x35,0x37,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,
0x78,0x5f,0x36,0x31,0x20,0x3a,0x20,0x69,0x33,0x32,0x20,0x3d,0x20,0x67,0x6c,0x5f,
0x49,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x49,0x6e,0x64,0x65,0x78,0x3b,0x0a,0x20,
0x20,0x70,0x61,0x72,0x61,0x6d,0x20,0x3d,0x20,0x78,0x5f,0x36,0x31,0x3b,0x0a,0x20,
0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x36,0x32,0x20,0x3a,0x20,0x76,0x65,0x63,0x33,
0x66,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x69,0x31,0x5f,0x28,0x26,0x28,
0x70,0x61,0x72,0x61,0x6d,0x29,0x29,0x3b,0x0a,0x20,0x20,0x78,0x5f,0x63,0x6f,0x6c,
0x6f,0x72,0x20,0x3d,0x20,0x78,0x5f,0x36,0x32,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,
0x20,0x78,0x5f,0x36,0x39,0x20,0x3a,0x20,0x66,0x33,0x32,0x20,0x3d,0x20,0x78,0x5f,
0x36,0x36,0x2e,0x72,0x61,0x64,0x69,0x75,0x73,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,
0x20,0x78,0x5f,0x37,0x32,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,
0x69,0x6e,0x5f,0x71,0x75,0x61,0x64,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,
0x5f,0x37,0x34,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,0x78,0x5f,
0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x3b,0x0a,0x20,0x20,0x78,0x5f,0x71,0x75,
0x61,0x64,0x20,0x3d,0x20,0x28,0x28,0x78,0x5f,0x37,0x32,0x20,0x2a,0x20,0x78,0x5f,
0x36,0x39,0x29,0x20,0x2b,0x20,0x78,0x5f,0x37,0x34,0x29,0x3b,0x0a,0x20,0x20,0x6c,
0x65,0x74,0x20,0x78,0x5f,0x38,0x33,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,
0x3d,0x20,0x78,0x5f,0x71,0x75,0x61,0x64,0x3b,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x50,
0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x76,0x65,0x63,0x34,0x66,0x28,
0x78,0x5f,0x38,0x33,0x2e,0x78,0x2c,0x20,0x78,0x5f,0x38,0x33,0x2e,0x79,0x2c,0x20,
0x30,0x2e,0x30,0x66,0x2c,0x20,0x31,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x20,0x20,0x72,
0x65,0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,
0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x40,0x6c,
0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x32,0x29,0x0a,0x20,0x20,0x78,0x5f,0x63,
0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x5f,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,
0x66,0x2c,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x33,
0x29,0x20,0x40,0x69,0x6e,0x74,0x65,0x72,0x70,0x6f,0x6c,0x61,0x74,0x65,0x28,0x66,
0x6c,0x61,0x74,0x29,0x0a,0x20,0x20,0x78,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x31,
0x20,0x3a,0x20,0x76,0x65,0x63,0x33,0x66,0x2c,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,
0x61,0x74,0x69,0x6f,0x6e,0x28,0x31,0x29,0x0a,0x20,0x20,0x78,0x5f,0x71,0x75,0x61,
0x64,0x5f,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x0a,0x20,0x20,0x40,
0x62,0x75,0x69,0x6c,0x74,0x69,0x6e,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,
0x29,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,
0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x2c,0x0a,0x7d,0x0a,0x0a,0x40,0x76,0x65,0x72,
0x74,0x65,0x78,0x0a,0x66,0x6e,0x20,0x6d,0x61,0x69,0x6e,0x28,0x40,0x62,0x75,0x69,
0x6c,0x74,0x69,0x6e,0x28,0x69,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,0x5f,0x69,0x6e,
0x64,0x65,0x78,0x29,0x20,0x67,0x6c,0x5f,0x49,0x6e,0x73,0x74,0x61,0x6e,0x63,0x65,
0x49,0x6e,0x64,0x65,0x78,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x75,0x33,
0x32,0x2c,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x30,0x29,0x20,
0x69,0x6e,0x5f,0x71,0x75,0x61,0x64,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,
0x76,0x65,0x63,0x32,0x66,0x29,0x20,0x2d,0x3e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,
0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x49,0x6e,0x73,0x74,0x61,0x6e,
0x63,0x65,0x49,0x6e,0x64,0x65,0x78,0x20,0x3d,0x20,0x62,0x69,0x74,0x63,0x61,0x73,
0x74,0x3c,0x69,0x33,0x32,0x3e,0x28,0x67,0x6c,0x5f,0x49,0x6e,0x73,0x74,0x61,0x6e,
0x63,0x65,0x49,0x6e,0x64,0x65,0x78,0x5f,0x70,0x61,0x72,0x61,0x6d,0x29,0x3b,0x0a,
0x20,0x20,0x69,0x6e,0x5f,0x71,0x75,0x61,0x64,0x20,0x3d,0x20,0x69,0x6e,0x5f,0x71,
0x75,0x61,0x64,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x6d,0x61,0x69,
0x6e,0x5f,0x31,0x28,0x29,0x3b,0x0a,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,
0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x28,0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,
0x6f,0x69,0x64,0x2c,0x20,0x78,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x2c,0x20,0x78,0x5f,
0x71,0x75,0x61,0x64,0x2c,0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,
0x6e,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
};
#endif
/*
diagnostic(off, derivative_uniformity);
struct fs_uniform {
/_ @offset(0) _/
radius : f32,
}
var<private> gl_FragDepth : f32;
var<private> x_quad : vec2f;
var<private> x_centroid : vec2f;
@group(0) @binding(8) var<uniform> x_20 : fs_uniform;
var<private> frag_color : vec4f;
var<private> x_color : vec3f;
fn main_1() {
let x_12 : vec2f = x_quad;
let x_14 : vec2f = x_centroid;
gl_FragDepth = length((x_12 - x_14));
let x_17 : f32 = gl_FragDepth;
let x_25 : f32 = x_20.radius;
if ((x_17 > x_25)) {
discard;
}
let x_37 : vec3f = x_color;
frag_color = vec4f(x_37.x, x_37.y, x_37.z, 1.0f);
return;
}
struct main_out {
@builtin(frag_depth)
gl_FragDepth_1 : f32,
@location(0)
frag_color_1 : vec4f,
}
@fragment
fn main(@location(1) x_quad_param : vec2f, @location(2) x_centroid_param : vec2f, @location(3) @interpolate(flat) x_color_param : vec3f) -> main_out {
x_quad = x_quad_param;
x_centroid = x_centroid_param;
x_color = x_color_param;
main_1();
return main_out(gl_FragDepth, frag_color);
}
*/
#if defined(SOKOL_WGPU)
static const uint8_t fs_source_wgsl[1047] = {
0x64,0x69,0x61,0x67,0x6e,0x6f,0x73,0x74,0x69,0x63,0x28,0x6f,0x66,0x66,0x2c,0x20,
0x64,0x65,0x72,0x69,0x76,0x61,0x74,0x69,0x76,0x65,0x5f,0x75,0x6e,0x69,0x66,0x6f,
0x72,0x6d,0x69,0x74,0x79,0x29,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
0x66,0x73,0x5f,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x7b,0x0a,0x20,0x20,0x2f,
0x2a,0x20,0x40,0x6f,0x66,0x66,0x73,0x65,0x74,0x28,0x30,0x29,0x20,0x2a,0x2f,0x0a,
0x20,0x20,0x72,0x61,0x64,0x69,0x75,0x73,0x20,0x3a,0x20,0x66,0x33,0x32,0x2c,0x0a,
0x7d,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,
0x67,0x6c,0x5f,0x46,0x72,0x61,0x67,0x44,0x65,0x70,0x74,0x68,0x20,0x3a,0x20,0x66,
0x33,0x32,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,
0x3e,0x20,0x78,0x5f,0x71,0x75,0x61,0x64,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,
0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,
0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x20,0x3a,0x20,0x76,0x65,0x63,
0x32,0x66,0x3b,0x0a,0x0a,0x40,0x67,0x72,0x6f,0x75,0x70,0x28,0x30,0x29,0x20,0x40,
0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x28,0x38,0x29,0x20,0x76,0x61,0x72,0x3c,0x75,
0x6e,0x69,0x66,0x6f,0x72,0x6d,0x3e,0x20,0x78,0x5f,0x32,0x30,0x20,0x3a,0x20,0x66,
0x73,0x5f,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x3c,
0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,
0x6c,0x6f,0x72,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x3b,0x0a,0x0a,0x76,0x61,
0x72,0x3c,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x3e,0x20,0x78,0x5f,0x63,0x6f,0x6c,
0x6f,0x72,0x20,0x3a,0x20,0x76,0x65,0x63,0x33,0x66,0x3b,0x0a,0x0a,0x66,0x6e,0x20,
0x6d,0x61,0x69,0x6e,0x5f,0x31,0x28,0x29,0x20,0x7b,0x0a,0x20,0x20,0x6c,0x65,0x74,
0x20,0x78,0x5f,0x31,0x32,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,
0x78,0x5f,0x71,0x75,0x61,0x64,0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,
0x31,0x34,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x20,0x3d,0x20,0x78,0x5f,0x63,
0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x3b,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x46,0x72,
0x61,0x67,0x44,0x65,0x70,0x74,0x68,0x20,0x3d,0x20,0x6c,0x65,0x6e,0x67,0x74,0x68,
0x28,0x28,0x78,0x5f,0x31,0x32,0x20,0x2d,0x20,0x78,0x5f,0x31,0x34,0x29,0x29,0x3b,
0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x31,0x37,0x20,0x3a,0x20,0x66,0x33,
0x32,0x20,0x3d,0x20,0x67,0x6c,0x5f,0x46,0x72,0x61,0x67,0x44,0x65,0x70,0x74,0x68,
0x3b,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,0x78,0x5f,0x32,0x35,0x20,0x3a,0x20,0x66,
0x33,0x32,0x20,0x3d,0x20,0x78,0x5f,0x32,0x30,0x2e,0x72,0x61,0x64,0x69,0x75,0x73,
0x3b,0x0a,0x20,0x20,0x69,0x66,0x20,0x28,0x28,0x78,0x5f,0x31,0x37,0x20,0x3e,0x20,
0x78,0x5f,0x32,0x35,0x29,0x29,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x64,0x69,0x73,
0x63,0x61,0x72,0x64,0x3b,0x0a,0x20,0x20,0x7d,0x0a,0x20,0x20,0x6c,0x65,0x74,0x20,
0x78,0x5f,0x33,0x37,0x20,0x3a,0x20,0x76,0x65,0x63,0x33,0x66,0x20,0x3d,0x20,0x78,
0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,
0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x76,0x65,0x63,0x34,0x66,0x28,0x78,0x5f,0x33,
0x37,0x2e,0x78,0x2c,0x20,0x78,0x5f,0x33,0x37,0x2e,0x79,0x2c,0x20,0x78,0x5f,0x33,
0x37,0x2e,0x7a,0x2c,0x20,0x31,0x2e,0x30,0x66,0x29,0x3b,0x0a,0x20,0x20,0x72,0x65,
0x74,0x75,0x72,0x6e,0x3b,0x0a,0x7d,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,
0x6d,0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x40,0x62,0x75,
0x69,0x6c,0x74,0x69,0x6e,0x28,0x66,0x72,0x61,0x67,0x5f,0x64,0x65,0x70,0x74,0x68,
0x29,0x0a,0x20,0x20,0x67,0x6c,0x5f,0x46,0x72,0x61,0x67,0x44,0x65,0x70,0x74,0x68,
0x5f,0x31,0x20,0x3a,0x20,0x66,0x33,0x32,0x2c,0x0a,0x20,0x20,0x40,0x6c,0x6f,0x63,
0x61,0x74,0x69,0x6f,0x6e,0x28,0x30,0x29,0x0a,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,
0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x31,0x20,0x3a,0x20,0x76,0x65,0x63,0x34,0x66,0x2c,
0x0a,0x7d,0x0a,0x0a,0x40,0x66,0x72,0x61,0x67,0x6d,0x65,0x6e,0x74,0x0a,0x66,0x6e,
0x20,0x6d,0x61,0x69,0x6e,0x28,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,
0x31,0x29,0x20,0x78,0x5f,0x71,0x75,0x61,0x64,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,
0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x20,0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,
0x6f,0x6e,0x28,0x32,0x29,0x20,0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,
0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,0x76,0x65,0x63,0x32,0x66,0x2c,0x20,
0x40,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x28,0x33,0x29,0x20,0x40,0x69,0x6e,
0x74,0x65,0x72,0x70,0x6f,0x6c,0x61,0x74,0x65,0x28,0x66,0x6c,0x61,0x74,0x29,0x20,
0x78,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x5f,0x70,0x61,0x72,0x61,0x6d,0x20,0x3a,0x20,
0x76,0x65,0x63,0x33,0x66,0x29,0x20,0x2d,0x3e,0x20,0x6d,0x61,0x69,0x6e,0x5f,0x6f,
0x75,0x74,0x20,0x7b,0x0a,0x20,0x20,0x78,0x5f,0x71,0x75,0x61,0x64,0x20,0x3d,0x20,
0x78,0x5f,0x71,0x75,0x61,0x64,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,
0x78,0x5f,0x63,0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x20,0x3d,0x20,0x78,0x5f,0x63,
0x65,0x6e,0x74,0x72,0x6f,0x69,0x64,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,
0x20,0x78,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x78,0x5f,0x63,0x6f,0x6c,
0x6f,0x72,0x5f,0x70,0x61,0x72,0x61,0x6d,0x3b,0x0a,0x20,0x20,0x6d,0x61,0x69,0x6e,
0x5f,0x31,0x28,0x29,0x3b,0x0a,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6d,
0x61,0x69,0x6e,0x5f,0x6f,0x75,0x74,0x28,0x67,0x6c,0x5f,0x46,0x72,0x61,0x67,0x44,
0x65,0x70,0x74,0x68,0x2c,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,
0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00,
};
#endif
static inline const sg_shader_desc* base_shader_desc(sg_backend backend) {
#if defined(SOKOL_WGPU)
if (backend == SG_BACKEND_WGPU) {
static sg_shader_desc desc;
static bool valid;
if (!valid) {
valid = true;
desc.vertex_func.source = (const char*)vs_source_wgsl;
desc.vertex_func.entry = "main";
desc.fragment_func.source = (const char*)fs_source_wgsl;
desc.fragment_func.entry = "main";
desc.attrs[0].base_type = SG_SHADERATTRBASETYPE_FLOAT;
desc.uniform_blocks[0].stage = SG_SHADERSTAGE_VERTEX;
desc.uniform_blocks[0].layout = SG_UNIFORMLAYOUT_STD140;
desc.uniform_blocks[0].size = 16;
desc.uniform_blocks[0].wgsl_group0_binding_n = 0;
desc.uniform_blocks[1].stage = SG_SHADERSTAGE_FRAGMENT;
desc.uniform_blocks[1].layout = SG_UNIFORMLAYOUT_STD140;
desc.uniform_blocks[1].size = 16;
desc.uniform_blocks[1].wgsl_group0_binding_n = 8;
desc.storage_buffers[0].stage = SG_SHADERSTAGE_VERTEX;
desc.storage_buffers[0].readonly = true;
desc.storage_buffers[0].wgsl_group1_binding_n = 32;
desc.label = "base_shader";
}
return &desc;
}
#endif /* SOKOL_WGPU */
return 0;
}

View File

@ -1,102 +1,144 @@
unsigned char src_shaders_sprite_wgsl[] = { unsigned char src_shaders_sprite_wgsl[] = {
0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x43, 0x65, 0x6c, 0x6c, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x53, 0x70, 0x72, 0x69, 0x74,
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x72, 0x69, 0x78, 0x3a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x66,
0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63,
0x56, 0x73, 0x49, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x56, 0x65, 0x72, 0x74, 0x74, 0x20, 0x56, 0x73, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20,
0x65, 0x78, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x76, 0x70, 0x3a, 0x20,
0x70, 0x75, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b,
0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x73, 0x49,
0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20,
0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74,
0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f,
0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61,
0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20,
0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x56, 0x65, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x74, 0x6f, 0x20, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28,
0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f, 0x73, 0x31, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63,
0x76, 0x65, 0x63, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x7b, 0x20, 0x2f, 0x2f,
0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65,
0x20, 0x40, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e,
0x65, 0x28, 0x66, 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x0d, 0x0a, 0x20, 0x20,
0x61, 0x6e, 0x63, 0x65, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70,
0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73,
0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28,
0x30, 0x29, 0x20, 0x40, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c,
0x61, 0x74, 0x65, 0x28, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x29, 0x20,
0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x0d, 0x0a,
0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x46, 0x7d, 0x3b, 0x0d, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x46,
0x73, 0x4f, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x73, 0x4f, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x46, 0x72, 0x61, 0x67, 0x6d,
0x65, 0x6e, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f, 0x65, 0x6e, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x75, 0x74, 0x70, 0x75, 0x74, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40,
0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x66, 0x72, 0x61, 0x67, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20,
0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x29, 0x20, 0x64, 0x65, 0x70, 0x74, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66,
0x68, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x62, 0x69,
0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72,
0x29, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75,
0x34, 0x66, 0x2c, 0x0d, 0x0a, 0x7d, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x20, 0x76, 0x73, 0x5f, 0x75,
0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x69, 0x3a, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x3a, 0x20, 0x56, 0x73, 0x55,
0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x66, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3b, 0x0d, 0x0a, 0x40, 0x62, 0x69,
0x0d, 0x0a, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72,
0x20, 0x72, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x66, 0x33, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74,
0x32, 0x28, 0x28, 0x28, 0x69, 0x20, 0x3e, 0x3e, 0x20, 0x20, 0x30, 0x29, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f,
0x20, 0x26, 0x20, 0x30, 0x78, 0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0d, 0x0a, 0x40, 0x62,
0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x67, 0x3a, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x29, 0x20, 0x40, 0x67,
0x33, 0x32, 0x20, 0x3d, 0x20, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20,
0x73, 0x61, 0x6d, 0x70, 0x3a, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65,
0x72, 0x3b, 0x0d, 0x0a, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67,
0x28, 0x32, 0x29, 0x20, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x31,
0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
0x65, 0x3e, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x3a, 0x20,
0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x53, 0x70, 0x72, 0x69, 0x74, 0x65,
0x3e, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, 0x65,
0x78, 0x20, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e,
0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x49, 0x29,
0x20, 0x2d, 0x3e, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x7b, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x3b, 0x0d,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f,
0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20,
0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x2c, 0x20,
0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x2e, 0x79, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x20,
0x2a, 0x20, 0x73, 0x70, 0x72, 0x69, 0x74, 0x65, 0x73, 0x5b, 0x69, 0x6e,
0x70, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65,
0x5d, 0x2e, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x76,
0x73, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x2e, 0x6d,
0x76, 0x70, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x2e, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x2e, 0x75, 0x76, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74,
0x70, 0x75, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f,
0x2f, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x20, 0x61, 0x20,
0x33, 0x32, 0x62, 0x69, 0x74, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x20, 0x63,
0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x28, 0x68, 0x65, 0x78, 0x20, 0x72, 0x65,
0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x29, 0x20, 0x69, 0x6e, 0x74, 0x6f, 0x20, 0x61, 0x20, 0x6e, 0x6f, 0x72,
0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x76, 0x65, 0x63, 0x34,
0x66, 0x0d, 0x0a, 0x2f, 0x2a, 0x66, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x76,
0x65, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x28, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20,
0x76, 0x65, 0x63, 0x34, 0x66, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20,
0x3d, 0x20, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75,
0x74, 0x20, 0x3e, 0x3e, 0x20, 0x20, 0x30, 0x29, 0x20, 0x26, 0x20, 0x30,
0x78, 0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x6c, 0x65, 0x74, 0x20, 0x67, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d,
0x20, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74,
0x20, 0x3e, 0x3e, 0x20, 0x20, 0x38, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x20, 0x3e, 0x3e, 0x20, 0x20, 0x38, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78,
0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x66, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
0x65, 0x74, 0x20, 0x62, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x65, 0x74, 0x20, 0x62, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20,
0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x20, 0x3e, 0x3e, 0x20, 0x31, 0x66, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20,
0x36, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x66, 0x66, 0x29, 0x29, 0x3b, 0x3e, 0x3e, 0x20, 0x31, 0x36, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x66,
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x66, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65,
0x20, 0x76, 0x65, 0x63, 0x33, 0x66, 0x28, 0x72, 0x20, 0x2f, 0x20, 0x32, 0x74, 0x20, 0x61, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x66,
0x35, 0x35, 0x2c, 0x20, 0x67, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x33, 0x32, 0x28, 0x28, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x3e,
0x20, 0x62, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x29, 0x3b, 0x0d, 0x0a, 0x3e, 0x20, 0x32, 0x34, 0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x66, 0x66,
0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x2f, 0x2f, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x29, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72,
0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28,
0x70, 0x28, 0x30, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, 0x69, 0x72, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x67, 0x20, 0x2f,
0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x20, 0x6d, 0x76, 0x70, 0x3a, 0x20, 0x6d, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x62, 0x20, 0x2f, 0x20, 0x32, 0x35,
0x61, 0x74, 0x34, 0x78, 0x34, 0x66, 0x3b, 0x0d, 0x0a, 0x40, 0x62, 0x69, 0x35, 0x2c, 0x20, 0x61, 0x20, 0x2f, 0x20, 0x32, 0x35, 0x35, 0x29, 0x3b,
0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x29, 0x20, 0x40, 0x67, 0x72, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x47, 0x65,
0x6f, 0x75, 0x70, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72,
0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3e, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x65, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x20, 0x69, 0x6e, 0x64, 0x65,
0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x43, 0x65, 0x6c, 0x78, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55,
0x6c, 0x3e, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, 0x56, 0x0d, 0x0a, 0x2f, 0x2a, 0x66, 0x6e, 0x20, 0x69, 0x6e, 0x64, 0x65,
0x65, 0x78, 0x0d, 0x0a, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x6f, 0x6d, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x28, 0x75,
0x69, 0x6e, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, 0x66, 0x2c, 0x20, 0x77, 0x69,
0x49, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x20, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x20, 0x68, 0x65,
0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d,
0x75, 0x74, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x3e, 0x20, 0x75, 0x33, 0x32, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20,
0x70, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x3d, 0x20, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f,
0x63, 0x34, 0x66, 0x28, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5b, 0x69, 0x6e, 0x72, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64,
0x70, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x74, 0x68, 0x29, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74,
0x5d, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x78, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74,
0x79, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x20, 0x79, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x20, 0x3d, 0x20, 0x63, 0x6c,
0x2f, 0x2a, 0x20, 0x2a, 0x20, 0x6d, 0x76, 0x70, 0x2a, 0x2f, 0x3b, 0x0d, 0x61, 0x6d, 0x70, 0x28, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x75, 0x76,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29,
0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x69, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29,
0x6e, 0x70, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x65, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x6e, 0x20, 0x79, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x2b, 0x20, 0x78, 0x3b, 0x0d, 0x0a, 0x7d, 0x2a, 0x2f, 0x0d, 0x0a, 0x0d,
0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x66,
0x6d, 0x65, 0x6e, 0x74, 0x0d, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e,
0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20,
0x56, 0x73, 0x32, 0x46, 0x73, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x46, 0x73, 0x2d, 0x3e, 0x20, 0x46, 0x73, 0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
0x4f, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3a, 0x20, 0x46, 0x73, 0x4f, 0x3a, 0x20, 0x46, 0x73, 0x4f, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c,
0x70, 0x75, 0x74, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65,
0x31, 0x2e, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x78, 0x2c, 0x20,
0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x73, 0x61, 0x6d, 0x70, 0x2c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e,
0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x75, 0x76, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75,
0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x6f, 0x74, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a
0x75, 0x74, 0x70, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20,
0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x66, 0x28, 0x63, 0x6f, 0x6c, 0x6f,
0x72, 0x28, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74,
0x61, 0x6e, 0x63, 0x65, 0x29, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b,
0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0d, 0x0a,
0x7d, 0x0d, 0x0a
}; };
unsigned int src_shaders_sprite_wgsl_len = 1179; unsigned int src_shaders_sprite_wgsl_len = 1687;

View File

@ -1,29 +1,38 @@
// This is an example on how to set up and use Sokol GP to draw a filled rectangle. #include "api.h"
// Includes Sokol GFX, Sokol GP and Sokol APP, doing all implementations.
#define SOKOL_IMPL
#define SOKOL_WGPU
#include "sokol_gfx.h"
#include "sokol_gp.h"
#include "sokol_app.h"
#include "sokol_glue.h"
#include "sokol_log.h"
#include "util/sokol_memtrack.h"
#include "math.h"
#include "rand.h"
#include "generated/sprite.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#define ALLOC(arg) smemtrack_alloc(arg, NULL) #define ALLOC(arg) smemtrack_alloc(arg, NULL)
#define FREE(arg) smemtrack_free(arg, NULL) #define FREE(arg) smemtrack_free(arg, NULL)
#define SAMPLE_COUNT 100000 #define GRID_X 1000
#define GRID_Y 1000
typedef struct vs_uniform_t {
mat4x4f mvp;
} uniform_t;
typedef struct renderer_t {
sg_pipeline pipeline; //Configured sprite pipeline
sg_pass_action clear_pass; //Render pass - Clear screen
uniform_t uniform; //Uniform data
} renderer_t;
typedef struct manager_t {
vector_t textures;
} manager_t;
typedef struct dragger_t {
bool dragging;
float origin_x, origin_y;
} dragger_t;
typedef struct userdata_t {
int width, height;
vec2f pan;
float zoom;
dragger_t dragger;
renderer_t renderer;
manager_t manager;
} userdata_t;
void js_log(int severity, const char* format, ...) void js_log(int severity, const char* format, ...)
{ {
@ -37,72 +46,74 @@ void js_log(int severity, const char* format, ...)
va_end(va); va_end(va);
slog_js_log(severity, buffer); slog_js_log(severity, buffer);
} }
void compute_mvp(Mat4 *ptr, Vec2 pan, float zoom) void compute_mvp(userdata_t *userdata)
{ {
const int width = sapp_width(), height = sapp_height(); userdata->renderer.uniform.mvp.e[0][0] = (2.0f / userdata->width) * userdata->zoom;
userdata->renderer.uniform.mvp.e[1][1] = (2.0f / userdata->height) * userdata->zoom;
ptr->Elements[0][0] = (2.0f * zoom)/width; userdata->renderer.uniform.mvp.e[0][3] = (2.0f / userdata->width) * userdata->pan.x;
ptr->Elements[0][1] = 0.0f; userdata->renderer.uniform.mvp.e[1][3] = (2.0f / userdata->height) * userdata->pan.y;
ptr->Elements[0][2] = 0.0f;
ptr->Elements[0][3] = 0.0f;
ptr->Elements[1][0] = 0.0f;
ptr->Elements[1][1] = (2.0f * zoom)/height;
ptr->Elements[1][2] = 0.0f;
ptr->Elements[1][3] = 0.0f;
ptr->Elements[2][0] = 0.0f;
ptr->Elements[2][1] = 0.0f;
ptr->Elements[2][2] = 1.0f;
ptr->Elements[2][3] = 0.0f;
ptr->Elements[3][0] = (-2.0f * pan.X * zoom)/width - 1.0f;
ptr->Elements[3][1] = (-2.0f * pan.Y * zoom)/height - 1.0f;
ptr->Elements[3][2] = 0.0f;
ptr->Elements[3][3] = 0.0f;
} }
typedef struct renderer_t {
sg_pipeline pipeline;
sg_pipeline compute;
sg_bindings binding;
sg_range uniform;
sg_pass_action pass;
sg_shader sprite_shader;
} renderer_t;
typedef struct userdata_t {
Vec2 pan;
float zoom;
renderer_t renderer;
Mat4 *mvp;
} userdata_t;
// Called on every frame of the application.
static void frame(void* _userdata) static void frame(void* _userdata)
{ {
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
simgui_new_frame(&(simgui_frame_desc_t){
.width = userdata->width,
.height = userdata->height,
.delta_time = sapp_frame_duration(),
.dpi_scale = 1.0f,
});
igSetNextWindowPos((ImVec2){20,20}, ImGuiCond_Once);
igSetNextWindowSize((ImVec2){600,200}, ImGuiCond_Once);
if (igBegin("Menu", 0, ImGuiWindowFlags_NoResize)) {
igText("Frame duration: %.4fms", sapp_frame_duration() * 1000.0);
igText("Zoom: %.3f", userdata->zoom);
igText("Pan: %.3f/%.3f", userdata->pan.x, userdata->pan.y);
}
igEnd();
sg_begin_pass(&(sg_pass){ sg_begin_pass(&(sg_pass){
.action = userdata->renderer.pass, .action = userdata->renderer.clear_pass,
.swapchain = sglue_swapchain(), .swapchain = sglue_swapchain(),
}); });
sg_apply_pipeline(userdata->renderer.pipeline); const uint32_t length = vector_length(&userdata->manager.textures);
sg_apply_bindings(&userdata->renderer.binding); if(length > 0)
//sg_apply_uniforms(0, &userdata->renderer.uniform); {
sg_apply_pipeline(userdata->renderer.pipeline);
sg_draw(0, 4, SAMPLE_COUNT); for(uint32_t i = 0; i < length; i++)
{
texture_t* texture = (texture_t*) vector_get(&userdata->manager.textures, i);
if(texture->dirty)
{
const sg_range range = vector_range(&texture->sprites);
sg_update_buffer(texture->binding.storage_buffers[0], &range);
texture->dirty = false;
}
sg_apply_bindings(&texture->binding);
sg_apply_uniforms(0, &SG_RANGE(userdata->renderer.uniform));
sg_draw(0, 6, vector_length(&texture->sprites));
}
}
simgui_render();
sg_end_pass(); sg_end_pass();
sg_commit(); sg_commit();
} }
// Called when the application is initializing.
static void init(void* _userdata) static void init(void* _userdata)
{ {
rand_seed(1); rand_seed(1);
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
// Initialize Sokol GFX.
sg_desc sgdesc = { sg_desc sgdesc = {
.environment = sglue_environment(), .environment = sglue_environment(),
.logger.func = slog_func, .logger.func = slog_func,
@ -113,46 +124,81 @@ static void init(void* _userdata)
exit(-1); exit(-1);
} }
const Vec2 quad[4] = { const vec2f quad[4] = {
{0.0f, 1.0f}, // bottom left {-2.0f, 2.0f}, // bottom left
{1.0f, 1.0f}, // bottom right {2.0f, 2.0f}, // bottom right
{1.0f, 0.0f}, // top right {2.0f, -2.0f}, // top right
{0.0f, 0.0f}, // top left {-2.0f, -2.0f}, // top left
}; };
const uint16_t indices[] = { const uint16_t indices[] = {
0, 1, 2, 0, 2, 3, 0, 1, 2, 0, 2, 3,
}; };
userdata->width = sapp_width();
userdata->height = sapp_height();
userdata->pan = (vec2f) { 0.0f, 0.0f };
userdata->zoom = 2;
Mat4 mvp = M4(); vec2f* tmp_buffer = malloc(sizeof(vec2f) * GRID_X * GRID_Y);
compute_mvp(&mvp, V2(0, 0), 1);
Vec2* tmp_buffer = malloc(sizeof(Vec2) * SAMPLE_COUNT); uint32_t i = 0;
for(uint32_t x = 0; x < GRID_X; x++)
for(uint32_t i = 0; i < SAMPLE_COUNT; i++)
{ {
tmp_buffer[i].X = next_float(); for(uint32_t y = 0; y < GRID_Y; y++)
tmp_buffer[i].Y = next_float(); {
const float angle = next_float_max(PI), radius = next_float_max(0.5f);
tmp_buffer[i].x = x + sin(angle) * radius - GRID_X / 2.0f;
tmp_buffer[i].y = y + cos(angle) * radius - GRID_Y / 2.0f;
i++;
}
} }
sg_shader sprite_shader = sg_make_shader(&(sg_shader_desc) { sg_shader sprite_shader = sg_make_shader(&(sg_shader_desc) {
.vertex_func = { .vertex_func = {
.source = src_shaders_sprite_wgsl, .source = (const char*) src_shaders_sprite_wgsl,
.entry = "vs_main", .entry = "vs_main",
}, },
.fragment_func = { .fragment_func = {
.source = src_shaders_sprite_wgsl, .source = (const char*) src_shaders_sprite_wgsl,
.entry = "fs_main", .entry = "fs_main",
}, },
.storage_buffers[0] = { .images = {
.wgsl_group1_binding_n = 0, [0] = {
.stage = SG_SHADERSTAGE_VERTEX, .stage = SG_SHADERSTAGE_FRAGMENT,
.readonly = true, .image_type = SG_IMAGETYPE_2D,
.wgsl_group1_binding_n = 0,
.sample_type = SG_IMAGESAMPLETYPE_FLOAT,
},
},
.samplers = {
[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.sampler_type = SG_SAMPLERTYPE_FILTERING,
.wgsl_group1_binding_n = 1,
}
},
.image_sampler_pairs = {
[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.image_slot = 0,
.sampler_slot = 0,
}
},
.storage_buffers = {
[0] = {
.wgsl_group1_binding_n = 2,
.stage = SG_SHADERSTAGE_VERTEX,
.readonly = true,
},
},
.uniform_blocks = {
[0] = {
.size = sizeof(uniform_t),
.stage = SG_SHADERSTAGE_VERTEX,
.wgsl_group0_binding_n = 0,
},
}, },
/*.uniform_blocks[0] = {
.size = sizeof(float) * 16, //mat4x4f
.stage = SG_SHADERSTAGE_VERTEX,
.wgsl_group0_binding_n = 0,
},*/
.attrs[0] = { .attrs[0] = {
.base_type = SG_SHADERATTRBASETYPE_FLOAT, .base_type = SG_SHADERATTRBASETYPE_FLOAT,
}, },
@ -160,97 +206,103 @@ static void init(void* _userdata)
}); });
userdata->renderer = (renderer_t) { userdata->renderer = (renderer_t) {
.pass = (sg_pass_action) { .clear_pass = (sg_pass_action) {
.colors[0] = { .clear_value = { 0.0f, 0.0f, 0.0f, 1.0f }, .load_action = SG_LOADACTION_CLEAR } .colors[0] = { .clear_value = { 1.0f, 1.0f, 1.0f, 1.0f }, .load_action = SG_LOADACTION_CLEAR }
}, },
.pipeline = sg_make_pipeline(&(sg_pipeline_desc) { .pipeline = sg_make_pipeline(&(sg_pipeline_desc) {
.shader = sprite_shader, .shader = sprite_shader,
.depth.write_enabled = true,
.index_type = SG_INDEXTYPE_UINT16, .index_type = SG_INDEXTYPE_UINT16,
.layout.attrs = { .layout.attrs = {
[0].format = SG_VERTEXFORMAT_FLOAT2, [0].format = SG_VERTEXFORMAT_FLOAT2,
}, },
.label = "Sprite pipeline", .label = "Sprite pipeline",
}), }),
/*.compute = sg_make_pipeline(&(sg_pipeline_desc) { .uniform = (uniform_t) {
.compute = true, .mvp = {
.shader = sg_make_shader(compute_shader_desc(sg_query_backend())), 1.0f, 0.0f, 0.0f, 0.0f,
}),*/ 0.0f, 1.0f, 0.0f, 0.0f,
.binding = (sg_bindings) { 0.0f, 0.0f, 1.0f, 0.0f,
.vertex_buffers = { 0.0f, 0.0f, 0.0f, 1.0f
[0] = sg_make_buffer(&(sg_buffer_desc) {
.type = SG_BUFFERTYPE_VERTEXBUFFER,
.data = SG_RANGE(quad),
.label = "Vertices"
}),
}, },
.index_buffer = sg_make_buffer(&(sg_buffer_desc) { }
.type = SG_BUFFERTYPE_INDEXBUFFER,
.data = SG_RANGE(indices),
.label = "Indices"
}),
.storage_buffers = {
[0] = sg_make_buffer(&(sg_buffer_desc) {
.type = SG_BUFFERTYPE_STORAGEBUFFER,
.data = {
.ptr = tmp_buffer,
.size = sizeof(Vec2) * SAMPLE_COUNT,
},
.label = "SSBO"
}),
},
},
.uniform = SG_RANGE(mvp),
}; };
userdata->pan = (Vec2) { .X = 0, .Y = 0 }; userdata->manager = (manager_t) {
userdata->zoom = 1; .textures = vector_create(sizeof(texture_t)),
userdata->mvp = &mvp; };
compute_mvp(userdata);
FREE(tmp_buffer); FREE(tmp_buffer);
simgui_setup(&(simgui_desc_t) {
.logger.func = slog_func,
.allocator = {
.alloc_fn = smemtrack_alloc,
.free_fn = smemtrack_free,
},
});
} }
// Called when the application is shutting down.
static void cleanup(void* _userdata) static void cleanup(void* _userdata)
{ {
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
vector_free(&userdata->manager.textures);
FREE(userdata); FREE(userdata);
smemtrack_info_t info = smemtrack_info(); simgui_shutdown();
js_log(3, "Leaks: %d. Amount: %db", info.num_allocs, info.num_bytes);
sg_shutdown(); sg_shutdown();
} }
static void event(const sapp_event* event, void* _userdata) static void event(const sapp_event* event, void* _userdata)
{ {
userdata_t* userdata = (userdata_t*) _userdata; userdata_t* userdata = (userdata_t*) _userdata;
if(simgui_handle_event(event))
return;
switch(event->type) switch(event->type)
{ {
case SAPP_EVENTTYPE_RESIZED:
userdata->width = sapp_width();
userdata->height = sapp_height();
compute_mvp(userdata);
break;
case SAPP_EVENTTYPE_MOUSE_DOWN: case SAPP_EVENTTYPE_MOUSE_DOWN:
if(event->modifiers & SAPP_MODIFIER_RMB)
{
userdata->dragger.dragging = true;
userdata->dragger.origin_x = event->mouse_x;
userdata->dragger.origin_y = event->mouse_y;
}
break; break;
case SAPP_EVENTTYPE_MOUSE_UP: case SAPP_EVENTTYPE_MOUSE_UP:
userdata->dragger.dragging = false;
break; break;
case SAPP_EVENTTYPE_MOUSE_MOVE: case SAPP_EVENTTYPE_MOUSE_MOVE:
if(userdata->dragger.dragging)
{
userdata->pan.x += event->mouse_dx;
userdata->pan.y -= event->mouse_dy;
compute_mvp(userdata);
}
break; break;
case SAPP_EVENTTYPE_MOUSE_SCROLL: case SAPP_EVENTTYPE_MOUSE_SCROLL:
if((userdata->zoom >= 3.0f && event->scroll_y > 0.0f) || (userdata->zoom <= 0.1f && event->scroll_y < 0.0f)) if((userdata->zoom >= 6.0f && event->scroll_y > 0.0f) || (userdata->zoom <= 0.1f && event->scroll_y < 0.0f))
return; return;
const float diff = expf(event->scroll_y * 0.01f); const float diff = expf(event->scroll_y * 0.01f);
const float width = sapp_widthf(), height = sapp_heightf(); userdata->zoom = _sg_clamp(userdata->zoom * diff, 0.1f, 6.0f);
userdata->pan.X = userdata->pan.X - (event->mouse_x / (diff * userdata->zoom) - event->mouse_x / userdata->zoom); compute_mvp(userdata);
userdata->pan.Y = userdata->pan.Y - (event->mouse_y / (diff * userdata->zoom) - event->mouse_y / userdata->zoom);
userdata->zoom = _sg_clamp(userdata->zoom * diff, 0.1f, 3.0f);
compute_mvp(userdata->mvp, userdata->pan, userdata->zoom);
js_log(3, "Zoom: %f. Pan: %f/%f", userdata->zoom, userdata->pan.X, userdata->pan.Y);
break; break;
default: default:
@ -258,7 +310,6 @@ static void event(const sapp_event* event, void* _userdata)
} }
} }
// Implement application main through Sokol APP.
sapp_desc sokol_main(int argc, char* argv[]) sapp_desc sokol_main(int argc, char* argv[])
{ {
userdata_t* userdata = (userdata_t*) ALLOC(sizeof(userdata_t)); userdata_t* userdata = (userdata_t*) ALLOC(sizeof(userdata_t));

3978
src/math.h

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,27 @@
uint32_t seed; #ifndef RAND_H
#define RAND_H
uint32_t xorshift32(void); #include "api.h"
void rand_seed(uint32_t _seed);
uint32_t next_int(void);
uint32_t next_int_max(uint32_t max);
uint32_t next_int_minmax(uint32_t min, uint32_t max);
float next_float(void);
float next_float_max(float_t max);
float next_float_minmax(float_t min, float_t max);
uint32_t xorshift32(void) static uint32_t seed;
static uint32_t xorshift32(void);
static void rand_seed(uint32_t _seed);
static uint32_t next_int(void);
static uint32_t next_int_max(uint32_t max);
static uint32_t next_int_minmax(uint32_t min, uint32_t max);
static float next_float(void);
static float next_float_max(float max);
static float next_float_minmax(float min, float max);
static uint32_t xorshift32(void)
{ {
seed ^= seed<<13; seed ^= seed<<13;
seed ^= seed>>17; seed ^= seed>>17;
seed ^= seed<<5; seed ^= seed<<5;
return seed; return seed;
} }
void rand_seed(uint32_t _seed) static void rand_seed(uint32_t _seed)
{ {
if(_seed == 0) if(_seed == 0)
return; return;
@ -25,35 +30,37 @@ void rand_seed(uint32_t _seed)
xorshift32(); xorshift32();
} }
// PRNG [0-UINT32_MAX] // PRNG [0-UINT32_MAX]
uint32_t next_int(void) static uint32_t next_int(void)
{ {
return xorshift32(); return xorshift32();
} }
// PRNG [0-max] // PRNG [0-max]
uint32_t next_int_max(uint32_t max) static uint32_t next_int_max(uint32_t max)
{ {
return (uint32_t) floorf(xorshift32() / (float) UINT32_MAX * max); return (uint32_t) floorf(xorshift32() / (float) UINT32_MAX * max);
} }
// PRNG [min-max] // PRNG [min-max]
uint32_t next_int_minmax(uint32_t min, uint32_t max) static uint32_t next_int_minmax(uint32_t min, uint32_t max)
{ {
const float x = xorshift32() / (float) UINT32_MAX; const float x = (float) xorshift32() / UINT32_MAX;
//(1.0f - Time) * A + Time * B //(1.0f - Time) * A + Time * B
return (1.0f - x) * min + x * max; return (1.0f - x) * min + x * max;
} }
// PRNG [0-1] // PRNG [0-1]
float next_float(void) static float next_float(void)
{ {
return xorshift32() / (float) UINT32_MAX; return (float) xorshift32() / UINT32_MAX;
} }
// PRNG [0-max] // PRNG [0-max]
float next_float_max(float_t max) static float next_float_max(float max)
{ {
return xorshift32() / (float) UINT32_MAX * max; return (float) xorshift32() / UINT32_MAX * max;
} }
// PRNG [min-max] // PRNG [min-max]
float next_float_minmax(float_t min, float_t max) static float next_float_minmax(float min, float max)
{ {
const float x = xorshift32() / (float) UINT32_MAX; const float x = (float) xorshift32() / UINT32_MAX;
return (1.0f - x) * min + x * max; return (1.0f - x) * min + x * max;
} }
#endif

View File

@ -1,61 +0,0 @@
@block common
@ctype vec2 position_t;
struct cell
{
vec2 pos;
};
vec3 color(int i)
{
float r = ((i >> 0) & 0xff)/255.0f;
float g = ((i >> 8) & 0xff)/255.0f;
float b = ((i >> 16) & 0xff)/255.0f;
return vec3(r, g, b);
}
@end
@vs vs
@include_block common
layout(binding = 0) uniform vs_uniform {
float radius;
};
layout(location = 0) in vec2 in_quad;
layout(location = 1) out vec2 _quad;
layout(location = 2) out vec2 _centroid;
layout(location = 3) flat out vec3 _color;
readonly: layout(binding = 0) readonly buffer vs_ssbo {
cell cells[];
};
void main()
{
_centroid = cells[gl_InstanceIndex].pos;
_color = color(gl_InstanceIndex);
_quad = radius * in_quad + _centroid;
gl_Position = vec4(_quad, 0.0, 1.0);
}
@end
@fs fs
@include_block common
layout(binding = 1) uniform fs_uniform {
float radius;
};
layout(location = 0) out vec4 frag_color;
layout(location = 1) in vec2 _quad;
layout(location = 2) in vec2 _centroid;
layout(location = 3) flat in vec3 _color;
void main()
{
gl_FragDepth = length(_quad - _centroid);
if(gl_FragDepth > radius) discard;
frag_color = vec4(_color, 1.0);
}
@end
@program base vs fs

View File

@ -1,47 +1,56 @@
struct Cell { struct Sprite {
position: vec2f, matrix: mat4x4f,
};
struct VsUniform {
mvp: mat4x4f,
}; };
struct VsI { //Vertex shader input struct VsI { //Vertex shader input
@builtin(instance_index) instance: u32, @builtin(instance_index) instance: u32,
@location(0) position: vec2f, @location(0) position: vec2f,
@location(1) uv: vec2f,
}; };
struct Vs2Fs { //Vertex shader to Fragment shader struct Vs2Fs { //Vertex shader to Fragment shader
@builtin(position) pos: vec4f, @builtin(position) pos: vec4f,
@location(0) @interpolate(flat) instance: u32, @location(0) @interpolate(linear) uv: vec2f,
}; };
struct FsO { //Fragment shader output struct FsO { //Fragment shader output
@builtin(frag_depth) depth: f32,
@location(0) color: vec4f, @location(0) color: vec4f,
}; };
fn color(i: u32) -> vec3f @binding(0) @group(0) var<uniform> vs_uniforms: VsUniform;
{ @binding(0) @group(1) var tex: texture_2d<f32>;
let r: f32 = f32(((i >> 0) & 0xff)); @binding(1) @group(1) var samp: sampler;
let g: f32 = f32(((i >> 8) & 0xff)); @binding(2) @group(1) var<storage> sprites: array<Sprite>;
let b: f32 = f32(((i >> 16) & 0xff));
return vec3f(r / 255, g / 255, b / 255);
}
//@binding(0) @group(0) var<uniform> mvp: mat4x4f; @vertex fn vs_main(input: VsI) -> Vs2Fs {
@binding(0) @group(1) var<storage> cells: array<Cell>;
@vertex
fn vs_main(input: VsI) -> Vs2Fs {
var output: Vs2Fs; var output: Vs2Fs;
output.pos = vec4f(cells[input.instance].position.xy, 0.0, 0.0)/* * mvp*/; output.pos = vec4f(input.position.x, input.position.y, 0, 0) * sprites[input.instance].matrix * vs_uniforms.mvp;
output.instance = input.instance; output.uv = input.uv;
return output; return output;
} }
@fragment // Convert a 32bit uint color (hex representation) into a normalized vec4f
fn fs_main(input: Vs2Fs) -> FsO { /*fn convertColor(input: u32) -> vec4f {
let r: f32 = f32(((input >> 0) & 0xff));
let g: f32 = f32(((input >> 8) & 0xff));
let b: f32 = f32(((input >> 16) & 0xff));
let a: f32 = f32(((input >> 24) & 0xff));
return vec4f(r / 255, g / 255, b / 255, a / 255);
}*/
// Get the texture array index from the UV
/*fn indexFromCoord(uv: vec2f, width: u32, height: u32) -> u32 {
let x: u32 = clamp(floor(uv.x * width), 0, width);
let y: u32 = clamp(floor(uv.y * height), 0, height);
return y * width + x;
}*/
@fragment fn fs_main(input: Vs2Fs) -> FsO {
var output: FsO; var output: FsO;
output.depth = 1.0; output.color = textureSample(tex, samp, input.uv);
output.color = vec4f(1.0, 0.0, 1.0, 1.0);
//output.color = vec4f(color(input.instance), 1.0);
return output; return output;
} }

17
src/sprite.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef SPRITE_H
#define SPRITE_H
#include "api.h"
typedef struct texture_t {
uint32_t id; //Texture ID
sg_bindings binding; //Texture bindings (texture, sampler and buffer)
vector_t sprites;
bool dirty;
} texture_t;
typedef struct sprite_t {
mat4x4f transform;
} sprite_t;
#endif

236
src/util.h Normal file
View File

@ -0,0 +1,236 @@
#ifndef UTIL_H
#define UTIL_H
#include "api.h"
/*typedef struct linked_list_t {
linked_item_t *first, *last;
uint16_t size;
} linked_list_t;
typedef struct linked_item_t {
linked_item_t *next, *prev;
void *data;
} linked_item_t;
typedef void (*linked_list_callback)(void *item);
//Currently, these are the only method required.
//Many more could be implemented but this is unnecessary.
static void l_list_push(linked_list_t *l_list, void *item);
static void l_list_append(linked_list_t *l_list, void *item);
static void* l_list_pop(linked_list_t *l_list);
static void* l_list_unppend(linked_list_t *l_list);
static void l_list_each(linked_list_t *l_list, linked_list_callback callback);
static inline void l_list_push(linked_list_t *l_list, void *item)
{
linked_item_t l_item = (linked_item_t) { .data = item, .prev = l_list->last, .next = nullptr };
if(l_list->first == nullptr)
l_list->first = &l_item;
l_list->last->next = &l_item;
l_list->last = &l_item;
l_list->size++;
}
static inline void l_list_append(linked_list_t *l_list, void *item)
{
linked_item_t l_item = (linked_item_t) { .data = item, .prev = nullptr, .next = l_list->last };
if(l_list->last == nullptr)
l_list->last = &l_item;
l_list->first->prev = &l_item;
l_list->first = &l_item;
l_list->size++;
}
static inline void* l_list_pop(linked_list_t *l_list)
{
if(l_list->last == nullptr)
return;
if(l_list->first == l_list->last)
l_list->first = nullptr;
linked_item_t *item = l_list->last->prev;
l_list->last->prev = nullptr;
l_list->last = item;
l_list->size--;
}
static inline void* l_list_unppend(linked_list_t *l_list)
{
if(l_list->first == nullptr)
return;
if(l_list->last == l_list->first)
l_list->last = nullptr;
linked_item_t *item = l_list->first->next;
l_list->first->next = nullptr;
l_list->first = item;
l_list->size--;
}
static inline void l_list_each(linked_list_t *l_list, linked_list_callback callback)
{
}*/
typedef struct vector_t {
void **data; //Memory pool
uint16_t stripe; //Bit per item
uint32_t size; //Current amount of items
uint32_t capacity; //Max capacity
} vector_t;
#define MAX_BUCKET_SIZE (0xffffffffu)
#define MAX_STRIPE_SIZE (0xffffu)
#define FIXED_START (0xfffu)
static vector_t vector_create(uint16_t stripe); //Create a new vector with a default size
static void vector_clear(vector_t *vector);
static void vector_free(vector_t *vector);
static uint32_t vector_length(vector_t *vector);
static void* vector_get(vector_t *vector, uint32_t index);
static void vector_set(vector_t *vector, uint32_t index, void *data);
static uint32_t vector_push(vector_t *vector, void *data);
static sg_range vector_range(vector_t *vector);
static vector_t vector_create(uint16_t stripe)
{
assert(stripe >= sizeof(uint32_t));
assert(stripe <= MAX_STRIPE_SIZE);
assert(FIXED_START * stripe <= MAX_BUCKET_SIZE);
return (vector_t) {
.capacity = FIXED_START,
.size = 0,
.stripe = stripe,
.data = (void**) malloc(FIXED_START * stripe),
};
}
static void vector_clear(vector_t *vector)
{
vector->size = 0;
}
static void vector_free(vector_t *vector)
{
free(vector->data);
}
static uint32_t vector_length(vector_t *vector)
{
return vector->size;
}
static void* vector_get(vector_t *vector, uint32_t index)
{
assert(index > 0);
assert(index < vector->size);
return vector->data[index * vector->stripe];
}
static void vector_set(vector_t *vector, uint32_t index, void *data)
{
assert(index > 0);
assert(index < vector->size);
vector->data[index * vector->stripe] = data;
}
static uint32_t vector_push(vector_t *vector, void *data)
{
if(vector->size >= vector->capacity)
{
vector->capacity *= 2;
vector->data = (void**) realloc(vector->data, vector->capacity * vector->stripe);
}
return vector->size++;
}
static sg_range vector_range(vector_t *vector)
{
return (sg_range) {
.ptr = vector->data,
.size = vector->size,
};
}
typedef struct mem_pool_t {
void **data; //Memory pool
uint16_t stripe; //Bit per item
uint32_t size; //Current amount of items
uint32_t capacity; //Max capacity
uint32_t free; //Linked list of available indices
} mem_pool_t;
static mem_pool_t pool_create(uint16_t stripe); //Create a new memory pool with a default size
static void pool_clear(mem_pool_t *pool);
static void pool_free(mem_pool_t *pool);
static uint32_t pool_add(mem_pool_t *pool); //Request a new free index
static void* pool_get(mem_pool_t *pool, uint32_t index); //Get the pointer
static void pool_remove(mem_pool_t *pool, uint32_t index); //Flag the given index as free
static mem_pool_t pool_create(uint16_t stripe)
{
assert(stripe >= sizeof(uint32_t));
assert(stripe <= MAX_STRIPE_SIZE);
assert(FIXED_START * stripe <= MAX_BUCKET_SIZE);
return (mem_pool_t) {
.capacity = FIXED_START,
.size = 0,
.stripe = stripe,
.free = UINT32_MAX,
.data = (void**) malloc(FIXED_START * stripe),
};
}
static void pool_clear(mem_pool_t *pool)
{
pool->size = 0;
pool->free = UINT32_MAX;
}
static void pool_free(mem_pool_t *pool)
{
free(pool->data);
}
static uint32_t pool_add(mem_pool_t *pool)
{
if(pool->free != UINT32_MAX)
{
const uint32_t index = pool->free;
pool->free = (uint32_t) pool->data[index * pool->stripe];
return index;
}
else
{
if(pool->size >= pool->capacity)
{
pool->capacity *= 2;
pool->data = (void**) realloc(pool->data, pool->capacity * pool->stripe);
}
return pool->size++;
}
}
static void* pool_get(mem_pool_t *pool, uint32_t index)
{
assert(index > 0);
assert(index < pool->capacity);
return pool->data[index * pool->stripe];
}
static void pool_remove(mem_pool_t *pool, uint32_t index)
{
const uint32_t pos = index * pool->stripe;
pool->data[pos] = (void*) pool->free;
pool->free = index;
}
#endif