sokol-samples

repository·master·Indexed 21 days ago

https://github.com/floooh/sokol-samples

A collection of example code for the sokol graphics library, demonstrating various backends (Metal, D3D11, OpenGL, WebGL, WebGPU) and platforms (macOS, Windows, Linux, Emscripten, iOS, Android). The repository utilizes the fibs meta-build-system and includes reference implementations for QOI (Quite OK Image Format) and the spine-c runtime compatible with Spine 4.1.xx.

Tokens
4.7K
Snippets
9
Records
24
Agent score
74%

What's inside sokol-samples

  1. Overview of QOI (Quite OK Image Format)

    master
    QOI is a single-file, MIT-licensed C/C++ library designed for fast, lossless image compression. It aims to provide a sweet spot between compression ratio and throughput. While its compression ratio is typically lower than PNG (specifically libPNG), its throughput is significantly higher. The format is intentionally simple to facilitate easy porting to other programming languages.
  2. Overview of vecmath.h

    master

    vecmath.h is a comprehensive vector and matrix math library for C and C++. It is designed to provide functionality similar to shader languages like GLSL and HLSL, with some parts modeled after the DirectX D3DX library.

    Key characteristics:

    • No SIMD intrinsics: It implements functions in a straightforward way without relying on SIMD, allowing compilers to optimize as needed.
    • C-First Design: Primarily a C library, but provides pragmatic C++ support (e.g., using namespace vecmath and operator overloading).
    • Predictable API: Uses standard terminology and consistent naming conventions.
    • Row-Major Matrices: Matrices are row-major; if using an API like OpenGL that expects column-major, you must transpose them first.
  3. How to extend spine-c for rendering

    master

    The spine-c runtime is a non-rendering library. To use it with a graphics API (like Sokol, OpenGL, or SFML), you must implement three specific extension methods to bridge the runtime with your renderer:

    1. _spAtlasPage_createTexture: Loads a texture and stores the texture handle and its dimensions (width, height) in the void* rendererObject, width, and height fields of an spAtlasPage struct.
    2. _spAtlasPage_disposeTexture: Handles the disposal of textures previously loaded via _spAtlasPage_createTexture.
    3. _spUtil_readFile: Handles file reading. If you do not need custom logic, you can use the provided _readFile which uses standard fopen.

    Rendering Workflow: Once these are implemented, you can load Spine animation data. To render, you must:

    1. Enumerate the slots for a skeleton.
    2. Render the attachment for each slot.
    3. Access the void* rendererObject field on the attachment (which is populated during loading) to retrieve your renderer-specific texture or data.

    For example, when using an AtlasAttachmentLoader with a texture atlas, a RegionAttachment will have its void* rendererObject set to an AtlasRegion. You can then use that to find its AtlasPage and the corresponding texture handle stored in the page's void* rendererObject.

  4. Vector and Matrix Types

    master

    The library provides several fundamental types for vectors and matrices.

    Vectors:

    • vec2_t: 2-component (x, y)
    • vec3_t: 3-component (x, y, z)
    • vec4_t: 4-component (x, y, z, w)

    Matrices (Row-Major): Matrices are composed of rows, where each row is a vector type.

    • mat22_t to mat24_t: 2 rows
    • mat32_t to mat34_t: 3 rows
    • mat42_t to mat44_t: 4 rows

    C++ Specifics: In C++, you can use class-equivalents without the _t suffix (e.g., vec3, mat44) which support overloaded constructors and operators.

  5. QOI Format Specifications and Implementation Limits

    master

    Format Details

    • MIME Type: image/qoi
    • File Extension: .qoi
    • Versioning: The format is finalized and does not use a version number in the file header, ensuring long-term compatibility.

    Implementation Limitations

    This specific implementation is not a streaming encoder/decoder. It loads the entire image file into RAM before processing. Consequently, it is limited to images with a maximum size of 400 million pixels. It will safely refuse to encode or decode anything larger than this limit.

  6. Spine-c compatibility and architecture

    master

    Compatibility

    • Spine Version: spine-c is compatible with data exported from Spine 4.1.xx.
    • Features: Supports all Spine features.

    Architecture

    spine-c uses an Object-Oriented (OOP) style implemented in ANSI C89. Each "class" consists of a struct and a set of functions prefixed with that struct's name (e.g., spSkeleton...).

    This architecture allows for extensibility. You can provide your own implementations for core interfaces such as:

    • spAttachmentLoader
    • spAttachment
    • spTimeline
  7. Build sokol-samples manually without a build system

    master

    For manual integration into your own projects, you can build samples directly using your system compiler. The expected directory structure assumes sokol-samples, sokol, and sokol-tools-bin are cloned side-by-side.

    macOS (Clang)

    Metal Sample: cc cube-metal.c osxentry.m sokol_gfx.m -o cube-metal -fobjc-arc -I../../sokol -framework Metal -framework AppKit -framework QuartzCore

    sokol-app (sapp) with Metal:

    1. Compile shaders: ../../sokol-tools-bin/bin/osx/sokol-shdc -i cube-sapp.glsl -o cube-sapp.glsl.h -l metal_macos
    2. Compile C code: cc cube-sapp.c ../libs/sokol/sokol.m -o cube-sapp -DSOKOL_METAL -fobjc-arc -I../../sokol -I ../libs -framework Metal -framework AppKit -framework QuartzCore -framework AudioToolbox

    Windows (MSVC)

    Run from a Developer Command Prompt.

    D3D11 Sample: cl cube-d3d11.c d3d11entry.c /I..//..//sokol

    sokol-app (sapp) with D3D11:

    1. Compile shaders: ..\..\sokol-tools-bin\bin\win32\sokol-shdc -i cube-sapp.glsl -o cube-sapp.glsl.h -l hlsl5
    2. Compile C code: cl cube-sapp.c ..\libs\sokol\sokol.c /DSOKOL_D3D11 /I..\..\sokol /I..\libs

    Windows (MSYS2/MinGW GCC)

    Use the -mwin32 flag for proper platform detection.

    sokol-app (sapp) with D3D11:

    1. Compile shaders: ../../sokol-tools-bin/bin/win32/sokol-shdc -i cube-sapp.glsl -o cube-sapp.glsl.h -l hlsl5:glsl430
    2. Compile C code: gcc cube-sapp.c ../libs/sokol/sokol.c -o cube-sapp-d3d11 -mwin32 -O2 -DSOKOL_D3D11 -I../../sokol -I ../libs -lkernel32 -luser32 -lshell32 -ldxgi -ld3d11 -lole32 -lgdi32

    Linux (GCC)

    GLFW Sample: cc cube-glfw.c glfw_glue.c flextgl/flextGL.c -o cube-glfw -I../../sokol -lGL -ldl -lm -lglfw3

    sokol-app (sapp) with GL:

    1. Compile shaders: ../../sokol-tools-bin/bin/linux/sokol-shdc -i cube-sapp.glsl -o cube-sapp.glsl.h -l glsl430
    2. Compile C code: cc cube-sapp.c ../libs/sokol/sokol.c -o cube-sapp -DSOKOL_GLCORE -pthread -I../../sokol -I../libs -lGL -ldl -lm -lX11 -lasound -lXi -lXcursor
    # Example: Manual build of a Metal sample on macOS
    cd sokol-samples/metal
    cc cube-metal.c osxentry.m sokol_gfx.m -o cube-metal -fobjc-arc -I../../sokol -framework Metal -framework AppKit -framework QuartzCore
  8. Cross-compile to Emscripten, iOS, or Android

    master

    You can use fibs to target different platforms.

    Emscripten (Web/WASM)

    1. Install the Emscripten SDK: ./fibs emsdk install
    2. Pick a config with -emsc- in the name, build, and run: ./fibs config sapp-gles-emsc-ninja-debug ./fibs build ./fibs run triangle-sapp (this opens your default browser).

    iOS

    1. Pick an iOS build config and open in Xcode: ./fibs config sapp-metal-ios-xcode-debug ./fibs open
    2. To build for a real device, set your iOS Team Id: ./fibs set iosteamid [your-team-id] ./fibs config sapp-metal-ios-xcode-debug

    Android

    1. Ensure JDK 17 is installed. Verify tools via ./fibs diag tools (look for java, javac, and unzip).
    2. Install the Android SDK/NDK: ./fibs android install
    3. Pick an Android config and build: ./fibs config sapp-gles-android-ninja-debug ./fibs build
    4. Run on an attached device: ./fibs run triangle-sapp
    # Emscripten example
    ./fibs emsdk install
    ./fibs config sapp-gles-emsc-ninja-debug
    ./fibs build
    ./fibs run triangle-sapp
    
    # iOS Team ID setup
    ./fibs set iosteamid [your-team-id]
    ./fibs config sapp-metal-ios-xcode-debug
    
    # Android setup
    ./fibs diag tools
    ./fibs android install
    ./fibs config sapp-gles-android-ninja-debug
    ./fibs build
    ./fibs run triangle-sapp
  9. Configure local sokol development

    master

    If you are actively developing sokol and want sokol-samples to use your local version instead of the one imported in .fibs/imports, follow these steps:

    1. Clone sokol into a 'sister directory' relative to sokol-samples: git clone https://github.com/floooh/sokol ../sokol
    2. Link the local directory to the sokol import: ./fibs link sokol ../sokol
    3. Verify the link: ./fibs list imports
    # Link local sokol repository
    ./fibs link sokol ../sokol
    
    # Verify
    ./fibs list imports
  10. Prerequisites for building sokol-samples

    master

    Before building or running samples, ensure the following tools are installed on your system:

    • deno: Required for the fibs build system.
    • cmake: Required for the build process.
    • C/C++ toolchain: Your system's default (MSVC, GCC, or Clang).
    • ninja: Optional but recommended for faster builds.

    Platform-specific requirements:

    Linux

    Install development packages for OpenGL, X11, ALSA, and Vulkan: libgl1-mesa-dev, libegl1-mesa-dev, mesa-common-dev, xorg-dev, libasound-dev, libvulkan-dev, vulkan-validationlayers, vulkan-tools.

    Windows

    • If using Vulkan, install the Vulkan SDK and ensure the VULKAN_SDK environment variable is valid.
    • Run builds from a 'Visual Studio Command Prompt' window.
    • For 64-bit builds, use the VSxxxx x64 Native Tools Command Prompt.
  11. Generate .basis files using basisu

    master

    To create .basis files for use in samples, use the basisu tool from the basis_universal repository. You can generate mipmaps during the conversion process using the -mipmap flag.

    Example commands:

    > basisu -mipmap testcard.png
    > basisu -mipmap testcard_alpha.png
    > basisu -mipmap testcard.png
  12. Run vecmath.h Unit Tests

    master

    The library includes over 1300 tests. To run them, you must compile the header file directly and define VECMATH_RUN_TESTS.

    Using Clang/GCC

    clang -xc vecmath.h -DVECMATH_RUN_TESTS

    Using MSVC

    cl -Tc vecmath.h -DVECMATH_RUN_TESTS

    Advanced Testing

    • D3DX Conformance: Define VECMATH_RUN_D3DX_TESTS to compare results against Microsoft's D3DX9 library (requires D3D9 headers/libs).
    • External Test Framework: To use testfw.h, place it in the same directory as vecmath.h and define VECMATH_USE_EXTERNAL_TESTFW.
    clang -xc vecmath.h -DVECMATH_RUN_TESTS