Basic Usage (WindowConfig)¶
Note
This section is only relevant when using
WindowConfig
.
Go to the Custom Usage section if your 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 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.
Basic Example¶
The WindowConfig
is
simply a class you extend to customize/implement initalization,
window parameters, rendering code, keybord 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 recieve 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 have 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 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 suboptimally 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
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¶
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))
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):
print("Mouse position:", x, y)
def mouse_drag_event(self, x, y):
print("Mouse drag:", x, y)
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))