Renderer · class
Mesh
Explained in Hello world.
class Meshimport { Mesh } from '@driftengine/core';Constructor
new
constructor(gl: WebGL2RenderingContext, data: MeshData, dynamic?: boolean, spread?: boolean)| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext | |
data | MeshData | |
dynamic? | boolean | |
spread? | boolean | Allocate the buffers now and fill them from uploads later. Off by default,
and the default is the fast path: filling a buffer with bufferData in one call skips the
zero-fill that bufferData(size) then bufferSubData pays for, and every mesh in the
engine that does not need to be spread should keep skipping it. |
Properties
| Name | Type | Description |
|---|---|---|
indexCountreadonly | number | Indices one draw of it issues; the batch-size rule reads it (cullsInstances). At zero the
mesh has nothing to draw and no verb draws it, as on WebGPU (GpuMesh.indexCount): a draw of
nothing is silent here but is still a call and a counted draw, and the two backends count the
same frame. |
boundsreadonly | Bounds | How big this mesh is, in its own space.MoreMeasured here because the positions are already in hand: the upload walks them anyway, so a
caller gets bounds for nothing and no |
isSkinnedreadonly | boolean | Whether this mesh carries a rig, which decides which flat program draws it. |
isSkinnedEightreadonly | boolean | Whether its rig moves a vertex by eight influences rather than four, which decides whether the
skinned program it takes is built with SKIN_EIGHT on. See skinning.ts. |
hasUvsreadonly | boolean | Whether it has texture coordinates, without which a material's maps read one texel. |
hasGrainreadonly | boolean | Whether it carries a grain lane, which is where second coordinates ride (lightmap.ts): what
a bone animation reads each vertex's bone from. |
vertexCountreadonly | number | How many vertices it has, which a cloth binding is checked against. |
morphreadonly | MorphTexture | null | This mesh's morph deltas, or null for geometry that does not deform.MoreOwned by the mesh rather than set per draw, which is the difference between this and the joint palette: a palette belongs to a pose and changes every frame, where deltas are geometry and never change. Uploaded once with the vertex buffers; only the weights are per-draw state. |
hasTangentsreadonly | boolean | Whether this mesh carries a tangent frame, for the shader that has to be told.MoreThe attribute cannot say so itself: |
Accessors
| Name | Type | Description |
|---|---|---|
completeget | boolean | Whether all of this mesh's geometry has reached the device.MoreFalse only between the steps of an incremental upload. |
Methods
draw
draw(gl: WebGL2RenderingContext): voidCaller is responsible for having the flat program + uniforms bound.
| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext |
createInstanceArray
createInstanceArray(gl: WebGL2RenderingContext, instances: WebGLBuffer, stride: number): WebGLVertexArrayObjectA vertex array for one instanced batch: every attribute this mesh binds from a buffer, its index buffer, and the batch's instance columns — the model matrix at 11 to 14, the tint at 15.
| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext | |
instances | WebGLBuffer | |
stride | number |
More
A batch owns its own array, which is what lets a mesh have more than one batch: a prop drawn once per region is one mesh and a batch per region. With one array a mesh had one batch, since a second would rebind the columns the first draws through and place one batch's instances by the other's matrices. The arrays share every buffer, so a batch costs its instances and nothing of the geometry. The caller deletes what this returns.
drawInstancesThrough
drawInstancesThrough(gl: WebGL2RenderingContext, vao: WebGLVertexArrayObject, count: number): voidDraw count instances through a batch's own vertex array. See createInstanceArray.
| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext | |
vao | WebGLVertexArrayObject | |
count | number |
dispose
dispose(gl: WebGL2RenderingContext): void| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext |
update
update(gl: WebGL2RenderingContext, positions: Float32Array, normals?: Float32Array): voidRewrite this mesh's positions, and its normals where the caller has them.
| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext | |
positions | Float32Array | |
normals? | Float32Array |
More
Only the two attributes that move. Colour, emissive and the rest describe what a surface is and do not change because it bent; rewriting them would be uploading unchanged bytes every frame. A caller with genuinely changing colour wants a second mesh or a tint.
The bounds are recomputed, because everything that decides whether this is on screen starts from them — a cloth that blew sideways out of its original box would be culled while still visible, which is the kind of bug that only shows up at the edge of the frame.
uploads
uploads(gl: WebGL2RenderingContext): Generator<void, void, void>Fill the buffers, a bounded step at a time. Done when it returns done.
| Parameter | Type | Description |
|---|---|---|
gl | WebGL2RenderingContext |
More
A step is one attribute, or a slice of one where the attribute is bigger than
UPLOAD_BYTES_PER_STEP. There is still no interleave here — this backend's three tight
buffers are the reason a consumer measured the same drive as smooth on WebGL2 and hitching
on the other one, and dividing an upload is not a reason to give that up.
The call that returns done is the one that does the last step's work, so a mesh of n
chunks takes exactly n calls.
The vertex array object is bound around each step because one of these writes an index
buffer, and an ELEMENT_ARRAY_BUFFER binding belongs to whichever array object is current —
writing it with somebody else's bound would quietly repoint their indices at this mesh.