Basic usage (WindowConfig)¶
Note
This section is only relevant when using
WindowConfig
.
Go to the Custom Usage section if you provide your own window
and context or want more control.
Using the WindowConfig
interface is the simplest way to start with moderngl-window.
This can work for 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.
Basic example¶
The 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 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
: Themoderngl_window.timers.clock.Timer
instance to control the current time (Values passed intorender
)
Resource loading¶
The 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 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
moderngl_window.resources
module has methods for this.
Generic events and window types¶
The WindowConfig
interface depends on the built in window types or a self-provided
window implementation of
BaseWindow
.
These window implementations convert 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 to 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
WINDOW
attribute directly.
Command line arguments¶
The 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 moderngl_window.parse_args()
for more details.
Window events¶
def resize(self, width: int, height: int):
print("Window was resized. buffer size is {} x {}".format(width, height))
def close(self):
print("The window is closing")
def iconify(self, iconify: bool):
print("Window was iconified:", iconify)
Keyboard input¶
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)
Mouse input¶
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))