"""Modern VAO-based GPU mesh."""
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Optional
from picogl.backend.geometry.mesh import GPUMesh
from picogl.backend.gl.enums import GLNumeric
from picogl.backend.gl.wrappers import gl_draw_elements
if TYPE_CHECKING:
from picogl.renderer.glmesh import GLMesh
[docs]
class ModernMesh(GPUMesh):
"""VAO-backed mesh; wraps :class:`GLMesh` or a pre-uploaded VAO object."""
def __init__(
self,
*,
gl_mesh: Optional["GLMesh"] = None,
vao: Any = None,
index_count: int = 0,
):
if gl_mesh is None and vao is None:
raise ValueError("ModernMesh requires gl_mesh or vao")
[docs]
self._gl_mesh = gl_mesh
[docs]
self._vao = vao if gl_mesh is None else gl_mesh.vao
[docs]
self._index_count = index_count if gl_mesh is None else gl_mesh.index_count
[docs]
def bind(self) -> None:
if self._gl_mesh is not None:
self._gl_mesh.upload()
self._gl_mesh.bind()
return
if self._vao is not None and hasattr(self._vao, "__enter__"):
self._vao.__enter__()
[docs]
def unbind(self) -> None:
if self._gl_mesh is not None:
self._gl_mesh.unbind()
elif self._vao is not None and hasattr(self._vao, "__exit__"):
self._vao.__exit__(None, None, None)
[docs]
def draw(self, mode: int) -> None:
if self._gl_mesh is not None:
self._gl_mesh.draw(mode=mode)
return
if getattr(self._vao, "ebo", None) is not None:
gl_draw_elements(
self._index_count,
GLNumeric.UNSIGNED_INT,
mode,
pointer=None,
)
elif hasattr(self._vao, "draw"):
self._vao.draw(index_count=self._index_count, mode=mode)
[docs]
def delete(self) -> None:
if self._gl_mesh is not None:
self._gl_mesh.delete()