DrawCallAssembler¶
The Draw Call Assembler helps you generate efficient draw call batches for your meshes. You submit per-object draw requests (a mesh handle, a transform, a material, a pass) and the assembler does the heavy lifting in native C: it frustum-culls, selects a level of detail, sorts to minimize state changes, and collapses identical objects into instanced batches. It can then issue the draws for you, or hand back GPU-ready buffers so you can draw them yourself.
For a guided, example-first introduction, see the Draw Call Assembler user guide. This page is the flat API reference.
Usage¶
Registering meshes and submitting instances¶
use GL\Rendering\DrawCallAssembler;
use GL\Math\{Mat4, Vec3};
$assembler = new DrawCallAssembler();
$shipHandle = $assembler->registerMesh(
vao: $vao,
vertexCount: $vertexCount,
aabbMin: $aabbMin,
aabbMax: $aabbMax,
);
$assembler->bindTransformBuffer($vao, 2);
// each frame
$assembler->clearInstances();
$assembler->submit($shipHandle, $transform, materialId: 0);
Drawing the scene¶
Let the assembler issue the draws, running your callback before each one:
$assembler->execute(function (int $meshHandle, int $materialId, int $instanceOffset, int $instanceCount, int $flags) {
// the VAO is already bound; set uniforms, bind textures, etc.
});
Or build the packed buffers and drive the draws yourself:
$commandCount = $assembler->build();
$commands = $assembler->commandBuffer; // read with $commands[$i]
Constants¶
Sort modes¶
Passed to setSortMode.
public const SORT_NONE = 0; // keep submission order
public const SORT_FRONT_TO_BACK = 1; // nearest first (opaque default)
public const SORT_BACK_TO_FRONT = 2; // farthest first
Render passes¶
Passed as the $pass argument to submit.
public const PASS_OPAQUE = 0;
public const PASS_TRANSPARENT = 1; // sorted back-to-front automatically
public const PASS_DEPTH = 2;
public const PASS_USER = 3;
Instance flags¶
Combined as a bitmask in the $flags argument to submit.
public const FLAG_IGNORE_CULLING = 2; // draw even if outside the frustum
public const FLAG_DISABLE_INSTANCING = 4; // keep as its own draw call
public const FLAG_CUSTOM_SORT_KEY = 8; // use a custom sort key
Culling strategies¶
Passed to setCullingStrategy.
public const CULL_NONE = 0; // never cull, draw every instance
public const CULL_LINEAR = 1; // per-instance frustum test each frame (default)
public const CULL_OCTREE = 2; // persistent octree, rebuilt only when instances change
Properties¶
The buffers are filled after a call to build (and after execute, which builds internally). They contain only the instances that survived culling, in final draw order.
$commandBuffer¶
Packed draw commands, commandStride (8) uint32 values each: [mesh handle, vao id, index offset, draw count, base vertex, instance offset, instance count, material id].
$instanceTransformBuffer¶
One Mat4 per visible instance, transformStride (16) floats each.
$instanceMetaBuffer¶
Per-instance metadata, instanceMetaStride (4) uint32 values each: [mesh handle, material id, user id, flags].
$instancePayloadBuffer¶
Optional per-instance float payload (colors, skinning weights, and the like), in sorted order. See bindPayloadData.
$commandStride¶
The command buffer stride, in uint32 components, of one draw command entry (8).
$transformStride¶
The transform buffer stride, in float components, of one transform entry (16).
$instanceMetaStride¶
The metadata buffer stride, in uint32 components, of one metadata entry (4).
Methods¶
__construct¶
Creates a new assembler instance with preallocated capacities.
function __construct(int $initialMeshCapacity = 256, int $initialInstanceCapacity = 2048, int $initialCommandCapacity = 512)
- arguments
-
int$initialMeshCapacityNumber of mesh slots preallocated in the registry.int$initialInstanceCapacityNumber of instance slots backed by the buffers.int$initialCommandCapacityNumber of draw command slots.
registerMesh¶
Registers a mesh in the assembler's registry and returns a numeric handle you use to submit instances of it later. You remain the owner of any passed references; the assembler will not modify or delete them.
function registerMesh(int $vao, int $vertexOffset = 0, int $vertexCount = 0, int $indexOffset = 0, int $indexCount = 0, ?\GL\Math\Vec3 $aabbMin = null, ?\GL\Math\Vec3 $aabbMax = null, int $materialHint = 0, int $primitive = 0x0004) : int
- arguments
-
int$vaoOpenGL vertex array object handle that encapsulates buffers and layout.int$vertexOffsetStarting vertex inside the bound VBO (0 based).int$vertexCountNumber of vertices to draw when the mesh is rendered without indices.int$indexOffsetStarting index inside the EBO (set to 0 to draw arrays instead).int$indexCountNumber of indices used for indexed rendering (0 falls back to$vertexCountarrays).\GL\Math\Vec3|null$aabbMinOptional minimum point of the mesh bounds (used for frustum culling).\GL\Math\Vec3|null$aabbMaxOptional maximum point of the mesh bounds.int$materialHintOptional default material id applied whensubmit()omits a material.int$primitiveGL primitive value (defaults toGL_TRIANGLES= 0x0004).
- returns
-
intNumeric handle for the registered mesh.
setMeshMaterial¶
Updates or overrides the default material identifier attached to a mesh.
- arguments
-
int$meshHandleMesh handle returned byregisterMesh.int$materialIdThe new default material id.
setLodTable¶
Attaches level-of-detail alternatives to a mesh. When you submit the base mesh, the assembler substitutes a cheaper mesh past each distance threshold.
function setLodTable(int $meshHandle, \GL\Buffer\FloatBuffer $distanceThresholds, \GL\Buffer\UIntBuffer $meshHandles) : void
- arguments
-
int$meshHandleBase mesh handle (the one to be replaced) returned byregisterMesh.\GL\Buffer\FloatBuffer$distanceThresholdsDistances in ascending order.\GL\Buffer\UIntBuffer$meshHandlesMesh handle for each LOD level.
setAutoInstancing¶
Enables or disables automatic instancing for meshes submitted multiple times per frame. Enabled by default.
- arguments
-
bool$enabledWhether to collapse compatible instances into batched draws.
setSortMode¶
Selects the ordering applied to opaque draw calls.
- arguments
-
int$modeOne of theSORT_*constants.
setCullingStrategy¶
Selects the culling strategy used during build / execute. The two optional arguments tune the octree and are ignored by the other strategies; they only take effect when >= 0, and passing -1 leaves the current value untouched. Changing either rebuilds the tree.
function setCullingStrategy(int $strategy, int $octreeMaxDepth = -1, int $octreeMinLeafInstances = -1) : void
- arguments
-
int$strategyOne of theCULL_*constants.int$octreeMaxDepthMaximum octree subdivision depth. Increase for scenes with a large spatial extent and uneven density.int$octreeMinLeafInstancesA node stops subdividing once it holds this many instances or fewer.
setCameraData¶
Updates the camera state used for sorting, frustum culling, and LOD evaluation. The position drives LOD selection, while the view and projection matrices drive both sorting and frustum generation.
function setCameraData(?\GL\Math\Vec3 $cameraPosition = null, ?\GL\Math\Mat4 $viewMatrix = null, ?\GL\Math\Mat4 $projectionMatrix = null) : void
- arguments
-
\GL\Math\Vec3|null$cameraPositionCamera position used for LOD selection.\GL\Math\Mat4|null$viewMatrixView matrix used for frustum generation.\GL\Math\Mat4|null$projectionMatrixProjection matrix used for frustum generation.
setFrustumPlanes¶
Manually configures the six frustum planes used for culling. Each plane is a Vec4 holding the plane equation ax + by + cz + d = 0.
function setFrustumPlanes(\GL\Math\Vec4 $left, \GL\Math\Vec4 $right, \GL\Math\Vec4 $bottom, \GL\Math\Vec4 $top, \GL\Math\Vec4 $near, \GL\Math\Vec4 $far) : void
- arguments
-
\GL\Math\Vec4$leftLeft plane.\GL\Math\Vec4$rightRight plane.\GL\Math\Vec4$bottomBottom plane.\GL\Math\Vec4$topTop plane.\GL\Math\Vec4$nearNear plane.\GL\Math\Vec4$farFar plane.
bindTransformBuffer¶
Binds and sets up the instance transform buffer on a VAO for instanced rendering. It creates or reuses an internal VBO, sets up the four vec4 attribute locations the transform matrix occupies, and returns the next free attribute location. Must be called before execute.
- arguments
-
int$vaoThe vertex array object to configure.int$offsetThe starting vertex attribute location. For example,2puts the matrix at locations 2, 3, 4, 5.
- returns
-
intThe next available attribute location after the transform matrix.
bindPayloadData¶
Registers a FloatBuffer of custom per-instance data (colors, skinning weights, and the like) and how many floats make up each instance's payload. The data becomes available in $instancePayloadBuffer after build. Remember to also call bindPayloadBuffer to set up the attributes.
- arguments
-
\GL\Buffer\FloatBuffer$payloadBufferBuffer containing per-instance payload data.int$strideNumber of floats per instance in the payload buffer.
bindPayloadBuffer¶
Sets up the vertex attribute pointers for the payload data on a VAO. Must be called after bindPayloadData.
- arguments
-
int$vaoThe vertex array object to configure.int$offsetThe starting vertex attribute location.int$strideNumber of floats per payload entry (0 uses the stride bound viabindPayloadData).
- returns
-
intThe next available attribute location after the payload attributes.
clearInstances¶
Removes all recorded instances without touching the registered meshes. Call this at the top of each frame before submitting.
submit¶
Records a single mesh instance for the current frame.
function submit(int $meshHandle, \GL\Math\Mat4 $transform, int $materialId, int $pass = 0, int $programId = 0, int $flags = 0, float $sortBias = 0.0, int $userId = 0) : void
- arguments
-
int$meshHandleMesh handle fromregisterMesh.\GL\Math\Mat4$transformWorld transform.int$materialIdMaterial identifier.int$passRender pass identifier (one of thePASS_*constants).int$programIdOptional program/shader identifier used for batching and sorting.int$flagsOptional state overrides (FLAG_*bitmask).float$sortBiasExtra distance bias applied when sorting draws.int$userIdOptional user-supplied id mirrored into the metadata buffer.
build¶
Builds the final draw list, filling $commandBuffer, $instanceTransformBuffer, $instanceMetaBuffer, and $instancePayloadBuffer. Use this to handle and execute the draw calls manually; otherwise use execute.
- returns
-
intThe number of draw commands generated for this frame.
execute¶
Builds the draw list and issues the OpenGL draw calls. The callback runs before each draw so you can set up materials and other GL state; the VAO is bound and the draw issued by the assembler internally. You must call bindTransformBuffer before using this method.
The callback receives (int $meshHandle, int $materialId, int $instanceOffset, int $instanceCount, int $flags).
- arguments
-
callable$drawCallbackA "before draw" callback invoked once per draw command.
- returns
-
intThe number of draw commands executed.
commandCount¶
Returns the number of draw commands generated by the previous build call.
instanceCount¶
Returns the number of instances submitted so far for the current frame.
builtInstanceCount¶
Returns the number of instances that survived culling in the last build call.
clearMeshes¶
Completely removes all registered meshes and releases their buffers.
reset¶
Resets both the mesh registry and the current frame state.