v2026.9.4
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. Targets the **3.3 core profile**, forward-compatible. That is the highest common denominator across the platforms Objeck ships: Windows, Linux and macOS desktop all reach it, and macOS caps at 4.1 core so nothing above 4.1 is portable there. GLES-only hardware (Raspberry Pi and similar) is out of scope by construction. Layers, from thinnest to friendliest -- all public, so nothing is capped: * GLWindow -- a window and a 3.3 core context, opened and paced for you. * GL -- static state operations. Thin, but never per-vertex. * Shader -- a linked program; Flat/Textured/TexturedFog/Normals built in, so the common cases need no GLSL at all. * Mesh -- geometry uploaded once into buffer objects, drawn many times, with Cube/Plane/Quad/Sphere built in, OBJ loading, and instancing. * Texture2D -- a texture, from a file or generated; Solid/Checker built in. * Light -- one directional light plus ambient, written into a shader. * RenderTarget -- draw into a texture instead of the window, then sample it. * Material -- a surface: its texture, tint and shininess. * Frustum -- the six planes of a view, for skipping what is off screen. * ShadowMap -- shadows from a directional or spot light, depth pass and all. * PointShadow -- shadows from a point light, in every direction, via a cube map. * Overlay -- text and rectangles over the scene, positioned in pixels. * Transform -- position, rotation and scale, with a cached matrix. * Box, Scene -- a world of boxes: draws itself, and answers collision. ## Why the API is shaped this way The native call boundary is expensive: the VM resolves each native symbol by string on EVERY call (GetProcAddress/dlsym) and boxes every argument into a fresh holder. A 1:1 mapping of OpenGL onto that would be thousands of lookups and allocations per frame. So each call here does real work -- 'compile a program from two sources' is one call, not the five GL calls it decomposes into -- and bulk data crosses as whole arrays, never element by element. This happens to be exactly what GL 3.3 core wants anyway: upload geometry once, then draw with few calls. ## Adding a call One `void fn(VMContext&)` in the OpenGL section of core/lib/sdl/sdl.cpp, and one method here that names it. See that file's header for the two rules that matter (positional slot indices, and keeping each call coarse).

RayHit

What a ray ran into, and where. Returned by Scene->Raycast. Always an object, never Nil -- ask IsHit rather than checking for Nil, so a miss does not need a different code path from a hit. The normal is the surface the ray struck, which is what a decal, a ricochet or a spark effect needs to orient itself. For a box it is an axis direction; for a prop it points away from the prop's centre, because a prop is tested against its bounding SPHERE rather than its actual geometry.

Operations

GetBox #

Which box was struck.

method : public : GetBox() ~ Box

Return

TypeDescription
Boxthe box, or Nil when a prop was hit or nothing was

GetDistance #

How far along the ray the hit was, in world units.

method : public : GetDistance() ~ Float

Return

TypeDescription
Floatthe distance, or 0 on a miss

GetNormalX #

method : public : GetNormalX() ~ Float

Return

TypeDescription
Floatx of the surface normal at the hit

GetNormalY #

method : public : GetNormalY() ~ Float

Return

TypeDescription
Floaty of the surface normal at the hit

GetNormalZ #

method : public : GetNormalZ() ~ Float

Return

TypeDescription
Floatz of the surface normal at the hit

GetProp #

Which prop was struck.

method : public : GetProp() ~ Prop

Return

TypeDescription
Propthe prop, or Nil when a box was hit or nothing was

GetX #

method : public : GetX() ~ Float

Return

TypeDescription
Floatx of the point struck

GetY #

method : public : GetY() ~ Float

Return

TypeDescription
Floaty of the point struck

GetZ #

method : public : GetZ() ~ Float

Return

TypeDescription
Floatz of the point struck

IsHit #

Did the ray hit anything?

method : public : IsHit() ~ Bool

Return

TypeDescription
Booltrue when it did

New # constructor

A miss.

New()

New # constructor

A hit. Built by Scene->Raycast; there is no reason to construct one yourself, and no way to change it afterwards -- a result that can be edited after the fact is a result nobody can trust.

New(distance:Float, x:Float, y:Float, z:Float, nx:Float, ny:Float, nz:Float, box:Box, prop:Prop)

Parameters

NameTypeDescription
distanceFloathow far along the ray
xFloatwhere it struck
yFloatwhere it struck
zFloatwhere it struck
nxFloatsurface normal
nyFloatsurface normal
nzFloatsurface normal
boxBoxthe box struck, or Nil
propPropthe prop struck, or Nil