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.

Box

An axis-aligned box in the world: where it is, how big it is, what it looks like, and whether you can walk through it. One cube mesh is shared by every Box; the box only supplies a transform. That is what keeps a scene of hundreds of boxes down to one uploaded mesh. That shared mesh must span -1..1 on every axis, because the model matrix scales it by `half` directly and `half` is a half-extent. Hand Scene a mesh built to -0.5..0.5 instead -- the "unit quad" in Mesh's own example is built that way -- and every box renders at half the size it claims, while OverlapsXZ goes on using the full half-extents. Geometry and collision then disagree with no error anywhere: you walk into walls that are not where they are drawn. The model matrix is computed once and cached, because a static prop's transform does not change between frames. Moving the box invalidates it.

Operations

GetMaterial #

method : public : GetMaterial() ~ Material

Return

TypeDescription
Materialthe material, or Nil when this box only has a texture

GetModelMatrix #

The box's model matrix: translate then scale, cached after the first call.

method : public : GetModelMatrix() ~ Float[]

Return

TypeDescription
Floata 4x4 model matrix, column-major

IsOpaque #

method : public : IsOpaque() ~ Bool

Return

TypeDescription
Booltrue when nothing about this box needs sorting

IsSolid #

Whether this box blocks movement. Floors and ceilings are usually set non-solid: they are drawn but should not stop a walking character.

method : public : IsSolid() ~ Bool

Return

TypeDescription
Booltrue when the box blocks

New # constructor

New(center:Vector3, half:Vector3, texture:Texture2D)

Parameters

NameTypeDescription
centerVector3the box's centre
halfVector3half-extents on each axis, so a 2x2x2 cube has half 1,1,1 -- which is also why the shared mesh has to span -1..1; see the class note
textureTexture2Dthe texture to draw it with; may be Nil

OverlapsXZ #

Whether a circle in plan view overlaps this box. Deliberately 2D: a walking character should not be blocked by something overhead, and testing the full 3D box would do exactly that. Corners are treated conservatively -- a near-miss at a corner counts as a hit, which is the right way to be wrong about a wall.

method : public : OverlapsXZ(x:Float, z:Float, radius:Float) ~ Bool

Parameters

NameTypeDescription
xFloatcircle centre x
zFloatcircle centre z
radiusFloatcircle radius

Return

TypeDescription
Booltrue when they overlap

SetCenter #

Move the box, discarding the cached transform.

method : public : SetCenter(center:Vector3) ~ Nil

Parameters

NameTypeDescription
centerVector3the new centre

SetMaterial #

Give this box a full material rather than a bare texture. Takes precedence over the texture it was constructed with -- a box with a material uses the material's texture, its tint and its shininess. Passing Nil goes back to the plain texture, which is what every existing scene uses and still works.

method : public : SetMaterial(material:Material) ~ Nil

Parameters

NameTypeDescription
materialMaterialthe material, or Nil

SetOpacity #

How opaque this box is. A transparent box is drawn after every solid one, furthest first -- which is what Scene->SetEye is for. Without that ordering a pane in front of another writes depth and hides it, and the result looks worse than no transparency at all.

method : public : SetOpacity(opacity:Float) ~ Nil

Parameters

NameTypeDescription
opacityFloat0.0 invisible to 1.0 solid

SetSolid #

method : public : SetSolid(solid:Bool) ~ Nil

Parameters

NameTypeDescription
solidBoolfalse to make the box scenery that does not block