Skip to content

Shared GL shader module

Open Realm and Orion UI vendor byte-identical GL Shader releases under vendor/gl_shader/. The module contract describes GLSL generation, typed storage, profile limits, allocators and release synchronization. No game, SDL or engine math types are part of that module.

renderer/r_shader.c compiles the implementation once. renderer/shader_desc.h keeps the public R_LoadShader / R_ApplyShader API and field-description macros. R_LoadShader now supplies sizeof(shader.state) so the shared loader validates all offsets and fixed array capacities. Existing game descriptors and GLSL bodies stay renderer-owned. Profiles still follow GL_BACKEND and GLSL.

The reusable functions return failure and clean up rejected programs. Open Realm's wrapper deliberately exits on a built-in failure: ri.error is a logger and cannot guarantee termination. No failed program is cached or drawn. Storage uses the module's matching malloc/free pair; optional allocator hooks allow other consumers to choose their allocation policy.

Every active uniform uploads on the first draw. Later submissions compare exact field bytes and active array counts. Shrinking and growing an array both trigger an upload. Matrix transposition happens in CPU scratch storage; GLES uploads always use GL_FALSE. A submission always binds its own program, even after an external glUseProgram, with no global cached binding across GL contexts. Program-owned storage is released before destroying the owning context.

R_BuildShaderDeclarations and R_BuildShaderMain retain public inspection entry points and return -1 for invalid profiles/interfaces or undersized buffers. Compilation uses a sizing pass, so declarations are not limited to a fixed 2048-byte stack buffer. Uniform count == 1 now correctly declares [1].

make -j4 test-gl-shader test-renderer-model test-renderer-shadows
make -j4 test openwarcraft3 openwow opensc2
python3 tools/engine_boundary_audit.py --base origin/main

The shared contract tests capture the real implementation's GL calls, including failure cleanup, storage rejection, cache hits/misses, sampler arrays and GLES matrix semantics. Existing renderer suites cover actual game descriptors and retain fatal-error assertions. These tests don't prove all shader bodies work on a GLES driver; backend shader-resource limits still require driver validation.

See also model shaders, vendored dependencies, and renderer platforms.