Skip to main content

gl46

Python OpenGL 4.6 Direct State Access (DSA) utility library focused on compute and data-oriented workflows, wrapping PyOpenGL through an explicit GL protocol.

Overview

gl46 provides type-annotated, DSA-first GPU objects for OpenGL 4.6 core. Every GL call goes through a GL protocol (gl46.gl.GL), with a real PyOpenGLGL backend for the driver and a FakeGL recording backend for headless tests, so the same script runs against both.

Key classes, grouped by concern:

  • Buffers: Buffer, EBO, IndirectDrawBuffer (aliased as IBO), ShaderStorage
  • Textures: Texture2D, Texture2DArray, TextureCubeMapArray, TextureMultisample, TextureBuffer
  • Shaders and programs: Shader, ShaderStage, Program, ProgramPipeline, Sampler
  • Geometry and framebuffer state: VertexArray, VertexAttrib, Framebuffer, Renderbuffer, RenderbufferMultisample
  • Scene helpers: Material, Camera, Window
  • Compute, queries, and debug: Barrier (aliased as MemoryBarrier), Query, TransformFeedback, DebugOutput

Not included. Windowing and input are not part of the core API — thin optional backends (gl46.window_imgui, gl46.window_qt) provide windows, render loops, and input. There is no scene graph, no math types (use numpy / pyglm), and no bindless-texture or multi-draw-indirect layer yet.

gl46 is not a ModernGL replacement: it is a minimal, DSA-first, fully testable substrate for developers assembling their own rendering framework.

Requirements

  • Python 3.11+
  • uv as the package manager
  • glfw>=2.10.2
  • PyOpenGL (plus pyopengl-accelerate) for the real GL backend
  • An OpenGL 4.5+ driver; Window requests a 4.6 core context by default.

The core package has no windowing, GUI, or image-library dependency. imgui_bundle and PySide6 are optional extras, needed only by examples/imgui_scene.py and examples/qt_scene.py (uv sync --extra imgui or --extra qt; equivalent pip form: pip install "gl46[imgui]" or pip install "gl46[qt]"). Pillow is a separate optional extra for examples/instancing_mrt.py: pip install "gl46[examples]".

The committed uv.lock is resolved against a China mirror (Huawei Cloud); international contributors may want to override the index locally. This has no effect on users installing gl46 from PyPI.

Install

From PyPI (any project):

pip install gl46

Optional extras:

pip install "gl46[imgui]"      # ImGui backend (gl46.window_imgui)
pip install "gl46[qt]"         # PySide6 backend (gl46.window_qt)
pip install "gl46[examples]"   # Pillow, for examples/instancing_mrt.py

If you use uv:

uv add gl46
uv add "gl46[imgui]"           # etc.

Development install inside this repository:

uv sync --all-extras

Quick Start

Every gl46 call needs a current OpenGL 4.5+ context. The built-in Window creates one (pass visible=False for an offscreen context); you can also point gl46 at any other context you already own.

import numpy as np
from gl46 import Buffer, Window
from gl46.constants import GL_MAP_READ_BIT, GL_MAP_WRITE_BIT

with Window(320, 240, visible=False):           # creates a GL context
    buf = Buffer(
        16 * 4,
        flags=GL_MAP_READ_BIT | GL_MAP_WRITE_BIT,
        initial_data=np.arange(16, dtype=np.float32),
    )
    with buf.map_range(0, buf.size_bytes, GL_MAP_READ_BIT) as mapped:
        out = mapped.as_numpy(np.float32, (16,))
    print(out)   # [ 0.  1.  2. ... 15.]

For a full rendering example with a visible window, see examples/triangle.py.

Examples

Run any example with uv run python examples/<name>.py from the repo root. Each opens a visible window; press SPACE to capture the current frame as <name>_frame.png on the spot, and closing the window writes <name>_close.png.

uv run python examples/quickstart.py          # Quick Start Demo
uv run python examples/query_timing.py        # DSA timer-query GPU timing
uv run python examples/triangle.py            # VAO/VBO + a rotating triangle
uv run python examples/offscreen_render.py    # offscreen FBO + fullscreen present
uv run python examples/compute_sobel.py       # compute-shader Sobel + timing
uv run python examples/instancing_mrt.py      # instancing & MRT scene
uv run python examples/imgui_scene.py         # gl46 + ImGui overlay (imgui_bundle/immapp)
uv run python examples/qt_scene.py            # gl46 hosted in a QOpenGLWidget (PySide6)

Two examples need extra dependencies beyond the core package:

  • imgui_scene.py needs imgui-bundle>=1.92.900. Its SMOKE callback raises RuntimeError if the RunnerParams.app_shall_exit hook added in that version is missing.
  • instancing_mrt.py uses Pillow to load its assets (the examples extra); its mesh and texture files live under examples/data/, shaders under examples/shaders/.

imgui_scene.py captures imgui_scene.png (scene + overlay) on its second frame, since the ImGui overlay renders after the first frame; qt_scene.py captures qt_scene.png via grabFramebuffer() on first draw.

PySide6 is optional: uv sync --extra qt installs it (needed only for examples/qt_scene.py / gl46.window_qt).

Building your own framework

gl46 leaves the application shell to you, but ships two thin window backends.

GLFW + ImGui (imgui_bundle)

The loop belongs to immapp.run; you supply callbacks. The scene draws in custom_background (behind the ImGui layer), GUI widgets in show_gui, one-time setup in post_init. Input for your scene is read through the ImGui API (imgui.is_key_pressed / imgui.get_io()).

from gl46.window_imgui import run_imgui_app

def scene_render() -> None: ...  # draw with gl46 objects
def gui() -> None: ...           # imgui widgets

run_imgui_app(scene_render=scene_render, gui=gui,
              width=800, height=600, title="app")

PySide6 (Qt)

Subclass GL46Widget, override the three hooks, then host it with run_qt_app. The loop is Qt's event loop; repaint via a QTimer (default).

from gl46.window_qt import GL46Widget, run_qt_app

class AppWidget(GL46Widget):
    def initialize_gl(self) -> None: ...              # create gl46 objects
    def resize_gl(self, w: int, h: int) -> None: ...  # framebuffer pixels
    def paint_gl(self) -> None: ...                   # draw the frame

run_qt_app(AppWidget, title="app")

Testing

uv run pytest -q

The suite runs against the FakeGL backend (no GPU required).

Quality Gates

uv sync --all-extras
uv run ruff check src tests
uv run ruff format --check src tests
uv run mypy src

Project Structure

gl46/
|-- src/
|   `-- gl46/
|       |-- __init__.py
|       |-- py.typed
|       |-- barrier.py
|       |-- base.py
|       |-- buffer.py
|       |-- camera.py
|       |-- constants.py
|       |-- debug.py
|       |-- errors.py
|       |-- framebuffer.py
|       |-- gl.py
|       |-- material.py
|       |-- pipeline.py
|       |-- program.py
|       |-- query.py
|       |-- renderbuffer.py
|       |-- sampler.py
|       |-- shader.py
|       |-- texture.py
|       |-- transformfeedback.py
|       |-- version.py
|       |-- vertexarray.py
|       |-- window.py
|       |-- window_imgui.py
|       `-- window_qt.py
|-- tests/
|   |-- __init__.py
|   |-- conftest.py
|   |-- fake_gl.py
|   |-- test_barrier.py
|   |-- test_base.py
|   |-- test_buffer.py
|   |-- test_buffer_extra.py
|   |-- test_camera.py
|   |-- test_constants.py
|   |-- test_debug.py
|   |-- test_errors.py
|   |-- test_fake_gl.py
|   |-- test_framebuffer.py
|   |-- test_gl.py
|   |-- test_material.py
|   |-- test_pipeline.py
|   |-- test_program.py
|   |-- test_query.py
|   |-- test_renderbuffer.py
|   |-- test_sampler.py
|   |-- test_shader.py
|   |-- test_texture.py
|   |-- test_texture_extra.py
|   |-- test_transformfeedback.py
|   |-- test_utils.py
|   |-- test_vertexarray.py
|   |-- test_version.py
|   |-- test_window.py
|   |-- test_window_imgui.py
|   `-- test_window_qt.py
|-- examples/
|   |-- data/
|   |-- shaders/
|   |-- compute_sobel.py
|   |-- imgui_scene.py
|   |-- instancing_mrt.py
|   |-- offscreen_render.py
|   |-- qt_scene.py
|   |-- query_timing.py
|   |-- quickstart.py
|   `-- triangle.py
|-- pyproject.toml
|-- uv.lock
|-- README.md
`-- LICENSE

License

MIT

Metadata

Release files for gl46 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gl46 0.1.0
File Size Uploaded
gl46-0.1.0.tar.gz 3.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for gl46 0.1.0
File Interpreter ABI Platform
gl46-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 3.7 MB

Release files / gl46-0.1.0.tar.gz

Download URL gl46-0.1.0.tar.gz
Size 3.7 MB
Tags Source
SHA-256 checksum
How to use checksums
c5e5cb9eacd10ba1e01f21f2451ab039b252e704a9a2646285e446c18942f8dd
BLAKE2b-256 checksum
How to use checksums
7ffdaa2fd0abbd8a5678b0ae6326fce5dd796e5fb25888722fa47195ca28afe9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / gl46-0.1.0-py3-none-any.whl

Download URL gl46-0.1.0-py3-none-any.whl
Size 48.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e8fafee62d70ffca01ee83b7d8a4ec7fc2cf9d26c27693e913fed2a21b520615
BLAKE2b-256 checksum
How to use checksums
e76b61c9e70730b62558192dbcd98419e01796b47a3160c0d6c3d3b0dd57e35e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page