-
Notifications
You must be signed in to change notification settings - Fork 0
Modern Mode
Mark Brooks edited this page Sep 7, 2025
·
2 revisions
Modern Mode in PicoGL is built for shader‑based, OpenGL Core‑profile style rendering. It focuses on programmable pipelines, Vertex Array Objects (VAOs), and explicit buffer management — keeping boilerplate low while giving you access to the full power of your GPU.
⚠️ Note: Modern Mode and Legacy Mode are currently designed as separate paths. Mixing them in the same render context is not yet supported.
- Shader‑centric workflow – Vertex, Fragment (and optional Geometry) shaders are first‑class citizens.
- VAO/VBO management – Explicit control with convenience helpers.
- Uniforms & attributes – Easy binding and updating.
- Core profile compliance – Ideal for macOS (until full deprecation) and modern Linux/Windows drivers.
-
Full OpenGL escape hatch – Drop down to raw
gl*calls anytime.
from pathlib import Path
from typing import NoReturn
from examples.data.cube_data import g_vertex_buffer_data, g_color_buffer_data
from picogl.renderer import MeshData
from picogl.ui.backend.glut.window.object import RenderWindow
GLSL_DIR = Path(__file__).parent / "glsl" / "cube"
def main() -> NoReturn:
"""Initialize and render a cube using Modern Mode."""
data = MeshData.from_raw(vertices=g_vertex_buffer_data, colors=g_color_buffer_data)
render_window = RenderWindow(
width=800,
height=600,
title="Modern Cube",
glsl_dir=GLSL_DIR,
data=data,
)
render_window.initialize()
render_window.run()
if __name__ == "__main__":
main()from OpenGL.raw.GL.VERSION.GL_1_0 import GL_TRIANGLES
from picogl.backend.modern.core.vertex.array.object import VertexArrayObject
from picogl.renderer import GLContext, MeshData, RendererBase
class ModernCubeRenderer(RendererBase):
def __init__(self, context: GLContext, data: MeshData, glsl_dir: str):
super().__init__()
self.context, self.data, self.glsl_dir = context, data, glsl_dir
def initialize_shaders(self):
self.context.create_shader_program(
vertex_source_file="vertex.glsl",
fragment_source_file="fragment.glsl",
glsl_dir=self.glsl_dir,
)
def initialize_buffers(self):
vao = VertexArrayObject()
vao.add_vbo(index=0, data=self.data.vbo, size=3)
vao.add_vbo(index=1, data=self.data.cbo, size=3)
self.context.vaos = {"cube": vao}
def render(self) -> None:
vao = self.context.vaos["cube"]
shader = self.context.shader
with shader, vao:
shader.uniform("mvp_matrix", self.context.mvp_matrix)
shader.uniform("model_matrix", self.context.model_matrix)
vao.draw(mode=GL_TRIANGLES, index_count=self.data.vertex_count)- Organize GLSL source files alongside your Python code for clarity.
- Use
MeshData.from_raw()for quick tests; migrate to structured loaders (OBJ/GLTF) for real assets. - Encapsulate per‑object state in renderer classes to reduce coupling.
- Remember to manage OpenGL context creation (PicoGL windows handle this automatically).
- Explore the
examples/modernfolder for more complex demos. - Check out the Documentation for shader uniforms, texture binding, and advanced usage.
- File issues or feature requests on GitHub to help shape PicoGL’s Modern API.