Skip to content

Latest commit

 

History

History
180 lines (126 loc) · 5.79 KB

basic_usage.rst

File metadata and controls

180 lines (126 loc) · 5.79 KB

Basic usage (WindowConfig)

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.

Basic example

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: The moderngl.Context created by the configured window type
  • self.wnd: The window instance
  • self.timer: The :pymoderngl_window.timers.clock.Timer instance to control the current time (Values passed into render)

Resource loading

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.

Generic events and window types

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.

Command line arguments

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.

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, 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))