Note
This section is only relevant when using :py~moderngl_window.context.base.window.WindowConfig
. Go to the Custom Usage section if your provide your own window and context or want more control.
Using the :py~moderngl_window.context.base.window.WindowConfig
interface is the simplest way to start with moderngl-window. This can work for projects smaller projects and implies that this library provides the window and moderngl context.
The API docs for this class alone should cover a lot of ground, but we'll go through the basics here.
The :py~moderngl_window.context.base.window.WindowConfig
is simply a class you extend to customize/implement initialization, window parameters, rendering code, keyboard input, mouse input and access simpler shortcut methods for loading resources.
import moderngl_window as mglw
class Test(mglw.WindowConfig):
gl_version = (3, 3)
window_size = (1920, 1080)
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Do initialization here
self.prog = self.ctx.program(...)
self.vao = self.ctx.vertex_array(...)
self.texture = self.ctx.texture(self.wnd.size, 4)
def render(self, time, frametime):
# This method is called every frame
self.vao.render()
# Blocking call entering rendering/event loop
mglw.run_window_config(Test)
The :py~moderngl_window.context.base.window.WindowConfig
instance will by default receive three external instances in __init__
that can be accessed later with self
.
self.ctx
: Themoderngl.Context
created by the configured window typeself.wnd
: The window instanceself.timer
: The :pymoderngl_window.timers.clock.Timer
instance to control the current time (Values passed intorender
)
The :py~moderngl_window.context.base.window.WindowConfig
class has built in shortcuts to the resource loading system.
self.load_texture('background.png')
self.load_texture_array('tiles.png', layers=16)
self.load_program('myprogram.glsl')
self.load_text('textfile.txt')
self.load_json('config.json')
self.load_binary('data.bin')
self.load_scene('cube.obj')
self.load_scene('city.gltf')
All paths used in resource loading are relative to an absolute path provided in the :py~moderngl_window.context.base.window.WindowConfig
.
from pathlib import Path
class Test(mglw.WindowConfig):
resource_dir = (Path(__file__).parent / 'resources').resolve()
If you need more than one search path for your resources, the :pymoderngl_window.resources
module have methods for this.
The :py~moderngl_window.context.base.window.WindowConfig
interface depends on the built in window types or a self-provided window implementation of :py~moderngl_window.context.base.window.BaseWindow
. These window implementations converts window, key and mouse events into a unified system so the user can switch between different window types without altering the code.
Window libraries are not perfect and may at times work sub-optimally on some platforms. They might also have different performance profiles. The ability switch between window types by just changing a config value can be an advantage.
You can change what window class is used by passing in the --window
option. Optionally you can modify the :py~moderngl_window.conf.Settings.WINDOW
attribute directly.
The :py~moderngl_window.run_window_config
method also reads arguments from sys.argv
making the user able to override config values in the class.
Example:
python test.py --window glfw --fullscreen --vsync --samples 16 --cursor false --size 800x600
See code for :pymoderngl_window.parse_args
for more details.
Implement the resize
method to customize window resize handling.
def resize(self, width: int, height: int):
print("Window was resized. buffer size is {} x {}".format(width, height))
Implement the key_event
and unicode_char_entered
method to handle key events.
def key_event(self, key, action, modifiers):
# Key presses
if action == self.wnd.keys.ACTION_PRESS:
if key == self.wnd.keys.SPACE:
print("SPACE key was pressed")
# Using modifiers (shift and ctrl)
if key == self.wnd.keys.Z and modifiers.shift:
print("Shift + Z was pressed")
if key == self.wnd.keys.Z and modifiers.ctrl:
print("ctrl + Z was pressed")
# Key releases
elif action == self.wnd.keys.ACTION_RELEASE:
if key == self.wnd.keys.SPACE:
print("SPACE key was released")
def unicode_char_entered(self, char: str):
print('character entered:', char)
Implement the mouse_*
methods to handle mouse input.
def mouse_position_event(self, x, y, dx, dy):
print("Mouse position:", x, y, dx, dy)
def mouse_drag_event(self, x, y, dx, dy):
print("Mouse drag:", x, y, dx, dy)
def mouse_scroll_event(self, x_offset: float, y_offset: float):
prtin("Mouse wheel:', x_offset, y_offset)
def mouse_press_event(self, x, y, button):
print("Mouse button {} pressed at {}, {}".format(button, x, y))
def mouse_release_event(self, x: int, y: int, button: int):
print("Mouse button {} released at {}, {}".format(button, x, y))