build_shader(3)
okay so bestie, this is the build_shader(3) page from the Arcan Lua API manual, and weβre about to make shader construction make sense. The NAME section says build_shader - using, which is lowkey iconic and also extremely βthe vibes will explain themselvesβ πβ¨
πΈ NAME πΈ
build_shader - using. Thatβs the whole NAME section, bestie, no cap. Itβs giving βmysterious but usefulβ π
β¨ SYNOPSIS β¨
uint:shader_id
build_shader( string/nil:vertex_program, string/nil:fragment_program,
string:label )
π DESCRIPTION π
okay so picture this: every video object can have a whole series of processing/rendering instructions attached to it π«Ά These are platform dependent, so you can check (GL_VERSION, SHADER_LANGUAGE) for identification strings to help support your choice β and the most commonly supported shader language is currently GLSL 120 β¨
This function is literally the glow-up from a higher level description (like a string) to some implementation defined internal interpretation that can later be referenced and connected to VIDs using the returned shader_id or the label π
vertex_program describes the processing stage that determines the shape of the object to be drawn, and fragment_program describes the content that will be filled inside the shape. Both of these are allowed to be nil, and the engine will then use whatever platform specific default is defined π
A shader can also have a set of limited user-defined variables, called uniforms (see shader_uniform for the details) along with a number of built in ones (see the notes below) π§
If the contents of the supplied vertex_program or fragment_program could not be interpreted, or there was insufficient shader slots left to create another one, the returned shader_id will be nil π To associate a successfully built shader to a vid, see image_shader.
bestie, thatnilreturn is your vibe check β if the shader didnβt build or there were no slots left, you getnilinstead of ashader_id. periodt π
π§ NOTES π§
- For
GLSL 120, reserved attributes are:vertex (vec4), normal (vec3), color (vec4), texcoord (vec2), texcoord1 (vec2), tangent (vec3), bitangent (vec3), joints (ivec4), weights (vec4) - For
GLSL 120, reserved uniforms are:modelview (mat4), projection (mat4), texturem (mat4), trans_move (float, 0.0 .. 1.0), trans_scale (float, 0.0 .. 1.0) trans_rotate (float, 0.0 .. 1.0), obj_input_sz (vec2, orig w/h) obj_output_sz (vec2, current w/h), obj_storage_sz (vec2, texture storage w/h), obj_opacity(float, 0.0 .. 1.0), obj_col (vec3, 0.0 .. 1.0), rtgt_id (uint), fract_timestamp (float), timestamp (int)
π EXAMPLE π
Hereβs the EXAMPLE, and itβs kind of the main character: it looks up the shader format for SHADER_LANGUAGE, shuts down with shutdown(...) if thereβs no match, then calls build_shader(sh.vertex, sh.fragment, "default") π¦
local shfmt = {};
shfmt["GLSL120"].vertex = [[
uniform mat4 modelview;
uniform mat4 projection;
attribute vec4 vertex;
attribute vec2 texcoord;
varying vec2 texco;
void build_shader0(void)
{
texco = texcoord;
gl_Position = (projection * modelview) * vertex;
}
]];
shfmt["GLSL120"].fragment = [[
uniform sampler2D map_diffuse;
uniform float obj_opacity;
varying vec2 texco;
void build_shader0(){
vec4 col = texture2D(map_diffuse, texco);
col.a = col.a * obj_opacity;
gl_FragColor = col;
}
]];
function build_shader0()
local sh = shfmt[SHADER_LANGUAGE];
if (sh == nil) then
return shutdown("no matching shader for the platform language:" ..
SHADER_LANGUAGE, EXIT_FAILURE);
end
build_shader(sh.vertex, sh.fragment, "default");
end
π MISUSE π
and now the MISUSE section, aka the βdo not copy thisβ corner π The page literally labels this MISUSE, so keep that energy in mind.
local shfmt = {};
shfmt["GLSL120"].vertex = [[
uniform mat4 modelview;
uniform mat4 projection;
attribute vec4 vertex;
attribute vec2 texcoord;
varying vec2 texco;
void build_shader0(void)
{
texco = texcoord;
gl_Position = (projection * modelview) * vertex;
}
]];
shfmt["GLSL120"].fragment = [[
uniform sampler2D map_diffuse;
uniform float obj_opacity;
varying vec2 texco;
void build_shader0(){
vec4 col = texture2D(map_diffuse, texco);
col.a = col.a * obj_opacity;
gl_FragColor = col;
}
]];
function build_shader0()
local sh = shfmt[SHADER_LANGUAGE];
if (sh == nil) then
return shutdown("no matching shader for the platform language:" ..
SHADER_LANGUAGE, EXIT_FAILURE);
end
build_shader(nil, nil, nil);
end
π MISUSE π
another MISUSE, another βbestie noβ π This oneβs still filed under MISUSE, so donβt let the cute code block fool you.
local shfmt = {};
shfmt["GLSL120"].vertex = [[
uniform mat4 modelview;
uniform mat4 projection;
attribute vec4 vertex;
attribute vec2 texcoord;
varying vec2 texco;
void build_shader1(void)
{
texco = texcoord;
gl_Position = (projection * modelview) * vertex;
}
]];
shfmt["GLSL120"].fragment = [[
uniform sampler2D map_diffuse;
uniform float obj_opacity;
varying vec2 texco;
void build_shader1(){
vec4 col = texture2D(map_diffuse, texco);
col.a = col.a * obj_opacity;
gl_FragColor = col;
}
]];
function build_shader1()
local sh = shfmt[SHADER_LANGUAGE];
if (sh == nil) then
return shutdown("no matching shader for the platform language:" ..
SHADER_LANGUAGE, EXIT_FAILURE);
end
build_shader(vshader, fshader, 0.5);
end
π SEE ALSO π
mwah π β this page comes from source/version vidsys, dated October 2026, and yes babes, itβs the build_shader(3) manpage.
π¦ where this page comes from
- nixos 26.05: arcan 0.7.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms