OpenGLMesh
class · #include <rayrai/OpenGLMesh.hpp>
Inherits: std::enable_shared_from_this< OpenGLMesh >
Simple OpenGL mesh with indexed geometry and optional textures.
Keeps a CPU copy of the geometry plus a context-local VAO and (possibly shared) VBO/EBO. Constructors and every update/draw method require a current OpenGL context, except createCpuGeometry() and prepareGeometryAttributes(). Texture ids referenced by textures and material are not owned. Meshes are usually held by std::shared_ptr and may be shared between objects (see RayraiGlobalAsset), so material edits on a shared mesh affect every user. Non-copyable and non-movable.
Nested classes
structGeometryDiagnostics — Aggregated triangle statistics (see accumulateGeometryDiagnostics()).structMeshDiagnostics — Internal: per-mesh geometry/material record for structured diagnostics output (see collectMeshDiagnostics()).structPreparedAttributes — What prepareGeometryAttributes() derives besides the vertex attributes.structStagedGeometry — Where staging buffers (persistently mapped, OpenGL 4.4) hold this mesh's vertices and indices as uploadPreparedGeometry() stores them.structVertexSummaries — What precomputeVertexSummaries() and contentDigest() find.
Public types
RenderMode
enum class RenderModeMaterial filter applied by draw(); used to split a scene into shader passes.
| Enumerator | Description |
|---|---|
All | Draw regardless of shading type, using the simple-shader uniform path. |
SimpleOnly | Draw only meshes that do not use PBR shading. |
PbrOnly | Draw only PBR meshes (all passes). |
PbrNonTransmissiveOnly | PBR passes whose material is not transmissive. |
PbrTransmissiveOnly | PBR passes whose material is transmissive (glass path). |
PrimitiveTopology
enum class PrimitiveTopologyGL primitive used to interpret the index buffer.
| Enumerator | Description |
|---|---|
Triangles | GL_TRIANGLES. |
Lines | GL_LINES (width from setLineWidth()). |
Points | GL_POINTS (size from setPointSize()). |
Constructors & destructor
OpenGLMesh
OpenGLMesh(
const std::vector<Vertex> &vertices,
const std::vector<unsigned int> &indices,
const std::vector<Texture> &textures={},
const glm::vec4 &baseColor=glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
PrimitiveTopology primitiveTopology=PrimitiveTopology::Triangles)Construct a mesh and upload it to the GPU.
Parameters
| Parameter | Description |
|---|---|
vertices | Vertex array. |
indices | Index array. |
textures | Optional texture list. |
baseColor | Base color used when textures are absent. |
primitiveTopology | How indices are assembled into primitives. |
Missing tangents are generated and an empty TexCoords2 set is filled from TexCoords. The material type is TEXTURED when textures is non-empty, else SIMPLE_COLOR. GPU indices stay 32-bit (see createWithCompactIndices()).
OpenGLMesh(
std::vector<Vertex> &&vertices,
std::vector<unsigned int> &&indices,
const std::vector<Texture> &textures={},
const glm::vec4 &baseColor=glm::vec4(1.0f, 1.0f, 1.0f, 1.0f),
PrimitiveTopology primitiveTopology=PrimitiveTopology::Triangles)Construct a mesh by taking ownership of prepared CPU geometry.
Same as the copying constructor but moves vertices and indices.
Parameters
| Parameter | Description |
|---|---|
vertices | Vertex array (moved from). |
indices | Index array (moved from). |
textures | Optional texture list. |
baseColor | Base color used when textures are absent. |
primitiveTopology | How indices are assembled into primitives. |
OpenGLMesh(const OpenGLMesh &) = deleteOpenGLMesh(OpenGLMesh &&) = delete~OpenGLMesh
~OpenGLMesh()Public member functions
drawsInMode
bool drawsInMode(
RenderMode mode,
const raisin::Material *materialOverride) constWhether draw() with the same arguments would rasterize anything. It mirrors the mode and transmission filters draw() applies, including the nextPass chain, so a caller can skip a program bind and a whole submission instead of paying for a draw that returns immediately.
Parameters
| Parameter | Description |
|---|---|
mode | Material filter. |
materialOverride | Material to test instead of material, or nullptr. |
Returns True if draw() would issue at least one draw call.
sharedGpuAssetSnapshot
std::shared_ptr<const OpenGLMesh> sharedGpuAssetSnapshot()Freeze metadata before publishing to the asset cache. The template owns no VAO and remains immutable while worker-local materials are edited. Internal.
Returns The cached snapshot, or nullptr for meshes that reference any texture or a material next-pass (those are never shared across contexts).
gpuGeometryVisibleInCurrentContext
bool gpuGeometryVisibleInCurrentContext() constReturns True when this mesh's VBO/EBO are visible in the current GL context.
gpuGeometryBytes
size_t gpuGeometryBytes() constReturns Requested VBO + EBO allocation size for this mesh, in bytes.
prepareGeometryAttributes
void prepareGeometryAttributes()Compute missing tangents and UV statistics without a GL context.
preparedAttributes
PreparedAttributes preparedAttributes() constReturns The attributes the last prepareGeometryAttributes() derived.
restorePreparedGeometry
void restorePreparedGeometry(
std::vector<Vertex> &&vertices,
std::vector<unsigned int> &&indices,
const PreparedAttributes &attributes)Replace the CPU geometry with an already prepared copy, as prepareGeometryAttributes() would have left it. Internal: no GL calls; for caches of prepared meshes.
Parameters
| Parameter | Description |
|---|---|
vertices | Prepared vertex array. |
indices | Triangle index array. |
attributes | The attributes prepared with them. |
precomputeVertexSummaries
void precomputeVertexSummaries() constCompute what the first draws would otherwise scan vertices for: the local bounds and whether every vertex has the same color. Internal: no GL calls; workers call it before the render thread uses the mesh.
vertexSummaries
VertexSummaries vertexSummaries() constReturns The summaries of the current vertices and indices.
adoptVertexSummaries
void adoptVertexSummaries(const VertexSummaries &summaries) constAdopt summaries a cache stored for exactly these vertices and indices.
contentDigest
uint64_t contentDigest() constHash of vertices and indices; for summaries adopted from a cache of prepared geometry (until a method of this class changes the geometry), the digest stored with them. Internal: keys caches derived from the geometry.
uploadPreparedGeometry
void uploadPreparedGeometry(bool compactIndices=true)Upload an already-prepared CPU mesh on the context-owning thread. No-op if the mesh already has a VAO or borrows another mesh's buffers.
Parameters
| Parameter | Description |
|---|---|
compactIndices | Allow 16-bit GPU indices when lossless. |
void uploadPreparedGeometry(
bool compactIndices,
const StagedGeometry &staged)uploadPreparedGeometry() that copies the geometry on the GPU, from a staging buffer.
uploadsCompactIndices
bool uploadsCompactIndices(bool compactIndices) constReturns Whether an upload allowed compactIndices stores 16-bit indices (triangles whose indices all fit).
operator=
OpenGLMesh &operator=(const OpenGLMesh &) = deleteOpenGLMesh &operator=(OpenGLMesh &&) = deletedraw
void draw(const Shader &shader) constDraw the mesh using the provided shader.
Same as draw(shader, RenderMode::All). The shader is not bound here and must already be in use; the model matrix and objectColor are the caller's responsibility. Material depth/stencil/blend/cull state is applied around the draw call.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
void draw(
const Shader &shader,
RenderMode mode,
const raisin::Material *materialOverride=nullptr) constDraw the mesh if it matches the requested material render mode.
Non-PBR modes set the simple-shader material uniforms and bind the diffuse, specular and normal maps to units 0, 1 and 2 (white fallback when absent). PBR modes apply the full material (Material::applyTo()) and also draw its next-pass chain. The shader must already be in use.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected material uniforms. |
mode | Material filter for multi-pass rendering. |
materialOverride | Optional material to use instead of the mesh material (the mesh's textures are then ignored). |
drawInstanced
void drawInstanced(const Shader &shader, int instanceCount) constDraw the mesh with instancing using the mesh's own VAO.
Per-instance attributes must already be configured; usually prefer drawInstancedWithVao() with a VAO from instancedVaoForBuffer().
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
instanceCount | Number of instances to draw; <= 0 draws nothing. |
drawInstancedWithVao
void drawInstancedWithVao(
const Shader &shader,
int instanceCount,
unsigned int vao) constDraw the mesh with instancing using an explicit VAO variant.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
instanceCount | Number of instances to draw. |
vao | VAO from instancedVaoForBuffer(), or 0 for the mesh's own VAO. |
drawInstancedIndirect
void drawInstancedIndirect(
const Shader &shader,
unsigned int indirectBuffer) constDraw the mesh with an OpenGL DrawElementsIndirect command buffer.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
indirectBuffer | Buffer containing a DrawElementsIndirectCommand. |
drawInstancedIndirectWithVao
void drawInstancedIndirectWithVao(
const Shader &shader,
unsigned int indirectBuffer,
unsigned int vao,
size_t commandOffsetBytes=0) constDraw an indirect instanced command using an explicit VAO variant.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
indirectBuffer | Buffer containing a DrawElementsIndirectCommand; 0 draws nothing. |
vao | VAO from instancedVaoForBuffer(), or 0 for the mesh's own VAO. |
commandOffsetBytes | Byte offset of the command in indirectBuffer. |
drawInstancedMultiIndirect
void drawInstancedMultiIndirect(
const Shader &shader,
unsigned int indirectBuffer,
int commandCount,
int commandStrideBytes) constDraw several compatible DrawElementsIndirect commands against this mesh's VAO.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
indirectBuffer | Buffer containing tightly packed indirect commands. |
commandCount | Number of commands in indirectBuffer. |
commandStrideBytes | Stride between commands, or zero for tightly packed commands. |
drawInstancedMultiIndirectWithVao
void drawInstancedMultiIndirectWithVao(
const Shader &shader,
unsigned int indirectBuffer,
int commandCount,
int commandStrideBytes,
unsigned int vao) constDraw several indirect commands using an explicit VAO variant.
Parameters
| Parameter | Description |
|---|---|
shader | Shader with expected texture uniforms. |
indirectBuffer | Buffer containing the indirect commands. |
commandCount | Number of commands; <= 0 draws nothing. |
commandStrideBytes | Stride between commands, or zero for tightly packed commands. |
vao | VAO from instancedVaoForBuffer(), or 0 for the mesh's own VAO. |
instancedVaoForBuffer
unsigned int instancedVaoForBuffer(unsigned int instanceBuffer) constReturn a VAO whose base mesh attributes plus instance attributes use instanceBuffer.
The instance buffer holds one 80-byte record per instance: a column-major mat4 model matrix (attributes 3-6) followed by a vec4 color (attribute 7). VAOs are created on first use and cached per buffer; call releaseInstancedVaoForBuffer() before deleting the buffer.
Parameters
| Parameter | Description |
|---|---|
instanceBuffer | GL array buffer with instance records; 0 returns 0. |
Returns VAO id owned by this mesh, or 0 on failure.
unsigned int instancedVaoForBuffer(
unsigned int instanceBuffer,
bool compactFoliage) constInternal: as above, optionally with the compact foliage vertex layout.
Parameters
| Parameter | Description |
|---|---|
instanceBuffer | GL array buffer with instance records. |
compactFoliage | Use the packed foliage vertex stream when available. |
Returns VAO id owned by this mesh, or 0 on failure.
releaseInstancedVaoForBuffer
void releaseInstancedVaoForBuffer(unsigned int instanceBuffer) constDrop cached VAO variants that reference instanceBuffer.
Parameters
| Parameter | Description |
|---|---|
instanceBuffer | Instance buffer about to be deleted or replaced. |
drawWithBoundShader
void drawWithBoundShader(const Shader &shader) constSame as draw(), but assumes the caller has already bound shader. Currently equivalent to draw() (kept as an API hook for callers that used to pay a redundant shader bind cost; preserved for callers that opt in via OpenGLMesh::drawWithBoundShader).
Parameters
| Parameter | Description |
|---|---|
shader | Shader that is already in use. |
drawInstancedWithBoundShader
void drawInstancedWithBoundShader(
const Shader &shader,
int instanceCount) constEquivalent to drawInstanced(); kept for API parity with drawWithBoundShader().
Parameters
| Parameter | Description |
|---|---|
shader | Shader that is already in use. |
instanceCount | Number of instances to draw. |
drawIndexCount
size_t drawIndexCount() constReturns Number of indices issued per draw (the view range for range views).
indexElementBytes
size_t indexElementBytes() constGPU element width (2 or 4 bytes); CPU indices remain unsigned int. Raw VAO users must choose GL_UNSIGNED_SHORT or GL_UNSIGNED_INT accordingly.
Returns 2 or 4.
drawFirstIndex
size_t drawFirstIndex() constReturns First index of the draw range in the GPU index buffer (non-zero for range views).
drawBaseVertex
int drawBaseVertex() constReturns Base vertex added to each index when drawing (non-zero for range views).
setPrimitiveTopology
void setPrimitiveTopology(PrimitiveTopology topology)Set the OpenGL primitive topology used by this mesh.
Parameters
| Parameter | Description |
|---|---|
topology | New topology; the index buffer is reinterpreted, not rebuilt. |
primitiveTopology
PrimitiveTopology primitiveTopology() constReturns The OpenGL primitive topology used by this mesh.
setLineWidth
void setLineWidth(float width)Set GL line width for PrimitiveTopology::Lines meshes.
Parameters
| Parameter | Description |
|---|---|
width | Width in pixels, clamped to the driver's supported range when drawing. |
setPointSize
void setPointSize(float size)Set GL point size for PrimitiveTopology::Points meshes.
Parameters
| Parameter | Description |
|---|---|
size | Point size in pixels. |
usesPbrShading
bool usesPbrShading() constReturns True when this mesh should be rendered by the PBR shader (Material::usesPbrShading(), cached until invalidateMaterialCache()).
materialSortKey
uint64_t materialSortKey(
RenderMode mode=RenderMode::All,
const raisin::Material *materialOverride=nullptr) constCompact key for ordering opaque draws by material/texture state.
Parameters
| Parameter | Description |
|---|---|
mode | Render mode the draws will use. |
materialOverride | Material to key on instead of material, or nullptr. |
Returns Hash-like key mixing the PBR flag, texture ids and state flags; sort only, not unique.
updateMesh
void updateMesh(
const std::vector<Vertex> &vertices,
const std::vector<unsigned int> &indices)Update mesh data on the GPU.
Recomputes tangents. A mesh sharing buffers with others is first given its own private buffers, so other users are unaffected.
Parameters
| Parameter | Description |
|---|---|
vertices | New vertex data. |
indices | New index data; an empty vector keeps the current indices. |
updateIndices
void updateIndices(const std::vector<unsigned int> &indices)Replace the triangle index buffer, including clearing it with an empty vector.
Parameters
| Parameter | Description |
|---|---|
indices | New indices into the current vertex buffer. |
localBoundingSphere
bool localBoundingSphere(glm::vec3 ¢er, float &radius) constConservative local sphere, cached until geometry is uploaded again. Returns false when GPU-only uploads have detached the CPU geometry.
Parameters
| Parameter | Description |
|---|---|
center (out) | AABB center in object space. |
radius (out) | Half-diagonal of the AABB. |
Returns False if there are no vertices, a position is non-finite, or the GPU data no longer matches vertices.
localBoundingBox
bool localBoundingBox(glm::vec3 ¢er, glm::vec3 &halfExtents) constObject-space axis-aligned bounds, same caching and failure cases as localBoundingSphere().
Parameters
| Parameter | Description |
|---|---|
center (out) | AABB center. |
halfExtents (out) | AABB half extents. |
Returns False when bounds are unavailable.
updateVertices
void updateVertices(const std::vector<Vertex> &vertices)Update only vertex data on the GPU, keeping the existing index buffer.
Same as updateVertices(vertices, true).
Parameters
| Parameter | Description |
|---|---|
vertices | New vertex data. |
void updateVertices(
const std::vector<Vertex> &vertices,
bool recomputeTangents)Update only vertex data on the GPU, optionally preserving caller-provided tangents.
Parameters
| Parameter | Description |
|---|---|
vertices | New vertex data. |
recomputeTangents | True to rebuild tangents from the index buffer. |
vertexDisplacementUvStats
glm::vec4 vertexDisplacementUvStats() constMesh-average UV metrics consumed by heightmap vertex displacement: xy = |dP/du|, |dP/dv| in object units per raw UV unit (area weighted), zw = mean raw-UV edge length. Zero when the mesh has no usable UVs.
Returns The packed statistics.
updateVertexRange
bool updateVertexRange(
size_t firstVertex,
const Vertex *vertices,
size_t count)Update a contiguous vertex range while preserving the index buffer.
Updates both the CPU copy and the GPU buffer; tangents are not recomputed.
Parameters
| Parameter | Description |
|---|---|
firstVertex | Index of the first vertex to replace. |
vertices | Replacement vertices. |
count | Number of vertices. |
Returns False (nothing changed) if the range is empty or out of bounds.
uploadVertices
void uploadVertices(const Vertex *vertices, size_t count)Upload vertex data without copying it into the CPU-side mesh cache.
Unless vertices is vertices itself, CPU-based bounds become unavailable (see localBoundingSphere()).
Parameters
| Parameter | Description |
|---|---|
vertices | Pointer to vertex data. |
count | Number of vertices. |
applyTextureFilteringQuality
size_t applyTextureFilteringQuality(
float anisotropy,
float mipLodBias) constApply sampler quality to all 2D textures owned by this mesh/material.
Modifies the GL texture objects, so other meshes using the same textures are affected.
Parameters
| Parameter | Description |
|---|---|
anisotropy | Requested anisotropic filtering level. |
mipLodBias | Mip LOD bias. |
Returns Number of unique texture ids updated.
collectMaterialTextureIds
void collectMaterialTextureIds(std::vector<unsigned int> &textureIds) constAppend non-environment 2D material texture ids used by this mesh.
Environment/IBL maps are renderer resources and are reported separately by RayraiWindow diagnostics.
Parameters
| Parameter | Description |
|---|---|
textureIds (in, out) | Non-zero ids are appended (duplicates are kept). |
accumulateGeometryDiagnostics
void accumulateGeometryDiagnostics(
GeometryDiagnostics &diagnostics,
float tinyTriangleAreaThreshold) constAccumulate CPU-side triangle statistics for diagnostics.
Parameters
| Parameter | Description |
|---|---|
diagnostics (in, out) | Totals to add to. |
tinyTriangleAreaThreshold | Triangles with smaller (non-zero) area count as tiny. |
collectMeshDiagnostics
void collectMeshDiagnostics(
std::vector<MeshDiagnostics> &diagnostics,
float tinyTriangleAreaThreshold) constAppend per-mesh geometry/material diagnostics for structured JSON output.
Parameters
| Parameter | Description |
|---|---|
diagnostics (in, out) | One entry is appended. |
tinyTriangleAreaThreshold | Triangles with smaller (non-zero) area count as tiny. |
invalidateMaterialCache
void invalidateMaterialCache() constRefresh cached material-derived flags after direct material edits.
Call after changing material or textures in place so usesPbrShading() and the texture-slot cache are re-evaluated.
Static member functions
isPbrRenderMode static
static bool isPbrRenderMode(RenderMode mode)Parameters
| Parameter | Description |
|---|---|
mode | Render mode to test. |
Returns True for the three PBR-only render modes.
createIndexedRangeView static
static std::shared_ptr<OpenGLMesh> createIndexedRangeView(
std::shared_ptr<const OpenGLMesh> owner,
const std::vector<Vertex> &localVertices,
const std::vector<unsigned int> &localIndices,
size_t firstIndex,
int baseVertex,
const raisin::Material &viewMaterial,
const glm::vec4 &viewBaseColor,
const std::string &debugName={})Create a CPU-metadata view into owner's indexed GPU buffers.
The returned mesh has its own material/CPU geometry metadata but shares owner's VAO/EBO/VBO and draws the requested index range. It does not own or delete the shared GL handles, and holds a shared_ptr to owner so the borrowed GL handles cannot dangle.
Taking the owner as an explicit std::shared_ptr makes shared ownership a compile-time requirement (no shared_from_this/bad_weak_ptr fallback that could silently return a non-owning view), and the view is built without any throwaway GL upload — it never allocates its own VAO/VBO/EBO. Returns null if owner is null.
Parameters
| Parameter | Description |
|---|---|
owner | Mesh whose GPU buffers are borrowed. |
localVertices | CPU vertices for this view (bounds/diagnostics only). |
localIndices | CPU indices for this view; their count is the draw count. |
firstIndex | Offset, in indices, into owner's index buffer. |
baseVertex | Value added to each index when drawing. |
viewMaterial | Material of the view. |
viewBaseColor | Base color of the view. |
debugName | Diagnostics name; empty inherits owner's. |
Returns The view, or nullptr.
createSharedGpuGeometryView static
static std::shared_ptr<OpenGLMesh> createSharedGpuGeometryView(const std::shared_ptr<const OpenGLMesh> &owner)Create a context-local mesh wrapper that reuses another mesh's GPU buffers.
Buffer objects and textures are shared by OpenGL context share groups, while vertex array objects are context-local. This factory copies the CPU/material metadata, retains the shared VBO/EBO allocation, and creates a VAO in the caller's current context.
Parameters
| Parameter | Description |
|---|---|
owner | Source mesh; its buffers must be visible in the current context. |
Returns The view, or nullptr if owner is null, has no shareable buffers, or is not visible from the current context.
createCpuGeometry static
static std::shared_ptr<OpenGLMesh> createCpuGeometry(
const std::vector<Vertex> &vertices,
const std::vector<unsigned int> &indices,
const std::vector<Texture> &textures,
const glm::vec4 &baseColor,
bool prepareAttributes=true)Prepare geometry on a worker without issuing any OpenGL calls. Call uploadPreparedGeometry() on the GL thread before drawing.
Parameters
| Parameter | Description |
|---|---|
vertices | Vertex array. |
indices | Triangle index array. |
textures | Texture list (ids are only recorded). |
baseColor | Base color. |
prepareAttributes | Also run prepareGeometryAttributes(). |
Returns New mesh with no GL objects.
static std::shared_ptr<OpenGLMesh> createCpuGeometry(
std::vector<Vertex> &&vertices,
std::vector<unsigned int> &&indices,
const std::vector<Texture> &textures,
const glm::vec4 &baseColor,
bool prepareAttributes=true)createCpuGeometry() that takes over the vertex and index arrays instead of copying them.
createWithCompactIndices static
static std::shared_ptr<OpenGLMesh> createWithCompactIndices(
const std::vector<Vertex> &vertices,
const std::vector<unsigned int> &indices,
const std::vector<Texture> &textures={},
const glm::vec4 &baseColor=glm::vec4(1.f))Construct a new owned mesh with lossless compact GPU indices when possible. Generic constructors retain uint32 buffers for existing raw-VAO clients.
Parameters
| Parameter | Description |
|---|---|
vertices | Vertex array. |
indices | Triangle index array. |
textures | Optional texture list. |
baseColor | Base color used when textures are absent. |
Returns The new mesh (requires a current GL context).
Public attributes
vertices
std::vector<Vertex> verticesVertex list for the mesh.
indices
std::vector<unsigned int> indicesIndex list for the mesh, interpreted per primitiveTopology().
textures
std::vector<Texture> texturesList of textures associated with the mesh.
Used by the simple shader path: the first "texture_diffuse" entry also becomes Material::albedoMap at construction, and a "texture_specular" entry is bound to unit 1.
baseColor
glm::vec4 baseColorBase color used when textures are not present.
Copied into Material::baseColorFactor at construction. draw() does not upload it; callers such as RaisimObject read it to set objectColor.
material
raisin::Material materialMaterial data used by the optional PBR path.
debugSourceMeshName
std::string debugSourceMeshNameSource mesh name and imported primitive counts used by optional diagnostics.
debugImportedFaceCount
size_t debugImportedFaceCountInternal: face count reported by the importer.
debugImportedIndexCount
size_t debugImportedIndexCountInternal: index count reported by the importer.
debugGeneratedLodMaxUvClusterSpan
float debugGeneratedLodMaxUvClusterSpanInternal: largest UV span merged by LOD simplification.
generatedLodRelativeError
float generatedLodRelativeErrorActual normalized quadric/attribute error reported by the simplifier; -1 means unknown.
VAO
unsigned int VAOOpenGL vertex array object handle (context-local; owned unless this is a view).