v2026.9.7
All Bundles
Bundle

OpenGL 3.3 core rendering on top of SDL2. Builds on sdl2.obl for the window and context; this bundle is the GL side. Compile with -lib sdl2. Layers, thinnest first: GLWindow (window and context), GL (state), Shader, Mesh, Texture2D, Light, RenderTarget, Material, Frustum, ShadowMap, PointShadow, Overlay, Transform, and Box/Scene. All public, so nothing is capped. Targets the 3.3 core profile, forward-compatible: the highest common denominator across the desktop platforms Objeck ships, since macOS caps at 4.1 core. GLES-only hardware is out of scope by construction. See docs/opengl.md for setup, a minimal program, why the calls are coarse-grained, and how to add one.

Light

One light. Directional, point or spot. Build one with the factory that matches what you want, since each kind needs different things and a single constructor taking all of them would ask for values that do not apply: A single Light can be handed straight to a shader with ApplyTo, which is the common case. For more than one, put them in a LightRig.

Which way a direction points

TOWARD the light, not the way the light travels. A directional light of (0, 1, 0) is overhead, so upward-facing surfaces are brightest. This is the convention that makes the shader's dot product read naturally and it is the one people get backwards -- a scene lit from underneath is the symptom. A SPOT's aim is the opposite: the direction it shines, which is what you would point a torch along.

Example

sun := Light->Directional(Vector3->New(-0.3, 1.0, 0.4));
lamp := Light->Point(Vector3->New(0.0, 3.0, 0.0), 12.0);
torch := Light->Spot(position, aim, 15.0, 20.0, 30.0);

Operations

ApplyAt #

Write this light into one slot of a shader's light arrays. Used by LightRig; call that rather than this unless you are writing your own rig.

method : public : ApplyAt(shader:Shader, index:Int) ~ Nil

Parameters

NameTypeDescription
shaderShaderthe program
indexIntwhich slot

ApplyTo #

Write this light into a shader as its ONLY light, with a default ambient. The single-light case, and what most scenes want. For more than one, or to set the ambient yourself, use a LightRig.

method : public : ApplyTo(shader:Shader) ~ Nil

Parameters

NameTypeDescription
shaderShaderthe program to write into

Directional # function

A light infinitely far away: the sun.

function : Directional(direction:Vector3) ~ Light

Parameters

NameTypeDescription
directionVector3toward the light

Return

TypeDescription
Lightthe light

GetInnerCosine #

The cosine of the inner cone half-angle. Cosines rather than angles because that is what the shader compares against a dot product.

method : public : GetInnerCosine() ~ Float

Return

TypeDescription
Floatthe cosine

GetOuterCosine #

The cosine of the outer cone half-angle.

method : public : GetOuterCosine() ~ Float

Return

TypeDescription
Floatthe cosine

New # constructor

A white light from above with a little ambient, which is a reasonable starting point for seeing a scene at all.

New()

Point # function

A light at a position, fading to nothing at its range. The falloff reaches ZERO at the range rather than trailing off forever the way an inverse square does. A light that stops where it says it stops is what lets a scene have several without every one of them contributing to every surface.

function : Point(position:Vector3, range:Float) ~ Light

Parameters

NameTypeDescription
positionVector3where it is
rangeFloathow far its light reaches, in world units

Return

TypeDescription
Lightthe light

SetAmbient #

The light every surface gets regardless of which way it faces, used when this light is applied on its own. Without it, a face turned away is pure black -- correct for one light in a vacuum and wrong-looking for anything else, since real surfaces are lit by everything around them. In a LightRig the rig's ambient is used instead.

method : public : SetAmbient(r:Float, g:Float, b:Float) ~ Nil

Parameters

NameTypeDescription
rFloatred, 0..1
gFloatgreen, 0..1
bFloatblue, 0..1

SetAxis #

method : public : SetAxis(aim:Vector3) ~ Nil

Parameters

NameTypeDescription
aimVector3the direction a spot shines

SetColor #

method : public : SetColor(r:Float, g:Float, b:Float) ~ Nil

Parameters

NameTypeDescription
rFloatred, 0..1
gFloatgreen, 0..1
bFloatblue, 0..1

SetCone #

A spot's cone, in degrees from its axis. Stored as cosines, because the shader compares a dot product and converting back would cost an acos per fragment per light.

method : public : SetCone(inner_degrees:Float, outer_degrees:Float) ~ Nil

Parameters

NameTypeDescription
inner_degreesFloathalf-angle of the fully lit centre
outer_degreesFloathalf-angle where it reaches nothing

SetDirection #

method : public : SetDirection(direction:Vector3) ~ Nil

Parameters

NameTypeDescription
directionVector3toward the light, for a directional light

SetDirection #

method : public : SetDirection(x:Float, y:Float, z:Float) ~ Nil

Parameters

NameTypeDescription
xFloattoward the light, x
yFloattoward the light, y
zFloattoward the light, z

SetIntensity #

Scale the colour, for a light that pulses or dims.

method : public : SetIntensity(scale:Float) ~ Nil

Parameters

NameTypeDescription
scaleFloatmultiplied into the colour

SetPosition #

method : public : SetPosition(position:Vector3) ~ Nil

Parameters

NameTypeDescription
positionVector3where a point or spot light is

SetRange #

method : public : SetRange(range:Float) ~ Nil

Parameters

NameTypeDescription
rangeFloathow far a point or spot light reaches

Spot # function

A light at a position, shining along an axis within a cone.

function : Spot(position:Vector3, aim:Vector3, range:Float, inner_degrees:Float, outer_degrees:Float) ~ Light

Parameters

NameTypeDescription
positionVector3where it is
aimVector3the direction it shines -- the opposite sense to a directional light's direction, because this is where you point it
rangeFloathow far its light reaches
inner_degreesFloatthe half-angle of the fully lit centre
outer_degreesFloatthe half-angle where it reaches nothing; must be larger than inner_degrees or the edge has no width to fade across

Return

TypeDescription
Lightthe light