From 6ef9bff89c961996f37cbbab6a1838d38d6b410c Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Fri, 29 Nov 2024 00:50:52 +0100 Subject: [PATCH] Rename callback functions (on_ prefix) (#203) * Rename callback functions (on_ prefix) * Lingering import * Update CHANGELOG * basic docs + example * Deleted setup.cfg * docs: install * type and test fixes * typos * More formatting * Clarify on_close * Example tweaks --- CHANGELOG.md | 13 ++++ README.md | 2 +- docs/guide/basic_usage.rst | 26 +++---- docs/guide/install.rst | 14 +++- .../{animated_sprites.py => animated_gif.py} | 42 ++++++----- examples/advanced/base.py | 6 +- .../advanced/compute_render_to_texture.py | 17 ++--- examples/advanced/fragment_picking.py | 21 +++--- examples/advanced/navier_stokes.py | 30 +++----- examples/advanced/pygame2.py | 2 +- examples/advanced/pygame2_background_image.py | 21 +++--- examples/advanced/pygame2_simple.py | 2 +- examples/advanced/shader_includes.py | 15 ++-- examples/advanced/shadow_mapping.py | 21 ++---- examples/advanced/shadow_mapping_56.py | 21 ++---- examples/advanced/tetrahedral_mesh.py | 15 ++-- examples/advanced/voxel_cubes.py | 10 +-- examples/advanced/water.py | 56 ++++++++------- examples/base.py | 22 +++--- examples/cube_model.py | 8 +-- examples/cubes.py | 12 ++-- examples/custom_config_class.py | 56 +++++++-------- examples/custom_config_functions.py | 45 ++++++------ examples/drag_drop_file_input.py | 48 ++++++------- examples/geometry_bbox.py | 18 ++--- examples/geometry_cube.py | 2 +- examples/geometry_cube_instanced.py | 2 +- examples/geometry_lines.py | 8 +-- examples/geometry_quad_fs.py | 13 ++-- examples/geometry_quad_fs_mouse_scroll.py | 13 ++-- examples/gltf_scenes.py | 2 +- examples/headless.py | 4 +- examples/integration_imgui.py | 42 ++++++----- examples/integration_imgui_image.py | 23 +++--- examples/moderngl_logo.py | 26 +++---- examples/modify_parser.py | 2 +- examples/orbit_camera.py | 9 +-- examples/quit_confirm.py | 6 +- examples/scheduling_example.py | 8 +-- examples/skybox_cubemap.py | 30 ++++---- examples/ssao.py | 51 +++++-------- examples/text_simple.py | 2 +- examples/texture_array.py | 27 +++---- examples/uniform_block.py | 4 +- examples/video.py | 10 +-- examples/window_config.py | 7 +- examples/window_events.py | 31 ++++---- examples/with_pyopengl.py | 6 +- moderngl_window/capture/base.py | 2 - moderngl_window/conf/__init__.py | 8 +-- moderngl_window/context/base/__init__.py | 18 +++-- moderngl_window/context/base/keys.py | 1 - moderngl_window/context/base/window.py | 71 +++++++++---------- moderngl_window/context/pygame2/window.py | 1 - moderngl_window/geometry/__init__.py | 3 +- moderngl_window/geometry/cube.py | 2 +- moderngl_window/integrations/imgui.py | 1 - moderngl_window/integrations/imgui_bundle.py | 9 ++- moderngl_window/loaders/scene/gltf2.py | 4 +- moderngl_window/loaders/scene/wavefront.py | 5 +- moderngl_window/meta/texture.py | 2 +- moderngl_window/opengl/vao.py | 6 +- moderngl_window/resources/__init__.py | 1 - moderngl_window/scene/programs.py | 2 +- moderngl_window/text/bitmapped/text_2d.py | 3 +- moderngl_window/timers/clock.py | 2 +- setup.cfg | 7 -- tests/test_conf.py | 4 +- tests/test_moderngl_window.py | 4 +- 69 files changed, 498 insertions(+), 529 deletions(-) rename examples/advanced/{animated_sprites.py => animated_gif.py} (69%) delete mode 100644 setup.cfg diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c127a92..b55d981f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ ## 3.0.0 +* All callback functions now has an `on_` prefix meaning existing code will need updating. The old names was somewhat unambiguous and was a source of confusion. It also makes it easier to separate the callback functions from other methods. + * `render` -> `on_render` + * `resize` -> `on_resize` + * `close` -> `on_close` + * `iconify` -> `on_iconify` + * `key_event` -> `on_key_event` + * `mouse_position_event` -> `on_mouse_position_event` + * `mouse_press_event` -> `on_mouse_press_event` + * `mouse_release_event` -> `on_mouse_release_event` + * `mouse_drag_event` -> `on_mouse_drag_event` + * `mouse_scroll_event` -> `on_mouse_scroll_event` + * `unicode_char_entered` -> `on_unicode_char_entered` + * `files_dropped_event` -> `on_files_dropped_event` * Pyrr is now replaced with PyGLM * imgui is replaced with imgui-bundle * Numpy version is no longer restricted diff --git a/README.md b/README.md index 46b67a60..860b653d 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ import moderngl_window as mglw class Test(mglw.WindowConfig): gl_version = (3, 3) - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.clear(1.0, 0.0, 0.0, 0.0) Test.run() diff --git a/docs/guide/basic_usage.rst b/docs/guide/basic_usage.rst index a5ec7dfc..51ff0480 100644 --- a/docs/guide/basic_usage.rst +++ b/docs/guide/basic_usage.rst @@ -38,12 +38,12 @@ and access simpler shortcut methods for loading resources. self.vao = self.ctx.vertex_array(...) self.texture = self.ctx.texture(self.wnd.size, 4) - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): # This method is called every frame self.vao.render() # Blocking call entering rendering/event loop - mglw.run_window_config(Test) + Test.run() The :py:class:`~moderngl_window.context.base.window.WindowConfig` instance will by default receive three external instances in ``__init__`` @@ -125,24 +125,24 @@ Window events .. code:: python - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): print("Window was resized. buffer size is {} x {}".format(width, height)) - def close(self): + def on_close(self): print("The window is closing") - def iconify(self, iconify: bool): + def on_iconify(self, iconify: bool): print("Window was iconified:", iconify) Keyboard input -------------- -Implement the ``key_event`` and ``unicode_char_entered`` method to handle +Implement the ``on_key_event`` and ``on_unicode_char_entered`` method to handle key events. .. code:: python - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): # Key presses if action == self.wnd.keys.ACTION_PRESS: if key == self.wnd.keys.SPACE: @@ -161,7 +161,7 @@ key events. if key == self.wnd.keys.SPACE: print("SPACE key was released") - def unicode_char_entered(self, char: str): + def on_unicode_char_entered(self, char: str): print('character entered:', char) @@ -172,17 +172,17 @@ Implement the ``mouse_*`` methods to handle mouse input. .. code:: python - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): print("Mouse position:", x, y, dx, dy) - def mouse_drag_event(self, x, y, dx, dy): + def on_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): + def on_mouse_scroll_event(self, x_offset: float, y_offset: float): print("Mouse wheel:", x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_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): + def on_mouse_release_event(self, x: int, y: int, button: int): print("Mouse button {} released at {}, {}".format(button, x, y)) diff --git a/docs/guide/install.rst b/docs/guide/install.rst index 7a82056c..c257c86f 100644 --- a/docs/guide/install.rst +++ b/docs/guide/install.rst @@ -26,11 +26,19 @@ Optional dependencies for loaders:: # STL loading pip install moderngl-window[trimesh] +imgui:: + + # imgui-bundle + pip install moderngl-window[imgui] + Installing dependencies for window types:: + pip install moderngl-window[glfw] + pip install moderngl-window[pygame-ce] + pip install moderngl-window[pygame] + pip install moderngl-window[tk] pip install moderngl-window[PySide2] pip install moderngl-window[pyqt5] - pip install moderngl-window[glfw] pip install moderngl-window[PySDL2] Installing optional dependencies this way should ensure @@ -78,6 +86,6 @@ Running tests Assuming dev requirements are installed. -Run tests with ``tox``:: +Run tests with ``pytest``:: - pytest + pytest tests diff --git a/examples/advanced/animated_sprites.py b/examples/advanced/animated_gif.py similarity index 69% rename from examples/advanced/animated_sprites.py rename to examples/advanced/animated_gif.py index 13240afb..91310147 100644 --- a/examples/advanced/animated_sprites.py +++ b/examples/advanced/animated_gif.py @@ -1,3 +1,14 @@ +""" +Loads two gif files into texture arrays and renders them into an offscreen buffer +that is then displayed on the screen using nearest neighbor filtering. + +Possible improvements: +- Make the example configurable to load any gif file(s) +- Load the raw byte data for each frame and instead use a palette texture to + reduce the memory footprint +- Take the gif transparency key into account? +""" + from pathlib import Path import glm @@ -6,12 +17,8 @@ import moderngl_window as mglw from moderngl_window import geometry -# from moderngl_window.conf import settings -# settings.SCREENSHOT_PATH = 'screenshots' -# from moderngl_window import screenshot - -class Test(mglw.WindowConfig): +class AnimatedGif(mglw.WindowConfig): title = "Animated Sprite" resource_dir = (Path(__file__) / "../../resources").resolve() aspect_ratio = 320 / 256 @@ -21,13 +28,12 @@ def __init__(self, **kwargs): super().__init__(**kwargs) self.buffer_size = 320, 256 # Textures - self.background_texture = self.load_texture_array( - "textures/animated_sprites/giphy.gif" - ) + self.background_texture = self.load_texture_array("textures/animated_sprites/giphy.gif") self.background_texture.repeat_x = False self.background_texture.repeat_y = False self.caveman_texture = self.load_texture_array( - "textures/animated_sprites/player_2.gif", layers=35 + "textures/animated_sprites/player_2.gif", + layers=35, # Number of frames in the gif ) self.caveman_texture.repeat_x = False self.caveman_texture.repeat_y = False @@ -39,22 +45,18 @@ def __init__(self, **kwargs): self.quad_fs = geometry.quad_fs() # Programs - self.sprite_program = self.load_program( - "programs/animated_sprites/sprite_array.glsl" - ) + self.sprite_program = self.load_program("programs/animated_sprites/sprite_array.glsl") self.texture_program = self.load_program("programs/texture.glsl") # Offscreen buffer self.offscreen_texture = self.ctx.texture(self.buffer_size, 4) self.offscreen_texture.filter = moderngl.NEAREST, moderngl.NEAREST - self.offscreen = self.ctx.framebuffer( - color_attachments=[self.offscreen_texture] - ) + self.offscreen = self.ctx.framebuffer(color_attachments=[self.offscreen_texture]) self.projection = glm.ortho(0, 320, 0, 256, -1.0, 1.0) self.sprite_program["projection"].write(self.projection) - def render(self, time, frame_time): + def on_render(self, time, frame_time): # Render sprite of offscreen self.offscreen.use() self.ctx.clear(0.5, 0.5, 0.5, 0.0) @@ -75,10 +77,7 @@ def render(self, time, frame_time): self.offscreen_texture.use(location=0) self.quad_fs.render(self.texture_program) - # if self.wnd.frames < 100: - # screenshot.create(self.ctx.screen) - - def render_sprite(self, texture, blend=False, frame=0, position=(0, 0)): + def render_sprite(self, texture: moderngl.TextureArray, blend=False, frame=0, position=(0, 0)): if blend: self.ctx.enable(moderngl.BLEND) @@ -92,5 +91,4 @@ def render_sprite(self, texture, blend=False, frame=0, position=(0, 0)): if __name__ == "__main__": - mglw.run_window_config(Test) - # Test.run() + AnimatedGif.run() diff --git a/examples/advanced/base.py b/examples/advanced/base.py index 59e42b16..9ab2328e 100644 --- a/examples/advanced/base.py +++ b/examples/advanced/base.py @@ -10,7 +10,7 @@ def __init__(self, **kwargs): self.camera = KeyboardCamera(self.wnd.keys, aspect_ratio=self.wnd.aspect_ratio) self.camera_enabled = True - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if self.camera_enabled: @@ -24,9 +24,9 @@ def key_event(self, key, action, modifiers): if key == keys.SPACE: self.timer.toggle_pause() - def mouse_position_event(self, x: int, y: int, dx, dy): + def on_mouse_position_event(self, x: int, y: int, dx, dy): if self.camera_enabled: self.camera.rot_state(-dx, -dy) - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): self.camera.projection.update(aspect_ratio=self.wnd.aspect_ratio) diff --git a/examples/advanced/compute_render_to_texture.py b/examples/advanced/compute_render_to_texture.py index 56a402b4..67b0ffff 100644 --- a/examples/advanced/compute_render_to_texture.py +++ b/examples/advanced/compute_render_to_texture.py @@ -8,21 +8,22 @@ class ComputeRenderToTexture(mglw.WindowConfig): """Simple example rendering to a texture with a compute shader""" + title = "Render Texture Using Compute Shader" - resource_dir = (Path(__file__) / '../../resources').resolve() + resource_dir = (Path(__file__) / "../../resources").resolve() gl_version = 4, 3 aspect_ratio = 1.0 def __init__(self, **kwargs): super().__init__(**kwargs) - self.compute_shader = self.load_compute_shader('programs/compute/render_to_texture.glsl') - self.compute_shader['destTex'] = 0 - self.texture_program = self.load_program('programs/texture.glsl') + self.compute_shader = self.load_compute_shader("programs/compute/render_to_texture.glsl") + self.compute_shader["destTex"] = 0 + self.texture_program = self.load_program("programs/texture.glsl") self.quad_fs = geometry.quad_fs() self.texture = self.ctx.texture((256, 256), 4) self.texture.filter = mgl.NEAREST, mgl.NEAREST - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.ctx.clear(0.3, 0.3, 0.3) w, h = self.texture.size @@ -30,7 +31,7 @@ def render(self, time, frame_time): nx, ny, nz = int(w / gw), int(h / gh), 1 try: - self.compute_shader['time'] = time + self.compute_shader["time"] = time except Exception: pass # Automatically binds as a GL_R32F / r32f (read from the texture) @@ -42,5 +43,5 @@ def render(self, time, frame_time): self.quad_fs.render(self.texture_program) -if __name__ == '__main__': - mglw.run_window_config(ComputeRenderToTexture) +if __name__ == "__main__": + ComputeRenderToTexture.run() diff --git a/examples/advanced/fragment_picking.py b/examples/advanced/fragment_picking.py index a12df800..fadb20f1 100644 --- a/examples/advanced/fragment_picking.py +++ b/examples/advanced/fragment_picking.py @@ -45,7 +45,7 @@ def __init__(self, **kwargs): # Load scene cached to speed up loading! self.scene = self.load_scene("scenes/fragment_picking/centered.obj", cache=True) - # Grab the raw mesh/vertexarray + # Grab the raw mesh/vertex array self.mesh = self.scene.root_nodes[0].mesh.vao self.mesh_texture = self.scene.root_nodes[0].mesh.material.mat_texture.texture @@ -117,7 +117,7 @@ def __init__(self, **kwargs): # Marker geometry self.marker_buffer = self.ctx.buffer( reserve=self.marker_byte_size * 1000 - ) # Resever room for 1000 points + ) # Reserve room for 1000 points self.marker_vao = VAO(name="markers", mode=moderngl.POINTS) self.marker_vao.buffer( self.marker_buffer, "3f 3f 1f", ["in_position", "in_normal", "temperature"] @@ -129,7 +129,7 @@ def __init__(self, **kwargs): self.quad_depth = geometry.quad_2d(size=(0.25, 0.25), pos=(0.5, 0.875)) self.quad_positions = geometry.quad_2d(size=(0.25, 0.25), pos=(0.25, 0.875)) - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) translation = glm.translate(glm.vec3(0, 0, -45 + self.zoom)) @@ -179,12 +179,12 @@ def render_debug(self): self.offscreen_viewpos.use() self.quad_positions.render(self.texture_program) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): """Pick up mouse drag movements""" self.x_rot -= dx / 100 self.y_rot -= dy / 100 - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): """Attempts to get the view position from a fragment""" # only care about right mouse button clicks @@ -193,8 +193,9 @@ def mouse_press_event(self, x, y, button): # mouse coordinates starts in upper left corner # pixel positions starts and lower left corner - pos = int(x * self.wnd.pixel_ratio), int( - self.wnd.buffer_height - (y * self.wnd.pixel_ratio) + pos = ( + int(x * self.wnd.pixel_ratio), + int(self.wnd.buffer_height - (y * self.wnd.pixel_ratio)), ) print("Picking mouse position", x, y) print("Viewport position", pos) @@ -220,10 +221,10 @@ def mouse_press_event(self, x, y, button): ) self.num_markers += 1 - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): self.zoom += y_offset - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys # Key presses @@ -256,4 +257,4 @@ def save_markers(self, path: Path): if __name__ == "__main__": - moderngl_window.run_window_config(FragmentPicking) + FragmentPicking.run() diff --git a/examples/advanced/navier_stokes.py b/examples/advanced/navier_stokes.py index 93c498fb..52191546 100644 --- a/examples/advanced/navier_stokes.py +++ b/examples/advanced/navier_stokes.py @@ -60,22 +60,12 @@ def __init__(self, *args, **kwargs): self.walls_texture = self.ctx.texture(size, 1, dtype="f4") self.difference_texture = self.ctx.texture(size, 1, dtype="f4") - self.momentum_fbo_1 = self.ctx.framebuffer( - color_attachments=[self.momentum_texture_1] - ) - self.momentum_fbo_2 = self.ctx.framebuffer( - color_attachments=[self.momentum_texture_2] - ) - self.pressure_fbo_1 = self.ctx.framebuffer( - color_attachments=[self.pressure_texture_1] - ) - self.pressure_fbo_2 = self.ctx.framebuffer( - color_attachments=[self.pressure_texture_2] - ) + self.momentum_fbo_1 = self.ctx.framebuffer(color_attachments=[self.momentum_texture_1]) + self.momentum_fbo_2 = self.ctx.framebuffer(color_attachments=[self.momentum_texture_2]) + self.pressure_fbo_1 = self.ctx.framebuffer(color_attachments=[self.pressure_texture_1]) + self.pressure_fbo_2 = self.ctx.framebuffer(color_attachments=[self.pressure_texture_2]) self.walls_fbo = self.ctx.framebuffer(color_attachments=[self.walls_texture]) - self.difference_fbo = self.ctx.framebuffer( - color_attachments=[self.difference_texture] - ) + self.difference_fbo = self.ctx.framebuffer(color_attachments=[self.difference_texture]) # programs self.texture_prog = self.load_program("programs/navier-stokes/texture.glsl") @@ -134,7 +124,7 @@ def wall(self, x, y): self.drop_prog["write_value"].value = 1.0 self.drop_geometry.render(self.drop_prog) - def render(self, time, frame_time): + def on_render(self, time: float, frame_time: float): # calculate momentum self.momentum_fbo_1.use() self.momentum_texture_2.use(location=0) @@ -189,19 +179,19 @@ def pressure_swap(self): self.pressure_fbo_1, ) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): if button == self.wnd.mouse.left: self.drop(x, y) elif button == self.wnd.mouse.right: self.wall(x, y) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): if self.wnd.mouse_states.left: self.drop(x, y) elif self.wnd.mouse_states.right: self.wall(x, y) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if action == keys.ACTION_PRESS: @@ -210,4 +200,4 @@ def key_event(self, key, action, modifiers): if __name__ == "__main__": - moderngl_window.run_window_config(NavierStokes2D) + NavierStokes2D.run() diff --git a/examples/advanced/pygame2.py b/examples/advanced/pygame2.py index b441c88d..ffd5adaa 100644 --- a/examples/advanced/pygame2.py +++ b/examples/advanced/pygame2.py @@ -50,7 +50,7 @@ def __init__(self, **kwargs): ) self.texture_prog["m_model"].write(glm.mat4()) - def render(self, time, frametime): + def on_render(self, time, frametime): # time = self.wnd.frames / 30 self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) diff --git a/examples/advanced/pygame2_background_image.py b/examples/advanced/pygame2_background_image.py index 8240e604..a039d13e 100644 --- a/examples/advanced/pygame2_background_image.py +++ b/examples/advanced/pygame2_background_image.py @@ -5,6 +5,7 @@ Clears the screen using opengl with a constantly changing color value and alpha blend a pygame surface on top. """ + import math from pathlib import Path @@ -20,9 +21,10 @@ class Pygame(moderngl_window.WindowConfig): Example using pygame with moderngl. Needs to run with ``--window pygame2`` option. """ + title = "Pygame" window_size = 1280, 720 - resource_dir = (Path(__file__) / '../../resources').absolute() + resource_dir = (Path(__file__) / "../../resources").absolute() def __init__(self, **kwargs): super().__init__(**kwargs) @@ -34,18 +36,18 @@ def __init__(self, **kwargs): self.pg_texture.filter = moderngl.NEAREST, moderngl.NEAREST self.pg_texture.swizzle = "BGRA" - self.texture_program = self.load_program('programs/texture.glsl') - self.quad_texture = self.load_texture_2d('textures/python-bg.png') + self.texture_program = self.load_program("programs/texture.glsl") + self.quad_texture = self.load_texture_2d("textures/python-bg.png") self.quad_fs = geometry.quad_fs() - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.clear() self.ctx.enable(moderngl.BLEND) # Render background graphics self.quad_texture.use() - self.texture_program['texture0'].value = 0 + self.texture_program["texture0"].value = 0 self.quad_fs.render(self.texture_program) # Render foreground objects @@ -66,15 +68,16 @@ def render_pygame(self, time): ((i * 50) % 255, (i * 100) % 255, (i * 20) % 255), ( math.sin(time + time_offset) * 200 + self.window_size[0] // 2, - math.cos(time + time_offset) * 200 + self.window_size[1] // 2), + math.cos(time + time_offset) * 200 + self.window_size[1] // 2, + ), math.sin(time) * 7 + 15, ) # Get the buffer view of the Surface's pixels # and write this data into the texture - texture_data = self.pg_screen.get_view('1') + texture_data = self.pg_screen.get_view("1") self.pg_texture.write(texture_data) -if __name__ == '__main__': - moderngl_window.run_window_config(Pygame, args=('--window', 'pygame2')) +if __name__ == "__main__": + moderngl_window.run_window_config(Pygame, args=("--window", "pygame2")) diff --git a/examples/advanced/pygame2_simple.py b/examples/advanced/pygame2_simple.py index b075ea1f..cd794010 100644 --- a/examples/advanced/pygame2_simple.py +++ b/examples/advanced/pygame2_simple.py @@ -152,7 +152,7 @@ def __init__(self, **kwargs): ], ) - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): """Called every frame""" self.render_pygame(time) diff --git a/examples/advanced/shader_includes.py b/examples/advanced/shader_includes.py index 7a8fb8bc..264ceb1f 100644 --- a/examples/advanced/shader_includes.py +++ b/examples/advanced/shader_includes.py @@ -5,6 +5,7 @@ We include a library doing different blend types and render each quadrant of the screen with different blend types """ + from pathlib import Path import moderngl_window as mglw @@ -13,21 +14,21 @@ class ShaderInclude(mglw.WindowConfig): title = "Shader Include" - resource_dir = (Path(__file__) / '../../resources').resolve() + resource_dir = (Path(__file__) / "../../resources").resolve() aspect_ratio = 1 def __init__(self, **kwargs): super().__init__(**kwargs) - self.program = self.load_program('programs/blend_include.glsl') - self.texture_0 = self.load_texture_2d('textures/cubemaps/yokohama/negx.jpg') - self.texture_1 = self.load_texture_2d('textures/cubemaps/yokohama/negz.jpg') + self.program = self.load_program("programs/blend_include.glsl") + self.texture_0 = self.load_texture_2d("textures/cubemaps/yokohama/negx.jpg") + self.texture_1 = self.load_texture_2d("textures/cubemaps/yokohama/negz.jpg") self.quad_fs = geometry.quad_fs() - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.texture_0.use(location=0) self.texture_1.use(location=1) self.quad_fs.render(self.program) -if __name__ == '__main__': - mglw.run_window_config(ShaderInclude) +if __name__ == "__main__": + ShaderInclude.run() diff --git a/examples/advanced/shadow_mapping.py b/examples/advanced/shadow_mapping.py index cf565d84..b338ae54 100644 --- a/examples/advanced/shadow_mapping.py +++ b/examples/advanced/shadow_mapping.py @@ -10,7 +10,6 @@ import moderngl from base import CameraWindow -import moderngl_window from moderngl_window import geometry @@ -47,24 +46,18 @@ def __init__(self, **kwargs): self.offscreen_quad2 = geometry.quad_2d(size=(0.5, 0.5), pos=(0.25, 0.75)) # Programs - self.raw_depth_prog = self.load_program( - "programs/shadow_mapping/raw_depth.glsl" - ) - self.basic_light = self.load_program( - "programs/shadow_mapping/directional_light.glsl" - ) + self.raw_depth_prog = self.load_program("programs/shadow_mapping/raw_depth.glsl") + self.basic_light = self.load_program("programs/shadow_mapping/directional_light.glsl") self.basic_light["shadowMap"].value = 0 self.basic_light["color"].value = 1.0, 1.0, 1.0, 1.0 - self.shadowmap_program = self.load_program( - "programs/shadow_mapping/shadowmap.glsl" - ) + self.shadowmap_program = self.load_program("programs/shadow_mapping/shadowmap.glsl") self.texture_prog = self.load_program("programs/texture.glsl") self.texture_prog["texture0"].value = 0 self.sun_prog = self.load_program("programs/cube_simple.glsl") self.sun_prog["color"].value = 1, 1, 0, 1 self.lightpos = 0, 0, 0 - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.lightpos = glm.vec3(math.sin(time) * 20, 5, math.cos(time) * 20) scene_pos = glm.vec3(0, -5, -32) @@ -105,9 +98,7 @@ def render(self, time, frametime): # Render the sun position self.sun_prog["m_proj"].write(self.camera.projection.matrix) self.sun_prog["m_camera"].write(self.camera.matrix) - self.sun_prog["m_model"].write( - glm.translate(glm.vec3(self.lightpos + scene_pos)) - ) + self.sun_prog["m_model"].write(glm.translate(glm.vec3(self.lightpos + scene_pos))) self.sun.render(self.sun_prog) # --- PASS 3: Debug --- @@ -119,4 +110,4 @@ def render(self, time, frametime): if __name__ == "__main__": - moderngl_window.run_window_config(ShadowMapping) + ShadowMapping.run() diff --git a/examples/advanced/shadow_mapping_56.py b/examples/advanced/shadow_mapping_56.py index 9ea261b6..8f315233 100644 --- a/examples/advanced/shadow_mapping_56.py +++ b/examples/advanced/shadow_mapping_56.py @@ -10,7 +10,6 @@ import moderngl from base import CameraWindow -import moderngl_window from moderngl_window import geometry @@ -47,24 +46,18 @@ def __init__(self, **kwargs): self.offscreen_quad2 = geometry.quad_2d(size=(0.5, 0.5), pos=(0.25, 0.75)) # Programs - self.raw_depth_prog = self.load_program( - "programs/shadow_mapping/raw_depth.glsl" - ) - self.basic_light = self.load_program( - "programs/shadow_mapping/directional_light.glsl" - ) + self.raw_depth_prog = self.load_program("programs/shadow_mapping/raw_depth.glsl") + self.basic_light = self.load_program("programs/shadow_mapping/directional_light.glsl") self.basic_light["shadowMap"].value = 0 self.basic_light["color"].value = 1.0, 1.0, 1.0, 1.0 - self.shadowmap_program = self.load_program( - "programs/shadow_mapping/shadowmap.glsl" - ) + self.shadowmap_program = self.load_program("programs/shadow_mapping/shadowmap.glsl") self.texture_prog = self.load_program("programs/texture.glsl") self.texture_prog["texture0"].value = 0 self.sun_prog = self.load_program("programs/cube_simple.glsl") self.sun_prog["color"].value = 1, 1, 0, 1 self.lightpos = 0, 0, 0 - def render(self, time, frametime): + def on_render(self, time, frametime): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.lightpos = glm.vec3(math.sin(time) * 20, 5, math.cos(time) * 20) scene_pos = glm.vec3(0, -5, -32) @@ -105,9 +98,7 @@ def render(self, time, frametime): # Render the sun position self.sun_prog["m_proj"].write(self.camera.projection.matrix) self.sun_prog["m_camera"].write(self.camera.matrix) - self.sun_prog["m_model"].write( - glm.translate(glm.vec3(self.lightpos + scene_pos)) - ) + self.sun_prog["m_model"].write(glm.translate(glm.vec3(self.lightpos + scene_pos))) self.sun.render(self.sun_prog) # --- PASS 3: Debug --- @@ -119,4 +110,4 @@ def render(self, time, frametime): if __name__ == "__main__": - moderngl_window.run_window_config(ShadowMapping) + ShadowMapping.run() diff --git a/examples/advanced/tetrahedral_mesh.py b/examples/advanced/tetrahedral_mesh.py index aec5005b..1d180ee0 100644 --- a/examples/advanced/tetrahedral_mesh.py +++ b/examples/advanced/tetrahedral_mesh.py @@ -18,8 +18,8 @@ class VolumetricTetrahedralMesh(CameraWindow): An example rendering a volumetric mesh of the format: ``[[p1, p2, p3, p4], [p1, p2, p3, p4], ..]`` - were ```px``` represent a 3d point in a tetraherdon. - A geometry shader calculates and emits the tetraherdons + were ```px``` represent a 3d point in a tetrahedron. + A geometry shader calculates and emits the tetrahedrons as triangles and calculate normals on the fly while rendering data. This helps us avoid doing this expensive operation @@ -90,8 +90,7 @@ def __init__(self, **kwargs): self.query = self.ctx.query(samples=True, any_samples=True, time=True, primitives=True) self.total_elapsed = 0 - def render(self, time, frametime): - + def on_render(self, time: float, frametime: float): # Render background self.ctx.wireframe = False if not self.with_blending: @@ -133,8 +132,8 @@ def render(self, time, frametime): self.total_elapsed = self.query.elapsed - def key_event(self, key, action, modifiers): - super().key_event(key, action, modifiers) + def on_key_event(self, key, action, modifiers): + super().on_key_event(key, action, modifiers) keys = self.wnd.keys if action == keys.ACTION_PRESS: @@ -148,7 +147,7 @@ def key_event(self, key, action, modifiers): self.mesh_color = 0.0, 0.8, 0.0 self.line_color = 0.0, 0.0, 0.0 - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): if y_offset > 0: self.threshold += 0.01 else: @@ -156,7 +155,7 @@ def mouse_scroll_event(self, x_offset, y_offset): self.threshold = max(min(self.threshold, 1.0), 0.0) - def close(self): + def on_close(self): # 1 s = 1000000000 ns # 1 s = 1000000 μs avg = self.total_elapsed / self.wnd.frames diff --git a/examples/advanced/voxel_cubes.py b/examples/advanced/voxel_cubes.py index 211c0243..21d70f82 100644 --- a/examples/advanced/voxel_cubes.py +++ b/examples/advanced/voxel_cubes.py @@ -43,9 +43,7 @@ def __init__(self, *args, **kwargs): self.voxel.gen_instance_prog = self.load_program( "programs/voxel_cubes/gen_voxel_instance_data.glsl" ) - self.voxel.voxel_light_prog = self.load_program( - "programs/voxel_cubes/voxel_light.glsl" - ) + self.voxel.voxel_light_prog = self.load_program("programs/voxel_cubes/voxel_light.glsl") self.voxel.voxel_wireframe_prog = self.load_program( "programs/voxel_cubes/voxel_wireframe.glsl" ) @@ -55,7 +53,7 @@ def __init__(self, *args, **kwargs): self.current_layer = 0 self.fill = False - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.ctx.clear() # Render the lookup texture in the background self.ctx.enable_only(moderngl.NOTHING) @@ -178,9 +176,7 @@ def rebuild(self): def fill_layer(self, layer: int, value: int): x = (layer % 10) * self._size[0] y = (layer // 10) * self._size[1] - self.voxel_lookup.write( - array("B", [value] * 100 * 100), viewport=(x, y, 100, 100) - ) + self.voxel_lookup.write(array("B", [value] * 100 * 100), viewport=(x, y, 100, 100)) # NOTE: These functions can make adding and removing cubes extremely fast def add_cubes(self, positions): diff --git a/examples/advanced/water.py b/examples/advanced/water.py index 0de8f7cd..301c6ce5 100644 --- a/examples/advanced/water.py +++ b/examples/advanced/water.py @@ -3,6 +3,7 @@ Hold left mouse button to place drop in the surface """ + import random from pathlib import Path @@ -15,7 +16,7 @@ class Water(moderngl_window.WindowConfig): title = "Water" - resource_dir = (Path(__file__) / '../../resources').absolute() + resource_dir = (Path(__file__) / "../../resources").absolute() aspect_ratio = None # We'll do manual viewport for now window_size = 1280, 720 resizable = False @@ -36,31 +37,36 @@ def __init__(self, *args, **kwargs): self.fbo_2 = self.ctx.framebuffer(color_attachments=[self.texture_2]) self.fbo_2.viewport = self.viewport - drop = np.array([[0.0, 0.0, 1/6, 1/5, 1/4, 1/5, 1/6, 0.0, 0.0], - [0.0, 1/6, 1/5, 1/4, 1/3, 1/4, 1/5, 1/6, 0.0], - [1/6, 1/5, 1/4, 1/3, 1/2, 1/3, 1/4, 1/5, 1/6], - [1/5, 1/4, 1/3, 1/2, 1.0, 1/2, 1/3, 1/4, 1/5], - [1/4, 1/3, 1/2, 1.0, 1.0, 1.0, 1/2, 1/3, 1/4], - [1/5, 1/4, 1/3, 1/2, 1.0, 1/2, 1/3, 1/4, 1/5], - [1/6, 1/5, 1/4, 1/3, 1/2, 1/3, 1/4, 1/5, 1/6], - [0.0, 1/6, 1/5, 1/4, 1/3, 1/4, 1/5, 1/6, 0.0], - [0.0, 0.0, 1/6, 1/5, 1/4, 1/5, 1/6, 0.0, 0.0]]) - self.drops_texture = self.ctx.texture((9, 9), components=1, dtype='f4') - self.drops_texture.write(drop.astype('f4').tobytes()) + # fmt: off + drop = np.array([ + [0.0, 0.0, 1/6, 1/5, 1/4, 1/5, 1/6, 0.0, 0.0], + [0.0, 1/6, 1/5, 1/4, 1/3, 1/4, 1/5, 1/6, 0.0], + [1/6, 1/5, 1/4, 1/3, 1/2, 1/3, 1/4, 1/5, 1/6], + [1/5, 1/4, 1/3, 1/2, 1.0, 1/2, 1/3, 1/4, 1/5], + [1/4, 1/3, 1/2, 1.0, 1.0, 1.0, 1/2, 1/3, 1/4], + [1/5, 1/4, 1/3, 1/2, 1.0, 1/2, 1/3, 1/4, 1/5], + [1/6, 1/5, 1/4, 1/3, 1/2, 1/3, 1/4, 1/5, 1/6], + [0.0, 1/6, 1/5, 1/4, 1/3, 1/4, 1/5, 1/6, 0.0], + [0.0, 0.0, 1/6, 1/5, 1/4, 1/5, 1/6, 0.0, 0.0], + ]) + # fmt: on + + self.drops_texture = self.ctx.texture((9, 9), components=1, dtype="f4") + self.drops_texture.write(drop.astype("f4").tobytes()) # programs - self.drop_program = self.load_program('programs/water/drop.glsl') - self.wave_program = self.load_program('programs/water/wave.glsl') - self.texture_program = self.load_program('programs/water/texture.glsl') - self.wave_program['texture0'].value = 0 - self.wave_program['texture1'].value = 1 + self.drop_program = self.load_program("programs/water/drop.glsl") + self.wave_program = self.load_program("programs/water/wave.glsl") + self.texture_program = self.load_program("programs/water/texture.glsl") + self.wave_program["texture0"].value = 0 + self.wave_program["texture1"].value = 1 self.mouse_pos = 0, 0 self.wnd.fbo.viewport = self.viewport - def render(self, time, frame_time): + def on_render(self, time, frame_time): # randomize color - self.drop_program['color'].value = random.random(), random.random(), random.random() + self.drop_program["color"].value = random.random(), random.random(), random.random() self.fbo_2.use() @@ -69,7 +75,7 @@ def render(self, time, frame_time): self.ctx.enable(moderngl.BLEND) self.ctx.blend_func = moderngl.ONE, moderngl.ONE self.drops_texture.use() - self.drop_program['pos'].value = self.mouse_pos + self.drop_program["pos"].value = self.mouse_pos self.sprite.render(self.drop_program) self.ctx.disable(moderngl.BLEND) @@ -79,7 +85,7 @@ def render(self, time, frame_time): self.ctx.blend_func = moderngl.ONE, moderngl.ONE self.drops_texture.use() for i in range(10): - self.drop_program['pos'].value = random.random() * 2 - 1.0, random.random() * 2 - 1 + self.drop_program["pos"].value = random.random() * 2 - 1.0, random.random() * 2 - 1 self.sprite.render(self.drop_program) self.ctx.disable(moderngl.BLEND) @@ -100,15 +106,15 @@ def render(self, time, frame_time): self.texture_1, self.texture_2 = self.texture_2, self.texture_1 self.fbo_1, self.fbo_2 = self.fbo_2, self.fbo_1 - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): xx = x * 2 / self.wnd.size[0] - 1.0 yy = -y * 2 / self.wnd.size[1] + 1.0 self.mouse_pos = xx, yy - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): self.mouse_position_event(x, y, dx, dy) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys # Key presses @@ -117,5 +123,5 @@ def key_event(self, key, action, modifiers): screenshot.create(self.fbo_1) -if __name__ == '__main__': +if __name__ == "__main__": moderngl_window.run_window_config(Water) diff --git a/examples/base.py b/examples/base.py index a51da259..47ef9eb6 100644 --- a/examples/base.py +++ b/examples/base.py @@ -10,7 +10,7 @@ def __init__(self, **kwargs): self.camera = KeyboardCamera(self.wnd.keys, aspect_ratio=self.wnd.aspect_ratio) self.camera_enabled = True - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if self.camera_enabled: @@ -24,11 +24,11 @@ def key_event(self, key, action, modifiers): if key == keys.SPACE: self.timer.toggle_pause() - def mouse_position_event(self, x: int, y: int, dx, dy): + def on_mouse_position_event(self, x: int, y: int, dx, dy): if self.camera_enabled: self.camera.rot_state(-dx, -dy) - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): self.camera.projection.update(aspect_ratio=self.wnd.aspect_ratio) @@ -43,7 +43,7 @@ def __init__(self, **kwargs): self.camera = OrbitCamera(aspect_ratio=self.wnd.aspect_ratio) self.camera_enabled = True - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if action == keys.ACTION_PRESS: @@ -54,15 +54,15 @@ def key_event(self, key, action, modifiers): if key == keys.SPACE: self.timer.toggle_pause() - def mouse_position_event(self, x: int, y: int, dx, dy): + def on_mouse_position_event(self, x: int, y: int, dx, dy): if self.camera_enabled: self.camera.rot_state(dx, dy) - def mouse_scroll_event(self, x_offset: float, y_offset: float): + def on_mouse_scroll_event(self, x_offset: float, y_offset: float): if self.camera_enabled: self.camera.zoom_state(y_offset) - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): self.camera.projection.update(aspect_ratio=self.wnd.aspect_ratio) @@ -76,18 +76,18 @@ def __init__(self, **kwargs): super().__init__(**kwargs) self.camera = OrbitCamera(aspect_ratio=self.wnd.aspect_ratio) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if action == keys.ACTION_PRESS: if key == keys.SPACE: self.timer.toggle_pause() - def mouse_drag_event(self, x: int, y: int, dx, dy): + def on_mouse_drag_event(self, x: int, y: int, dx, dy): self.camera.rot_state(dx, dy) - def mouse_scroll_event(self, x_offset: float, y_offset: float): + def on_mouse_scroll_event(self, x_offset: float, y_offset: float): self.camera.zoom_state(y_offset) - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): self.camera.projection.update(aspect_ratio=self.wnd.aspect_ratio) diff --git a/examples/cube_model.py b/examples/cube_model.py index 7cdbca84..4929a94a 100644 --- a/examples/cube_model.py +++ b/examples/cube_model.py @@ -9,21 +9,21 @@ class CubeModel(CameraWindow): aspect_ratio = 16 / 9 - resource_dir = Path(__file__).parent.resolve() / 'resources' + resource_dir = Path(__file__).parent.resolve() / "resources" title = "Cube Model" def __init__(self, **kwargs): super().__init__(**kwargs) self.wnd.mouse_exclusivity = True - self.scene = self.load_scene('scenes/crate.obj') + self.scene = self.load_scene("scenes/crate.obj") # self.scene = self.load_scene('scenes/Apollo_17.stl') self.camera.projection.update(near=0.1, far=100.0) self.camera.velocity = 7.0 self.camera.mouse_sensitivity = 0.3 - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) translation = glm.translate(glm.vec3(0, 0, -1.5)) @@ -38,5 +38,5 @@ def render(self, time: float, frametime: float): ) -if __name__ == '__main__': +if __name__ == "__main__": moderngl_window.run_window_config(CubeModel) diff --git a/examples/cubes.py b/examples/cubes.py index 33922f9e..95a68347 100644 --- a/examples/cubes.py +++ b/examples/cubes.py @@ -14,7 +14,7 @@ class Cubes(moderngl_window.WindowConfig): title = "Cubes" resizable = True - aspect_ratio = None + aspect_ratio = 16 / 9 resource_dir = Path(__file__).parent.resolve() / "resources" def __init__(self, **kwargs): @@ -28,9 +28,9 @@ def __init__(self, **kwargs): self.box_t2_c3_v3 = self.load_scene("scenes/box/box-T2F_C3F_V3F.obj") self.box_t2_n3_v3 = self.load_scene("scenes/box/box-T2F_N3F_V3F.obj") - self.resize(*self.wnd.size) + self.on_resize(*self.wnd.size) - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) rot = glm.mat4(glm.quat(glm.vec3(time, time / 2, time / 3))) @@ -58,9 +58,9 @@ def render(self, time, frame_time): view = glm.translate(glm.vec3(5, -2, -10)) self.box_t2_n3_v3.draw(self.projection, view * rot) - def resize(self, width, height): - self.ctx.viewport = 0, 0, width, height - self.projection = glm.perspective(glm.radians(45), width / height, 1, 50) + def on_resize(self, width, height): + super().on_resize(width, height) + self.projection = glm.perspective(glm.radians(45), self.aspect_ratio, 1, 50) if __name__ == "__main__": diff --git a/examples/custom_config_class.py b/examples/custom_config_class.py index 7fa39555..5bb35f1b 100644 --- a/examples/custom_config_class.py +++ b/examples/custom_config_class.py @@ -11,25 +11,26 @@ class CustomSetup: Custom setup using a class. We create the window, main loop and register events. """ + def __init__(self): # Configure to use pyglet window - settings.WINDOW['class'] = 'moderngl_window.context.pyglet.Window' + settings.WINDOW["class"] = "moderngl_window.context.pyglet.Window" self.wnd = moderngl_window.create_window_from_settings() self.ctx = self.wnd.ctx # register event methods - self.wnd.resize_func = self.resize - self.wnd.iconify_func = self.iconify - self.wnd.key_event_func = self.key_event - self.wnd.mouse_position_event_func = self.mouse_position_event - self.wnd.mouse_drag_event_func = self.mouse_drag_event - self.wnd.mouse_scroll_event_func = self.mouse_scroll_event - self.wnd.mouse_press_event_func = self.mouse_press_event - self.wnd.mouse_release_event_func = self.mouse_release_event - self.wnd.unicode_char_entered_func = self.unicode_char_entered - self.wnd.close_func = self.close - - def render(self, time, frame_time): + self.wnd.resize_func = self.on_resize + self.wnd.iconify_func = self.on_iconify + self.wnd.key_event_func = self.on_key_event + self.wnd.mouse_position_event_func = self.on_mouse_position_event + self.wnd.mouse_drag_event_func = self.on_mouse_drag_event + self.wnd.mouse_scroll_event_func = self.on_mouse_scroll_event + self.wnd.mouse_press_event_func = self.on_mouse_press_event + self.wnd.mouse_release_event_func = self.on_mouse_release_event + self.wnd.unicode_char_entered_func = self.on_unicode_char_entered + self.wnd.close_func = self.on_close + + def on_render(self, time, frame_time): self.ctx.clear( (math.sin(time) + 1.0) / 2, (math.sin(time + 2) + 1.0) / 2, @@ -43,19 +44,19 @@ def run(self): while not self.wnd.is_closing: self.wnd.clear() time, frame_time = timer.next_frame() - self.render(time, frame_time) + self.on_render(time, frame_time) self.wnd.swap_buffers() self.wnd.destroy() - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): print("Window was resized. buffer size is {} x {}".format(width, height)) - def iconify(self, iconify: bool): + def on_iconify(self, iconify: bool): """Window hide/minimize and restore""" print("Window was iconified:", iconify) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys # Key presses @@ -95,36 +96,35 @@ def key_event(self, key, action, modifiers): if key == keys.T: title = list(self.wnd.title) random.shuffle(title) - self.wnd.title = ''.join(title) + self.wnd.title = "".join(title) # Toggle mouse exclusivity if key == keys.M: self.wnd.mouse_exclusivity = not self.wnd.mouse_exclusivity - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): print("Mouse position pos={} {} delta={} {}".format(x, y, dx, dy)) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): print("Mouse drag pos={} {} delta={} {}".format(x, y, dx, dy)) - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): print("mouse_scroll_event", x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): print("Mouse button {} pressed at {}, {}".format(button, x, y)) print("Mouse states:", self.wnd.mouse_states) - def mouse_release_event(self, x: int, y: int, button: int): + def on_mouse_release_event(self, x: int, y: int, button: int): print("Mouse button {} released at {}, {}".format(button, x, y)) print("Mouse states:", self.wnd.mouse_states) - def unicode_char_entered(self, char): + def on_unicode_char_entered(self, char): print("unicode_char_entered:", char) - def close(self): + def on_close(self): print("Window was closed") -if __name__ == '__main__': - app = CustomSetup() - app.run() +if __name__ == "__main__": + CustomSetup().run() diff --git a/examples/custom_config_functions.py b/examples/custom_config_functions.py index 5bd0874c..d30cc3d4 100644 --- a/examples/custom_config_functions.py +++ b/examples/custom_config_functions.py @@ -1,6 +1,7 @@ """ Custom usage: window creation and mapping callbacks functions at module level """ + import math import random @@ -14,19 +15,19 @@ def main(): global window # Configure to use pyglet window - settings.WINDOW['class'] = 'moderngl_window.context.pyglet.Window' + settings.WINDOW["class"] = "moderngl_window.context.pyglet.Window" window = moderngl_window.create_window_from_settings() # Map callback functions - window.resize_func = resize - window.iconify_func = iconify - window.key_event_func = key_event - window.mouse_position_event_func = mouse_position_event - window.mouse_drag_event_func = mouse_drag_event - window.mouse_scroll_event_func = mouse_scroll_event - window.mouse_press_event_func = mouse_press_event - window.mouse_release_event_func = mouse_release_event - window.unicode_char_entered_func = unicode_char_entered + window.resize_func = on_resize + window.iconify_func = on_iconify + window.key_event_func = on_key_event + window.mouse_position_event_func = on_mouse_position_event + window.mouse_drag_event_func = on_mouse_drag_event + window.mouse_scroll_event_func = on_mouse_scroll_event + window.mouse_press_event_func = on_mouse_press_event + window.mouse_release_event_func = on_mouse_release_event + window.unicode_char_entered_func = on_unicode_char_entered timer = Timer() timer.start() @@ -48,22 +49,22 @@ def main(): window.destroy() -def render(time: float, frametime: float): +def on_render(time: float, frametime: float): # We can also check if a key is in press state here if window.is_key_pressed(window.keys.SPACE): print("User is holding SPACE button") -def resize(width: int, height: int): +def on_resize(width: int, height: int): print("Window was resized. buffer size is {} x {}".format(width, height)) -def iconify(iconify: bool): +def on_iconify(iconify: bool): """Window hide/minimize and restore""" print("Window was iconified:", iconify) -def key_event(key, action, modifiers): +def on_key_event(key, action, modifiers): keys = window.keys # Key presses @@ -103,38 +104,38 @@ def key_event(key, action, modifiers): if key == keys.T: title = list(window.title) random.shuffle(title) - window.title = ''.join(title) + window.title = "".join(title) # Toggle mouse exclusivity if key == keys.M: window.mouse_exclusivity = not window.mouse_exclusivity -def mouse_position_event(x, y, dx, dy): +def on_mouse_position_event(x, y, dx, dy): print("Mouse position pos={} {} delta={} {}".format(x, y, dx, dy)) -def mouse_drag_event(x, y, dx, dy): +def on_mouse_drag_event(x, y, dx, dy): print("Mouse drag pos={} {} delta={} {}".format(x, y, dx, dy)) -def mouse_scroll_event(x_offset, y_offset): +def on_mouse_scroll_event(x_offset, y_offset): print("mouse_scroll_event", x_offset, y_offset) -def mouse_press_event(x, y, button): +def on_mouse_press_event(x, y, button): print("Mouse button {} pressed at {}, {}".format(button, x, y)) print("Mouse states:", window.mouse_states) -def mouse_release_event(x: int, y: int, button: int): +def on_mouse_release_event(x: int, y: int, button: int): print("Mouse button {} released at {}, {}".format(button, x, y)) print("Mouse states:", window.mouse_states) -def unicode_char_entered(char): +def on_unicode_char_entered(char): print("unicode_char_entered:", char) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/examples/drag_drop_file_input.py b/examples/drag_drop_file_input.py index 247aa52e..a8a84ce8 100644 --- a/examples/drag_drop_file_input.py +++ b/examples/drag_drop_file_input.py @@ -5,6 +5,7 @@ Currently only working with the Pyglet backend. """ + import os from pathlib import Path @@ -18,24 +19,24 @@ class Cubes(moderngl_window.WindowConfig): title = "Cubes" resizable = True aspect_ratio = None - resource_dir = Path(__file__).parent.resolve() / 'resources' + resource_dir = Path(__file__).parent.resolve() / "resources" def __init__(self, **kwargs): super().__init__(**kwargs) # Load the 6 different boxes with different vertex formats - self.box_top_left = self.load_scene('scenes/box/box-T2F_V3F.obj') - self.box_top_middle = self.load_scene('scenes/box/box-T2F_V3F.obj') - self.box_top_right = self.load_scene('scenes/box/box-T2F_V3F.obj') - self.box_bottom_left = self.load_scene('scenes/box/box-T2F_V3F.obj') - self.box_bottom_middle = self.load_scene('scenes/box/box-T2F_V3F.obj') - self.box_bottom_right = self.load_scene('scenes/box/box-T2F_V3F.obj') + self.box_top_left = self.load_scene("scenes/box/box-T2F_V3F.obj") + self.box_top_middle = self.load_scene("scenes/box/box-T2F_V3F.obj") + self.box_top_right = self.load_scene("scenes/box/box-T2F_V3F.obj") + self.box_bottom_left = self.load_scene("scenes/box/box-T2F_V3F.obj") + self.box_bottom_middle = self.load_scene("scenes/box/box-T2F_V3F.obj") + self.box_bottom_right = self.load_scene("scenes/box/box-T2F_V3F.obj") self.resize(*self.wnd.size) - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - rot = glm.mat4(glm.quat(glm.vec3(time, time/2, time/3))) + rot = glm.mat4(glm.quat(glm.vec3(time, time / 2, time / 3))) # Box top left view = glm.translate(glm.vec3(-5, 2, -10)) @@ -61,7 +62,7 @@ def render(self, time, frame_time): view = glm.translate(glm.vec3(5, -2, -10)) self.box_bottom_right.draw(self.projection, view * rot) - def resize(self, width, height): + def on_resize(self, width, height): self.ctx.viewport = 0, 0, width, height self.projection = glm.perspective(glm.radians(45), width / height, 1, 50) @@ -70,35 +71,34 @@ def _load_texture(self, path): print(type(tex)) return tex - def files_dropped_event(self, x, y, paths): + def on_files_dropped_event(self, x, y, paths): if x < self.wnd._window.width * 0.33: if y < self.wnd._window.height * 0.5: # Modify top left box - self.box_top_left.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_top_left.materials[0].mat_texture.texture = self._load_texture(paths[0]) else: # Modify bottom left box - self.box_bottom_left.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_bottom_left.materials[0].mat_texture.texture = self._load_texture(paths[0]) elif x < self.wnd._window.width * 0.66: if y < self.wnd._window.height * 0.5: # Modify top middle box - self.box_top_middle.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_top_middle.materials[0].mat_texture.texture = self._load_texture(paths[0]) else: # Modify bottom middle box - self.box_bottom_middle.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_bottom_middle.materials[0].mat_texture.texture = self._load_texture( + paths[0] + ) else: if y < self.wnd._window.height * 0.5: # Modify top right box - self.box_top_right.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_top_right.materials[0].mat_texture.texture = self._load_texture(paths[0]) else: # Modify bottom right box - self.box_bottom_right.materials[0].mat_texture.texture = \ - self._load_texture(paths[0]) + self.box_bottom_right.materials[0].mat_texture.texture = self._load_texture( + paths[0] + ) print(paths) -if __name__ == '__main__': + +if __name__ == "__main__": Cubes.run() diff --git a/examples/geometry_bbox.py b/examples/geometry_bbox.py index 26e915fc..357f0bf0 100644 --- a/examples/geometry_bbox.py +++ b/examples/geometry_bbox.py @@ -11,21 +11,21 @@ class GeometryBbox(CameraWindow): def __init__(self, **kwargs): super().__init__(**kwargs) self.wnd.mouse_exclusivity = True - self.prog = self.load_program('scene_default/bbox.glsl') + self.prog = self.load_program("scene_default/bbox.glsl") self.bbox = geometry.bbox() - self.prog['color'].value = (1, 1, 1) - self.prog['bb_min'].value = (-2, -2, -2) - self.prog['bb_max'].value = (2, 2, 2) - self.prog['m_model'].write(glm.translate(glm.vec3(0.0, 0.0, -8.0))) + self.prog["color"].value = (1, 1, 1) + self.prog["bb_min"].value = (-2, -2, -2) + self.prog["bb_max"].value = (2, 2, 2) + self.prog["m_model"].write(glm.translate(glm.vec3(0.0, 0.0, -8.0))) - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): self.ctx.clear() - self.prog['m_proj'].write(self.camera.projection.matrix) - self.prog['m_cam'].write(self.camera.matrix) + self.prog["m_proj"].write(self.camera.projection.matrix) + self.prog["m_cam"].write(self.camera.matrix) self.bbox.render(self.prog) -if __name__ == '__main__': +if __name__ == "__main__": moderngl_window.run_window_config(GeometryBbox) diff --git a/examples/geometry_cube.py b/examples/geometry_cube.py index 2e28099b..6de7c6a9 100644 --- a/examples/geometry_cube.py +++ b/examples/geometry_cube.py @@ -19,7 +19,7 @@ def __init__(self, **kwargs): self.prog = self.load_program("programs/cube_simple.glsl") self.prog["color"].value = 1.0, 1.0, 1.0, 1.0 - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) diff --git a/examples/geometry_cube_instanced.py b/examples/geometry_cube_instanced.py index 8fa5911f..b20c16f5 100644 --- a/examples/geometry_cube_instanced.py +++ b/examples/geometry_cube_instanced.py @@ -51,7 +51,7 @@ def gen_data(x_res, z_res, spacing=2.5): ) self.cube.buffer(self.instance_data, "3f 3f/i", ["in_offset", "in_color"]) - def render(self, time: float, frametime: float) -> None: + def on_render(self, time: float, frametime: float) -> None: self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) self.prog["m_proj"].write(self.camera.projection.matrix) diff --git a/examples/geometry_lines.py b/examples/geometry_lines.py index e7cfd039..ff0f5e4a 100644 --- a/examples/geometry_lines.py +++ b/examples/geometry_lines.py @@ -12,7 +12,7 @@ class LinesDemo(CameraWindow): """Rendering thick lines with geometry shader Example is basic and incomplete, but shows how - one could use the geometry shader to create thick lines. + one could use the geometry shader to create simple thick lines. """ gl_version = (3, 3) @@ -41,9 +41,7 @@ def gen_lines(): yield 1.0 - i * 2.0 / N yield 0.0 - buffer = self.ctx.buffer( - numpy.fromiter(gen_lines(), dtype="f4", count=N * 6).tobytes() - ) + buffer = self.ctx.buffer(numpy.fromiter(gen_lines(), dtype="f4", count=N * 6).tobytes()) self.lines = self.ctx.vertex_array( self.prog, [ @@ -51,7 +49,7 @@ def gen_lines(): ], ) - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): # self.ctx.enable_only(moderngl.DEPTH_TEST) self.prog["m_proj"].write(self.camera.projection.matrix) diff --git a/examples/geometry_quad_fs.py b/examples/geometry_quad_fs.py index 14fcdb54..9b39696e 100644 --- a/examples/geometry_quad_fs.py +++ b/examples/geometry_quad_fs.py @@ -3,26 +3,27 @@ import moderngl_window from moderngl_window import geometry, resources -resources.register_dir((Path(__file__).parent / 'resources').resolve()) +resources.register_dir((Path(__file__).parent / "resources").resolve()) class QuadFullscreen(moderngl_window.WindowConfig): + title = "Quad Fullscreen" window_size = 1980, 1024 aspect_ratio = 1980 / 1024 def __init__(self, **kwargs): super().__init__(**kwargs) self.quad = geometry.quad_fs() - self.texture = self.load_texture_2d('textures/python-bg.png') - self.prog = self.load_program('programs/texture.glsl') + self.texture = self.load_texture_2d("textures/python-bg.png") + self.prog = self.load_program("programs/texture.glsl") - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): self.ctx.clear() self.texture.use(location=0) - self.prog['texture0'].value = 0 + self.prog["texture0"].value = 0 self.quad.render(self.prog) -if __name__ == '__main__': +if __name__ == "__main__": moderngl_window.run_window_config(QuadFullscreen) diff --git a/examples/geometry_quad_fs_mouse_scroll.py b/examples/geometry_quad_fs_mouse_scroll.py index 42fb808c..e4d21262 100644 --- a/examples/geometry_quad_fs_mouse_scroll.py +++ b/examples/geometry_quad_fs_mouse_scroll.py @@ -1,3 +1,7 @@ +""" +Press and drag the mouse to scroll the texture +""" + from pathlib import Path import moderngl_window @@ -7,8 +11,7 @@ class QuadFullscreenScroll(moderngl_window.WindowConfig): - """Taking texture offset from mouse""" - + title = "Quad Fullscreen Scroll" aspect_ratio = None def __init__(self, **kwargs): @@ -18,7 +21,7 @@ def __init__(self, **kwargs): self.prog = self.load_program("programs/texture_mouse_scroll.glsl") self.mouse_pos = 0, 0 - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): self.ctx.clear() self.texture.use(location=0) @@ -29,10 +32,10 @@ def render(self, time: float, frame_time: float): ) self.quad.render(self.prog) - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): self.mouse_pos = self.mouse_pos[0] + dx, self.mouse_pos[1] + dy print(self.mouse_pos) if __name__ == "__main__": - moderngl_window.run_window_config(QuadFullscreenScroll) + QuadFullscreenScroll.run() diff --git a/examples/gltf_scenes.py b/examples/gltf_scenes.py index bbc5d883..9d3f98b2 100644 --- a/examples/gltf_scenes.py +++ b/examples/gltf_scenes.py @@ -81,7 +81,7 @@ def __init__(self, **kwargs): # if self.scene.diagonal_size > 0: # self.camera.velocity = self.scene.diagonal_size / 5.0 - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): """Render the scene""" self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) diff --git a/examples/headless.py b/examples/headless.py index 3167df68..7a34fca9 100644 --- a/examples/headless.py +++ b/examples/headless.py @@ -55,7 +55,7 @@ def __init__(self, **kwargs): prog, self.ctx.buffer(vertices), "in_vert", "in_color" ) - def render(self, time, frame_time): + def on_render(self, time, frame_time): """Render one frame, save to png and close it""" # Fill currently bound framebuffer with while background self.ctx.clear(1, 1, 1, 1) @@ -73,4 +73,4 @@ def render(self, time, frame_time): if __name__ == "__main__": - HeadlessTest.run() + moderngl_window.run_window_config(HeadlessTest, args=("--window", "headless")) diff --git a/examples/integration_imgui.py b/examples/integration_imgui.py index 62d26f53..209f4189 100644 --- a/examples/integration_imgui.py +++ b/examples/integration_imgui.py @@ -2,6 +2,7 @@ import glm import moderngl + # import imgui from imgui_bundle import imgui @@ -13,7 +14,7 @@ class WindowEvents(mglw.WindowConfig): gl_version = (3, 3) title = "imgui Integration" - resource_dir = (Path(__file__).parent / 'resources').resolve() + resource_dir = (Path(__file__).parent / "resources").resolve() aspect_ratio = None def __init__(self, **kwargs): @@ -23,18 +24,18 @@ def __init__(self, **kwargs): self.imgui = ModernglWindowRenderer(self.wnd) self.cube = geometry.cube(size=(2, 2, 2)) - self.prog = self.load_program('programs/cube_simple.glsl') - self.prog['color'].value = (1.0, 1.0, 1.0, 1.0) - self.prog['m_camera'].write(glm.mat4()) - self.prog['m_proj'].write(glm.perspective(glm.radians(75), self.wnd.aspect_ratio, 1, 100)) + self.prog = self.load_program("programs/cube_simple.glsl") + self.prog["color"].value = (1.0, 1.0, 1.0, 1.0) + self.prog["m_camera"].write(glm.mat4()) + self.prog["m_proj"].write(glm.perspective(glm.radians(75), self.wnd.aspect_ratio, 1, 100)) - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) translation = glm.translate(glm.vec3(0.0, 0.0, -3.5)) model = translation * rotation self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - self.prog['m_model'].write(model) + self.prog["m_model"].write(model) self.cube.render(self.prog) self.render_ui() @@ -43,10 +44,7 @@ def render_ui(self): imgui.new_frame() if imgui.begin_main_menu_bar(): if imgui.begin_menu("File", True): - - clicked_quit, selected_quit = imgui.menu_item( - "Quit", 'Cmd+Q', False, True - ) + clicked_quit, selected_quit = imgui.menu_item("Quit", "Cmd+Q", False, True) if clicked_quit: exit(1) @@ -58,37 +56,37 @@ def render_ui(self): imgui.begin("Custom window", True) imgui.text("Bar") - imgui.text_colored(imgui.ImVec4(0.2, 1., 0., 1.), "Eggs") + imgui.text_colored(imgui.ImVec4(0.2, 1.0, 0.0, 1.0), "Eggs") imgui.end() imgui.render() self.imgui.render(imgui.get_draw_data()) - def resize(self, width: int, height: int): - self.prog['m_proj'].write(glm.perspective(glm.radians(75), self.wnd.aspect_ratio, 1, 100)) + def on_resize(self, width: int, height: int): + self.prog["m_proj"].write(glm.perspective(glm.radians(75), self.wnd.aspect_ratio, 1, 100)) self.imgui.resize(width, height) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) - def mouse_release_event(self, x: int, y: int, button: int): + def on_mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) - def unicode_char_entered(self, char): + def on_unicode_char_entered(self, char): self.imgui.unicode_char_entered(char) -if __name__ == '__main__': +if __name__ == "__main__": mglw.run_window_config(WindowEvents) diff --git a/examples/integration_imgui_image.py b/examples/integration_imgui_image.py index 7dd43f23..9dc2b2bc 100644 --- a/examples/integration_imgui_image.py +++ b/examples/integration_imgui_image.py @@ -2,7 +2,7 @@ import glm import moderngl -# import imgui + from imgui_bundle import imgui import moderngl_window as mglw @@ -36,7 +36,7 @@ def __init__(self, **kwargs): # This is the color layer in the framebuffer self.imgui.register_texture(self.fbo.color_attachments[0]) - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): # Rotate/move cube rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) translation = glm.translate(glm.vec3(0.0, 0.0, -3.5)) @@ -58,7 +58,6 @@ def render_ui(self): imgui.new_frame() if imgui.begin_main_menu_bar(): if imgui.begin_menu("File", True): - clicked_quit, selected_quit = imgui.menu_item("Quit", "Cmd+Q", False, True) if clicked_quit: @@ -85,30 +84,30 @@ def render_ui(self): imgui.render() self.imgui.render(imgui.get_draw_data()) - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): self.imgui.resize(width, height) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) - def mouse_release_event(self, x: int, y: int, button: int): + def on_mouse_release_event(self, x: int, y: int, button: int): self.imgui.mouse_release_event(x, y, button) - def unicode_char_entered(self, char): + def on_unicode_char_entered(self, char): self.imgui.unicode_char_entered(char) if __name__ == "__main__": - mglw.run_window_config(WindowEvents) + WindowEvents.run() diff --git a/examples/moderngl_logo.py b/examples/moderngl_logo.py index 2aa8963d..96ec164b 100644 --- a/examples/moderngl_logo.py +++ b/examples/moderngl_logo.py @@ -10,7 +10,7 @@ class ModernglLogo(mglw.WindowConfig): def __init__(self, **kwargs): super().__init__(**kwargs) self.prog = self.ctx.program( - vertex_shader=''' + vertex_shader=""" #version 330 in vec2 vert; @@ -27,8 +27,8 @@ def __init__(self, **kwargs): mat2 rot = mat2(cos(r), sin(r), -sin(r), cos(r)); gl_Position = vec4((rot * vert) * scale, 0.0, 1.0); } - ''', - fragment_shader=''' + """, + fragment_shader=""" #version 330 in vec4 frag_color; @@ -37,14 +37,15 @@ def __init__(self, **kwargs): void main() { color = vec4(frag_color); } - ''', + """, ) - self.scale = self.prog['scale'] - self.rotation = self.prog['rotation'] + self.scale = self.prog["scale"] + self.rotation = self.prog["rotation"] self.scale.value = (0.5, self.aspect_ratio * 0.5) + # fmt: off vertices = np.array([ 1.0, 0.0, 1.0, 0.0, 0.0, 0.5, @@ -54,17 +55,18 @@ def __init__(self, **kwargs): -0.5, -0.86, 0.0, 0.0, 1.0, 0.5, - ]) + ], dtype="f4") + # fmt: on - self.vbo = self.ctx.buffer(vertices.astype('f4').tobytes()) - self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, 'vert', 'vert_color') + self.vbo = self.ctx.buffer(vertices.astype("f4").tobytes()) + self.vao = self.ctx.simple_vertex_array(self.prog, self.vbo, "vert", "vert_color") - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.clear(1.0, 1.0, 1.0) self.ctx.enable(moderngl.BLEND) self.rotation.value = time self.vao.render(instances=10) -if __name__ == '__main__': - mglw.run_window_config(ModernglLogo) +if __name__ == "__main__": + ModernglLogo.run() diff --git a/examples/modify_parser.py b/examples/modify_parser.py index 3efb5a20..fdd87510 100644 --- a/examples/modify_parser.py +++ b/examples/modify_parser.py @@ -58,7 +58,7 @@ def add_arguments(cls, parser): help="Override the window title", ) - def render(self, time, frame_time): + def on_render(self, time, frame_time): # Placeholder content self.ctx.clear( (math.sin(time) + 1.0) / 2, diff --git a/examples/orbit_camera.py b/examples/orbit_camera.py index 90433a2c..9eb948ee 100644 --- a/examples/orbit_camera.py +++ b/examples/orbit_camera.py @@ -8,21 +8,22 @@ class OrbitCamCrate(OrbitCameraWindow): """ Example showing how to use a OrbitCamera """ + aspect_ratio = 16 / 9 - resource_dir = Path(__file__).parent.resolve() / 'resources' + resource_dir = Path(__file__).parent.resolve() / "resources" title = "Crate.obj Model - Orbit Camera" def __init__(self, **kwargs): super().__init__(**kwargs) self.wnd.mouse_exclusivity = True - self.scene = self.load_scene('scenes/crate.obj') + self.scene = self.load_scene("scenes/crate.obj") self.camera.projection.update(near=0.1, far=100.0) self.camera.mouse_sensitivity = 0.75 self.camera.zoom = 2.5 - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.scene.draw( @@ -32,5 +33,5 @@ def render(self, time: float, frametime: float): ) -if __name__ == '__main__': +if __name__ == "__main__": OrbitCamCrate.run() diff --git a/examples/quit_confirm.py b/examples/quit_confirm.py index d78e4434..8aa95f55 100644 --- a/examples/quit_confirm.py +++ b/examples/quit_confirm.py @@ -14,11 +14,11 @@ def __init__(self, *args, **kwargs): self.mode = "normal" # normal / quit self.block_close = True - def render(self, time, frame_time): + def on_render(self, time, frame_time): if self.mode == "quit": self.writer_quit.draw((240, 380), size=120) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys if self.mode == "quit": if key == keys.Y: @@ -28,7 +28,7 @@ def key_event(self, key, action, modifiers): self.block_close = True self.mode = "normal" - def close(self, *args): + def on_close(self, *args): if self.block_close: self.mode = "quit" self.wnd.is_closing = False diff --git a/examples/scheduling_example.py b/examples/scheduling_example.py index 19c0e8c4..f260a3a7 100644 --- a/examples/scheduling_example.py +++ b/examples/scheduling_example.py @@ -15,7 +15,7 @@ def __init__(self, **kwargs): # create a instance of the Scheduler and tell it to use the windows internal timer # if we dont pass a timer `time.time()` will be used. # by using the internal Timer class the pause and time setting functions - # will effect our events aswell. + # will effect our events as well. self.scheduler = Scheduler(self.timer) # change the color every 1/2 seconds @@ -23,9 +23,7 @@ def __init__(self, **kwargs): # cancel the color changing event after 2 seconds using a priority of 2 self.scheduler.cancel(color_changing_event, delay=2) # restart it after another 2 seconds (4 seconds total) - color_changing_event = self.scheduler.run_every( - self.change_color, 1 / 2, initial_delay=4 - ) + color_changing_event = self.scheduler.run_every(self.change_color, 1 / 2, initial_delay=4) # after 5 seconds change the window title self.scheduler.run_once(self.change_title, 5, arguments=("Changed title",)) @@ -36,7 +34,7 @@ def change_title(self, new_title): def change_color(self): self.clear_color = (random.random(), random.random(), random.random(), 0) - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.scheduler.execute() diff --git a/examples/skybox_cubemap.py b/examples/skybox_cubemap.py index d40bf8d8..0d287232 100644 --- a/examples/skybox_cubemap.py +++ b/examples/skybox_cubemap.py @@ -3,14 +3,14 @@ import moderngl from base import CameraWindow -import moderngl_window from moderngl_window import geometry class Cubemap(CameraWindow): """Example loading and rendering a cubemap""" + title = "Skybox with cubemap" - resource_dir = (Path(__file__).parent / 'resources').resolve() + resource_dir = (Path(__file__).parent / "resources").resolve() aspect_ratio = None def __init__(self, **kwargs): @@ -18,19 +18,19 @@ def __init__(self, **kwargs): self.wnd.mouse_exclusivity = True self.cube = geometry.cube(size=(20, 20, 20)) self.texture = self.load_texture_cube( - neg_x='textures/cubemaps/yokohama/posx.jpg', - neg_y='textures/cubemaps/yokohama/negy.jpg', - neg_z='textures/cubemaps/yokohama/negz.jpg', - pos_x='textures/cubemaps/yokohama/negx.jpg', - pos_y='textures/cubemaps/yokohama/posy.jpg', - pos_z='textures/cubemaps/yokohama/posz.jpg', + neg_x="textures/cubemaps/yokohama/posx.jpg", + neg_y="textures/cubemaps/yokohama/negy.jpg", + neg_z="textures/cubemaps/yokohama/negz.jpg", + pos_x="textures/cubemaps/yokohama/negx.jpg", + pos_y="textures/cubemaps/yokohama/posy.jpg", + pos_z="textures/cubemaps/yokohama/posz.jpg", flip_x=True, ) - self.prog = self.load_program('programs/cubemap.glsl') + self.prog = self.load_program("programs/cubemap.glsl") - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.ctx.enable_only(moderngl.CULL_FACE) - self.ctx.front_face = 'cw' + self.ctx.front_face = "cw" cam = self.camera.matrix # Purge camera translation @@ -39,11 +39,11 @@ def render(self, time, frame_time): cam[3][2] = 0 self.texture.use(location=0) - self.prog['m_proj'].write(self.camera.projection.matrix) - self.prog['m_camera'].write(cam) + self.prog["m_proj"].write(self.camera.projection.matrix) + self.prog["m_camera"].write(cam) self.cube.render(self.prog) -if __name__ == '__main__': - moderngl_window.run_window_config(Cubemap) +if __name__ == "__main__": + Cubemap.run() diff --git a/examples/ssao.py b/examples/ssao.py index cfe9319b..4d4d9f3b 100644 --- a/examples/ssao.py +++ b/examples/ssao.py @@ -57,9 +57,7 @@ def __init__(self, **kwargs): self.ssao_buffer = self.ctx.framebuffer(color_attachments=[self.ssao_occlusion]) # Generate the blurred SSAO framebuffer. - self.ssao_blurred_occlusion = self.ctx.texture( - self.wnd.buffer_size, 1, dtype="f1" - ) + self.ssao_blurred_occlusion = self.ctx.texture(self.wnd.buffer_size, 1, dtype="f1") self.ssao_blurred_buffer = self.ctx.framebuffer( color_attachments=[self.ssao_blurred_occlusion] ) @@ -93,9 +91,7 @@ def __init__(self, **kwargs): # Generate SSAO samples (in tangent space coordinates, with z along the normal). self.n_ssao_samples = 64 # If you change this number, also change ssao.glsl. self.ssao_std_dev = 0.1 - self.ssao_samples = np.random.normal( - 0.0, self.ssao_std_dev, (self.n_ssao_samples, 3) - ) + self.ssao_samples = np.random.normal(0.0, self.ssao_std_dev, (self.n_ssao_samples, 3)) self.ssao_samples[:, 2] = np.abs(self.ssao_samples[:, 2]) self.ssao_program["samples"].write(self.ssao_samples.ravel().astype("f4")) @@ -118,7 +114,7 @@ def __init__(self, **kwargs): print(self.wnd.ctx.error) self.imgui = ModernglWindowRenderer(self.wnd) - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.average_frame_time = ( self.frame_time_decay_factor * self.average_frame_time + (1.0 - self.frame_time_decay_factor) * frametime @@ -167,16 +163,12 @@ def render(self, time: float, frametime: float): self.ctx.screen.clear(1.0, 1.0, 1.0) self.ctx.screen.use() self.shading_program["m_camera_inverse"].write(glm.inverse(camera_matrix)) - self.shading_program["m_projection_inverse"].write( - glm.inverse(projection_matrix) - ) + self.shading_program["m_projection_inverse"].write(glm.inverse(projection_matrix)) self.shading_program["v_camera_pos"].value = camera_pos self.shading_program["camera_pos"].value = camera_pos self.shading_program["light_pos"].value = camera_pos self.shading_program["base_color"].value = tuple(self.base_color) - self.shading_program["material_properties"].value = tuple( - self.material_properties - ) + self.shading_program["material_properties"].value = tuple(self.material_properties) self.shading_program["render_mode"].value = self.render_mode self.g_view_z.use(location=0) self.g_normal.use(location=1) @@ -194,18 +186,11 @@ def render_ui(self): imgui.begin("Debug Panel", False) imgui.text(f"Frame time: {1000.0 * self.average_frame_time:.1f} ms") imgui.text(f"FPS: {1.0 / self.average_frame_time:.1f}") - _, self.render_mode = imgui.combo( - "render mode", self.render_mode, self.render_modes - ) - _, self.ssao_z_offset = imgui.slider_float( - "SSAO z-offset", self.ssao_z_offset, -0.3, 0.3 - ) + _, self.render_mode = imgui.combo("render mode", self.render_mode, self.render_modes) + _, self.ssao_z_offset = imgui.slider_float("SSAO z-offset", self.ssao_z_offset, -0.3, 0.3) _, self.ssao_blur = imgui.checkbox("blur occlusion texture", self.ssao_blur) - _, self.base_color = imgui.color_edit3( - "color", - self.base_color - ) + _, self.base_color = imgui.color_edit3("color", self.base_color) _, self.material_properties[0] = imgui.slider_float( "ambient", self.material_properties[0], 0.0, 1.0 ) @@ -223,30 +208,30 @@ def render_ui(self): imgui.render() self.imgui.render(imgui.get_draw_data()) - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): self.imgui.mouse_position_event(x, y, dx, dy) - def mouse_drag_event(self, x: int, y: int, dx, dy): + def on_mouse_drag_event(self, x: int, y: int, dx, dy): self.imgui.mouse_drag_event(x, y, dx, dy) if not self.imgui.io.want_capture_mouse: - super().mouse_drag_event(x, y, dx, dy) + super().on_mouse_drag_event(x, y, dx, dy) - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): self.imgui.mouse_scroll_event(x_offset, y_offset) if not self.imgui.io.want_capture_mouse: - super().mouse_scroll_event(x_offset, y_offset) + super().on_mouse_scroll_event(x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): self.imgui.mouse_press_event(x, y, button) - def mouse_release_event(self, x, y, button): + def on_mouse_release_event(self, x, y, button): self.imgui.mouse_release_event(x, y, button) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): self.imgui.key_event(key, action, modifiers) if not self.imgui.io.want_capture_keyboard: - super().key_event(key, action, modifiers) + super().on_key_event(key, action, modifiers) if __name__ == "__main__": - moderngl_window.run_window_config(SSAODemo) + SSAODemo.run() diff --git a/examples/text_simple.py b/examples/text_simple.py index 5ef6ae19..2dc00ab0 100644 --- a/examples/text_simple.py +++ b/examples/text_simple.py @@ -11,7 +11,7 @@ def __init__(self, *args, **kwargs): self.writer = TextWriter2D() self.writer.text = "Hello ModernGL!" - def render(self, time, frame_time): + def on_render(self, time, frame_time): self.writer.draw((240, 380), size=120) diff --git a/examples/texture_array.py b/examples/texture_array.py index 804b0635..2c029da0 100644 --- a/examples/texture_array.py +++ b/examples/texture_array.py @@ -4,7 +4,6 @@ import moderngl from base import CameraWindow -import moderngl_window from moderngl_window import geometry @@ -13,8 +12,9 @@ class TextureArrayExample(CameraWindow): Cycles different texture layers in an array texture rendered on a cube. """ + title = "Texture Array" - resource_dir = (Path(__file__).parent / 'resources').resolve() + resource_dir = (Path(__file__).parent / "resources").resolve() def __init__(self, **kwargs): super().__init__(**kwargs) @@ -22,26 +22,27 @@ def __init__(self, **kwargs): self.num_layers = 10 self.cube = geometry.cube(size=(2, 2, 2)) self.texture = self.load_texture_array( - 'textures/array.png', layers=self.num_layers, mipmap=True, anisotrpy=8.0) - self.prog = self.load_program('programs/cube_texture_array.glsl') - self.prog['texture0'].value = 0 - self.prog['num_layers'].value = 10 + "textures/array.png", layers=self.num_layers, mipmap=True, anisotrpy=8.0 + ) + self.prog = self.load_program("programs/cube_texture_array.glsl") + self.prog["texture0"].value = 0 + self.prog["num_layers"].value = 10 - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) translation = glm.translate(glm.vec3(0.0, 0.0, -3.5)) modelview = translation * rotation - self.prog['m_proj'].write(self.camera.projection.matrix) - self.prog['m_model'].write(modelview) - self.prog['m_camera'].write(self.camera.matrix) - self.prog['time'].value = time + self.prog["m_proj"].write(self.camera.projection.matrix) + self.prog["m_model"].write(modelview) + self.prog["m_camera"].write(self.camera.matrix) + self.prog["time"].value = time self.texture.use(location=0) self.cube.render(self.prog) -if __name__ == '__main__': - moderngl_window.run_window_config(TextureArrayExample) +if __name__ == "__main__": + TextureArrayExample.run() diff --git a/examples/uniform_block.py b/examples/uniform_block.py index 227e1dd7..08e44a64 100644 --- a/examples/uniform_block.py +++ b/examples/uniform_block.py @@ -103,7 +103,7 @@ def __init__(self, **kwargs): ], ) - def render(self, time=0.0, frametime=0.0, target: moderngl.Framebuffer = None): + def on_render(self, time=0.0, frametime=0.0, target: moderngl.Framebuffer = None): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) @@ -120,4 +120,4 @@ def render(self, time=0.0, frametime=0.0, target: moderngl.Framebuffer = None): if __name__ == "__main__": - moderngl_window.run_window_config(CubeSimple) + CubeSimple.run() diff --git a/examples/video.py b/examples/video.py index 54ed3ca2..5c62c9ec 100644 --- a/examples/video.py +++ b/examples/video.py @@ -16,7 +16,6 @@ class Decoder: - def __init__(self, path: Union[str, Path]): self.container = av.open(str(path)) self.video = self.container.streams[0] @@ -80,7 +79,6 @@ def gen_frames(self): class Player: - def __init__(self, ctx: moderngl.Context, path: Union[str, Path]): self._ctx = ctx self._path = path @@ -161,9 +159,7 @@ class VideoTest(moderngl_window.WindowConfig): def __init__(self, **kwargs): super().__init__(**kwargs) - self.player = Player( - self.ctx, self.resource_dir / "videos/Lightning - 33049.mp4" - ) + self.player = Player(self.ctx, self.resource_dir / "videos/Lightning - 33049.mp4") print("duration :", self.player.duration) print("fps :", self.player.fps) print("video_size :", self.player.video_size) @@ -173,12 +169,12 @@ def __init__(self, **kwargs): self.quad = geometry.quad_fs() self.program = self.load_program("programs/texture_flipped.glsl") - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.player.update(math.fmod(time, 5)) self.player.texture.use(0) self.quad.render(self.program) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys # Key presses diff --git a/examples/window_config.py b/examples/window_config.py index fadf59a6..08a6b88a 100644 --- a/examples/window_config.py +++ b/examples/window_config.py @@ -5,13 +5,14 @@ class BasicWindowConfig(moderngl_window.WindowConfig): """Minimal WindowConfig example""" + gl_version = (3, 3) title = "Basic Window Config" def __init__(self, **kwargs): super().__init__(**kwargs) - def render(self, time, frametime): + def on_render(self, time: float, frametime: float): self.ctx.clear( (math.sin(time) + 1.0) / 2, (math.sin(time + 2) + 1.0) / 2, @@ -19,5 +20,5 @@ def render(self, time, frametime): ) -if __name__ == '__main__': - moderngl_window.run_window_config(BasicWindowConfig) +if __name__ == "__main__": + BasicWindowConfig.run() diff --git a/examples/window_events.py b/examples/window_events.py index ad6c25ca..eb56a643 100644 --- a/examples/window_events.py +++ b/examples/window_events.py @@ -8,6 +8,7 @@ class WindowEvents(moderngl_window.WindowConfig): """ Demonstrates handling mouse, keyboard, render and resize events """ + gl_version = (3, 3) title = "Window Events" cursor = True @@ -17,7 +18,7 @@ def __init__(self, **kwargs): super().__init__(**kwargs) # self.wnd.exit_key = None - def render(self, time: float, frametime: float): + def on_render(self, time: float, frametime: float): self.ctx.clear( (math.sin(time) + 1.0) / 2, (math.sin(time + 2) + 1.0) / 2, @@ -28,17 +29,17 @@ def render(self, time: float, frametime: float): if self.wnd.is_key_pressed(self.wnd.keys.SPACE): print("User is holding SPACE button") - def resize(self, width: int, height: int): + def on_resize(self, width: int, height: int): print("Window was resized. buffer size is {} x {}".format(width, height)) - def close(self): + def on_close(self): print("Window is closing") - def iconify(self, iconify: bool): + def on_iconify(self, iconify: bool): """Window hide/minimize and restore""" print("Window was iconified:", iconify) - def key_event(self, key, action, modifiers): + def on_key_event(self, key, action, modifiers): keys = self.wnd.keys # Key presses @@ -94,7 +95,7 @@ def key_event(self, key, action, modifiers): if key == keys.T: title = list(self.wnd.title) random.shuffle(title) - self.wnd.title = ''.join(title) + self.wnd.title = "".join(title) # Toggle mouse exclusivity if key == keys.M: @@ -102,31 +103,31 @@ def key_event(self, key, action, modifiers): # Check number vs. numpad if key == keys.NUMBER_0: - print('NUMBER 0') + print("NUMBER 0") if key == keys.NUMPAD_0: - print('NUMPAD 0') + print("NUMPAD 0") - def mouse_position_event(self, x, y, dx, dy): + def on_mouse_position_event(self, x, y, dx, dy): print("Mouse position pos={} {} delta={} {}".format(x, y, dx, dy)) - def mouse_drag_event(self, x, y, dx, dy): + def on_mouse_drag_event(self, x, y, dx, dy): print("Mouse drag pos={} {} delta={} {}".format(x, y, dx, dy)) - def mouse_scroll_event(self, x_offset, y_offset): + def on_mouse_scroll_event(self, x_offset, y_offset): print("mouse_scroll_event", x_offset, y_offset) - def mouse_press_event(self, x, y, button): + def on_mouse_press_event(self, x, y, button): print("Mouse button {} pressed at {}, {}".format(button, x, y)) print("Mouse states:", self.wnd.mouse_states) - def mouse_release_event(self, x: int, y: int, button: int): + def on_mouse_release_event(self, x: int, y: int, button: int): print("Mouse button {} released at {}, {}".format(button, x, y)) print("Mouse states:", self.wnd.mouse_states) - def unicode_char_entered(self, char): + def on_unicode_char_entered(self, char): print("unicode_char_entered:", char) -if __name__ == '__main__': +if __name__ == "__main__": moderngl_window.run_window_config(WindowEvents) diff --git a/examples/with_pyopengl.py b/examples/with_pyopengl.py index a68c1e7c..abd020ec 100644 --- a/examples/with_pyopengl.py +++ b/examples/with_pyopengl.py @@ -12,7 +12,7 @@ class PyOpenGL(moderngl_window.WindowConfig): def __init__(self, **kwargs): super().__init__(**kwargs) - def render(self, time, frametime): + def on_render(self, time, frametime): GL.glClearColor( (math.sin(time) + 1.0) / 2, (math.sin(time + 2) + 1.0) / 2, @@ -22,5 +22,5 @@ def render(self, time, frametime): GL.glClear(GL.GL_COLOR_BUFFER_BIT) -if __name__ == '__main__': - moderngl_window.run_window_config(PyOpenGL) +if __name__ == "__main__": + PyOpenGL.run() diff --git a/moderngl_window/capture/base.py b/moderngl_window/capture/base.py index 20369215..439bae46 100644 --- a/moderngl_window/capture/base.py +++ b/moderngl_window/capture/base.py @@ -25,7 +25,6 @@ def __init__( source: Union[moderngl.Texture, moderngl.Framebuffer], framerate: Union[int, float] = 60, ): - self._source = source self._framerate = framerate @@ -141,7 +140,6 @@ def save(self) -> None: dt = 1.0 / self._framerate if self._timer.time - self._last_time > dt: - # start counting self._last_time = self._timer.time diff --git a/moderngl_window/conf/__init__.py b/moderngl_window/conf/__init__.py index c3108b12..aca79dd6 100644 --- a/moderngl_window/conf/__init__.py +++ b/moderngl_window/conf/__init__.py @@ -322,15 +322,13 @@ def apply_from_cls(self, cls: Any) -> None: """ self.apply_from_iterable(cls.__dict__.items()) - def apply_from_iterable(self, iterable: Union[Iterable[Any], Generator[Any]]) -> None: + def apply_from_iterable(self, iterable: Iterable[tuple[str, Any]]) -> None: """ - Apply (key, value) pairs from an interable or generator + Apply (key, value) pairs from an iterable or generator """ if not isinstance(iterable, Iterable) and not isinstance(self, Generator): raise ValueError( - "Input value is not a generator or interable, but of type: {}".format( - type(iterable) - ) + "Input value is not a generator or iterable, but of type: {}".format(type(iterable)) ) for name, value in iterable: diff --git a/moderngl_window/context/base/__init__.py b/moderngl_window/context/base/__init__.py index c2fec8d8..20aaa73c 100644 --- a/moderngl_window/context/base/__init__.py +++ b/moderngl_window/context/base/__init__.py @@ -1,7 +1,11 @@ -from moderngl_window.context.base.keys import BaseKeys as BaseKeys # noqa -from moderngl_window.context.base.keys import \ - KeyModifiers as KeyModifiers # noqa -from moderngl_window.context.base.window import \ - BaseWindow as BaseWindow # noqa -from moderngl_window.context.base.window import \ - WindowConfig as WindowConfig # noqa +from moderngl_window.context.base.keys import BaseKeys as BaseKeys +from moderngl_window.context.base.keys import KeyModifiers as KeyModifiers +from moderngl_window.context.base.window import BaseWindow as BaseWindow +from moderngl_window.context.base.window import WindowConfig as WindowConfig + +__all__ = [ + "BaseKeys", + "KeyModifiers", + "BaseWindow", + "WindowConfig", +] diff --git a/moderngl_window/context/base/keys.py b/moderngl_window/context/base/keys.py index 5fa9788f..a4695d80 100644 --- a/moderngl_window/context/base/keys.py +++ b/moderngl_window/context/base/keys.py @@ -1,4 +1,3 @@ -# flake8: noqa E741 from typing import Any diff --git a/moderngl_window/context/base/window.py b/moderngl_window/context/base/window.py index 5565966b..67da5cbd 100644 --- a/moderngl_window/context/base/window.py +++ b/moderngl_window/context/base/window.py @@ -420,7 +420,7 @@ def config(self) -> Optional["WindowConfig"]: DEPRECATED PROPERTY. This is not handled in `WindowConfig.__init__` This property can also be set. - Assinging a WindowConfig instance will automatically + Assigning a WindowConfig instance will automatically set up the necessary event callback methods:: window.config = window_config_instance @@ -1112,19 +1112,18 @@ def assign_event_callbacks(self) -> None: Look for methods in the class instance and assign them to callbacks. This method is call by ``__init__``. """ - self.wnd.render_func = getattr(self, "render", dummy_func) - self.wnd.resize_func = getattr(self, "resize", dummy_func) - self.wnd.close_func = getattr(self, "close", dummy_func) - self.wnd.iconify_func = getattr(self, "iconify", dummy_func) - self.wnd.key_event_func = getattr(self, "key_event", dummy_func) - self.wnd.mouse_position_event_func = getattr(self, "mouse_position_event", dummy_func) - self.wnd.mouse_press_event_func = getattr(self, "mouse_press_event", dummy_func) - self.wnd.mouse_release_event_func = getattr(self, "mouse_release_event", dummy_func) - self.wnd.mouse_drag_event_func = getattr(self, "mouse_drag_event", dummy_func) - self.wnd.mouse_scroll_event_func = getattr(self, "mouse_scroll_event", dummy_func) - self.wnd.unicode_char_entered_func = getattr(self, "unicode_char_entered", dummy_func) - - self.wnd.files_dropped_event_func = getattr(self, "files_dropped_event", dummy_func) + self.wnd.render_func = getattr(self, "on_render", dummy_func) + self.wnd.resize_func = getattr(self, "on_resize", dummy_func) + self.wnd.close_func = getattr(self, "on_close", dummy_func) + self.wnd.iconify_func = getattr(self, "on_iconify", dummy_func) + self.wnd.key_event_func = getattr(self, "on_key_event", dummy_func) + self.wnd.mouse_position_event_func = getattr(self, "on_mouse_position_event", dummy_func) + self.wnd.mouse_press_event_func = getattr(self, "on_mouse_press_event", dummy_func) + self.wnd.mouse_release_event_func = getattr(self, "on_mouse_release_event", dummy_func) + self.wnd.mouse_drag_event_func = getattr(self, "on_mouse_drag_event", dummy_func) + self.wnd.mouse_scroll_event_func = getattr(self, "on_mouse_scroll_event", dummy_func) + self.wnd.unicode_char_entered_func = getattr(self, "on_unicode_char_entered", dummy_func) + self.wnd.files_dropped_event_func = getattr(self, "on_files_dropped_event", dummy_func) @classmethod def run(cls: type["WindowConfig"]) -> None: @@ -1149,16 +1148,16 @@ def add_arguments(cls: type["WindowConfig"], parser: ArgumentParser) -> None: """ pass - def render(self, time: float, frame_time: float) -> None: + def on_render(self, time: float, frame_time: float) -> None: """Renders the assigned effect Args: time (float): Current time in seconds frame_time (float): Delta time from last frame in seconds """ - raise NotImplementedError("WindowConfig.render not implemented") + raise NotImplementedError("WindowConfig.on_render not implemented") - def resize(self, width: int, height: int) -> None: + def on_resize(self, width: int, height: int) -> None: """ Called every time the window is resized in case the we need to do internal adjustments. @@ -1168,10 +1167,10 @@ def resize(self, width: int, height: int) -> None: height (int): height in buffer size (not window size) """ - def close(self) -> None: - """Called when the window is closed""" + def on_close(self) -> None: + """Called when the window is about to close""" - def files_dropped_event(self, x: int, y: int, paths: list[str]) -> None: + def on_files_dropped_event(self, x: int, y: int, paths: list[str]) -> None: """ Called when files dropped onto the window @@ -1181,7 +1180,7 @@ def files_dropped_event(self, x: int, y: int, paths: list[str]) -> None: paths (list): List of file paths dropped """ - def iconify(self, iconified: bool) -> None: + def on_iconify(self, iconified: bool) -> None: """ Called when the window is minimized/iconified or restored from this state @@ -1190,7 +1189,7 @@ def iconify(self, iconified: bool) -> None: iconified (bool): If ``True`` the window is iconified/minimized. Otherwise restored. """ - def key_event(self, key: Any, action: Any, modifiers: KeyModifiers) -> None: + def on_key_event(self, key: Any, action: Any, modifiers: KeyModifiers) -> None: """ Called for every key press and release. Depending on the library used, key events may @@ -1204,45 +1203,45 @@ def key_event(self, key: Any, action: Any, modifiers: KeyModifiers) -> None: modifiers: Modifier state for shift, ctrl and alt """ - def mouse_position_event(self, x: int, y: int, dx: int, dy: int) -> None: + def on_mouse_position_event(self, x: int, y: int, dx: int, dy: int) -> None: """Reports the current mouse cursor position in the window Args: - x (int): X postion of the mouse cursor + x (int): X position of the mouse cursor y (int): Y position of the mouse cursor - dx (int): X delta postion + dx (int): X delta position dy (int): Y delta position """ - def mouse_drag_event(self, x: int, y: int, dx: int, dy: int) -> None: + def on_mouse_drag_event(self, x: int, y: int, dx: int, dy: int) -> None: """Called when the mouse is moved while a button is pressed. Args: - x (int): X postion of the mouse cursor + x (int): X position of the mouse cursor y (int): Y position of the mouse cursor - dx (int): X delta postion + dx (int): X delta position dy (int): Y delta position """ - def mouse_press_event(self, x: int, y: int, button: int) -> None: + def on_mouse_press_event(self, x: int, y: int, button: int) -> None: """Called when a mouse button in pressed Args: - x (int): X position the press ocurred - y (int): Y position the press ocurred + x (int): X position the press occurred + y (int): Y position the press occurred button (int): 1 = Left button, 2 = right button """ - def mouse_release_event(self, x: int, y: int, button: int) -> None: + def on_mouse_release_event(self, x: int, y: int, button: int) -> None: """Called when a mouse button in released Args: - x (int): X position the release ocurred - y (int): Y position the release ocurred + x (int): X position the release occurred + y (int): Y position the release occurred button (int): 1 = Left button, 2 = right button """ - def mouse_scroll_event(self, x_offset: float, y_offset: float) -> None: + def on_mouse_scroll_event(self, x_offset: float, y_offset: float) -> None: """Called when the mouse wheel is scrolled. Some input devices also support horizontal scrolling, @@ -1253,7 +1252,7 @@ def mouse_scroll_event(self, x_offset: float, y_offset: float) -> None: y_offset (int): Y scroll offset """ - def unicode_char_entered(self, char: str) -> None: + def on_unicode_char_entered(self, char: str) -> None: """Called when the user entered a unicode character. Args: diff --git a/moderngl_window/context/pygame2/window.py b/moderngl_window/context/pygame2/window.py index 7ca55d2c..2959e326 100644 --- a/moderngl_window/context/pygame2/window.py +++ b/moderngl_window/context/pygame2/window.py @@ -307,7 +307,6 @@ def process_events(self) -> None: self.resize(event.size[0], event.size[1]) elif event.type == pygame.ACTIVEEVENT: - # # We might support these in the future # Mouse cursor state # if event.state == 0: diff --git a/moderngl_window/geometry/__init__.py b/moderngl_window/geometry/__init__.py index c512434b..c736900e 100644 --- a/moderngl_window/geometry/__init__.py +++ b/moderngl_window/geometry/__init__.py @@ -1,5 +1,4 @@ -from moderngl_window.geometry.attributes import \ - AttributeNames as AttributeNames +from moderngl_window.geometry.attributes import AttributeNames as AttributeNames from moderngl_window.geometry.bbox import bbox as bbox from moderngl_window.geometry.cube import cube as cube from moderngl_window.geometry.quad import quad_2d as quad_2d diff --git a/moderngl_window/geometry/cube.py b/moderngl_window/geometry/cube.py index 1da50e39..f685e6cc 100644 --- a/moderngl_window/geometry/cube.py +++ b/moderngl_window/geometry/cube.py @@ -8,7 +8,7 @@ def cube( size: tuple[float, float, float] = (1.0, 1.0, 1.0), - center: tuple[float, float, float]=(0.0, 0.0, 0.0), + center: tuple[float, float, float] = (0.0, 0.0, 0.0), normals: bool = True, uvs: bool = True, name: Optional[str] = None, diff --git a/moderngl_window/integrations/imgui.py b/moderngl_window/integrations/imgui.py index 8acbe83b..ae644b90 100644 --- a/moderngl_window/integrations/imgui.py +++ b/moderngl_window/integrations/imgui.py @@ -76,7 +76,6 @@ def unicode_char_entered(self, char): class ModernGLRenderer(BaseOpenGLRenderer): - VERTEX_SHADER_SRC = """ #version 330 uniform mat4 ProjMtx; diff --git a/moderngl_window/integrations/imgui_bundle.py b/moderngl_window/integrations/imgui_bundle.py index 147bd0cc..4348f8d1 100644 --- a/moderngl_window/integrations/imgui_bundle.py +++ b/moderngl_window/integrations/imgui_bundle.py @@ -6,6 +6,8 @@ class ModernglWindowMixin: + io: imgui.IO + def resize(self, width: int, height: int): self.io.display_size = self.wnd.size self.io.display_framebuffer_scale = compute_fb_scale(self.wnd.size, self.wnd.buffer_size) @@ -104,7 +106,6 @@ def shutdown(self): class ModernGLRenderer(BaseOpenGLRenderer): - VERTEX_SHADER_SRC = """ #version 330 uniform mat4 ProjMtx; @@ -139,10 +140,12 @@ def __init__(self, *args, **kwargs): self._vao = None self._textures = {} self.wnd = kwargs.get("wnd") - self.ctx = self.wnd.ctx if self.wnd and self.wnd.ctx else kwargs.get("ctx") + self.ctx: moderngl.Context = ( + self.wnd.ctx if self.wnd and self.wnd.ctx else kwargs.get("ctx") + ) if not self.ctx: - raise ValueError("Missing moderngl context") + raise RuntimeError("Missing moderngl context") assert isinstance(self.ctx, moderngl.Context) diff --git a/moderngl_window/loaders/scene/gltf2.py b/moderngl_window/loaders/scene/gltf2.py index 4278e1dc..5121bae6 100644 --- a/moderngl_window/loaders/scene/gltf2.py +++ b/moderngl_window/loaders/scene/gltf2.py @@ -441,7 +441,6 @@ def __init__(self, data: dict[str, Any]): self.accessor = None def __init__(self, data: dict[str, Any], meta: SceneDescription): - self.meta = meta self.name = data.get("name", "") self.primitives = [GLTFMesh.Primitives(p) for p in data["primitives"]] @@ -462,7 +461,6 @@ def load(self, materials: list[Material]) -> list[Mesh]: # Read all primitives as separate meshes for now # According to the spec they can have different materials and vertex format for primitive in self.primitives: - vao = VAO(self.name, mode=primitive.mode or moderngl.TRIANGLES) # Index buffer @@ -761,7 +759,7 @@ def __init__(self, data: dict[str, Any]) -> None: z=self.rotation[2], w=self.rotation[3], ) - self.matrix = self.matrix * glm.mat4(quat) + self.matrix = self.matrix * glm.mat4_cast(quat) if self.scale is not None: self.matrix = self.matrix * glm.scale(self.scale) diff --git a/moderngl_window/loaders/scene/wavefront.py b/moderngl_window/loaders/scene/wavefront.py index 80dd24b1..f70a28cf 100644 --- a/moderngl_window/loaders/scene/wavefront.py +++ b/moderngl_window/loaders/scene/wavefront.py @@ -64,7 +64,8 @@ def load_vertex_buffer( ) vao = VAO(material.name, mode=moderngl.TRIANGLES) - vao.buffer(fd.read(length).encode(), buffer_format, attributes) + # FIXME: Are we actually reading from text or byte stream here? + vao.buffer(fd.read(length), buffer_format, attributes) setattr(material, "vao", vao) setattr(material, "buffer_format", buffer_format) @@ -76,7 +77,7 @@ def load_vertex_buffer( class Loader(BaseLoader): - """Loade wavefront/obj files""" + """Load wavefront/obj files""" kind = "wavefront" file_extensions = [ diff --git a/moderngl_window/meta/texture.py b/moderngl_window/meta/texture.py index 01c3983c..36220081 100644 --- a/moderngl_window/meta/texture.py +++ b/moderngl_window/meta/texture.py @@ -34,7 +34,7 @@ def __init__( flip_y: bool = True, mipmap: bool = False, mipmap_levels: Optional[tuple[int, int]] = None, - anisotropy: float =1.0, + anisotropy: float = 1.0, image: Optional[Image] = None, layers: Optional[int] = None, pos_x: Optional[str] = None, diff --git a/moderngl_window/opengl/vao.py b/moderngl_window/opengl/vao.py index 74ccfae5..ebe7f59b 100644 --- a/moderngl_window/opengl/vao.py +++ b/moderngl_window/opengl/vao.py @@ -64,7 +64,6 @@ def content(self, attributes: list[str]) -> Optional[tuple[object, ...]]: formats = [] attrs = [] for attrib_format, attrib in zip(self.attrib_formats, self.attributes): - if attrib not in attributes: formats.append(attrib_format.pad_str()) continue @@ -92,7 +91,7 @@ class VAO: Represents a vertex array object. This is a wrapper class over ``moderngl.VertexArray`` to make interactions - with programs/shaders simpler. Named buffers are added correspoding with + with programs/shaders simpler. Named buffers are added corresponding with attribute names in a vertex shader. When rendering the VAO an internal ``moderngl.VertextArray`` is created automatically mapping the named buffers compatible with the supplied program. This program is cached internally. @@ -153,7 +152,7 @@ def __init__(self, name: str = "", mode: int = moderngl.TRIANGLES): @property def ctx(self) -> moderngl.Context: - """moderngl.Context: The actite moderngl context""" + """moderngl.Context: The active moderngl context""" return mglw.ctx() def render( @@ -339,7 +338,6 @@ def instance(self, program: moderngl.Program) -> moderngl.VertexArray: # Make sure all attributes are covered for attrib_name in program_attributes: - # Do we have a buffer mapping to this attribute? if not sum(buffer.has_attribute(attrib_name) for buffer in self._buffers): raise VAOError( diff --git a/moderngl_window/resources/__init__.py b/moderngl_window/resources/__init__.py index 610b0017..9dc9c41f 100644 --- a/moderngl_window/resources/__init__.py +++ b/moderngl_window/resources/__init__.py @@ -7,7 +7,6 @@ from moderngl_window.exceptions import ImproperlyConfigured from moderngl_window.resources.data import data as data from moderngl_window.resources.programs import programs as programs -# from moderngl_window.resources.tracks import tracks # noqa from moderngl_window.resources.scenes import scenes as scenes from moderngl_window.resources.textures import TextureAny as TextureAny from moderngl_window.resources.textures import textures as textures diff --git a/moderngl_window/scene/programs.py b/moderngl_window/scene/programs.py index d8c077b8..df66d5de 100644 --- a/moderngl_window/scene/programs.py +++ b/moderngl_window/scene/programs.py @@ -153,7 +153,7 @@ def apply(self, mesh: Mesh) -> "MeshProgram" | None: class TextureProgram(MeshProgram): """Plan textured""" - def __init__(self, program: moderngl.Program = None, **kwargs: Any) -> None: + def __init__(self, program: Optional[moderngl.Program] = None, **kwargs: Any) -> None: super().__init__(program=None) self.program = programs.load(ProgramDescription(path="scene_default/texture.glsl")) diff --git a/moderngl_window/text/bitmapped/text_2d.py b/moderngl_window/text/bitmapped/text_2d.py index b4fef2b4..0a6c9efd 100644 --- a/moderngl_window/text/bitmapped/text_2d.py +++ b/moderngl_window/text/bitmapped/text_2d.py @@ -6,8 +6,7 @@ import numpy from moderngl_window import resources -from moderngl_window.meta import (DataDescription, ProgramDescription, - TextureDescription) +from moderngl_window.meta import DataDescription, ProgramDescription, TextureDescription from moderngl_window.opengl.vao import VAO from .base import BaseText, FontMeta diff --git a/moderngl_window/timers/clock.py b/moderngl_window/timers/clock.py index 5ede9fec..80fe7eaa 100644 --- a/moderngl_window/timers/clock.py +++ b/moderngl_window/timers/clock.py @@ -35,7 +35,7 @@ def time(self) -> float: if self._start_time is None: return 0.0 - if self.is_paused: + if self.is_paused and self._pause_time is not None: return self._pause_time - self._offset - self._start_time return time.time() - self._start_time - self._offset diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 96e05fc4..00000000 --- a/setup.cfg +++ /dev/null @@ -1,7 +0,0 @@ -# All values are merged into pyproject.toml, but -# as of flake8 6.1 it still doesn't read config -# from the tool.flake8 namespace in pyproject.toml - -[flake8] -max-line-length = 120 -max-complexity = 10 diff --git a/tests/test_conf.py b/tests/test_conf.py index cff045d5..0868fc34 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -72,13 +72,13 @@ def gen(): self.assertEqual(settings.SOMETHING, 1) def test_apply_from_iterator_error(self): - """Ensure ValueError is rasied if not iterable""" + """Ensure ValueError is raised if not iterable""" with self.assertRaises(ValueError): settings = Settings() settings.apply_from_iterable(1337) def test_repr(self): - """Ensure string represenation is somewhat reasonable""" + """Ensure string representation is somewhat reasonable""" value = str(Settings()) self.assertIsInstance(value, str) self.assertGreater(len(value), 100) diff --git a/tests/test_moderngl_window.py b/tests/test_moderngl_window.py index d5fbc2ff..e2b696e3 100644 --- a/tests/test_moderngl_window.py +++ b/tests/test_moderngl_window.py @@ -8,7 +8,7 @@ def swap_buffers(self): - """Swapbuffers closing window after 3 frames""" + """Swap buffers closing window after 3 frames""" self._frames += 1 if self._frames > 3: self.close() @@ -19,7 +19,7 @@ class Config(mglw.WindowConfig): def __init__(self, **kwargs): super().__init__(**kwargs) - def render(self, time: float, frame_time: float): + def on_render(self, time: float, frame_time: float): pass