#if defined(SOKOL_IMPL) && !defined(SOKOL_SPRITEBATCH_IMPL) #define SOKOL_SPRITEBATCH_IMPL #endif #ifndef SOKOL_SPRITEBATCH_INCLUDED #define SOKOL_SPRITEBATCH_INCLUDED (1) #if !defined(SOKOL_GFX_INCLUDED) #error "Please include sokol_gfx.h before sokol_spritebatch.h" #endif #if defined(SOKOL_API_DECL) && !defined(SOKOL_SPRITEBATCH_API_DECL) #define SOKOL_SPRITEBATCH_API_DECL SOKOL_API_DECL #endif #ifndef SOKOL_SPRITEBATCH_API_DECL #if defined(_WIN32) && defined(SOKOL_DLL) && defined(SOKOL_SPRITEBATCH_IMPL) #define SOKOL_SPRITEBATCH_API_DECL __declspec(dllexport) #elif defined(_WIN32) && defined(SOKOL_DLL) #define SOKOL_SPRITEBATCH_API_DECL __declspec(dllimport) #else #define SOKOL_SPRITEBATCH_API_DECL extern #endif #endif #ifdef __cplusplus extern "C" { #endif typedef enum sbatch_sprite_flags { SBATCH_FLIP_NONE = 0, SBATCH_FLIP_X = 1 << 0, SBATCH_FLIP_Y = 1 << 1, SBATCH_FLIP_BOTH = SBATCH_FLIP_Y | SBATCH_FLIP_X } sbatch_sprite_flags; typedef struct sbatch_float2 { float x; float y; } sbatch_float2; typedef struct sbatch_rect { float x; float y; float width; float height; } sbatch_rect; typedef struct sbatch_sprite { sg_image image; sbatch_float2 position; sbatch_rect source; const sg_color* color; float rotation; sbatch_float2 origin; sbatch_float2 scale; uint32_t flags; float depth; } sbatch_sprite; typedef struct sbatch_sprite_rect { sg_image image; sbatch_rect destination; sbatch_rect source; const sg_color* color; float rotation; sbatch_float2 origin; uint32_t flags; float depth; } sbatch_sprite_rect; typedef struct sbatch_desc { int context_pool_size; int pipeline_pool_size; sg_pixel_format color_format; sg_pixel_format depth_format; int sample_count; } sbatch_desc; typedef struct sbatch_context { uint32_t id; } sbatch_context; typedef struct sbatch_pipeline { uint32_t id; } sbatch_pipeline; typedef struct sbatch_context_desc { int canvas_width; int canvas_height; int max_sprites; sbatch_pipeline pipeline; const char* label; } sbatch_context_desc; SOKOL_SPRITEBATCH_API_DECL void sbatch_setup(const sbatch_desc* desc); SOKOL_SPRITEBATCH_API_DECL void sbatch_shutdown(void); SOKOL_SPRITEBATCH_API_DECL int sbatch_frame(); SOKOL_SPRITEBATCH_API_DECL sbatch_pipeline sbatch_make_pipeline(const sg_pipeline_desc* desc); SOKOL_SPRITEBATCH_API_DECL void sbatch_destroy_pipeline(sbatch_pipeline context); SOKOL_SPRITEBATCH_API_DECL sbatch_context sbatch_make_context(const sbatch_context_desc* desc); SOKOL_SPRITEBATCH_API_DECL void sbatch_destroy_context(sbatch_context context); SOKOL_SPRITEBATCH_API_DECL void sbatch_begin(sbatch_context context); SOKOL_SPRITEBATCH_API_DECL void sbatch_push_sprite(const sbatch_sprite* sprite); SOKOL_SPRITEBATCH_API_DECL void sbatch_push_sprite_rect(const sbatch_sprite_rect* sprite); SOKOL_SPRITEBATCH_API_DECL void sbatch_end(void); SOKOL_SPRITEBATCH_API_DECL void sbatch_apply_fs_uniforms(int ub_index, const sg_range* data); SOKOL_SPRITEBATCH_API_DECL void sbatch_premultiply_alpha_rgba8(uint8_t* pixels, int pixel_count); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* SOKOL_SPRITEBATCH_INCLUDED */ /*-- IMPLEMENTATION ----------------------------------------------------------*/ #ifdef SOKOL_SPRITEBATCH_IMPL #define SOKOL_SPRITEBATCH_IMPL_INCLUDED (1) #include /* memset */ #include /* sinf, cosf */ #ifndef SOKOL_API_IMPL #define SOKOL_API_IMPL #endif #ifndef SOKOL_ASSERT #include #define SOKOL_ASSERT(c) assert(c) #endif #ifndef SOKOL_MALLOC #include #define SOKOL_MALLOC(s) malloc(s) #define SOKOL_FREE(result) free(result) #endif #ifndef SOKOL_DEBUG #ifndef NDEBUG #define SOKOL_DEBUG (1) #endif #endif #ifndef SOKOL_LOG #ifdef SOKOL_DEBUG #include #define SOKOL_LOG(s) { SOKOL_ASSERT(s); puts(s); } #else #define SOKOL_LOG(s) #endif #endif #define _SBATCH_IMAGE_SLOT_MASK (0xFFFF) #define _SBATCH_DEFAULT(val, def) (((val) == 0) ? (def) : (val)) #define _SBATCH_MAX_VERTICES (1 << 16) #define _SBATCH_MAX_QUADS (_SBATCH_MAX_VERTICES / 4) #define _SBATCH_MAX_INDICES (_SBATCH_MAX_QUADS * 6) #define _SBATCH_INITIAL_BATCH_CAPACITY (32) #define _SBATCH_INVALID_SLOT_INDEX (0) #define _SBATCH_SLOT_SHIFT (16) #define _SBATCH_MAX_POOL_SIZE (1<<_SBATCH_SLOT_SHIFT) #define _SBATCH_SLOT_MASK (_SBATCH_MAX_POOL_SIZE-1) #define _SBATCH_STRBUF_LEN (96) typedef struct { float x; float y; float z; float u; float v; uint32_t rgba; } _sbatch_vertex; typedef struct { uint32_t id; sg_resource_state state; } _sbatch_slot; typedef struct { char buf[_SBATCH_STRBUF_LEN]; } _sbatch_str; typedef struct _sbatch_fs_uniform_state { int ub_index; const sg_range* data; } _sbatch_fs_uniform_state; typedef struct { _sbatch_str label; _sbatch_slot slot; sbatch_context_desc desc; int sprite_count; _sbatch_vertex* vertices; sg_image* images; sg_buffer vertex_buffer; sbatch_pipeline pipeline; int update_frame_index; _sbatch_fs_uniform_state fs_uniform_state; } _sbatch_context; typedef struct { int size; int queue_top; uint32_t* gen_ctrs; int* free_queue; } _sbatch_pool; typedef struct { _sbatch_pool pool; _sbatch_context* contexts; } _sbatch_context_pool; typedef struct { _sbatch_str label; _sbatch_slot slot; sg_pipeline_desc desc; sg_pipeline pipeline; } _sbatch_pipeline; typedef struct { _sbatch_pool pool; _sbatch_pipeline* pipelines; } _sbatch_pipeline_pool; typedef struct { sg_image image; int width; int height; float texel_width; float texel_height; } _sbatch_sprite_data; typedef struct { _sbatch_sprite_data* data; size_t size; } _sbatch_sprite_pool; typedef struct { bool begin_called; _sbatch_slot slot; sg_bindings bindings; sg_shader shader; sbatch_pipeline pipeline; sbatch_context ctx_id; _sbatch_context_pool context_pool; _sbatch_pipeline_pool pipeline_pool; _sbatch_sprite_pool sprite_pool; sg_buffer index_buffer; int frame_index; } _sbatch_t; typedef struct { float m[4][4]; } _sbatch_mat4x4; static _sbatch_t _sbatch; /* Embedded source code compiled with: sokol-shdc -i sgl.glsl -o sgl.h -l glsl330:glsl100:hlsl4:metal_macos:metal_ios:metal_sim:wgpu -b @vs vs uniform vs_params { mat4 mvp; }; in vec3 pos; in vec2 texcoord0; in vec4 color0; out vec2 uv; out vec4 color; void main() { gl_Position = mvp * vec4(pos, 1.0f); uv = texcoord0; color = color0; } @end @fs fs uniform sampler2D tex; in vec2 uv; in vec4 color; out vec4 frag_color; void main() { frag_color = color * texture(tex, uv); } @end @program spritebatch vs fs */ #include #include #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_vs_pos (0) #define ATTR_vs_texcoord0 (1) #define ATTR_vs_color0 (2) #define SLOT_tex (0) #define SLOT_vs_params (0) #pragma pack(push,1) SOKOL_SHDC_ALIGN(16) typedef struct vs_params_t { float mvp[16]; } vs_params_t; #pragma pack(pop) /* #version 330 uniform vec4 vs_params[4]; layout(location = 0) in vec3 pos; out vec2 uv; layout(location = 1) in vec2 texcoord0; out vec4 color; layout(location = 2) in vec4 color0; void main() { gl_Position = mat4(vs_params[0], vs_params[1], vs_params[2], vs_params[3]) * vec4(pos, 1.0); uv = texcoord0; color = color0; } */ static const char vs_source_glsl330[337] = { 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e, 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61, 0x72,0x61,0x6d,0x73,0x5b,0x34,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,0x33,0x20,0x70,0x6f,0x73,0x3b,0x0a,0x6f,0x75,0x74,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,0x69,0x6e,0x20, 0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a, 0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,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,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74, 0x69,0x6f,0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x76,0x73,0x5f,0x70,0x61, 0x72,0x61,0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61, 0x6d,0x73,0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73, 0x5b,0x32,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33, 0x5d,0x29,0x20,0x2a,0x20,0x76,0x65,0x63,0x34,0x28,0x70,0x6f,0x73,0x2c,0x20,0x31, 0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65, 0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c, 0x6f,0x72,0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a, 0x00, }; /* #version 330 uniform sampler2D tex; layout(location = 0) out vec4 frag_color; in vec4 color; in vec2 uv; void main() { frag_color = color * texture(tex, uv); } */ static const char fs_source_glsl330[169] = { 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x33,0x30,0x0a,0x0a,0x75,0x6e, 0x69,0x66,0x6f,0x72,0x6d,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x32,0x44,0x20, 0x74,0x65,0x78,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, 0x69,0x6e,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x69, 0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,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,0x63,0x6f,0x6c,0x6f,0x72, 0x20,0x2a,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x74,0x65,0x78,0x2c,0x20, 0x75,0x76,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* #version 100 uniform vec4 vs_params[4]; attribute vec3 pos; varying vec2 uv; attribute vec2 texcoord0; varying vec4 color; attribute vec4 color0; void main() { gl_Position = mat4(vs_params[0], vs_params[1], vs_params[2], vs_params[3]) * vec4(pos, 1.0); uv = texcoord0; color = color0; } */ static const char vs_source_glsl100[303] = { 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x30,0x30,0x0a,0x0a,0x75,0x6e, 0x69,0x66,0x6f,0x72,0x6d,0x20,0x76,0x65,0x63,0x34,0x20,0x76,0x73,0x5f,0x70,0x61, 0x72,0x61,0x6d,0x73,0x5b,0x34,0x5d,0x3b,0x0a,0x61,0x74,0x74,0x72,0x69,0x62,0x75, 0x74,0x65,0x20,0x76,0x65,0x63,0x33,0x20,0x70,0x6f,0x73,0x3b,0x0a,0x76,0x61,0x72, 0x79,0x69,0x6e,0x67,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x61,0x74, 0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x20,0x76,0x65,0x63,0x32,0x20,0x74,0x65,0x78, 0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x76,0x61,0x72,0x79,0x69,0x6e,0x67,0x20, 0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x61,0x74,0x74,0x72, 0x69,0x62,0x75,0x74,0x65,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,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f, 0x6e,0x20,0x3d,0x20,0x6d,0x61,0x74,0x34,0x28,0x76,0x73,0x5f,0x70,0x61,0x72,0x61, 0x6d,0x73,0x5b,0x30,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73, 0x5b,0x31,0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x32, 0x5d,0x2c,0x20,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x5b,0x33,0x5d,0x29, 0x20,0x2a,0x20,0x76,0x65,0x63,0x34,0x28,0x70,0x6f,0x73,0x2c,0x20,0x31,0x2e,0x30, 0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x75,0x76,0x20,0x3d,0x20,0x74,0x65,0x78,0x63, 0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x63,0x6f,0x6c,0x6f,0x72, 0x20,0x3d,0x20,0x63,0x6f,0x6c,0x6f,0x72,0x30,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* #version 100 precision mediump float; precision highp int; uniform highp sampler2D tex; varying highp vec4 color; varying highp vec2 uv; void main() { gl_FragData[0] = color * texture2D(tex, uv); } */ static const char fs_source_glsl100[207] = { 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x31,0x30,0x30,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,0x3b,0x0a,0x0a,0x76,0x61,0x72,0x79,0x69,0x6e, 0x67,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34,0x20,0x63,0x6f,0x6c, 0x6f,0x72,0x3b,0x0a,0x76,0x61,0x72,0x79,0x69,0x6e,0x67,0x20,0x68,0x69,0x67,0x68, 0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64, 0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67,0x6c, 0x5f,0x46,0x72,0x61,0x67,0x44,0x61,0x74,0x61,0x5b,0x30,0x5d,0x20,0x3d,0x20,0x63, 0x6f,0x6c,0x6f,0x72,0x20,0x2a,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x44, 0x28,0x74,0x65,0x78,0x2c,0x20,0x75,0x76,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* cbuffer vs_params : register(b0) { row_major float4x4 _21_mvp : packoffset(c0); }; static float4 gl_Position; static float3 pos; static float2 uv; static float2 texcoord0; static float4 color; static float4 color0; struct SPIRV_Cross_Input { float3 pos : TEXCOORD0; float2 texcoord0 : TEXCOORD1; float4 color0 : TEXCOORD2; }; struct SPIRV_Cross_Output { float2 uv : TEXCOORD0; float4 color : TEXCOORD1; float4 gl_Position : SV_Position; }; #line 18 "gfx.glsl" void vert_main() { #line 18 "gfx.glsl" gl_Position = mul(float4(pos, 1.0f), _21_mvp); #line 19 "gfx.glsl" uv = texcoord0; #line 20 "gfx.glsl" color = color0; } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { pos = stage_input.pos; texcoord0 = stage_input.texcoord0; color0 = stage_input.color0; vert_main(); SPIRV_Cross_Output stage_output; stage_output.gl_Position = gl_Position; stage_output.uv = uv; stage_output.color = color; return stage_output; } */ static const uint8_t vs_bytecode_hlsl4[884] = { 0x44,0x58,0x42,0x43,0x5f,0x8c,0xaf,0xe1,0x5e,0x2d,0xba,0x0e,0x85,0xba,0xeb,0xc5, 0x0c,0x64,0x6d,0x0c,0x01,0x00,0x00,0x00,0x74,0x03,0x00,0x00,0x05,0x00,0x00,0x00, 0x34,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x58,0x01,0x00,0x00,0xc8,0x01,0x00,0x00, 0xf8,0x02,0x00,0x00,0x52,0x44,0x45,0x46,0xb8,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xfe,0xff, 0x10,0x81,0x00,0x00,0x90,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d, 0x73,0x00,0xab,0xab,0x3c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x60,0x00,0x00,0x00, 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x5f,0x32,0x31,0x5f,0x6d,0x76,0x70,0x00,0x02,0x00,0x03,0x00, 0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4d,0x69,0x63,0x72, 0x6f,0x73,0x6f,0x66,0x74,0x20,0x28,0x52,0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53, 0x68,0x61,0x64,0x65,0x72,0x20,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31, 0x30,0x2e,0x31,0x00,0x49,0x53,0x47,0x4e,0x5c,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x00,0x00,0x50,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x03,0x03,0x00,0x00,0x50,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43, 0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab,0x4f,0x53,0x47,0x4e,0x68,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0c,0x00,0x00, 0x50,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0f,0x00,0x00,0x00, 0x54,0x45,0x58,0x43,0x4f,0x4f,0x52,0x44,0x00,0x53,0x56,0x5f,0x50,0x6f,0x73,0x69, 0x74,0x69,0x6f,0x6e,0x00,0xab,0xab,0xab,0x53,0x48,0x44,0x52,0x28,0x01,0x00,0x00, 0x40,0x00,0x01,0x00,0x4a,0x00,0x00,0x00,0x59,0x00,0x00,0x04,0x46,0x8e,0x20,0x00, 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x72,0x10,0x10,0x00, 0x00,0x00,0x00,0x00,0x5f,0x00,0x00,0x03,0x32,0x10,0x10,0x00,0x01,0x00,0x00,0x00, 0x5f,0x00,0x00,0x03,0xf2,0x10,0x10,0x00,0x02,0x00,0x00,0x00,0x65,0x00,0x00,0x03, 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00, 0x01,0x00,0x00,0x00,0x67,0x00,0x00,0x04,0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x68,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x36,0x00,0x00,0x05, 0x32,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x10,0x00,0x01,0x00,0x00,0x00, 0x36,0x00,0x00,0x05,0xf2,0x20,0x10,0x00,0x01,0x00,0x00,0x00,0x46,0x1e,0x10,0x00, 0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x08,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00, 0x56,0x15,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x32,0x00,0x00,0x0a,0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00, 0x06,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x32,0x00,0x00,0x0a, 0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0xa6,0x1a,0x10,0x00,0x00,0x00,0x00,0x00, 0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x46,0x0e,0x10,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xf2,0x20,0x10,0x00,0x02,0x00,0x00,0x00, 0x46,0x0e,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x8e,0x20,0x00,0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x3e,0x00,0x00,0x01,0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00, 0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, }; /* Texture2D tex : register(t0); SamplerState _tex_sampler : register(s0); static float4 frag_color; static float4 color; static float2 uv; struct SPIRV_Cross_Input { float2 uv : TEXCOORD0; float4 color : TEXCOORD1; }; struct SPIRV_Cross_Output { float4 frag_color : SV_Target0; }; #line 14 "gfx.glsl" void frag_main() { #line 14 "gfx.glsl" frag_color = color * tex.Sample(_tex_sampler, uv); } SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) { color = stage_input.color; uv = stage_input.uv; frag_main(); SPIRV_Cross_Output stage_output; stage_output.frag_color = frag_color; return stage_output; } */ static const uint8_t fs_bytecode_hlsl4[620] = { 0x44,0x58,0x42,0x43,0xd1,0x93,0x1f,0x1b,0x9d,0x70,0x90,0xeb,0xc2,0x7c,0x26,0x07, 0xdf,0x52,0xda,0x49,0x01,0x00,0x00,0x00,0x6c,0x02,0x00,0x00,0x05,0x00,0x00,0x00, 0x34,0x00,0x00,0x00,0xd4,0x00,0x00,0x00,0x20,0x01,0x00,0x00,0x54,0x01,0x00,0x00, 0xf0,0x01,0x00,0x00,0x52,0x44,0x45,0x46,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x04,0xff,0xff, 0x10,0x81,0x00,0x00,0x6d,0x00,0x00,0x00,0x5c,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x69,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x05,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x5f,0x74,0x65,0x78,0x5f,0x73,0x61,0x6d, 0x70,0x6c,0x65,0x72,0x00,0x74,0x65,0x78,0x00,0x4d,0x69,0x63,0x72,0x6f,0x73,0x6f, 0x66,0x74,0x20,0x28,0x52,0x29,0x20,0x48,0x4c,0x53,0x4c,0x20,0x53,0x68,0x61,0x64, 0x65,0x72,0x20,0x43,0x6f,0x6d,0x70,0x69,0x6c,0x65,0x72,0x20,0x31,0x30,0x2e,0x31, 0x00,0xab,0xab,0xab,0x49,0x53,0x47,0x4e,0x44,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x08,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x00,0x00,0x38,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x0f,0x0f,0x00,0x00,0x54,0x45,0x58,0x43,0x4f,0x4f,0x52,0x44,0x00,0xab,0xab,0xab, 0x4f,0x53,0x47,0x4e,0x2c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x53,0x56,0x5f,0x54,0x61,0x72,0x67,0x65, 0x74,0x00,0xab,0xab,0x53,0x48,0x44,0x52,0x94,0x00,0x00,0x00,0x40,0x00,0x00,0x00, 0x25,0x00,0x00,0x00,0x5a,0x00,0x00,0x03,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00, 0x58,0x18,0x00,0x04,0x00,0x70,0x10,0x00,0x00,0x00,0x00,0x00,0x55,0x55,0x00,0x00, 0x62,0x10,0x00,0x03,0x32,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x00,0x03, 0xf2,0x10,0x10,0x00,0x01,0x00,0x00,0x00,0x65,0x00,0x00,0x03,0xf2,0x20,0x10,0x00, 0x00,0x00,0x00,0x00,0x68,0x00,0x00,0x02,0x01,0x00,0x00,0x00,0x45,0x00,0x00,0x09, 0xf2,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x10,0x10,0x00,0x00,0x00,0x00,0x00, 0x46,0x7e,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x10,0x00,0x00,0x00,0x00,0x00, 0x38,0x00,0x00,0x07,0xf2,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x46,0x0e,0x10,0x00, 0x00,0x00,0x00,0x00,0x46,0x1e,0x10,0x00,0x01,0x00,0x00,0x00,0x3e,0x00,0x00,0x01, 0x53,0x54,0x41,0x54,0x74,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, }; /* #include #include using namespace metal; struct vs_params { float4x4 mvp; }; struct main0_out { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; float4 gl_Position [[position]]; }; struct main0_in { float3 pos [[attribute(0)]]; float2 texcoord0 [[attribute(1)]]; float4 color0 [[attribute(2)]]; }; #line 18 "gfx.glsl" vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _21 [[buffer(0)]]) { main0_out out = {}; #line 18 "gfx.glsl" out.gl_Position = _21.mvp * float4(in.pos, 1.0); #line 19 "gfx.glsl" out.uv = in.texcoord0; #line 20 "gfx.glsl" out.color = in.color0; return out; } */ static const char vs_source_metal_macos[689] = { 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,0x76, 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, 0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,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,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,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,0x33,0x20,0x70,0x6f,0x73,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,0x74,0x65,0x78,0x63, 0x6f,0x6f,0x72,0x64,0x30,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, 0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c, 0x73,0x6c,0x22,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,0x76,0x73, 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x32,0x31,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22, 0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75, 0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20, 0x5f,0x32,0x31,0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34, 0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x23, 0x6c,0x69,0x6e,0x65,0x20,0x31,0x39,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73, 0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x75,0x76,0x20,0x3d,0x20, 0x69,0x6e,0x2e,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x23,0x6c, 0x69,0x6e,0x65,0x20,0x32,0x30,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c, 0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,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 #include using namespace metal; struct main0_out { float4 frag_color [[color(0)]]; }; struct main0_in { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; }; #line 14 "gfx.glsl" fragment main0_out main0(main0_in in [[stage_in]], texture2d tex [[texture(0)]], sampler texSmplr [[sampler(0)]]) { main0_out out = {}; #line 14 "gfx.glsl" out.frag_color = in.color * tex.sample(texSmplr, in.uv); return out; } */ static const char fs_source_metal_macos[486] = { 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, 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,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,0x23,0x6c,0x69,0x6e,0x65,0x20, 0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,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,0x74,0x65, 0x78,0x53,0x6d,0x70,0x6c,0x72,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67, 0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61, 0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c, 0x6f,0x72,0x20,0x2a,0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28, 0x74,0x65,0x78,0x53,0x6d,0x70,0x6c,0x72,0x2c,0x20,0x69,0x6e,0x2e,0x75,0x76,0x29, 0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74, 0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* #include #include using namespace metal; struct vs_params { float4x4 mvp; }; struct main0_out { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; float4 gl_Position [[position]]; }; struct main0_in { float3 pos [[attribute(0)]]; float2 texcoord0 [[attribute(1)]]; float4 color0 [[attribute(2)]]; }; #line 18 "gfx.glsl" vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _21 [[buffer(0)]]) { main0_out out = {}; #line 18 "gfx.glsl" out.gl_Position = _21.mvp * float4(in.pos, 1.0); #line 19 "gfx.glsl" out.uv = in.texcoord0; #line 20 "gfx.glsl" out.color = in.color0; return out; } */ static const char vs_source_metal_ios[689] = { 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,0x76, 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, 0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,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,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,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,0x33,0x20,0x70,0x6f,0x73,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,0x74,0x65,0x78,0x63, 0x6f,0x6f,0x72,0x64,0x30,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, 0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c, 0x73,0x6c,0x22,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,0x76,0x73, 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x32,0x31,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22, 0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75, 0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20, 0x5f,0x32,0x31,0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34, 0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x23, 0x6c,0x69,0x6e,0x65,0x20,0x31,0x39,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73, 0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x75,0x76,0x20,0x3d,0x20, 0x69,0x6e,0x2e,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x23,0x6c, 0x69,0x6e,0x65,0x20,0x32,0x30,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c, 0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,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 #include using namespace metal; struct main0_out { float4 frag_color [[color(0)]]; }; struct main0_in { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; }; #line 14 "gfx.glsl" fragment main0_out main0(main0_in in [[stage_in]], texture2d tex [[texture(0)]], sampler texSmplr [[sampler(0)]]) { main0_out out = {}; #line 14 "gfx.glsl" out.frag_color = in.color * tex.sample(texSmplr, in.uv); return out; } */ static const char fs_source_metal_ios[486] = { 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, 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,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,0x23,0x6c,0x69,0x6e,0x65,0x20, 0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,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,0x74,0x65, 0x78,0x53,0x6d,0x70,0x6c,0x72,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67, 0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61, 0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c, 0x6f,0x72,0x20,0x2a,0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28, 0x74,0x65,0x78,0x53,0x6d,0x70,0x6c,0x72,0x2c,0x20,0x69,0x6e,0x2e,0x75,0x76,0x29, 0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74, 0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* #include #include using namespace metal; struct vs_params { float4x4 mvp; }; struct main0_out { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; float4 gl_Position [[position]]; }; struct main0_in { float3 pos [[attribute(0)]]; float2 texcoord0 [[attribute(1)]]; float4 color0 [[attribute(2)]]; }; #line 18 "gfx.glsl" vertex main0_out main0(main0_in in [[stage_in]], constant vs_params& _21 [[buffer(0)]]) { main0_out out = {}; #line 18 "gfx.glsl" out.gl_Position = _21.mvp * float4(in.pos, 1.0); #line 19 "gfx.glsl" out.uv = in.texcoord0; #line 20 "gfx.glsl" out.color = in.color0; return out; } */ static const char vs_source_metal_sim[689] = { 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,0x76, 0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, 0x6c,0x6f,0x61,0x74,0x34,0x78,0x34,0x20,0x6d,0x76,0x70,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,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,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,0x33,0x20,0x70,0x6f,0x73,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,0x74,0x65,0x78,0x63, 0x6f,0x6f,0x72,0x64,0x30,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, 0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c, 0x73,0x6c,0x22,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,0x76,0x73, 0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x26,0x20,0x5f,0x32,0x31,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x38,0x20,0x22, 0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75, 0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20, 0x5f,0x32,0x31,0x2e,0x6d,0x76,0x70,0x20,0x2a,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34, 0x28,0x69,0x6e,0x2e,0x70,0x6f,0x73,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x23, 0x6c,0x69,0x6e,0x65,0x20,0x31,0x39,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73, 0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x75,0x76,0x20,0x3d,0x20, 0x69,0x6e,0x2e,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x30,0x3b,0x0a,0x23,0x6c, 0x69,0x6e,0x65,0x20,0x32,0x30,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c, 0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,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 #include using namespace metal; struct main0_out { float4 frag_color [[color(0)]]; }; struct main0_in { float2 uv [[user(locn0)]]; float4 color [[user(locn1)]]; }; #line 14 "gfx.glsl" fragment main0_out main0(main0_in in [[stage_in]], texture2d tex [[texture(0)]], sampler texSmplr [[sampler(0)]]) { main0_out out = {}; #line 14 "gfx.glsl" out.frag_color = in.color * tex.sample(texSmplr, in.uv); return out; } */ static const char fs_source_metal_sim[486] = { 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, 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,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,0x23,0x6c,0x69,0x6e,0x65,0x20, 0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x22,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,0x74,0x65, 0x78,0x53,0x6d,0x70,0x6c,0x72,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,0x23,0x6c,0x69,0x6e,0x65,0x20,0x31,0x34,0x20,0x22,0x67,0x66,0x78,0x2e,0x67, 0x6c,0x73,0x6c,0x22,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61, 0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x63,0x6f,0x6c, 0x6f,0x72,0x20,0x2a,0x20,0x74,0x65,0x78,0x2e,0x73,0x61,0x6d,0x70,0x6c,0x65,0x28, 0x74,0x65,0x78,0x53,0x6d,0x70,0x6c,0x72,0x2c,0x20,0x69,0x6e,0x2e,0x75,0x76,0x29, 0x3b,0x0a,0x20,0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74, 0x3b,0x0a,0x7d,0x0a,0x0a,0x00, }; /* #version 450 layout(set = 0, binding = 0, std140) uniform vs_params { mat4 mvp; } _21; layout(location = 0) in vec3 pos; layout(location = 0) out vec2 uv; layout(location = 1) in vec2 texcoord0; layout(location = 1) out vec4 color; layout(location = 2) in vec4 color0; void main() { gl_Position = _21.mvp * vec4(pos, 1.0); uv = texcoord0; color = color0; } */ static const uint8_t vs_bytecode_wgpu[1716] = { 0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x2f,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00, 0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30, 0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x0f,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e, 0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x27,0x00,0x00,0x00, 0x29,0x00,0x00,0x00,0x2b,0x00,0x00,0x00,0x2d,0x00,0x00,0x00,0x07,0x00,0x03,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x05,0x00,0x07,0x00,0x00,0x00, 0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00, 0x02,0x00,0x00,0x00,0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f, 0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64, 0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30, 0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f, 0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70, 0x65,0x6e,0x67,0x6c,0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64, 0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72, 0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e, 0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f, 0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e, 0x76,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f, 0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e, 0x74,0x72,0x79,0x2d,0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23, 0x6c,0x69,0x6e,0x65,0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00, 0x6d,0x61,0x69,0x6e,0x00,0x00,0x00,0x00,0x05,0x00,0x06,0x00,0x0d,0x00,0x00,0x00, 0x67,0x6c,0x5f,0x50,0x65,0x72,0x56,0x65,0x72,0x74,0x65,0x78,0x00,0x00,0x00,0x00, 0x06,0x00,0x06,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50, 0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x00,0x06,0x00,0x07,0x00,0x0d,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x67,0x6c,0x5f,0x50,0x6f,0x69,0x6e,0x74,0x53,0x69,0x7a,0x65, 0x00,0x00,0x00,0x00,0x06,0x00,0x07,0x00,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x67,0x6c,0x5f,0x43,0x6c,0x69,0x70,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00, 0x06,0x00,0x07,0x00,0x0d,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x67,0x6c,0x5f,0x43, 0x75,0x6c,0x6c,0x44,0x69,0x73,0x74,0x61,0x6e,0x63,0x65,0x00,0x05,0x00,0x03,0x00, 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x13,0x00,0x00,0x00, 0x76,0x73,0x5f,0x70,0x61,0x72,0x61,0x6d,0x73,0x00,0x00,0x00,0x06,0x00,0x04,0x00, 0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6d,0x76,0x70,0x00,0x05,0x00,0x03,0x00, 0x15,0x00,0x00,0x00,0x5f,0x32,0x31,0x00,0x05,0x00,0x03,0x00,0x1b,0x00,0x00,0x00, 0x70,0x6f,0x73,0x00,0x05,0x00,0x03,0x00,0x27,0x00,0x00,0x00,0x75,0x76,0x00,0x00, 0x05,0x00,0x05,0x00,0x29,0x00,0x00,0x00,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64, 0x30,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2b,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f, 0x72,0x00,0x00,0x00,0x05,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f, 0x72,0x30,0x00,0x00,0x48,0x00,0x05,0x00,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x0d,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,0x00,0x05,0x00, 0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x48,0x00,0x05,0x00,0x0d,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x0d,0x00,0x00,0x00,0x02,0x00,0x00,0x00, 0x48,0x00,0x04,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00, 0x48,0x00,0x05,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x23,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x48,0x00,0x05,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x07,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x47,0x00,0x03,0x00,0x13,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x22,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x21,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x1b,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x27,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x29,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x2b,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x2d,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00, 0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x08,0x00,0x00,0x00, 0x20,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x15,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x20,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x1c,0x00,0x04,0x00,0x0c,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x0b,0x00,0x00,0x00,0x1e,0x00,0x06,0x00,0x0d,0x00,0x00,0x00,0x09,0x00,0x00,0x00, 0x08,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x20,0x00,0x04,0x00, 0x0e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x3b,0x00,0x04,0x00, 0x0e,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x15,0x00,0x04,0x00, 0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00, 0x10,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x04,0x00, 0x12,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x1e,0x00,0x03,0x00, 0x13,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x14,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x14,0x00,0x00,0x00, 0x15,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x16,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x19,0x00,0x00,0x00, 0x08,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x1a,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x1a,0x00,0x00,0x00, 0x1b,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x2b,0x00,0x04,0x00,0x08,0x00,0x00,0x00, 0x1d,0x00,0x00,0x00,0x00,0x00,0x80,0x3f,0x20,0x00,0x04,0x00,0x23,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x25,0x00,0x00,0x00, 0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x26,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x26,0x00,0x00,0x00, 0x27,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x28,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x25,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x28,0x00,0x00,0x00, 0x29,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x23,0x00,0x00,0x00, 0x2b,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x2c,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x2c,0x00,0x00,0x00, 0x2d,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00, 0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00, 0x06,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x10,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x16,0x00,0x00,0x00,0x17,0x00,0x00,0x00, 0x15,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x12,0x00,0x00,0x00, 0x18,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x19,0x00,0x00,0x00, 0x1c,0x00,0x00,0x00,0x1b,0x00,0x00,0x00,0x51,0x00,0x05,0x00,0x08,0x00,0x00,0x00, 0x1e,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x51,0x00,0x05,0x00, 0x08,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x51,0x00,0x05,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x1c,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x50,0x00,0x07,0x00,0x09,0x00,0x00,0x00,0x21,0x00,0x00,0x00, 0x1e,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x1d,0x00,0x00,0x00, 0x91,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x18,0x00,0x00,0x00, 0x21,0x00,0x00,0x00,0x41,0x00,0x05,0x00,0x23,0x00,0x00,0x00,0x24,0x00,0x00,0x00, 0x0f,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x24,0x00,0x00,0x00, 0x22,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x11,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x3d,0x00,0x04,0x00,0x25,0x00,0x00,0x00,0x2a,0x00,0x00,0x00, 0x29,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x27,0x00,0x00,0x00,0x2a,0x00,0x00,0x00, 0x08,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x3d,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0x2d,0x00,0x00,0x00, 0x3e,0x00,0x03,0x00,0x2b,0x00,0x00,0x00,0x2e,0x00,0x00,0x00,0xfd,0x00,0x01,0x00, 0x38,0x00,0x01,0x00, }; /* #version 450 layout(location = 0, set = 2, binding = 0) uniform sampler2D tex; layout(location = 0) out vec4 frag_color; layout(location = 1) in vec4 color; layout(location = 0) in vec2 uv; void main() { frag_color = color * texture(tex, uv); } */ static const uint8_t fs_bytecode_wgpu[924] = { 0x03,0x02,0x23,0x07,0x00,0x00,0x01,0x00,0x08,0x00,0x08,0x00,0x1a,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x11,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x0b,0x00,0x06,0x00, 0x02,0x00,0x00,0x00,0x47,0x4c,0x53,0x4c,0x2e,0x73,0x74,0x64,0x2e,0x34,0x35,0x30, 0x00,0x00,0x00,0x00,0x0e,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x0f,0x00,0x08,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6d,0x61,0x69,0x6e, 0x00,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x0d,0x00,0x00,0x00,0x16,0x00,0x00,0x00, 0x10,0x00,0x03,0x00,0x05,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x07,0x00,0x03,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x05,0x00,0x07,0x00,0x00,0x00, 0x67,0x66,0x78,0x2e,0x67,0x6c,0x73,0x6c,0x00,0x00,0x00,0x00,0x03,0x00,0x37,0x00, 0x02,0x00,0x00,0x00,0xc2,0x01,0x00,0x00,0x01,0x00,0x00,0x00,0x2f,0x2f,0x20,0x4f, 0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64, 0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x30, 0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f, 0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x63,0x6c,0x69,0x65,0x6e,0x74,0x20,0x6f,0x70, 0x65,0x6e,0x67,0x6c,0x31,0x30,0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64, 0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72, 0x67,0x65,0x74,0x2d,0x65,0x6e,0x76,0x20,0x76,0x75,0x6c,0x6b,0x61,0x6e,0x31,0x2e, 0x30,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f,0x64,0x75,0x6c,0x65,0x50,0x72,0x6f, 0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x74,0x61,0x72,0x67,0x65,0x74,0x2d,0x65,0x6e, 0x76,0x20,0x6f,0x70,0x65,0x6e,0x67,0x6c,0x0a,0x2f,0x2f,0x20,0x4f,0x70,0x4d,0x6f, 0x64,0x75,0x6c,0x65,0x50,0x72,0x6f,0x63,0x65,0x73,0x73,0x65,0x64,0x20,0x65,0x6e, 0x74,0x72,0x79,0x2d,0x70,0x6f,0x69,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x0a,0x23, 0x6c,0x69,0x6e,0x65,0x20,0x31,0x0a,0x00,0x05,0x00,0x04,0x00,0x05,0x00,0x00,0x00, 0x6d,0x61,0x69,0x6e,0x00,0x00,0x00,0x00,0x05,0x00,0x05,0x00,0x0b,0x00,0x00,0x00, 0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x05,0x00,0x04,0x00, 0x0d,0x00,0x00,0x00,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x05,0x00,0x03,0x00, 0x12,0x00,0x00,0x00,0x74,0x65,0x78,0x00,0x05,0x00,0x03,0x00,0x16,0x00,0x00,0x00, 0x75,0x76,0x00,0x00,0x47,0x00,0x04,0x00,0x0b,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x0d,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x22,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x12,0x00,0x00,0x00,0x21,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x47,0x00,0x04,0x00,0x16,0x00,0x00,0x00,0x1e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x13,0x00,0x02,0x00,0x03,0x00,0x00,0x00,0x21,0x00,0x03,0x00, 0x04,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x00,0x03,0x00,0x08,0x00,0x00,0x00, 0x20,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x04,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 0x09,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x0a,0x00,0x00,0x00,0x0b,0x00,0x00,0x00, 0x03,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x09,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x0c,0x00,0x00,0x00,0x0d,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x19,0x00,0x09,0x00,0x0f,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1b,0x00,0x03,0x00,0x10,0x00,0x00,0x00, 0x0f,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x10,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x11,0x00,0x00,0x00,0x12,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x17,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x08,0x00,0x00,0x00, 0x02,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x01,0x00,0x00,0x00, 0x14,0x00,0x00,0x00,0x3b,0x00,0x04,0x00,0x15,0x00,0x00,0x00,0x16,0x00,0x00,0x00, 0x01,0x00,0x00,0x00,0x36,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xf8,0x00,0x02,0x00,0x06,0x00,0x00,0x00, 0x08,0x00,0x04,0x00,0x07,0x00,0x00,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x3d,0x00,0x04,0x00,0x09,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x0d,0x00,0x00,0x00, 0x3d,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x12,0x00,0x00,0x00, 0x3d,0x00,0x04,0x00,0x14,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x16,0x00,0x00,0x00, 0x57,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x13,0x00,0x00,0x00, 0x17,0x00,0x00,0x00,0x85,0x00,0x05,0x00,0x09,0x00,0x00,0x00,0x19,0x00,0x00,0x00, 0x0e,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x3e,0x00,0x03,0x00,0x0b,0x00,0x00,0x00, 0x19,0x00,0x00,0x00,0xfd,0x00,0x01,0x00,0x38,0x00,0x01,0x00, }; #if !defined(SOKOL_GFX_INCLUDED) #error "Please include sokol_gfx.h before sgl.h" #endif static inline const sg_shader_desc* spritebatch_shader_desc(sg_backend backend) { if (backend == SG_BACKEND_GLCORE33) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.attrs[0].name = "pos"; desc.attrs[1].name = "texcoord0"; desc.attrs[2].name = "color0"; desc.vs.source = vs_source_glsl330; desc.vs.entry = "main"; desc.vs.uniform_blocks[0].size = 64; desc.vs.uniform_blocks[0].uniforms[0].name = "vs_params"; desc.vs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4; desc.vs.uniform_blocks[0].uniforms[0].array_count = 4; desc.fs.source = fs_source_glsl330; desc.fs.entry = "main"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_GLES2) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.attrs[0].name = "pos"; desc.attrs[1].name = "texcoord0"; desc.attrs[2].name = "color0"; desc.vs.source = vs_source_glsl100; desc.vs.entry = "main"; desc.vs.uniform_blocks[0].size = 64; desc.vs.uniform_blocks[0].uniforms[0].name = "vs_params"; desc.vs.uniform_blocks[0].uniforms[0].type = SG_UNIFORMTYPE_FLOAT4; desc.vs.uniform_blocks[0].uniforms[0].array_count = 4; desc.fs.source = fs_source_glsl100; desc.fs.entry = "main"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_D3D11) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.attrs[0].sem_name = "TEXCOORD"; desc.attrs[0].sem_index = 0; desc.attrs[1].sem_name = "TEXCOORD"; desc.attrs[1].sem_index = 1; desc.attrs[2].sem_name = "TEXCOORD"; desc.attrs[2].sem_index = 2; desc.vs.bytecode.ptr = vs_bytecode_hlsl4; desc.vs.bytecode.size = 884; desc.vs.entry = "main"; desc.vs.uniform_blocks[0].size = 64; desc.fs.bytecode.ptr = fs_bytecode_hlsl4; desc.fs.bytecode.size = 620; desc.fs.entry = "main"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_METAL_MACOS) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.vs.source = vs_source_metal_macos; desc.vs.entry = "main0"; desc.vs.uniform_blocks[0].size = 64; desc.fs.source = fs_source_metal_macos; desc.fs.entry = "main0"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_METAL_IOS) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.vs.source = vs_source_metal_ios; desc.vs.entry = "main0"; desc.vs.uniform_blocks[0].size = 64; desc.fs.source = fs_source_metal_ios; desc.fs.entry = "main0"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_METAL_SIMULATOR) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.vs.source = vs_source_metal_sim; desc.vs.entry = "main0"; desc.vs.uniform_blocks[0].size = 64; desc.fs.source = fs_source_metal_sim; desc.fs.entry = "main0"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } if (backend == SG_BACKEND_WGPU) { static sg_shader_desc desc; static bool valid; if (!valid) { valid = true; desc.vs.bytecode.ptr = vs_bytecode_wgpu; desc.vs.bytecode.size = 1716; desc.vs.entry = "main"; desc.vs.uniform_blocks[0].size = 64; desc.fs.bytecode.ptr = fs_bytecode_wgpu; desc.fs.bytecode.size = 924; desc.fs.entry = "main"; desc.fs.images[0].name = "tex"; desc.fs.images[0].image_type = SG_IMAGETYPE_2D; desc.fs.images[0].sampler_type = SG_SAMPLERTYPE_FLOAT; desc.label = "spritebatch_shader"; }; return &desc; } return 0; } static void _sbatch_strcpy(_sbatch_str* dst, const char* src) { SOKOL_ASSERT(dst); if (src) { #if defined(_MSC_VER) strncpy_s(dst->buf, _SBATCH_STRBUF_LEN, src, (_SBATCH_STRBUF_LEN - 1)); #else strncpy(dst->buf, src, _SBATCH_STRBUF_LEN); #endif dst->buf[_SBATCH_STRBUF_LEN - 1] = 0; } else { memset(dst->buf, 0, _SBATCH_STRBUF_LEN); } } static _sbatch_str _sbatch_make_str(const char* str) { _sbatch_str res; _sbatch_strcpy(&res, str); return res; } static void _sbatch_init_pool(_sbatch_pool* pool, int num) { SOKOL_ASSERT(pool && (num >= 1)); /* slot 0 is reserved for the 'invalid id', so bump the pool size by 1 */ pool->size = num + 1; pool->queue_top = 0; /* generation counters indexable by pool slot index, slot 0 is reserved */ const size_t gen_ctrs_size = sizeof(uint32_t) * (size_t)pool->size; pool->gen_ctrs = (uint32_t*)SOKOL_MALLOC(gen_ctrs_size); SOKOL_ASSERT(pool->gen_ctrs); memset(pool->gen_ctrs, 0, gen_ctrs_size); /* it's not a bug to only reserve 'num' here */ pool->free_queue = (int*)SOKOL_MALLOC(sizeof(int) * (size_t)num); SOKOL_ASSERT(pool->free_queue); /* never allocate the zero-th pool item since the invalid id is 0 */ for (int i = pool->size - 1; i >= 1; i--) { pool->free_queue[pool->queue_top++] = i; } } static void _sbatch_discard_pool(_sbatch_pool* pool) { SOKOL_ASSERT(pool); SOKOL_ASSERT(pool->free_queue); SOKOL_FREE(pool->free_queue); pool->free_queue = 0; SOKOL_ASSERT(pool->gen_ctrs); SOKOL_FREE(pool->gen_ctrs); pool->gen_ctrs = 0; pool->size = 0; pool->queue_top = 0; } static int _sbatch_pool_alloc_index(_sbatch_pool* pool) { SOKOL_ASSERT(pool); SOKOL_ASSERT(pool->free_queue); if (pool->queue_top > 0) { const int slot_index = pool->free_queue[--pool->queue_top]; SOKOL_ASSERT((slot_index > 0) && (slot_index < pool->size)); return slot_index; } /* pool exhausted */ return _SBATCH_INVALID_SLOT_INDEX; } static void _sbatch_pool_free_index(_sbatch_pool* pool, int slot_index) { SOKOL_ASSERT((slot_index > _SBATCH_INVALID_SLOT_INDEX) && (slot_index < pool->size)); SOKOL_ASSERT(pool); SOKOL_ASSERT(pool->free_queue); SOKOL_ASSERT(pool->queue_top < pool->size); #ifdef SOKOL_DEBUG /* debug check against double-free */ for (int i = 0; i < pool->queue_top; i++) { SOKOL_ASSERT(pool->free_queue[i] != slot_index); } #endif pool->free_queue[pool->queue_top++] = slot_index; SOKOL_ASSERT(pool->queue_top <= (pool->size - 1)); } /* allocate the slot at slot_index: - bump the slot's generation counter - create a resource id from the generation counter and slot index - set the slot's id to this id - set the slot's state to ALLOC - return the resource id */ static uint32_t _sbatch_slot_alloc(_sbatch_pool* pool, _sbatch_slot* slot, int slot_index) { /* FIXME: add handling for an overflowing generation counter, for now, just overflow (another option is to disable the slot) */ SOKOL_ASSERT(pool && pool->gen_ctrs); SOKOL_ASSERT((slot_index > _SBATCH_INVALID_SLOT_INDEX) && (slot_index < pool->size)); SOKOL_ASSERT((slot->state == SG_RESOURCESTATE_INITIAL) && (slot->id == SG_INVALID_ID)); const uint32_t ctr = ++pool->gen_ctrs[slot_index]; slot->id = (ctr << _SBATCH_SLOT_SHIFT) | (slot_index & _SBATCH_SLOT_MASK); slot->state = SG_RESOURCESTATE_ALLOC; return slot->id; } /* extract slot index from id */ static int _sbatch_slot_index(uint32_t id) { const int slot_index = (int)(id & _SBATCH_SLOT_MASK); SOKOL_ASSERT(_SBATCH_INVALID_SLOT_INDEX != slot_index); return slot_index; } static void _sbatch_setup_context_pool(const sbatch_desc* desc) { SOKOL_ASSERT(desc); /* note: the pool will have an additional item, since slot 0 is reserved */ SOKOL_ASSERT((desc->context_pool_size > 0) && (desc->context_pool_size < _SBATCH_MAX_POOL_SIZE)); _sbatch_init_pool(&_sbatch.context_pool.pool, desc->context_pool_size); const size_t pool_byte_size = sizeof(_sbatch_context) * (size_t)_sbatch.context_pool.pool.size; _sbatch.context_pool.contexts = (_sbatch_context*)SOKOL_MALLOC(pool_byte_size); SOKOL_ASSERT(_sbatch.context_pool.contexts); memset(_sbatch.context_pool.contexts, 0, pool_byte_size); } static void _sbatch_discard_context_pool(void) { SOKOL_ASSERT(_sbatch.context_pool.contexts); SOKOL_FREE(_sbatch.context_pool.contexts); _sbatch.context_pool.contexts = 0; _sbatch_discard_pool(&_sbatch.context_pool.pool); } /* get context pointer without id-check */ static _sbatch_context* _sbatch_context_at(uint32_t ctx_id) { SOKOL_ASSERT(SG_INVALID_ID != ctx_id); const int slot_index = _sbatch_slot_index(ctx_id); SOKOL_ASSERT((slot_index > _SBATCH_INVALID_SLOT_INDEX) && (slot_index < _sbatch.context_pool.pool.size)); return &_sbatch.context_pool.contexts[slot_index]; } /* get context pointer with id-check, returns 0 if no match */ static _sbatch_context* _sbatch_lookup_context(uint32_t ctx_id) { if (SG_INVALID_ID != ctx_id) { _sbatch_context* ctx = _sbatch_context_at(ctx_id); if (ctx->slot.id == ctx_id) { return ctx; } } return NULL; } /* make context handle from raw uint32_t id */ static sbatch_context _sbatch_make_ctx_id(uint32_t ctx_id) { sbatch_context ctx; ctx.id = ctx_id; return ctx; } static sbatch_context _sbatch_alloc_context(void) { sbatch_context ctx_id; const int slot_index = _sbatch_pool_alloc_index(&_sbatch.context_pool.pool); if (_SBATCH_INVALID_SLOT_INDEX != slot_index) { ctx_id = _sbatch_make_ctx_id(_sbatch_slot_alloc(&_sbatch.context_pool.pool, &_sbatch.context_pool.contexts[slot_index].slot, slot_index)); } else { /* pool is exhausted */ ctx_id = _sbatch_make_ctx_id(SG_INVALID_ID); } return ctx_id; } static void _sbatch_setup_pipeline_pool(const sbatch_desc* desc) { SOKOL_ASSERT(desc); /* note: the pool will have an additional item, since slot 0 is reserved */ SOKOL_ASSERT((desc->pipeline_pool_size > 0) && (desc->pipeline_pool_size < _SBATCH_MAX_POOL_SIZE)); _sbatch_init_pool(&_sbatch.pipeline_pool.pool, desc->pipeline_pool_size); const size_t pool_byte_size = sizeof(_sbatch_pipeline) * (size_t)_sbatch.pipeline_pool.pool.size; _sbatch.pipeline_pool.pipelines = (_sbatch_pipeline*)SOKOL_MALLOC(pool_byte_size); SOKOL_ASSERT(_sbatch.pipeline_pool.pipelines); memset(_sbatch.pipeline_pool.pipelines, 0, pool_byte_size); } static void _sbatch_discard_pipeline_pool(void) { SOKOL_ASSERT(_sbatch.pipeline_pool.pipelines); SOKOL_FREE(_sbatch.pipeline_pool.pipelines); _sbatch.pipeline_pool.pipelines = 0; _sbatch_discard_pool(&_sbatch.pipeline_pool.pool); } /* get pipeline pointer without id-check */ static _sbatch_pipeline* _sbatch_pipeline_at(uint32_t pip_id) { SOKOL_ASSERT(SG_INVALID_ID != pip_id); const int slot_index = _sbatch_slot_index(pip_id); SOKOL_ASSERT((slot_index > _SBATCH_INVALID_SLOT_INDEX) && (slot_index < _sbatch.pipeline_pool.pool.size)); return &_sbatch.pipeline_pool.pipelines[slot_index]; } /* get pipeline pointer with id-check, returns 0 if no match */ static _sbatch_pipeline* _sbatch_lookup_pipeline(uint32_t pip_id) { if (SG_INVALID_ID != pip_id) { _sbatch_pipeline* pip = _sbatch_pipeline_at(pip_id); if (pip->slot.id == pip_id) { return pip; } } return NULL; } /* make pipeline handle from raw uint32_t id */ static sbatch_pipeline _sbatch_make_pip_id(uint32_t pip_id) { sbatch_pipeline pip; pip.id = pip_id; return pip; } static sbatch_pipeline _sbatch_alloc_pipeline(void) { sbatch_pipeline pip_id; const int slot_index = _sbatch_pool_alloc_index(&_sbatch.pipeline_pool.pool); if (_SBATCH_INVALID_SLOT_INDEX != slot_index) { pip_id = _sbatch_make_pip_id(_sbatch_slot_alloc(&_sbatch.pipeline_pool.pool, &_sbatch.pipeline_pool.pipelines[slot_index].slot, slot_index)); } else { /* pool is exhausted */ pip_id = _sbatch_make_pip_id(SG_INVALID_ID); } return pip_id; } static sbatch_context_desc _sbatch_context_desc_defaults(const sbatch_context_desc* desc) { sbatch_context_desc res = *desc; res.max_sprites = _SBATCH_DEFAULT(res.max_sprites, 4096); res.canvas_height = _SBATCH_DEFAULT(res.canvas_height, 480); res.canvas_width = _SBATCH_DEFAULT(res.canvas_width, 640); return res; } static void _sbatch_init_context(sbatch_context ctx_id, const sbatch_context_desc* in_desc) { sg_push_debug_group("sokol-spritebatch"); SOKOL_ASSERT((ctx_id.id != SG_INVALID_ID) && in_desc); _sbatch_context* ctx = _sbatch_lookup_context(ctx_id.id); SOKOL_ASSERT(ctx); ctx->update_frame_index = -1; ctx->desc = _sbatch_context_desc_defaults(in_desc); ctx->label = _sbatch_make_str(ctx->desc.label); ctx->desc.label = NULL; const int max_vertices = 4 * ctx->desc.max_sprites; const size_t vbuf_size = (size_t)max_vertices * sizeof(_sbatch_vertex); ctx->vertices = (_sbatch_vertex*)SOKOL_MALLOC(vbuf_size); SOKOL_ASSERT(ctx->vertices); ctx->images = (sg_image*)SOKOL_MALLOC((size_t)ctx->desc.max_sprites * sizeof(sg_image)); SOKOL_ASSERT(ctx->images); ctx->pipeline.id = _SBATCH_DEFAULT(in_desc->pipeline.id, _sbatch.pipeline.id); ctx->sprite_count = 0; sg_buffer_desc vbuf_desc; memset(&vbuf_desc, 0, sizeof(vbuf_desc)); vbuf_desc.size = vbuf_size; vbuf_desc.type = SG_BUFFERTYPE_VERTEXBUFFER; vbuf_desc.usage = SG_USAGE_STREAM; vbuf_desc.label = "sokol-spritebatch-vertices"; ctx->vertex_buffer = sg_make_buffer(&vbuf_desc); SOKOL_ASSERT(SG_INVALID_ID != ctx->vertex_buffer.id); sg_pop_debug_group(); } static void _sbatch_destroy_context(sbatch_context ctx_id) { _sbatch_context* ctx = _sbatch_lookup_context(ctx_id.id); if (ctx) { if (ctx->vertices) { SOKOL_FREE(ctx->vertices); } if (ctx->images) { SOKOL_FREE(ctx->images); } sg_push_debug_group("sokol-spritebatch"); sg_destroy_buffer(ctx->vertex_buffer); sg_pop_debug_group(); memset(ctx, 0, sizeof(*ctx)); _sbatch_pool_free_index(&_sbatch.context_pool.pool, _sbatch_slot_index(ctx_id.id)); } } static sg_pipeline_desc _sbatch_pipeline_desc_defaults(const sg_pipeline_desc* desc) { sg_pipeline_desc pipeline_desc = *desc; pipeline_desc.color_count = _SBATCH_DEFAULT(pipeline_desc.color_count, 1); if (pipeline_desc.color_count == 1) { pipeline_desc.colors[0].blend.enabled = _SBATCH_DEFAULT(desc->colors[0].blend.enabled, true); pipeline_desc.colors[0].blend.src_factor_rgb = _SBATCH_DEFAULT(desc->colors[0].blend.src_factor_rgb, SG_BLENDFACTOR_ONE); pipeline_desc.colors[0].blend.src_factor_alpha = _SBATCH_DEFAULT(desc->colors[0].blend.src_factor_rgb, SG_BLENDFACTOR_ONE); pipeline_desc.colors[0].blend.dst_factor_rgb = _SBATCH_DEFAULT(desc->colors[0].blend.src_factor_rgb, SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA); pipeline_desc.colors[0].blend.dst_factor_alpha = _SBATCH_DEFAULT(desc->colors[0].blend.src_factor_rgb, SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA); } pipeline_desc.shader.id = _SBATCH_DEFAULT(desc->shader.id, _sbatch.shader.id); pipeline_desc.index_type = SG_INDEXTYPE_UINT16; pipeline_desc.layout.attrs[0].format = SG_VERTEXFORMAT_FLOAT3; pipeline_desc.layout.attrs[1].format = SG_VERTEXFORMAT_FLOAT2; pipeline_desc.layout.attrs[2].format = SG_VERTEXFORMAT_UBYTE4N; pipeline_desc.label = _SBATCH_DEFAULT(desc->label, "sokol-spritebatch-pipline"); return pipeline_desc; } static void _sbatch_init_pipeline(sbatch_pipeline pip_id, const sg_pipeline_desc* in_desc) { sg_push_debug_group("sokol-spritebatch"); SOKOL_ASSERT((pip_id.id != SG_INVALID_ID) && in_desc); _sbatch_pipeline* pip = _sbatch_lookup_pipeline(pip_id.id); SOKOL_ASSERT(pip); pip->desc = _sbatch_pipeline_desc_defaults(in_desc); pip->label = _sbatch_make_str(pip->desc.label); pip->desc.label = NULL; pip->pipeline = sg_make_pipeline(&pip->desc); SOKOL_ASSERT(pip->pipeline.id != SG_INVALID_ID); sg_pop_debug_group(); } static void _sbatch_destroy_pipeline(sbatch_pipeline pip_id) { _sbatch_pipeline* pip = _sbatch_lookup_pipeline(pip_id.id); if (pip) { sg_push_debug_group("sokol-spritebatch"); sg_destroy_pipeline(pip->pipeline); sg_pop_debug_group(); memset(pip, 0, sizeof(*pip)); _sbatch_pool_free_index(&_sbatch.pipeline_pool.pool, _sbatch_slot_index(pip_id.id)); } } static uint32_t _sbatch_pack_color_bytes(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { return (uint32_t)a << 24 | (uint32_t)b << 16 | (uint32_t)g << 8 | (uint32_t)r; } static float _sbatch_clampf(float v, float low, float high) { if (v < low) { return low; } if (v > high) { return high; } return v; } static uint32_t _sbatch_pack_color(const sg_color* color) { const uint8_t r = (uint8_t)(_sbatch_clampf(color->r, 0.0f, 1.0f) * 255.0f); const uint8_t g = (uint8_t)(_sbatch_clampf(color->g, 0.0f, 1.0f) * 255.0f); const uint8_t b = (uint8_t)(_sbatch_clampf(color->b, 0.0f, 1.0f) * 255.0f); const uint8_t a = (uint8_t)(_sbatch_clampf(color->a, 0.0f, 1.0f) * 255.0f); return _sbatch_pack_color_bytes(r, g, b, a); } static int _sg_image_slot_index(uint32_t id) { int slot_index = (int)(id & _SBATCH_IMAGE_SLOT_MASK); SOKOL_ASSERT(0 != slot_index); return slot_index; } static void _sbatch_setup_sprite_pool(void) { sg_desc sg_desc = sg_query_desc(); const int num_slots = sg_desc.image_pool_size; _sbatch.sprite_pool.size = (size_t)num_slots * sizeof(_sbatch_sprite_data); _sbatch.sprite_pool.data = (_sbatch_sprite_data*)SOKOL_MALLOC(_sbatch.sprite_pool.size); SOKOL_ASSERT(_sbatch.sprite_pool.data); memset(_sbatch.sprite_pool.data, 0, _sbatch.sprite_pool.size); } static void _sbatch_init_quad_rotated( _sbatch_vertex* vertices, float x, float y, float dx, float dy, float w, float h, float sin, float cos, uint32_t rgba, sbatch_float2 top_left, sbatch_float2 bottom_right, float depth) { _sbatch_vertex* top_left_vertex = vertices; top_left_vertex->x = x + dx * cos - dy * sin; top_left_vertex->y = y + dx * sin + dy * cos; top_left_vertex->z = depth; top_left_vertex->rgba = rgba; top_left_vertex->u = top_left.x; top_left_vertex->v = top_left.y; _sbatch_vertex* top_right_vertex = vertices + 1; top_right_vertex->x = x + (dx + w) * cos - dy * sin; top_right_vertex->y = y + (dx + w) * sin + dy * cos; top_right_vertex->z = depth; top_right_vertex->rgba = rgba; top_right_vertex->u = bottom_right.x; top_right_vertex->v = top_left.y; _sbatch_vertex* bottom_left_vertex = vertices + 2; bottom_left_vertex->x = x + dx * cos - (dy + h) * sin; bottom_left_vertex->y = y + dx * sin + (dy + h) * cos; bottom_left_vertex->z = depth; bottom_left_vertex->rgba = rgba; bottom_left_vertex->u = top_left.x; bottom_left_vertex->v = bottom_right.y; _sbatch_vertex* bottom_right_vertex = vertices + 3; bottom_right_vertex->x = x + (dx + w) * cos - (dy + h) * sin; bottom_right_vertex->y = y + (dx + w) * sin + (dy + h) * cos; bottom_right_vertex->z = depth; bottom_right_vertex->rgba = rgba; bottom_right_vertex->u = bottom_right.x; bottom_right_vertex->v = bottom_right.y; } static void _sbatch_init_quad( _sbatch_vertex* vertices, float x, float y, float w, float h, uint32_t rgba, sbatch_float2 top_left, sbatch_float2 bottom_right, float depth) { _sbatch_vertex* top_left_vertex = vertices; top_left_vertex->x = x; top_left_vertex->y = y; top_left_vertex->z = depth; top_left_vertex->rgba = rgba; top_left_vertex->u = top_left.x; top_left_vertex->v = top_left.y; _sbatch_vertex* top_right_vertex = vertices + 1; top_right_vertex->x = x + w; top_right_vertex->y = y; top_right_vertex->z = depth; top_right_vertex->rgba = rgba; top_right_vertex->u = bottom_right.x; top_right_vertex->v = top_left.y; _sbatch_vertex* bottom_left_vertex = vertices + 2; bottom_left_vertex->x = x; bottom_left_vertex->y = y + h; bottom_left_vertex->z = depth; bottom_left_vertex->rgba = rgba; bottom_left_vertex->u = top_left.x; bottom_left_vertex->v = bottom_right.y; _sbatch_vertex* bottom_right_vertex = vertices + 3; bottom_right_vertex->x = x + w; bottom_right_vertex->y = y + h; bottom_right_vertex->z = depth; bottom_right_vertex->rgba = rgba; bottom_right_vertex->u = bottom_right.x; bottom_right_vertex->v = bottom_right.y; } static void _sbatch_init_index_buffer(void) { uint16_t* index_buffer = (uint16_t*)SOKOL_MALLOC(_SBATCH_MAX_INDICES * sizeof(uint16_t)); SOKOL_ASSERT(index_buffer); uint16_t* index_ptr = index_buffer; for (uint32_t i = 0; i < _SBATCH_MAX_QUADS; i++, index_ptr += 6) { // Triangle 1 *(index_ptr + 0) = (uint16_t)(i * 4); *(index_ptr + 1) = (uint16_t)(i * 4 + 1); *(index_ptr + 2) = (uint16_t)(i * 4 + 2); // Triangle 2 *(index_ptr + 3) = (uint16_t)(i * 4 + 1); *(index_ptr + 4) = (uint16_t)(i * 4 + 3); *(index_ptr + 5) = (uint16_t)(i * 4 + 2); } sg_buffer_desc index_buffer_desc; memset(&index_buffer_desc, 0, sizeof(index_buffer_desc)); index_buffer_desc.size = _SBATCH_MAX_INDICES * sizeof(uint16_t); index_buffer_desc.type = SG_BUFFERTYPE_INDEXBUFFER; index_buffer_desc.usage = SG_USAGE_IMMUTABLE; index_buffer_desc.label = "sokol-spritebatch-indices"; index_buffer_desc.data.size = _SBATCH_MAX_INDICES * sizeof(uint16_t); index_buffer_desc.data.ptr = index_buffer; _sbatch.index_buffer = sg_make_buffer(&index_buffer_desc); SOKOL_ASSERT(SG_INVALID_ID != _sbatch.index_buffer.id); SOKOL_FREE(index_buffer); _sbatch.bindings.index_buffer = _sbatch.index_buffer; } static bool _sbatch_rect_is_valid(const sbatch_rect* rect) { if (rect->width != 0.0f && rect->height != 0.0f) { return true; } return false; } SOKOL_SPRITEBATCH_API_DECL int sbatch_frame() { return ++_sbatch.frame_index; } SOKOL_API_IMPL void sbatch_setup(const sbatch_desc* desc) { memset(&_sbatch, 0, sizeof _sbatch); sbatch_desc batch_desc = *desc; batch_desc.context_pool_size = _SBATCH_DEFAULT(batch_desc.context_pool_size, 32); batch_desc.pipeline_pool_size = _SBATCH_DEFAULT(batch_desc.pipeline_pool_size, 32); _sbatch_setup_context_pool(&batch_desc); _sbatch_setup_pipeline_pool(&batch_desc); _sbatch_setup_sprite_pool(); _sbatch.shader = sg_make_shader(spritebatch_shader_desc(sg_query_backend())); sg_pipeline_desc pipeline_desc; memset(&pipeline_desc, 0, sizeof(sg_pipeline_desc)); pipeline_desc.shader = _sbatch.shader; pipeline_desc.label = "spritebatch-default-pipeline"; pipeline_desc.color_count = 1; pipeline_desc.colors[0].pixel_format = desc->color_format; pipeline_desc.depth.pixel_format = desc->depth_format; pipeline_desc.sample_count = desc->sample_count; _sbatch.pipeline = sbatch_make_pipeline(&pipeline_desc); _sbatch_init_index_buffer(); } SOKOL_API_IMPL void sbatch_shutdown(void) { sg_destroy_buffer(_sbatch.index_buffer); sbatch_destroy_pipeline(_sbatch.pipeline); sg_destroy_shader(_sbatch.shader); SOKOL_FREE(_sbatch.sprite_pool.data); _sbatch_discard_pipeline_pool(); _sbatch_discard_context_pool(); } SOKOL_SPRITEBATCH_API_DECL sbatch_pipeline sbatch_make_pipeline(const sg_pipeline_desc* desc) { SOKOL_ASSERT(desc); const sbatch_pipeline result = _sbatch_alloc_pipeline(); _sbatch_init_pipeline(result, desc); return result; } SOKOL_SPRITEBATCH_API_DECL void sbatch_destroy_pipeline(sbatch_pipeline pipeline) { SOKOL_ASSERT(pipeline.id != SG_INVALID_ID); _sbatch_destroy_pipeline(pipeline); } SOKOL_API_IMPL sbatch_context sbatch_make_context(const sbatch_context_desc* desc) { SOKOL_ASSERT(desc); const sbatch_context result = _sbatch_alloc_context(); _sbatch_init_context(result, desc); return result; } SOKOL_API_IMPL void sbatch_destroy_context(sbatch_context context) { SOKOL_ASSERT(context.id != SG_INVALID_ID); _sbatch_destroy_context(context); } SOKOL_API_IMPL void sbatch_begin(sbatch_context context) { SOKOL_ASSERT(context.id != SG_INVALID_ID); _sbatch.ctx_id = context; SOKOL_ASSERT(!_sbatch.begin_called); _sbatch.begin_called = true; _sbatch_context* ctx = _sbatch_context_at(_sbatch.ctx_id.id); // a sbatch_context object can only be used in one sbatch_begin call per frame. SOKOL_ASSERT(_sbatch.frame_index != ctx->update_frame_index); ctx->update_frame_index = _sbatch.frame_index; SOKOL_ASSERT(ctx); _sbatch.bindings.vertex_buffers[0] = ctx->vertex_buffer; } SOKOL_API_IMPL void sbatch_push_sprite(const sbatch_sprite* sprite) { SOKOL_ASSERT(sprite); SOKOL_ASSERT(sprite->image.id != SG_INVALID_ID); _sbatch_context* ctx = _sbatch_context_at(_sbatch.ctx_id.id); SOKOL_ASSERT(ctx); if (ctx->sprite_count < ctx->desc.max_sprites) { const int sprite_index = ctx->sprite_count++; _sbatch_sprite_data* cached_sprite_data = &_sbatch.sprite_pool.data[_sg_image_slot_index(sprite->image.id)]; if (cached_sprite_data->image.id != sprite->image.id) { const sg_image_info info = sg_query_image_info(sprite->image); cached_sprite_data->height = info.height; cached_sprite_data->width = info.width; cached_sprite_data->texel_height = 1.0f / (float)info.height; cached_sprite_data->texel_width = 1.0f / (float)info.width; cached_sprite_data->image = sprite->image; } const sbatch_float2 scale = { _SBATCH_DEFAULT(sprite->scale.x, 1.0f), _SBATCH_DEFAULT(sprite->scale.y, 1.0f) }; const sbatch_float2 scaled_origin = { scale.x * sprite->origin.x, scale.y * sprite->origin.y }; float width, height; sbatch_float2 tex_coord_top_left; sbatch_float2 tex_coord_bottom_right; if (_sbatch_rect_is_valid(&sprite->source)) { width = sprite->source.width * scale.x; height = sprite->source.height * scale.y; tex_coord_top_left.x = sprite->source.x * cached_sprite_data->texel_width; tex_coord_top_left.y = sprite->source.y * cached_sprite_data->texel_height; tex_coord_bottom_right.x = (sprite->source.x + sprite->source.width) * cached_sprite_data->texel_width; tex_coord_bottom_right.y = (sprite->source.y + sprite->source.height) * cached_sprite_data->texel_height; } else { width = (float)cached_sprite_data->width * scale.x; height = (float)cached_sprite_data->height * scale.y; tex_coord_top_left.x = 0.0f; tex_coord_top_left.y = 0.0f; tex_coord_bottom_right.x = 1.0f; tex_coord_bottom_right.y = 1.0f; } if ((sprite->flags & SBATCH_FLIP_Y) != SBATCH_FLIP_NONE) { const float temp = tex_coord_bottom_right.y; tex_coord_bottom_right.y = tex_coord_top_left.y; tex_coord_top_left.y = temp; } if ((sprite->flags & SBATCH_FLIP_X) != SBATCH_FLIP_NONE) { const float temp = tex_coord_bottom_right.x; tex_coord_bottom_right.x = tex_coord_top_left.x; tex_coord_top_left.x = temp; } uint32_t packed_color = sprite->color ? _sbatch_pack_color(sprite->color) : 0xFFFFFFFF; ctx->images[sprite_index] = sprite->image; const int base_vertex_index = sprite_index * 4; _sbatch_vertex* vertices = ctx->vertices + base_vertex_index; if (sprite->rotation == 0.0f) { _sbatch_init_quad(vertices, sprite->position.x - scaled_origin.x, sprite->position.y - scaled_origin.y, width, height, packed_color, tex_coord_top_left, tex_coord_bottom_right, sprite->depth); } else { _sbatch_init_quad_rotated(vertices, sprite->position.x, sprite->position.y, -scaled_origin.x, -scaled_origin.y, width, height, sinf(sprite->rotation), cosf(sprite->rotation), packed_color, tex_coord_top_left, tex_coord_bottom_right, sprite->depth); } } else { if (ctx->label.buf[0] != '\0') { SOKOL_LOG("sokol_spritebatch.h: dropped sprites, increase max_sprites of sbatch_context:"); SOKOL_LOG(ctx->label.buf); } else { SOKOL_LOG("sokol_spritebatch.h: dropped sprites, increase max_sprites"); } } } SOKOL_API_IMPL void sbatch_push_sprite_rect(const sbatch_sprite_rect* sprite) { SOKOL_ASSERT(sprite); SOKOL_ASSERT(sprite->image.id != SG_INVALID_ID); _sbatch_context* ctx = _sbatch_context_at(_sbatch.ctx_id.id); SOKOL_ASSERT(ctx); if (ctx->sprite_count < ctx->desc.max_sprites) { const int sprite_index = ctx->sprite_count++; _sbatch_sprite_data* cached_sprite_data = &_sbatch.sprite_pool.data[_sg_image_slot_index(sprite->image.id)]; if (cached_sprite_data->image.id != sprite->image.id) { const sg_image_info info = sg_query_image_info(sprite->image); cached_sprite_data->height = info.height; cached_sprite_data->width = info.width; cached_sprite_data->texel_height = 1.0f / (float)info.height; cached_sprite_data->texel_width = 1.0f / (float)info.width; cached_sprite_data->image = sprite->image; } sbatch_float2 scaled_origin; sbatch_float2 tex_coord_top_left; sbatch_float2 tex_coord_bottom_right; if (_sbatch_rect_is_valid(&sprite->source)) { tex_coord_top_left.x = sprite->source.x * cached_sprite_data->texel_width; tex_coord_top_left.y = sprite->source.y * cached_sprite_data->texel_height; tex_coord_bottom_right.x = (sprite->source.x + sprite->source.width) * cached_sprite_data->texel_width; tex_coord_bottom_right.y = (sprite->source.y + sprite->source.height) * cached_sprite_data->texel_height; scaled_origin.x = sprite->origin.x * sprite->destination.width / sprite->source.width; scaled_origin.y = sprite->origin.y * sprite->destination.height / sprite->source.height; } else { tex_coord_top_left.x = 0.0f; tex_coord_top_left.y = 0.0f; tex_coord_bottom_right.x = 1.0f; tex_coord_bottom_right.y = 1.0f; scaled_origin.x = sprite->origin.x * sprite->destination.width * cached_sprite_data->texel_width; scaled_origin.y = sprite->origin.y * sprite->destination.height * cached_sprite_data->texel_height; } if ((sprite->flags & SBATCH_FLIP_Y) != SBATCH_FLIP_NONE) { const float temp = tex_coord_bottom_right.y; tex_coord_bottom_right.y = tex_coord_top_left.y; tex_coord_top_left.y = temp; } if ((sprite->flags & SBATCH_FLIP_X) != SBATCH_FLIP_NONE) { const float temp = tex_coord_bottom_right.x; tex_coord_bottom_right.x = tex_coord_top_left.x; tex_coord_top_left.x = temp; } uint32_t packed_color = sprite->color ? _sbatch_pack_color(sprite->color) : 0xFFFFFFFF; ctx->images[sprite_index] = sprite->image; const int base_vertex_index = sprite_index * 4; _sbatch_vertex* vertices = ctx->vertices + base_vertex_index; if (sprite->rotation == 0.0f) { _sbatch_init_quad(vertices, sprite->destination.x - scaled_origin.x, sprite->destination.y - scaled_origin.y, sprite->destination.width, sprite->destination.height, packed_color, tex_coord_top_left, tex_coord_bottom_right, sprite->depth); } else { _sbatch_init_quad_rotated(vertices, sprite->destination.x, sprite->destination.y, -scaled_origin.x, -scaled_origin.y, sprite->destination.width, sprite->destination.height, sinf(sprite->rotation), cosf(sprite->rotation), packed_color, tex_coord_top_left, tex_coord_bottom_right, sprite->depth); } } else { if (ctx->label.buf[0] != '\0') { SOKOL_LOG("sokol_spritebatch.h: dropped sprites, increase max_sprites of sbatch_context:"); SOKOL_LOG(ctx->label.buf); } else { SOKOL_LOG("sokol_spritebatch.h: dropped sprites, increase max_sprites"); } } } static void _sbatch_draw(int base_element, sg_image current_image, int num_elements) { _sbatch.bindings.fs_images[0] = current_image; sg_apply_bindings(&_sbatch.bindings); sg_draw(base_element, num_elements, 1); } static _sbatch_mat4x4 _sbatch_orthographic_off_center(float left, float right, float bottom, float top, float z_near, float z_far) { _sbatch_mat4x4 result; result.m[0][0] = 2.0f / (right - left); result.m[0][1] = 0.0f; result.m[0][2] = 0.0f; result.m[0][3] = 0.0f; result.m[1][0] = 0.0f; result.m[1][1] = 2.0f / (top - bottom); result.m[1][2] = 0.0f; result.m[1][3] = 0.0f; result.m[2][0] = 0.0f; result.m[2][1] = 0.0f; result.m[2][2] = 1.0f / (z_near - z_far); result.m[2][3] = 0.0f; result.m[3][0] = (left + right) / (left - right); result.m[3][1] = (bottom + top) / (bottom - top); result.m[3][2] = z_near / (z_near - z_far); result.m[3][3] = 1.0f; return result; } void sbatch_end(void) { SOKOL_ASSERT(_sbatch.begin_called); _sbatch.begin_called = false; _sbatch_context* ctx = _sbatch_context_at(_sbatch.ctx_id.id); SOKOL_ASSERT(ctx); if (ctx->sprite_count == 0) { return; } const int max_vertices = 4 * ctx->sprite_count; const size_t vbuf_size = (size_t)max_vertices * sizeof(_sbatch_vertex); const sg_range range = { ctx->vertices, vbuf_size }; sg_update_buffer(ctx->vertex_buffer, &range); int batch_size = 0; int base_element = 0; sg_image current_image = ctx->images[0]; const _sbatch_pipeline* pipeline = _sbatch_pipeline_at(ctx->pipeline.id); sg_apply_pipeline(pipeline->pipeline); sg_apply_viewportf(0.0f, 0.0f, (float)ctx->desc.canvas_width, (float)ctx->desc.canvas_height, true); _sbatch_mat4x4 matrix = _sbatch_orthographic_off_center(0.0f, (float)ctx->desc.canvas_width, (float)ctx->desc.canvas_height, 0.0f, 0.0f, 1000.0f); const sg_range matrix_range = { &matrix, sizeof matrix }; sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &matrix_range); if(ctx->fs_uniform_state.data) { sg_apply_uniforms(SG_SHADERSTAGE_FS, ctx->fs_uniform_state.ub_index, ctx->fs_uniform_state.data); } for (int i = 0; i < ctx->sprite_count; ++i, ++batch_size) { if (ctx->images[i].id != current_image.id) { const int num_elements = batch_size * 6; _sbatch_draw(base_element, current_image, num_elements); batch_size = 0; base_element += num_elements; current_image = ctx->images[i]; } } const int num_elements = batch_size * 6; _sbatch_draw(base_element, current_image, num_elements); ctx->sprite_count = 0; } SOKOL_API_IMPL void sbatch_apply_fs_uniforms(int ub_index, const sg_range* data) { SOKOL_ASSERT(data); SOKOL_ASSERT(data->ptr); _sbatch_context* ctx = _sbatch_context_at(_sbatch.ctx_id.id); ctx->fs_uniform_state.ub_index = ub_index; ctx->fs_uniform_state.data = data; } SOKOL_API_IMPL void sbatch_premultiply_alpha_rgba8(uint8_t* pixels, int pixel_count) { SOKOL_ASSERT(pixels); for (int i = 0; i < pixel_count; ++i) { pixels[0] = pixels[0] * pixels[3] / 255; pixels[1] = pixels[1] * pixels[3] / 255; pixels[2] = pixels[2] * pixels[3] / 255; pixels += 4; } } #endif /* SOKOL_SPRITEBATCH_IMPL */