Ape GFX is a low-level graphics API for desktop games written in Odin.
The API is Sokol-like where that helps: explicit handles, small descriptors, immediate-mode draw calls, and user-controlled resource lifetime. It is not trying to copy Sokol wholesale. Sokol treats web, mobile, and older graphics APIs as first-class targets; Ape GFX is deliberately narrower. The goal is a modern desktop-native graphics substrate for engines that want WebGPU-style resource contracts, Slang reflection, and explicit backend concepts without browser or mobile constraints.
This repo is the graphics layer only. It is not a renderer, material system, scene graph, gameplay framework, or asset pipeline.
Ape GFX is D3D12-first on Windows, with the public contract shaped around Slang reflection and modern explicit graphics APIs:
gfx.Backend.D3D12is the Windows backend target.Backend.Autoresolves to D3D12 when a native window is supplied.- Shader packages use
D3D12_DXILplus Vulkan SPIR-V metadata. - Generated shader bindings emit D3D12 native-slot constants.
- Samples are backend-neutral folders under
samples/. - The D3D12 runtime backend runs the current sample suite, including render targets, depth, MSAA, transient uniforms, compute, and indirect dispatch/draw.
The Vulkan backend remains a design pressure target, not current runtime work.
- Odin on
PATH - Slang shared libraries available to
tools/ape_shaderc - Windows for the D3D12 backend work
- PowerShell only for repo-level convenience wrappers
Build the repo task runner:
odin build .\tools\apeCompile all sample shaders:
odin run .\tools\ape -- shader compile -allRun the core validation gate:
odin run .\tools\ape -- validate coreBuild every sample:
odin run .\tools\ape -- sample build allvalidate full compiles shaders, runs public contract/tooling tests, builds
every sample, and runs every sample with the auto-exit guard:
odin run .\tools\ape -- validate fullThe render loop is intentionally small:
gfx.begin_pass(&ctx, {
label = "main pass",
action = gfx.default_pass_action(),
})
gfx.apply_pipeline(&ctx, pipeline)
gfx.apply_bindings(&ctx, bindings)
triangle_shader.apply_uniform_FrameUniforms(&ctx, &frame_uniforms)
gfx.draw(&ctx, 0, vertex_count)
gfx.end_pass(&ctx)
gfx.commit(&ctx)Resource creation is explicit:
vertex_buffer, ok := gfx.create_buffer(&ctx, {
label = "triangle vertices",
usage = {.Vertex, .Immutable},
data = gfx.range(vertices[:]),
})
if !ok {
fmt.eprintln("vertex buffer failed: ", gfx.last_error(&ctx))
return
}
defer gfx.destroy(&ctx, vertex_buffer)gfx: public graphics API, validation, and backend dispatchshader:.ashaderloading and conversion togfx.Shader_Descgfx_app: sample/application helpers for resize, shader setup, textures, and hot reloadapp: small window/event layer used by samplestools/ape: Odin task runner for shader compilation, docs, validation, and sample buildstools/ape_shaderc: Slang compiler/package toolsamples/ape_math: sample-only matrix helpers
Shader sources live in assets/shaders/*.slang.
Compile one shader package:
odin run .\tools\ape -- shader compile -shader-name textured_quadCompile all checked-in sample shaders:
odin run .\tools\ape -- shader compile -allEach compile writes:
- D3D12 DXIL bytecode
- Vulkan SPIR-V bytecode for later backend work
build/shaders/<name>.ashader- generated Odin bindings in
assets/shaders/generated/<name>/bindings.odin
Generated bindings are the preferred way to use shader slots,
ParameterBlock<> resource groups, uniforms, simple vertex layouts, storage
metadata, and compute dispatch helpers. Manual Pipeline_Desc.layout
overrides still exist for compact vertex formats, instancing, multiple
streams, and other engine-level layouts.
Samples are backend-neutral and build through tools/ape:
odin run .\tools\ape -- sample build triangle_minimal
odin run .\tools\ape -- sample build allCurrent samples:
cleartriangle_minimaltrianglecubetextured_quadtextured_cubedynamic_texturerender_to_texturedepth_render_to_texturemrtmsaagfx_labimproved_shadowstransient_uniformstriangle_indirectdispatch_indirectgpu_driven_indirect
gfx_lab remains the main API ergonomics sample.
Regenerate the checked-in API docs with:
odin run .\tools\ape -- docs generateUseful public docs:
docs/gfx-descriptor-contracts.mddocs/gfx-error-model.mddocs/gfx-public-api-audit.mddocs/gfx-slang-reflection-contract.mddocs/api/README.md