Overview of sokol-shdc
mastersokol_gfx.h. It automates the process of converting shader source code into C/C++ code that can be easily integrated into Sokol-based graphics applications.repository·master·Indexed 43 days ago
https://github.com/floooh/sokol-toolsCommand line tools for sokol headers, featuring sokol_shdc, a shader cross-compiler and code-generator for sokol_gfx.h. It translates annotated GLSL (Vulkan-style version 450) into various shader dialects and language-specific headers for C, Zig, Rust, Odin, and others.
sokol_gfx.h. It automates the process of converting shader source code into C/C++ code that can be easily integrated into Sokol-based graphics applications.sokol-gfx or other language bindings.To use sokol-shdc, you must annotate your GLSL source with @-tags. These tags allow you to pack multiple shader stages (vertex, fragment, etc.) into a single file and define shader programs.
Common tags:
@vs [name]: Marks the start of a vertex shader stage.@fs [name]: Marks the start of a fragment shader stage.@end: Marks the end of a shader stage.@program [name] [vs_name] [fs_name]: Defines a shader program by linking a vertex shader and a fragment shader.For compatibility with other GLSL parsers, you can prefix tags with #pragma sokol (e.g., #pragma sokol @program ...).
@vs vs
layout(binding=0) uniform vs_params {
mat4 mvp;
};
in vec4 position;
in vec2 texcoord0;
out vec2 uv;
void main() {
gl_Position = mvp * position;
uv = texcoord0;
}
@end
@fs fs
layout(binding=0) uniform texture2D tex;
layout(binding=0) uniform sampler smp;
in vec2 uv;
out vec4 frag_color;
void main() {
frag_color = texture(sampler2D(tex,smp), uv);
}
@end
@program texcube vs fssokol_shdc tool is a shader cross-compiler and code-generator specifically designed for use with sokol_gfx.h. Detailed documentation for this tool can be found in docs/sokol-shdc.md.By default, sokol-shdc maps GLSL types to standard C types (e.g., mat4 to float[16]). If you use a math library like GLM or HandmadeMath, use the @ctype tag at the top of your GLSL file to map types to your library's specific types. This ensures the generated C structs are directly compatible with your math types.
Supported GLSL types for mapping: float, vec2, vec3, vec4, int, int2, int3, int4, and mat4.
Requirement: Mapped C/C++ types must match these byte sizes:
mat4: 64 bytesvec4, int4: 16 bytesvec3, int3: 12 bytesvec2, int2: 8 bytesfloat, int: 4 bytes@ctype mat4 hmm_mat4
@ctype vec4 hmm_vec4
@vs my_vs
layout(binding=0) uniform shape_uniforms {
mat4 mvp;
mat4 model;
vec4 shape_color;
vec4 light_dir;
vec4 eye_pos;
};
@endAll resources must use explicit layout(binding=N) annotations. These bindings map to specific indices in the sokol-gfx API. Bindings must be unique within their respective spaces for a given @program.
layout(binding=N) uniform { ... } where 0 <= N < 8. Maps to ub_slot in sg_apply_uniforms(N, ...).layout(binding=N) texture2D ... or layout(binding=N) buffer ... where 0 <= N < 32. Maps to the index in sg_bindings.views[N].layout(binding=N) sampler ... where 0 <= N < 12. Maps to the index in sg_bindings.samplers[N].// Uniform Block
layout(binding=0) uniform vs_params { mat4 mvp; };
// Texture and Sampler
layout(binding=1) uniform texture2D tex;
layout(binding=1) uniform sampler smp;
// Storage Buffer
layout(binding=2) readonly buffer in_ssbo { vec4 data[]; };To create a usable shader program, you must use the @program tag to link your defined stages. The name provided to @program determines the name of the generated C function used to retrieve the sg_shader_desc and the prefix for generated constants.
For a vertex-fragment pair:
@vs my_vertex_shader
...
@end
@fs my_fragment_shader
...
@end
@program my_program my_vertex_shader my_fragment_shaderThis generates a C function:
static const sg_shader_desc* my_program_shader_desc(sg_backend backend);@program my_program my_vertex_shader my_fragment_shaderTo debug the tools using an IDE, use ./fibs config to select a specific debug configuration for your platform and editor, then use ./fibs open to launch the project.
# Select a debug configuration
./fibs config macos-xcode-debug
./fibs config macos-vscode-debug
./fibs config win-vstudio-debug
./fibs config win-vscode-debug
./fibs config linux-vscode-debug
# Launch the project in your IDE
./fibs openFor fips projects, sokol-shdc can be integrated directly into the build process.
sokol-tools-bin to your fips.yml imports:imports:
sokol-tools-bin:
git: https://github.com/floooh/sokol-tools-bin./fips fetch and ./fips update.sokol_shader() macro in your CMakeLists.txt for each GLSL file:fips_begin_app(triangle windowed)
sokol_shader(triangle.glsl ${slang})
fips_end_app()Note: The ${slang} variable should be set based on your target platform (e.g., glsl300es for GLES3, hlsl5 for D3D11, metal_macos for Metal).
# Example of setting the slang variable based on platform
if (SOKOL_USE_D3D11)
add_definitions(-DSOKOL_D3D11)
set(slang "hlsl5")
elseif (SOKOL_USE_METAL)
add_definitions(-DSOKOL_METAL)
set(slang "metal_macos")
endif()You can use preprocessor checks in your GLSL source to write code that behaves differently depending on the target language (GLSL, HLSL, MSL, or WGSL). These checks are evaluated during the initial compiler pass and should be used inside @vs, @fs, or @block blocks.
#if SOKOL_GLSL
// target shader language is a GLSL dialect
#endif
#if SOKOL_HLSL
// target shader language is HLSL
#endif
#if SOKOL_MSL
// target shader language is MetalSL
#endif
#if SOKOL_WGSL
// target shader language is WGSL
#endif#if SOKOL_GLSL
// target shader language is a GLSL dialect
#endifYou can run sokol-shdc as an offline tool from the command line. Precompiled 64-bit binaries for Windows, Linux, and macOS are available in the sokol-tools-bin repository.
Basic Usage Example:
To convert a file named shd.glsl into a C header shd.h supporting multiple dialects:
./sokol-shdc --input shd.glsl --output shd.h --slang glsl430:hlsl5:metal_macos