This release is a pre-release and may not be stable for production use.
OpenGLContext 3.0.0a1
OpenGLContext renders 3D scenes with PyOpenGL, in a window belonging to whichever GUI toolkit your application already uses. It loads glTF 2.0 and VRML97 worlds, draws them through a core-profile pipeline with physically based materials, and lets you walk around inside them with game-style physics and positional audio.
The primary focus of the library has always been to provide a way to create simple demos and tests for the PyOpenGL library. With the 3.0 release OpenGLContext is closer to a game engine than a demonstration library. It is still the primary suite of test cases run to verify PyOpenGL behaviour, but it is also a relatively broad framework on which you can create your own demos or tools.
What it does
-
Renders into five GUI toolkits — GLFW (recommended for core-profile and PBR rendering), GLUT, Pygame, wxPython and Qt/PySide — owning the window or embedded as one canvas in a larger application. Backends are plug-ins, so an application can register its own.
-
Loads scenes — glTF 2.0 and GLB with animation, skinning and morph targets; VRML97; Wavefront OBJ; and streamed 3D Tiles datasets, from a file or over the network. PK3 files with a secondary package.
-
Draws them — physically based materials, image-based lighting, shadows, transmission and bloom, particle effects, fog, TrueType text, and instancing that collapses repeated shapes into a single draw.
-
Lets you interact — click to pick objects in the scene, move through it in examine, fly, walk or first-person mode, respond to mouse, keyboard and timer events, and put panels, widgets and a settings screen over the top.
-
Game-style physics — rigid bodies, collision, joints and gravity zones, and a character who walks on the terrain you can see.
-
Game-style positional audio — sounds placed in the scene and heard from where the listener stands.
-
Viewer Application —
oglc-view model.glb. With embedded links to sample content you can browse through the embedded UI.
Install
Needs Python 3.10+ and a platform with Desktop OpenGL 3.3+
pip install "OpenGLContext[glfw,draco,audio]"
oglc-view model.glb
or, with uv:
uv run --with "OpenGLContext[glfw,draco,audio]" oglc-view
Extras add optional pieces: audio for sound you can hear, draco for
Draco-compressed glTF, pygame and wx for those backends, all for
everything.
Documentation
docs/documentation.html is the index — installation, tutorials, and a page per feature. docs/structure.html describes how the pieces fit together.
Development
The 3.0.0 release of OpenGLContext makes use of Large Language models during the development process. A few of the stand-in models for weapons were also generated via LLMs.
Releasing
.github/workflows/release.yml runs on every push
to main. It compares __version__ in
OpenGLContext/__init__.py against PyPI: if that
version is already published the run stops there, and if it is new the sdist and
wheel are built, checked and uploaded. Bumping the version is what cuts a
release; a push that leaves it alone does nothing.
Three checks stand between the build and the upload — twine check --strict on
the metadata, scripts/check_release_artifact.py on both artifacts, and a
comparison of the built filenames against the version that was looked up.
The test suite is not among them. It renders real frames and wants a live GL context, which a stock runner does not have, so run it locally and confirm it is green before bumping the version:
python -m pytest tests/
python scripts/check_release_artifact.py --source-root . dist/*.whl dist/*.tar.gz
Uploading uses PyPI trusted publishing, so no API token is stored anywhere. It
needs a publisher registered on the PyPI project for this repository with
workflow release.yml and the environment field left blank: the OIDC claim
carries no environment, and a publisher that names one will not match.
Changelog
3.0.0a1
The major version marks the removals at the end of this entry: several sub-packages and the visitor-based renderer are gone, so code that imported them needs changing. Everything else here is additive.
-
glTF 2.0, as a loader package (
loaders/gltf/) and the format the viewer leads with:.gltf/.glb, local or over http(s), with animation, skinning, morph targets, sparse accessors, computed tangents and theKHR_materials_*/KHR_texture_transform/unlit/specular-glossiness family.KHR_draco_mesh_compressiondecodes when the optionalDracoPyis installed. Seedocs/gltf.html. -
Physically-based rendering — a metallic/roughness uber-shader and PBR render pass,
PBRMaterial, image-based lighting (analytic or a runtime probe, with Radiance.hdrpanoramas), screen-space transmission and emissive bloom.docs/pbr.html,docs/ubershader.html. -
Shadow maps, per-light, with cascades for directional lights and an fps-adaptive cascade count. Replaces the removed stencil-volume path.
docs/shadows.html. -
Instanced rendering, automatic: the pass batches shapes that share geometry and a compatible appearance into one
glDrawElementsInstanced, for VRMLUSE/DEF, shared glTF meshes andEXT_mesh_gpu_instancingalike.docs/instancing.html. -
One viewer,
oglc-view, for glTF, VRML97, OBJ and 3D Tiles: format is chosen from the source by a registeredSceneAdapter, so a third party adds a format without touching the viewer. It carries a launch menu, a model library, and settings and controls screens.oglc-vrml,oglc-gltfandoglc-tilesare deprecated aliases for it.docs/viewer.html. -
An overlay UI (
ui/) — panels, widgets, layout and a skin, drawn in one batched call, with a settings screen generated from a node's own fields, a console and a key-bindings editor.docs/overlayui.html. -
Rigid-body physics and character movement — collision, gravity, joints and gravity zones through the
omi_physicspackage, first-person and examine navigation, declared movement modes, and a terrain-walking mode.docs/physics.html,docs/navigation.html. -
Terrain and 3D Tiles — an OGC 3D Tiles streaming runtime with screen-space-error LOD, async paging and eviction; splat-textured heightfield terrain; and instanced vegetation.
docs/terrain.html. -
Spatial audio — VRML97's
SoundandAudioClipplay, alongside glTF'sKHR_audio_emitter, through theomi_audiopackage.docs/audio.html. -
Particle systems, fog, and a HUD/debug overlay with frame timing and loop instrumentation.
docs/particles.html,docs/hud.html. -
Untrusted assets are contained. A document that names external resources — a glTF's buffers, images and audio, a 3D Tiles tileset's content and nested tilesets — may only reach what its own origin permits: same-origin http(s) for a document fetched over the network (re-checked on every redirect hop), and the document's own directory for one loaded from disk. Every fetched resource is size-capped, and the download cache is per-user rather than in shared system temp. The policy lives in one module,
loaders/resolver.py. -
Packaging modernised —
pyproject.tomlwith PEP 639 licence metadata, andscripts/check_release_artifact.py, which refuses an artifact carrying files the source tree no longer has. -
glTF audio codec extensions. A
KHR_audio_emittersource may offer the same sound in Ogg Vorbis throughOMI_audio_ogg_vorbis, keeping its own MP3 as the fallback; the Vorbis is decoded and preferred. Which OMI extensions are supported at all is tabulated indocs/gltf.html; the codec rules are indocs/audio.html. -
Removed code that nothing reached any more. None of the five GUI backends is affected.
-
browsersub-package — the unfinished wxPython "browser" shell and the VPython-compatiblevisualAPI (never finished past prototype, see the 2.0.0c1 note below). The one piece anything outside it used,appdatadirectory(), is nowOpenGLContext.userpaths. Theoglc-visualscript goes with it. -
shadowsub-package — stencil shadow volumes, which required the fixed-function pipeline and an infinite-perspective projection. Dynamic shadows are shadow maps (seedocs/shadows.html); thevrml_view_shadowscript goes with it. -
scenegraph.tree— the volumetric/space-colonization tree. Shipped vegetation is instanced glTF with impostors. -
The visitor-based multi-pass renderer —
RenderPass,VisitingRenderPass,Opaque/Transparent/SelectRenderPass,OverallPass,PassSetandRenderVisitor. Rendering has gone through the flat pass (passes/_flat.py) for some time; these were reachable only from the two sub-packages removed above.renderpass.pynow just selects a flat pass,rendervisitor.pyjust binds the activeViewpoint, andvisitor.pyis thefind()traversal.docs/renderprocess.html, which documented the removed system, is withdrawn. -
DisplayListCompiler/DisplayListRenderer— unreachable: the compiler-selection weighting always preferredArrayGeometryCompiler(1.0 over 0.9), so noIndexedFaceSethas compiled to a display list in a long time. Display lists themselves remain, for the bitmap font providers that use them. -
scenegraph.nurbsshader(superseded bynurbstess, which is the one wired intonurbs.py),move.fps(superseded bymove.modes.FPSMode),passes.flat,events.tkeventsandevents.fxevents(no Tk or FOX context exists to reach them).
-
-
DisplayList.__del__no longer reports an error when its context has already gone away; there is nothing to release in that case.
2.0.0c1 -> 2.1.0a1
-
PyOpenGL 3.x compatibility
-
Support for Numpy
-
PyVRML97 project split back out into separate project
-
A few more tests/demos
-
Register and look up node-types explicitly using plug-in framework.
-
Register and look up context-types explicitly using plug-in framework.
-
Expose scripts for
vrml_viewandchoosecontext.
2.0.0b1 -> 2.0.0c1
Refactoring and code cleanup:
-
Major scripts moved to the
binsubdirectory. -
Contexts now have classmethods for their "main" functions.
-
Scripts to choose the default context class and font.
-
Application data directory now hidden on non-Win32 platforms (
.OpenGLContextinstead ofOpenGLContext). -
Mechanism for specifying context attributes (size, depth, buffer type, etceteras). See the
contextdefinition.ContextDefinitionNode-class for details. -
Default
getScenegraphimplementation ofgetattr(self,'sg',None). -
Force flush before swap buffers (attempt to compensate for rendering artefacts on Linux).
Non-standard MouseOver node for constructing buttons.
-
PyGame interactivity fixes
- Work on making the PyGame interactions, particularly keyboard repeats, act in the same way as the keyboard interactions under wxPython and GLUT
-
wxTestingContexticons- wxPython testing context now has icons set for the frame so that it isn't showing the (ugly) default windows icons.
-
A few more tests/demos
-
wx_with_controls.py— demo of wxPython context + interacting control outside the context -
arbwindowpos.py— ARB extension for pixel-level positioning of bitmap position within the rendering window
-
-
Resources directory w/ OpenGLContext icons for easy import
-
Dispatcher module completely factored out into the SourceForge pydispatcher project.
-
Switched
registerCallbackto using class-methods, switched demo to using those methods to allow non-context-dependent registration of mouse events. -
Refactoring of mouse-based events, addition of code to allow "captured" and "bubbling" events (parent recieves events before/after children and can cancel further propagation).
-
Bug Fixes:
-
Try
ImageTexturestub when PIL not available -
Workaround for strange bug with wxPython where the main thread appears as two different objects, depending on whether it's in a callback or not.
-
Test for bugs in PyOpenGL's feedback mode operation
-
-
Additionally, some work has been done on the
browsersub-package, but it is still not finished to even prototype stages yet. It may, however, be useful as a source of sample code to some people.
2.0.0a4 -> 2.0.0b1
-
Optimization and accelerator modules:
- The entire rendering pipeline has been noticeably sped up, with a number of key performance bottlenecks rewritten using C modules (which should compile on any Python+Numeric setup).
-
Frustum Culling:
-
Bounding box calculation for common geometry types, including caching and automatic updating of bounding boxes.
-
Frustum extraction from model view matrix.
-
-
Polygonal and Bitmap Text (TTF):
-
Use of (new) ttfquery package based on the fonttools package allows scanning for system fonts (or fonts in a given directory) and doing primitive face-name matching for those fonts. Uses direct extraction of font outlines for polygonal text.
-
Context customization point for setup
-
Eliminated
BitmapTextnode, useFontStyle.format ='bitmap'instead.
-
-
All rendering methods and functions are now given a "mode" argument, and generally pass that argument to the functions they call to provide access to the current renderpass, context, etc.
-
GLE-based extrusion geometry types added
-
Added object for managing initialized extensions for a given context
-
Added some utility mechanisms for dealing with parametric equations of planes expressed as 4-item arrays.
-
Switch to using Mip-mapped textures by default
-
Polygon tessellation code reworked and generalized (used by the polygonal text engine, for instance).
-
Added (disabled) code to use display lists instead of array geometry for rendering indexed face sets.
-
Broke out vertex and polygon classes from IFS module
-
wxPython context:
-
Added wants-chars style to work properly in panels
-
wxPython context should also be somewhat more stable, particularly when used with Python 2.2.3. Workarounds for Python 2.2.2 bugs are still in place, but they do not guarantee that no errors will occur, merely reduce the likelihood when using Python 2.2.2.
-
Added ability to provide an OpenGL
attribListforwxContext.
-
-
Bug Fixes (too many to list everything):
-
Textures and display-lists in particular have significant bug fixes checked in. Many of these were simply making the objects context-specific. Also caught strange bug where display list creation is returning 0 rather than raising exceptions.
-
Textured transparent geometry (i.e. geometry whose textures have Alpha channels) are now rendered during the transparent rendering pass, rather than the opaque rendering pass.
-
Fix for unlit textured geometry not showing white as base colour.
-
TextureTransformlogic bug eliminated (was occasionally leaving the texture transform active). -
The cache API is now easier to use, and hopefully will not be triggering Python 2.2.2 errors anymore.
-
Python 2.3 compatibility revisions
-
Removed premature optimisation which was eliminating USE'd transparent shapes even though the matrices were different.
-
Fix for
build_normalPerVertexto properly build the normals (produces true smoothing, rather than the rather strange looking results of the previous version).
-
2.0.0a3 -> 2.0.0a4
-
PROTOs:
-
Initial support for prototyped nodes added, which allows for loading a wider swath of VRML content. No support for EXTERNPROTO as-of-yet.
-
Refactored
vrml.vrml97.prototypesintovrml.routeandvrml.vrml97.scriptmodules
-
-
Events:
-
Partial rework of the mouse-events API to allow the events to be handled during the event-cascade, addition of support for event-cascade deferal of event processing to eventhandler mix-in and Context classes.
-
Addition of support in the event base class for tracking visited node/field combinations, calling of base-class initializer from the sub-class initializer's.
-
ROUTEs are now active for fields
-
IS mappings now work for PROTO fields (sub-class of ROUTE)
-
Introduction of
Eventclass in the vrml package, should become the base-class forOpenGLContext.events.event
-
-
Cleanup of bugs in
Shape,SwitchandWGLFontwhere corner-cases were not properly caught (e.g. no geometry,whichChoiceout-of-bounds, no text on a line) -
IndexedFaceSet:-
Reworked generation code extensively, now supports colour-per-face and normal-per-face modes of VRML97
-
Added a few sanity checks as well.
-
-
PixelTexturenode added. -
Preliminary
CylinderandConeimplementations. -
Stub implementations of
LOD,InlineandBillboardnodes. -
Fix for transparent-geometry rendering (depth-buffer-testing enabled).
-
Consolidated
vrml.nodeandvrml.vrml97.nodeintovrml.node. Moved fieldtypes tovrmlpackage instead of VRML97 package -
Made default testing-context preference-sequence wx, Pygame, then GLUT
-
Made all Bindable types also act as Children, since they are present in the scenegraph hierarchy.
-
Fix for parsing hexidecimal-encoded SFImage fields (as seen in
PixelTextures). -
Work-around for Python 2.2.2 calling of receiver methods in dispatcher.
-
Considerably more robust
getFieldimplementation inprotofunctions
2.0.0a2 -> 2.0.0a3
-
Major Documentation updates (almost all doc-strings are updated in all modules).
-
Loaders:
-
Fixed bug with local-file loading where a local-file combined with the url
../would give a result of:z:../, we now create a file-path url in cases where a local-file is loaded. -
Moved
vrml2pklgzscript to loaders module. -
Re-added "dump" method to VRML97 loader.
-
-
ViewPlatform:
-
Fix for the
straightenmethod -
Elimination of
distanceattribute -
Switch to new-style classes
-
Loosening of the API for
setPositionandsetOrientation -
Fix for bug in the "forward" method
-
Mix-in:
- Eliminated
trackballattribute andunProjectmethod, commented out the unused slider interface
- Eliminated
-
-
Minor tweaks/optimisations to
vectorutilities. -
Nodes:
-
Changed
Node.externalURLback to a simple attribute value of the class (bug-fix) -
Made
SFNodeandMFNodedonaterootSceneGraphto children without them when values are set. -
Eliminated unused
WeakMFNodefield-type -
Fixed bug in
WeakFieldimplementation (returned a weak reference) -
Added a
boundfield toCubeBackground. -
Fixed inheritence for
WeakSFNode, eliminated cube-background work-around forrootSceneGraphtracking. -
Texture/ImageTexture:
-
Refactored PIL texture conversions
-
Fixed typo/copying bug in
Texture.__del__ -
Fix for image loading (default
baseURIre-instated), reduced levels on a number of log messages
-
-
Fix for cube-background render when last
glColorset the color to black. -
Added fields
Backgroundto shadow those inCubeBackgroundwhich preventImageTextureobjects being linearised to VRML97 where they shouldn't be.
-
-
Complete rework of the
field.Fieldimplementation to eliminate the seperate "fieldtype" objects in favour of making fieldtypes the actual type (class) of the field. [ MAJOR CHANGE ] -
Unused methods deleted from
OverallPass -
Fixed bug in the
builtin( )function, it would only properly report for Nodes before, instead of working for both Nodes or prototypes/classes. -
Events:
-
Eliminated use of Start and Stop Timer Events as parents for Pause and Resume events
-
InternalTime's now generateFractionalEvents in a few more places. -
Moved the examine manager to the events package
-
EventManger.registerCallbackraisesNotImplementedErrorinstead ofSystemErrorif a sub-class doesn't implement the method. -
Minor cleanup in
EventandEventHandlerclasses
-
-
Switch a few classes to being new-style classes.
-
Testing Code:
-
ambient_onlymade a sub-class of thevrml_viewtest -
Removed obsolete glut stencil buffer test script
-
2.0.0a1 -> 2.0.0a2
-
Made
scenegraph.regDefNamede-register references to the object by it's previousdefNameif possible. -
Added PROTO name declaration to
BitmapText -
Changed
NurbsTrimmedSurfacename toTrimmedSurfaceto follow the nurbs-extension naming scheme -
Added
standardPrototypefunction toloaders.vrml97to allow for programmatic registry of standardPrototypes for the loader -
Documentation updates.
-
A few setup and manifest changes.
-
Added a texture-specific log to the
debug/logsmodule. -
Addition of "root" protofunction for getting the root scenegraph for a node (doesn't currently support automatically setting the root field for children, however)
-
Elimination of weakref dicts for implementating scenegraph, uses protofunctions instead
-
Elimination of "DEF" and "PROTO" references in favour of
protofunctions.defNameandprotofunctions.protoName -
Image and Texture Loading:
-
Initial support for loading textures across the network, basically it's the original VRML97 loader with a bit of refactoring to support both images and scenes.
-
Caching textures (only creating a single OpenGL texture if there are multiple
ImageTextures which use the same PIL image) -
PIL paletted texture -> RGB
-
PIL resize of non-power-of-two textures
-
-
IFS Tesellation — commented out debugging code when IFS runs out of vertex indices before it runs out of other indices, just considers itself done now (lets some malformed content load)
-
.cvsignorefiles added throughout -
Added missing attribution for glprint test
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openglcontext-3.0.0a1.tar.gz.
File metadata
- Download URL: openglcontext-3.0.0a1.tar.gz
- Upload date:
- Size: 3.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88aeb83b6ac1c3c4607bfd20c51c63125ca8b5183abbeb6849aefaadd546e18d
|
|
| MD5 |
23dc666ad75ac88e2f526aeac15dfb15
|
|
| BLAKE2b-256 |
d9a76d810c937e7969990913093d074f28eb842a1263d970f3b583561a1f28dd
|
Provenance
The following attestation bundles were made for openglcontext-3.0.0a1.tar.gz:
Publisher:
release.yml on mcfletch/openglcontext
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openglcontext-3.0.0a1.tar.gz -
Subject digest:
88aeb83b6ac1c3c4607bfd20c51c63125ca8b5183abbeb6849aefaadd546e18d - Sigstore transparency entry: 2340881749
- Sigstore integration time:
-
Permalink:
mcfletch/openglcontext@4b8f55e99643598ce4cc000b7766e5c605093e85 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mcfletch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4b8f55e99643598ce4cc000b7766e5c605093e85 -
Trigger Event:
push
-
Statement type:
File details
Details for the file openglcontext-3.0.0a1-py3-none-any.whl.
File metadata
- Download URL: openglcontext-3.0.0a1-py3-none-any.whl
- Upload date:
- Size: 1.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7bab117f60ca247f5a6605a8fad5c7c5f45ef702f14a3863d17f8143bcaae0e
|
|
| MD5 |
fff5b84f78e9fd8c33374aa6c31fd96c
|
|
| BLAKE2b-256 |
90fce608c5d44b01e6f8ae7cf3ada3f694dc6c42dc678b0edfa86470b0607d20
|
Provenance
The following attestation bundles were made for openglcontext-3.0.0a1-py3-none-any.whl:
Publisher:
release.yml on mcfletch/openglcontext
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openglcontext-3.0.0a1-py3-none-any.whl -
Subject digest:
f7bab117f60ca247f5a6605a8fad5c7c5f45ef702f14a3863d17f8143bcaae0e - Sigstore transparency entry: 2340881781
- Sigstore integration time:
-
Permalink:
mcfletch/openglcontext@4b8f55e99643598ce4cc000b7766e5c605093e85 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/mcfletch
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4b8f55e99643598ce4cc000b7766e5c605093e85 -
Trigger Event:
push
-
Statement type: