diff --git a/README.md b/README.md index 1466327..84a239b 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ and resources to make this project possible. ### Testing & Utility -* Pyrr (https://github.com/adamlwgriffiths/Pyrr) +* PyGLM (https://github.com/Zuzu-Typ/PyGLM) * numpy (https://github.com/numpy/numpy) * pytest (https://docs.pytest.org/en/latest/) * flake8 (https://gitlab.com/pycqa/flake8) diff --git a/examples/advanced/animated_sprites.py b/examples/advanced/animated_sprites.py index e9387a1..fa93dd3 100644 --- a/examples/advanced/animated_sprites.py +++ b/examples/advanced/animated_sprites.py @@ -2,7 +2,7 @@ from pathlib import Path import moderngl_window as mglw from moderngl_window import geometry -from pyrr import Matrix44 +import glm # from moderngl_window.conf import settings # settings.SCREENSHOT_PATH = 'screenshots' @@ -41,7 +41,7 @@ def __init__(self, **kwargs): self.offscreen_texture.filter = moderngl.NEAREST, moderngl.NEAREST self.offscreen = self.ctx.framebuffer(color_attachments=[self.offscreen_texture]) - self.projection = Matrix44.orthogonal_projection(0, 320, 0, 256, -1.0, 1.0, dtype='f4') + self.projection = glm.orthographic(0, 320, 0, 256, -1.0, 1.0) self.sprite_program['projection'].write(self.projection) def render(self, time, frame_time): diff --git a/examples/advanced/boids.py b/examples/advanced/boids.py index f76a8b7..81ce77e 100644 --- a/examples/advanced/boids.py +++ b/examples/advanced/boids.py @@ -1,7 +1,7 @@ from pathlib import Path import random import numpy -from pyrr import matrix44 +import glm import moderngl import moderngl_window @@ -61,11 +61,10 @@ def gen_initial_data(n, x_area=2.0, y_area=2.0): self.boids_transform_program = self.load_program('programs/boids/boids_transform.glsl') # Prepare for rendering - self.m_proj = matrix44.create_orthogonal_projection( + self.m_proj = glm.orthographic( -self.aspect_ratio, self.aspect_ratio, -1.0, 1.0, -1.0, 1.0, - dtype='f4', ) self.boids_render_program['m_proj'].write(self.m_proj.tobytes()) self.boids_transform_program['data'].value = 0 diff --git a/examples/advanced/fragment_picking.py b/examples/advanced/fragment_picking.py index 4c7d128..5772414 100644 --- a/examples/advanced/fragment_picking.py +++ b/examples/advanced/fragment_picking.py @@ -2,7 +2,7 @@ from pathlib import Path import moderngl -from pyrr import Matrix44 +import glm import moderngl_window from moderngl_window import geometry from moderngl_window.opengl.projection import Projection3D @@ -126,8 +126,8 @@ def __init__(self, **kwargs): def render(self, time, frametime): self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - translation = Matrix44.from_translation((0, 0, -45 + self.zoom), dtype='f4') - rotation = Matrix44.from_eulers((self.y_rot, self.x_rot, 0), dtype='f4') + translation = glm.translate(glm.vec3(0, 0, -45 + self.zoom)) + rotation = glm.mat4(glm.quat(glm.vec3(self.y_rot, self.x_rot, 0))) self.modelview = translation * rotation # Render the scene to offscreen buffer diff --git a/examples/advanced/navier_stokes.py b/examples/advanced/navier_stokes.py index b89544a..31c3021 100644 --- a/examples/advanced/navier_stokes.py +++ b/examples/advanced/navier_stokes.py @@ -8,7 +8,7 @@ import random from pathlib import Path import numpy as np -from pyrr import matrix44 +import glm import moderngl_window from moderngl_window import geometry @@ -31,11 +31,10 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # various vars - self.m_proj = matrix44.create_orthogonal_projection( + self.m_proj = glm.orthographic( 0, self.wnd.buffer_width, 0, self.wnd.buffer_height, -1, 1, - dtype='f4', ) size = self.wnd.buffer_size diff --git a/examples/advanced/pygame2.py b/examples/advanced/pygame2.py index 95c44e8..3ae7b01 100644 --- a/examples/advanced/pygame2.py +++ b/examples/advanced/pygame2.py @@ -8,7 +8,7 @@ import moderngl import moderngl_window from moderngl_window import geometry -from pyrr import matrix44 +import glm # from moderngl_window.conf import settings # settings.SCREENSHOT_PATH = 'capture' @@ -41,8 +41,8 @@ def __init__(self, **kwargs): # Simple geometry and shader to render self.cube = geometry.cube(size=(2.0, 2.0, 2.0)) self.texture_prog = self.load_program('programs/cube_simple_texture.glsl') - self.texture_prog['m_proj'].write(matrix44.create_perspective_projection(60, self.wnd.aspect_ratio, 1, 100, dtype='f4')) - self.texture_prog['m_model'].write(matrix44.create_identity(dtype='f4')) + self.texture_prog['m_proj'].write(glm.perspective(glm.radians(60), self.wnd.aspect_ratio, 1, 100)) + self.texture_prog['m_model'].write(glm.mat4()) def render(self, time, frametime): # time = self.wnd.frames / 30 @@ -50,9 +50,9 @@ def render(self, time, frametime): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) self.render_pygame(time) - rotate = matrix44.create_from_eulers((time, time * 1.2, time * 1.3), dtype='f4') - translate = matrix44.create_from_translation((0, 0, -3.5), dtype='f4') - camera = matrix44.multiply(rotate, translate) + rotate = glm.mat4(glm.quat(glm.vec3(time, time * 1.2, time * 1.3))) + translate = glm.translate(glm.vec3(0, 0, -3.5)) + camera = rotate * translate self.texture_prog['m_camera'].write(camera) self.pg_texture.use() diff --git a/examples/advanced/shadow_mapping.py b/examples/advanced/shadow_mapping.py index dbd5f0e..3bebd40 100644 --- a/examples/advanced/shadow_mapping.py +++ b/examples/advanced/shadow_mapping.py @@ -4,7 +4,7 @@ """ import math from pathlib import Path -from pyrr import Matrix44, matrix44, Vector3 +import glm import moderngl import moderngl_window @@ -59,15 +59,15 @@ def __init__(self, **kwargs): def render(self, time, frametime): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - self.lightpos = Vector3((math.sin(time) * 20, 5, math.cos(time) * 20), dtype='f4') - scene_pos = Vector3((0, -5, -32), dtype='f4') + self.lightpos = glm.vec3(math.sin(time) * 20, 5, math.cos(time) * 20) + scene_pos = glm.vec3(0, -5, -32) # --- PASS 1: Render shadow map self.offscreen.clear() self.offscreen.use() - depth_projection = Matrix44.orthogonal_projection(-20, 20, -20, 20, -20, 40, dtype='f4') - depth_view = Matrix44.look_at(self.lightpos, (0, 0, 0), (0, 1, 0), dtype='f4') + depth_projection = glm.orthographic(-20, 20, -20, 20, -20, 40) + depth_view = glm.lookAt(self.lightpos, (0, 0, 0), (0, 1, 0)) depth_mvp = depth_projection * depth_view self.shadowmap_program['mvp'].write(depth_mvp) @@ -79,15 +79,14 @@ def render(self, time, frametime): self.wnd.use() self.basic_light['m_proj'].write(self.camera.projection.matrix) self.basic_light['m_camera'].write(self.camera.matrix) - self.basic_light['m_model'].write(Matrix44.from_translation(scene_pos, dtype='f4')) - bias_matrix = Matrix44( + self.basic_light['m_model'].write(glm.translate(glm.vec3(scene_pos))) + bias_matrix = glm.mat4( [[0.5, 0.0, 0.0, 0.0], [0.0, 0.5, 0.0, 0.0], [0.0, 0.0, 0.5, 0.0], [0.5, 0.5, 0.5, 1.0]], - dtype='f4', ) - self.basic_light['m_shadow_bias'].write(matrix44.multiply(depth_mvp, bias_matrix)) + self.basic_light['m_shadow_bias'].write(depth_mvp * bias_matrix) self.basic_light['lightDir'].write(self.lightpos) self.offscreen_depth.use(location=0) self.floor.render(self.basic_light) @@ -97,7 +96,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(Matrix44.from_translation(self.lightpos + scene_pos, dtype='f4')) + self.sun_prog['m_model'].write(glm.translate(glm.vec3(self.lightpos + scene_pos))) self.sun.render(self.sun_prog) # --- PASS 3: Debug --- diff --git a/examples/advanced/shadow_mapping_56.py b/examples/advanced/shadow_mapping_56.py index 38efbe2..ee294d7 100644 --- a/examples/advanced/shadow_mapping_56.py +++ b/examples/advanced/shadow_mapping_56.py @@ -4,7 +4,7 @@ """ import math from pathlib import Path -from pyrr import Matrix44, matrix44, Vector3 +import glm import moderngl import moderngl_window @@ -59,15 +59,15 @@ def __init__(self, **kwargs): def render(self, time, frametime): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - self.lightpos = Vector3((math.sin(time) * 20, 5, math.cos(time) * 20), dtype='f4') - scene_pos = Vector3((0, -5, -32), dtype='f4') + self.lightpos = glm.vec3(math.sin(time) * 20, 5, math.cos(time) * 20) + scene_pos = glm.vec3(0, -5, -32) # --- PASS 1: Render shadow map self.offscreen.clear() self.offscreen.use() - depth_projection = Matrix44.orthogonal_projection(-20, 20, -20, 20, -20, 40, dtype='f4') - depth_view = Matrix44.look_at(self.lightpos, (0, 0, 0), (0, 1, 0), dtype='f4') + depth_projection = glm.orthographic(-20, 20, -20, 20, -20, 40) + depth_view = glm.lookAt(self.lightpos, (0, 0, 0), (0, 1, 0)) depth_mvp = depth_projection * depth_view self.shadowmap_program['mvp'].write(depth_mvp) @@ -79,15 +79,14 @@ def render(self, time, frametime): self.wnd.use() self.basic_light['m_proj'].write(self.camera.projection.matrix) self.basic_light['m_camera'].write(self.camera.matrix) - self.basic_light['m_model'].write(Matrix44.from_translation(scene_pos, dtype='f4')) - bias_matrix = Matrix44( + self.basic_light['m_model'].write(glm.translate(glm.vec3(scene_pos))) + bias_matrix = glm.mat4( [[0.5, 0.0, 0.0, 0.0], [0.0, 0.5, 0.0, 0.0], [0.0, 0.0, 0.5, 0.0], [0.5, 0.5, 0.5, 1.0]], - dtype='f4', ) - self.basic_light['m_shadow_bias'].write(matrix44.multiply(depth_mvp, bias_matrix)) + self.basic_light['m_shadow_bias'].write(depth_mvp * bias_matrix) self.basic_light['lightDir'].write(self.lightpos) self.offscreen_depth.use(location=0) self.floor.render(self.basic_light) @@ -97,7 +96,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(Matrix44.from_translation(self.lightpos + scene_pos, dtype='f4')) + self.sun_prog['m_model'].write(glm.translate(glm.vec3(self.lightpos + scene_pos))) self.sun.render(self.sun_prog) # --- PASS 3: Debug --- diff --git a/examples/advanced/tetrahedral_mesh.py b/examples/advanced/tetrahedral_mesh.py index 083bbe2..32115b0 100644 --- a/examples/advanced/tetrahedral_mesh.py +++ b/examples/advanced/tetrahedral_mesh.py @@ -1,6 +1,6 @@ from pathlib import Path import numpy as np -from pyrr import Matrix44 +import glm import moderngl import moderngl_window @@ -105,9 +105,9 @@ def render(self, time, frametime): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) # Render tetrahedral mesh - translate = Matrix44.from_translation((0.0, 2.5, -15.0), dtype='f4') - rotate = Matrix44.from_eulers((np.radians(180), 0, 0), dtype='f4') - scale = Matrix44.from_scale((400, 400, 400), dtype='f4') + translate = glm.translate(glm.vec3(0.0, 2.5, -15.0)) + rotate = glm.mat4(glm.quat(glm.vec3(np.radians(180), 0, 0))) + scale = glm.scale(glm.vec3(400, 400, 400)) mat = self.camera.matrix * translate * rotate * scale # All render calls inside this context are timed diff --git a/examples/advanced/voxel_cubes.py b/examples/advanced/voxel_cubes.py index 4810d1b..e12a252 100644 --- a/examples/advanced/voxel_cubes.py +++ b/examples/advanced/voxel_cubes.py @@ -20,10 +20,9 @@ import moderngl from moderngl.program_members import varying -from pyrr.matrix44 import inverse from moderngl_window import geometry from base import CameraWindow -from pyrr import Matrix44, Matrix33 +import glm class CubeVoxel(CameraWindow): @@ -129,11 +128,10 @@ def max_cubes(self) -> int: def render_wireframe(self, *, projection_matrix, camera_matrix, model_matrix=None): self.ctx.wireframe = True - translate = Matrix44.from_translation(( + translate = glm.translate(glm.vec3( -self._size[0] / 2, -self._size[0] / 2, -self._size[0] * 2), - dtype='f4', ) mat = camera_matrix * translate self.voxel_wireframe_prog["m_proj"].write(projection_matrix) @@ -144,14 +142,13 @@ def render_wireframe(self, *, projection_matrix, camera_matrix, model_matrix=Non def render(self, *, projection_matrix, camera_matrix, model_matrix=None): """Render out the voxel to the screen""" - translate = Matrix44.from_translation(( + translate = glm.translate(glm.vec3( -self._size[0] / 2, -self._size[0] / 2, -self._size[0] * 2), - dtype='f4', ) mat = camera_matrix * translate - normal = Matrix33.from_matrix44(mat).inverse.transpose().astype("f4").tobytes() + normal = glm.transpose(glm.inverse(glm.mat3(mat))).to_bytes() self.voxel_light_prog["m_proj"].write(projection_matrix) self.voxel_light_prog["m_modelview"].write(mat) self.voxel_light_prog["m_normal"].write(normal) diff --git a/examples/cube_model.py b/examples/cube_model.py index a6b1e78..b9e8e95 100644 --- a/examples/cube_model.py +++ b/examples/cube_model.py @@ -1,5 +1,5 @@ from pathlib import Path -from pyrr import Matrix44 +import glm import moderngl import moderngl_window @@ -25,8 +25,8 @@ def __init__(self, **kwargs): def render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - translation = Matrix44.from_translation((0, 0, -1.5)) - rotation = Matrix44.from_eulers((0, 0, 0)) + translation = glm.translate(glm.vec3(0, 0, -1.5)) + rotation = glm.mat4(glm.quat(glm.vec3(0, 0, 0))) model_matrix = translation * rotation camera_matrix = self.camera.matrix * model_matrix diff --git a/examples/cubes.py b/examples/cubes.py index cb856e4..f6808bc 100644 --- a/examples/cubes.py +++ b/examples/cubes.py @@ -7,7 +7,7 @@ import moderngl import moderngl_window -from pyrr import Matrix44 +import glm class Cubes(moderngl_window.WindowConfig): @@ -31,35 +31,35 @@ def __init__(self, **kwargs): def render(self, time, frame_time): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - rot = Matrix44.from_eulers((time, time/2, time/3)) + rot = glm.mat4(glm.quat(glm.vec3(time, time/2, time/3))) # Box 1 - view = Matrix44.from_translation((-5, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(-5, 2, -10)) self.box_v3.draw(self.projection, view * rot) # Box 2 - view = Matrix44.from_translation((0, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(0, 2, -10)) self.box_c3_v3.draw(self.projection, view * rot) # Box 3 - view = Matrix44.from_translation((5, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(5, 2, -10)) self.box_n3_v3.draw(self.projection, view * rot) # Box 4 - view = Matrix44.from_translation((-5, -2, -10), dtype='f4') + view = glm.translate(glm.vec3(-5, -2, -10)) self.box_t2_v3.draw(self.projection, view * rot) # Box 5 - view = Matrix44.from_translation((0, -2, -10), dtype='f4') + view = glm.translate(glm.vec3(0, -2, -10)) self.box_t2_c3_v3.draw(self.projection, view * rot) # Box 6 - view = Matrix44.from_translation((5, -2, -10), dtype='f4') + 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 = Matrix44.perspective_projection(45, width / height, 1, 50, dtype='f4') + self.projection = glm.perspective(glm.radians(45), width / height, 1, 50) if __name__ == '__main__': diff --git a/examples/drag_drop_file_input.py b/examples/drag_drop_file_input.py index 1fc6b2d..ba54771 100644 --- a/examples/drag_drop_file_input.py +++ b/examples/drag_drop_file_input.py @@ -11,7 +11,7 @@ import moderngl import moderngl_window -from pyrr import Matrix44 +import glm class Cubes(moderngl_window.WindowConfig): @@ -35,35 +35,35 @@ def __init__(self, **kwargs): def render(self, time, frame_time): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) - rot = Matrix44.from_eulers((time, time/2, time/3)) + rot = glm.mat4(glm.quat(glm.vec3(time, time/2, time/3))) # Box top left - view = Matrix44.from_translation((-5, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(-5, 2, -10)) self.box_top_left.draw(self.projection, view * rot) # Box top middle - view = Matrix44.from_translation((0, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(0, 2, -10)) self.box_top_middle.draw(self.projection, view * rot) # Box top right - view = Matrix44.from_translation((5, 2, -10), dtype='f4') + view = glm.translate(glm.vec3(5, 2, -10)) self.box_top_right.draw(self.projection, view * rot) # Box bottom left - view = Matrix44.from_translation((-5, -2, -10), dtype='f4') + view = glm.translate(glm.vec3(-5, -2, -10)) self.box_bottom_left.draw(self.projection, view * rot) # Box bottom middle - view = Matrix44.from_translation((0, -2, -10), dtype='f4') + view = glm.translate(glm.vec3(0, -2, -10)) self.box_bottom_middle.draw(self.projection, view * rot) # Box bottom right - view = Matrix44.from_translation((5, -2, -10), dtype='f4') + view = glm.translate(glm.vec3(5, -2, -10)) self.box_bottom_right.draw(self.projection, view * rot) def resize(self, width, height): self.ctx.viewport = 0, 0, width, height - self.projection = Matrix44.perspective_projection(45, width / height, 1, 50, dtype='f4') + self.projection = glm.perspective(glm.radians(45), width / height, 1, 50) def _load_texture(self, path): tex = self.load_texture_2d(os.path.relpath(path, self.resource_dir)) diff --git a/examples/geometry_bbox.py b/examples/geometry_bbox.py index 0f7cc60..94e5efe 100644 --- a/examples/geometry_bbox.py +++ b/examples/geometry_bbox.py @@ -1,4 +1,4 @@ -from pyrr import Matrix44 +import glm import moderngl_window from moderngl_window import geometry @@ -18,7 +18,7 @@ def __init__(self, **kwargs): 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(Matrix44.from_translation([0.0, 0.0, -8.0], dtype='f4')) + self.prog['m_model'].write(glm.translate(glm.vec3(0.0, 0.0, -8.0))) def render(self, time: float, frame_time: float): self.ctx.clear() diff --git a/examples/geometry_cube.py b/examples/geometry_cube.py index e657774..36ad58c 100644 --- a/examples/geometry_cube.py +++ b/examples/geometry_cube.py @@ -1,5 +1,5 @@ from pathlib import Path -from pyrr import Matrix44, Vector3 +import glm import moderngl import moderngl_window @@ -22,8 +22,8 @@ def __init__(self, **kwargs): def render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) - rotation = Matrix44.from_eulers((time, time, time), dtype='f4') - translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') + 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) diff --git a/examples/geometry_cube_instanced.py b/examples/geometry_cube_instanced.py index 41486aa..43baadb 100644 --- a/examples/geometry_cube_instanced.py +++ b/examples/geometry_cube_instanced.py @@ -7,7 +7,7 @@ from pathlib import Path import numpy -from pyrr import Matrix44 +import glm import moderngl import moderngl_window from moderngl_window import geometry @@ -26,7 +26,7 @@ def __init__(self, **kwargs): self.camera.projection.update(near=1, far=1000) self.cube = geometry.cube(size=(2, 2, 2)) self.prog = self.load_program('programs/cube_simple_instanced.glsl') - self.prog['m_model'].write(Matrix44.identity(dtype='f4')) + self.prog['m_model'].write(glm.mat4()) # Generate per instance data represeting a grid of cubes N = 100 diff --git a/examples/geometry_lines.py b/examples/geometry_lines.py index 015d5de..9039ae1 100644 --- a/examples/geometry_lines.py +++ b/examples/geometry_lines.py @@ -1,5 +1,5 @@ from pathlib import Path -from pyrr import Matrix44 +import glm import numpy import moderngl @@ -24,7 +24,7 @@ def __init__(self, **kwargs): self.prog = self.load_program('programs/lines/lines.glsl') self.prog['color'].value = (1.0, 1.0, 1.0, 1.0) - self.prog['m_model'].write(Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4')) + self.prog['m_model'].write(glm.translate(glm.vec3(0.0, 0.0, -3.5))) N = 10 # Create lines geometry diff --git a/examples/gltf_scenes.py b/examples/gltf_scenes.py index 5d7b33c..ba6ba4b 100644 --- a/examples/gltf_scenes.py +++ b/examples/gltf_scenes.py @@ -1,5 +1,5 @@ from pathlib import Path -from pyrr import Matrix44 +import glm import moderngl import moderngl_window as mglw @@ -70,7 +70,7 @@ def render(self, time: float, frame_time: float): self.ctx.enable_only(moderngl.DEPTH_TEST | moderngl.CULL_FACE) # Move camera in on the z axis slightly by default - translation = Matrix44.from_translation((0, 0, -1.5), dtype='f4') + translation = glm.translate(glm.vec3(0, 0, -1.5)) camera_matrix = self.camera.matrix * translation self.scene.draw( diff --git a/examples/integration_imgui.py b/examples/integration_imgui.py index e0eb42f..44e0b64 100644 --- a/examples/integration_imgui.py +++ b/examples/integration_imgui.py @@ -1,7 +1,7 @@ from pathlib import Path import imgui import moderngl -from pyrr import Matrix44 +import glm import moderngl_window as mglw from moderngl_window import geometry from moderngl_window.integrations.imgui import ModernglWindowRenderer @@ -22,12 +22,12 @@ def __init__(self, **kwargs): 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(Matrix44.identity(dtype='f4')) - self.prog['m_proj'].write(Matrix44.perspective_projection(75, self.wnd.aspect_ratio, 1, 100, dtype='f4')) + 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): - rotation = Matrix44.from_eulers((time, time, time), dtype='f4') - translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') + 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) @@ -62,7 +62,7 @@ def render_ui(self): self.imgui.render(imgui.get_draw_data()) def resize(self, width: int, height: int): - self.prog['m_proj'].write(Matrix44.perspective_projection(75, self.wnd.aspect_ratio, 1, 100, dtype='f4')) + 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): diff --git a/examples/integration_imgui_image.py b/examples/integration_imgui_image.py index 2b8035b..eb10d89 100644 --- a/examples/integration_imgui_image.py +++ b/examples/integration_imgui_image.py @@ -1,7 +1,7 @@ from pathlib import Path import imgui import moderngl -from pyrr import Matrix44 +import glm import moderngl_window as mglw from moderngl_window import geometry from moderngl_window.integrations.imgui import ModernglWindowRenderer @@ -24,8 +24,8 @@ def __init__(self, **kwargs): 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(Matrix44.identity(dtype='f4')) - self.prog['m_proj'].write(Matrix44.perspective_projection(75, 1.0, 1, 100, dtype='f4')) + self.prog['m_camera'].write(glm.mat4()) + self.prog['m_proj'].write(glm.perspective(glm.radians(75), 1.0, 1, 100)) self.fbo = self.ctx.framebuffer( color_attachments=self.ctx.texture((512, 512), 4), @@ -37,8 +37,8 @@ def __init__(self, **kwargs): def render(self, time: float, frametime: float): # Rotate/move cube - rotation = Matrix44.from_eulers((time, time, time), dtype='f4') - translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') + rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) + translation = glm.translate(glm.vec3(0.0, 0.0, -3.5)) model = translation * rotation # Render cube to offscreen texture / fbo diff --git a/examples/orbit_camera.py b/examples/orbit_camera.py index 92faf9f..90433a2 100644 --- a/examples/orbit_camera.py +++ b/examples/orbit_camera.py @@ -2,7 +2,6 @@ import moderngl from base import OrbitCameraWindow -from pyrr import Matrix44 class OrbitCamCrate(OrbitCameraWindow): diff --git a/examples/skybox_cubemap.py b/examples/skybox_cubemap.py index 3945954..159ce8a 100644 --- a/examples/skybox_cubemap.py +++ b/examples/skybox_cubemap.py @@ -1,5 +1,4 @@ from pathlib import Path -from pyrr import Matrix44 import moderngl import moderngl_window from moderngl_window import geometry diff --git a/examples/texture_array.py b/examples/texture_array.py index 0a7afcc..5ec1c24 100644 --- a/examples/texture_array.py +++ b/examples/texture_array.py @@ -1,5 +1,5 @@ from pathlib import Path -from pyrr import Matrix44 +import glm import moderngl @@ -30,8 +30,8 @@ def __init__(self, **kwargs): def render(self, time: float, frametime: float): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) - rotation = Matrix44.from_eulers((time, time, time), dtype='f4') - translation = Matrix44.from_translation((0.0, 0.0, -3.5), dtype='f4') + 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) diff --git a/examples/uniform_block.py b/examples/uniform_block.py index 2865cf7..96cccbc 100644 --- a/examples/uniform_block.py +++ b/examples/uniform_block.py @@ -1,4 +1,4 @@ -from pyrr import Matrix44 +import glm import moderngl import moderngl_window @@ -62,10 +62,9 @@ def __init__(self, **kwargs): self.vao1 = self.cube.instance(self.prog1) self.vao2 = self.cube.instance(self.prog2) - self.m_proj = Matrix44.perspective_projection( - 75, self.wnd.aspect_ratio, # fov, aspect + self.m_proj = glm.perspective( + glm.radians(75), self.wnd.aspect_ratio, # fov, aspect 0.1, 100.0, # near, far - dtype='f4', ) proj_uniform1 = self.prog1['Projection'] @@ -104,8 +103,8 @@ def __init__(self, **kwargs): def render(self, time=0.0, frametime=0.0, target: moderngl.Framebuffer = None): self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST) - rotation = Matrix44.from_eulers((time, time, time), dtype='f4') - translation = Matrix44.from_translation((0.0, 0.0, -5.0), dtype='f4') + rotation = glm.mat4(glm.quat(glm.vec3(time, time, time))) + translation = glm.translate(glm.vec3(0.0, 0.0, -5.0)) modelview = translation * rotation self.view_buffer.write(modelview) diff --git a/moderngl_window/loaders/scene/gltf2.py b/moderngl_window/loaders/scene/gltf2.py index 9e1f39e..da612cc 100644 --- a/moderngl_window/loaders/scene/gltf2.py +++ b/moderngl_window/loaders/scene/gltf2.py @@ -8,7 +8,7 @@ import numpy from PIL import Image -from pyrr import Matrix44, quaternion +import glm import moderngl import moderngl_window @@ -267,7 +267,7 @@ def load_node(self, meta, parent=None): self.scene.nodes.append(node) if meta.matrix is not None: - node.matrix = Matrix44(value=meta.matrix) + node.matrix = glm.mat4(meta.matrix) if meta.mesh is not None: # Since we split up meshes with multiple primitives, this can be a list @@ -741,12 +741,12 @@ def __init__(self, data): self.scale = data.get("scale") if self.matrix: - self.matrix = Matrix44(self.matrix) + self.matrix = glm.mat4(*self.matrix) else: - self.matrix = Matrix44.identity() + self.matrix = glm.mat4() if self.translation is not None: - self.matrix = self.matrix * Matrix44.from_translation(self.translation) + self.matrix = self.matrix * glm.translate(self.translation) if self.rotation is not None: quat = quaternion.create( @@ -755,10 +755,10 @@ def __init__(self, data): z=self.rotation[2], w=self.rotation[3], ) - self.matrix = self.matrix * Matrix44.from_quaternion(quat).transpose() + self.matrix = self.matrix * glm.transpose(glm.mat4(quat)) if self.scale is not None: - self.matrix = self.matrix * Matrix44.from_scale(self.scale) + self.matrix = self.matrix * glm.scale(self.scale) @property def has_children(self): diff --git a/moderngl_window/opengl/projection.py b/moderngl_window/opengl/projection.py index 5fc9ff3..ff0d1c8 100644 --- a/moderngl_window/opengl/projection.py +++ b/moderngl_window/opengl/projection.py @@ -1,7 +1,7 @@ from typing import Tuple import numpy as np -from pyrr import Matrix44 +import glm class Projection3D: @@ -69,10 +69,10 @@ def update( self._near = near or self._near self._far = far or self._far - self._matrix = Matrix44.perspective_projection( - self._fov, self._aspect_ratio, self._near, self._far, dtype="f4", + self._matrix = glm.perspective( + glm.radians(self._fov), self._aspect_ratio, self._near, self._far ) - self._matrix_bytes = self._matrix.tobytes() + self._matrix_bytes = self._matrix.to_bytes() def tobytes(self) -> bytes: """Get the byte representation of the projection matrix diff --git a/moderngl_window/scene/camera.py b/moderngl_window/scene/camera.py index 051a079..79fd463 100644 --- a/moderngl_window/scene/camera.py +++ b/moderngl_window/scene/camera.py @@ -3,7 +3,7 @@ import numpy from moderngl_window.utils.keymaps import QWERTY, KeyMapFactory -from pyrr import Vector3, Matrix44, vector, vector3 +import glm from moderngl_window.opengl.projection import Projection3D from moderngl_window.context.base import BaseKeys @@ -46,17 +46,17 @@ def __init__(self, fov=60.0, aspect_ratio=1.0, near=1.0, far=100.0): near (float): Near plane far (float): Far plane """ - self.position = Vector3([0.0, 0.0, 0.0]) + self.position = glm.vec3(0.0, 0.0, 0.0) # Default camera placement - self.up = Vector3([0.0, 1.0, 0.0]) - self.right = Vector3([1.0, 0.0, 0.0]) - self.dir = Vector3([0.0, 0.0, -1.0]) + self.up = glm.vec3(0.0, 1.0, 0.0) + self.right = glm.vec3(1.0, 0.0, 0.0) + self.dir = glm.vec3(0.0, 0.0, -1.0) # Yaw and Pitch self._yaw = -90.0 self._pitch = 0.0 # World up vector - self._up = Vector3([0.0, 1.0, 0.0]) + self._up = glm.vec3(0.0, 1.0, 0.0) # Projection self._projection = Projection3D(aspect_ratio, fov, near, far) @@ -74,7 +74,7 @@ def set_position(self, x, y, z) -> None: y (float): y position z (float): z position """ - self.position = Vector3([float(x), float(y), float(z)]) + self.position = glm.vec3(float(x), float(y), float(z)) def set_rotation(self, yaw, pitch) -> None: """Set the rotation of the camera. @@ -115,14 +115,14 @@ def matrix(self) -> numpy.ndarray: def _update_yaw_and_pitch(self) -> None: """Updates the camera vectors based on the current yaw and pitch""" - front = Vector3([0.0, 0.0, 0.0]) + front = glm.vec3(0.0, 0.0, 0.0) front.x = cos(radians(self.yaw)) * cos(radians(self.pitch)) front.y = sin(radians(self.pitch)) front.z = sin(radians(self.yaw)) * cos(radians(self.pitch)) - self.dir = vector.normalise(front) - self.right = vector.normalise(vector3.cross(self.dir, self._up)) - self.up = vector.normalise(vector3.cross(self.right, self.dir)) + self.dir = glm.normalize(front) + self.right = glm.normalize(glm.cross(self.dir, self._up)) + self.up = glm.normalize(glm.cross(self.right, self.dir)) def look_at(self, vec=None, pos=None) -> numpy.ndarray: """Look at a specific point @@ -130,13 +130,13 @@ def look_at(self, vec=None, pos=None) -> numpy.ndarray: Either ``vec`` or ``pos`` needs to be supplied. Keyword Args: - vec (pyrr.Vector3): position + vec (glm.vec3): position pos (tuple/list): list of tuple ``[x, y, x]`` / ``(x, y, x)`` Returns: numpy.ndarray: Camera matrix """ if pos is not None: - vec = Vector3(pos) + vec = glm.vec3(pos) if vec is None: raise ValueError("vector or pos must be set") @@ -153,16 +153,16 @@ def _gl_look_at(self, pos, target, up) -> numpy.ndarray: Returns: numpy.ndarray: The matrix """ - z = vector.normalise(pos - target) - x = vector.normalise(vector3.cross(vector.normalise(up), z)) - y = vector3.cross(z, x) + z = glm.normalize(pos - target) + x = glm.normalize(glm.cross(glm.normalize(up), z)) + y = glm.cross(z, x) - translate = Matrix44.identity(dtype="f4") + translate = glm.mat4() translate[3][0] = -pos.x translate[3][1] = -pos.y translate[3][2] = -pos.z - rotate = Matrix44.identity(dtype="f4") + rotate = glm.mat4() rotate[0][0] = x[0] # -- X rotate[1][0] = x[1] rotate[2][0] = x[2] @@ -509,11 +509,10 @@ def matrix(self) -> numpy.ndarray: sin(radians(self.angle_x)) * sin(radians(self.angle_y)) * self.radius + self.target[2], ) self.set_position(*position) - return Matrix44.look_at( + return glm.lookAt( position, self.target, # what to look at self.up, # camera up direction (change for rolling the camera) - dtype="f4", ) @property diff --git a/moderngl_window/scene/mesh.py b/moderngl_window/scene/mesh.py index 4d9af29..b53599a 100644 --- a/moderngl_window/scene/mesh.py +++ b/moderngl_window/scene/mesh.py @@ -1,5 +1,5 @@ -from pyrr import matrix44 import numpy +import glm class Mesh: @@ -107,14 +107,12 @@ def calc_global_bbox(self, view_matrix, bbox_min, bbox_max): bbox_min, bbox_max: Combined bbox """ # Copy and extend to vec4 - bb1 = numpy.append(self.bbox_min[:], 1.0).astype("f4") - bb2 = numpy.append(self.bbox_max[:], 1.0).astype("f4") + bb1 = glm.vec4(*self.bbox_min[:], 1.0) + bb2 = glm.vec4(*self.bbox_max[:], 1.0) # Transform the bbox values - bmin = (matrix44.apply_to_vector(view_matrix, bb1),) - bmax = (matrix44.apply_to_vector(view_matrix, bb2),) - bmin = numpy.asarray(bmin, dtype="f4")[0] - bmax = numpy.asarray(bmax, dtype="f4")[0] + bmin = numpy.asarray(view_matrix * bb1, dtype="f4") + bmax = numpy.asarray(view_matrix * bb2, dtype="f4") # If a rotation happened there is an axis change and we have to ensure max-min is positive for i in range(3): diff --git a/moderngl_window/scene/node.py b/moderngl_window/scene/node.py index 14cce6f..c7587cc 100644 --- a/moderngl_window/scene/node.py +++ b/moderngl_window/scene/node.py @@ -3,7 +3,7 @@ """ from typing import List, TYPE_CHECKING import numpy -from pyrr import matrix44 +import glm if TYPE_CHECKING: from moderngl_window.scene import Camera, Mesh @@ -28,7 +28,7 @@ def __init__(self, name=None, camera=None, mesh=None, matrix=None): self._camera = camera self._mesh = mesh # Local node matrix - self._matrix = matrix.astype("f4") if matrix is not None else None + self._matrix = matrix if matrix is not None else None # Global matrix self._matrix_global = None @@ -155,7 +155,7 @@ def calc_global_bbox(self, view_matrix, bbox_min, bbox_max): bbox_max: max bbox values """ if self._matrix is not None: - view_matrix = matrix44.multiply(self._matrix, view_matrix) + view_matrix = self._matrix * view_matrix if self._mesh: bbox_min, bbox_max = self._mesh.calc_global_bbox( @@ -174,14 +174,12 @@ def calc_model_mat(self, model_matrix): model_matrix (numpy.ndarray): model matrix """ if self._matrix is not None: - self._matrix_global = matrix44.multiply(self._matrix, model_matrix).astype( - "f4" - ) + self._matrix_global = self._matrix * model_matrix for child in self._children: child.calc_model_mat(self._matrix_global) else: - self._matrix_global = model_matrix.astype("f4") + self._matrix_global = model_matrix for child in self._children: child.calc_model_mat(model_matrix) diff --git a/moderngl_window/scene/scene.py b/moderngl_window/scene/scene.py index 8a2b00b..dafed52 100644 --- a/moderngl_window/scene/scene.py +++ b/moderngl_window/scene/scene.py @@ -4,7 +4,7 @@ from typing import TYPE_CHECKING import logging import numpy -from pyrr import matrix44, vector3 +import glm import moderngl import moderngl_window as mglw @@ -71,7 +71,7 @@ def __init__(self, name, **kwargs): ) self.ctx.extra["DEFAULT_WIREFRAME_PROGRAM"] = self.wireframe_program - self._matrix = matrix44.create_identity(dtype="f4") + self._matrix = glm.mat4() @property def ctx(self) -> moderngl.Context: @@ -87,15 +87,15 @@ def matrix(self) -> numpy.ndarray: return self._matrix @matrix.setter - def matrix(self, matrix: numpy.ndarray): - self._matrix = matrix.astype("f4") + def matrix(self, matrix: glm.mat4): + self._matrix = matrix for node in self.root_nodes: node.calc_model_mat(self._matrix) def draw( self, - projection_matrix: numpy.ndarray = None, - camera_matrix: numpy.ndarray = None, + projection_matrix: glm.mat4 = None, + camera_matrix: glm.mat4 = None, time=0.0, ) -> None: """Draw all the nodes in the scene. @@ -107,8 +107,8 @@ def draw( """ for node in self.root_nodes: node.draw( - projection_matrix=projection_matrix.astype("f4"), - camera_matrix=camera_matrix.astype("f4"), + projection_matrix=projection_matrix, + camera_matrix=camera_matrix, time=time, ) @@ -129,8 +129,8 @@ def draw_bbox( children (bool): Will draw bounding boxes for meshes as well color (tuple): Color of the bounding boxes """ - projection_matrix = projection_matrix.astype("f4") - camera_matrix = camera_matrix.astype("f4") + projection_matrix = projection_matrix + camera_matrix = camera_matrix # Scene bounding box self.bbox_program["m_proj"].write(projection_matrix) @@ -161,8 +161,8 @@ def draw_wireframe( children (bool): Will draw bounding boxes for meshes as well color (tuple): Color of the wireframes """ - projection_matrix = projection_matrix.astype("f4") - camera_matrix = camera_matrix.astype("f4") + projection_matrix = projection_matrix + camera_matrix = camera_matrix self.wireframe_program["m_proj"].write(projection_matrix) self.wireframe_program["m_model"].write(self._matrix) @@ -228,13 +228,13 @@ def calc_scene_bbox(self) -> None: bbox_min, bbox_max = None, None for node in self.root_nodes: bbox_min, bbox_max = node.calc_global_bbox( - matrix44.create_identity(dtype="f4"), bbox_min, bbox_max + glm.mat4(), bbox_min, bbox_max ) self.bbox_min = bbox_min self.bbox_max = bbox_max - self.diagonal_size = vector3.length(self.bbox_max - self.bbox_min) + self.diagonal_size = glm.length(self.bbox_max - self.bbox_min) def prepare(self) -> None: """prepare the scene for rendering. @@ -244,7 +244,7 @@ def prepare(self) -> None: """ self.apply_mesh_programs() # Recursively calculate model matrices - self.matrix = matrix44.create_identity(dtype="f4") + self.matrix = glm.mat4() def find_node(self, name: str = None) -> "Node": """Finds a :py:class:`~moderngl_window.scene.Node` diff --git a/moderngl_window/text/bitmapped/text_2d.py b/moderngl_window/text/bitmapped/text_2d.py index c774a92..a5d7780 100644 --- a/moderngl_window/text/bitmapped/text_2d.py +++ b/moderngl_window/text/bitmapped/text_2d.py @@ -1,5 +1,5 @@ import numpy -from pyrr import matrix44 +import glm from pathlib import Path @@ -75,7 +75,7 @@ def draw(self, pos, length=-1, size=24.0): # Calculate ortho projection based on viewport vp = self.ctx.fbo.viewport w, h = vp[2], vp[3] - projection = matrix44.create_orthogonal_projection_matrix( + projection = glm.orthographic( 0, # left w, # right 0, # bottom diff --git a/pyproject.toml b/pyproject.toml index dffe88b..d1e0d7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,7 @@ dependencies = [ "moderngl<6", "pyglet>=2.0.0", "numpy>=1.16,<2", - "pyrr>=0.10.3,<1", + "pyglm>=2.7.0,<3", "Pillow>=10.0.1", ] @@ -130,7 +130,7 @@ module = "PyQt5.*" ignore_missing_imports = true [[tool.mypy.overrides]] -module = "pyrr.*" +module = "PyGLM.*" ignore_missing_imports = true [[tool.mypy.overrides]] diff --git a/tests/test_camera.py b/tests/test_camera.py index a643809..d6e2b7a 100644 --- a/tests/test_camera.py +++ b/tests/test_camera.py @@ -1,6 +1,6 @@ from unittest import TestCase import numpy as np -from pyrr import Vector3 +import glm from moderngl_window.scene import Camera, KeyboardCamera from moderngl_window.scene import camera as cam @@ -14,9 +14,9 @@ class CameraTest(TestCase): def test_camera(self): camera = Camera(fov=60, aspect_ratio=1.0, near=1.0, far=100.0) self.assertIsInstance(camera.projection, Projection3D) - self.assertIsInstance(camera.matrix, np.ndarray) + self.assertIsInstance(camera.matrix, glm.mat4) - camera.look_at(vec=Vector3((1, 2, 3))) + camera.look_at(vec=glm.vec3(1, 2, 3)) camera.look_at(pos=(4, 5, 6)) camera.set_position(1, 1, 1) @@ -27,7 +27,7 @@ def test_keyboardcamera(self): self.assertEqual(camera.mouse_sensitivity, 10.0) self.assertEqual(camera.velocity, 10.0) self.assertIsInstance(camera.projection, Projection3D) - self.assertIsInstance(camera.matrix, np.ndarray) + self.assertIsInstance(camera.matrix, glm.mat4) camera.key_input(BaseKeys.UP, BaseKeys.ACTION_PRESS, KeyModifiers) diff --git a/tests/test_projection.py b/tests/test_projection.py index bbeda1e..9eff4b3 100644 --- a/tests/test_projection.py +++ b/tests/test_projection.py @@ -1,5 +1,5 @@ from unittest import TestCase -import numpy +import glm from moderngl_window.opengl.projection import Projection3D @@ -15,7 +15,7 @@ def test_default(self): self.assertIsInstance(proj.projection_constants, tuple) self.assertAlmostEqual(proj.projection_constants[0], 1.01, places=2) self.assertAlmostEqual(proj.projection_constants[1], -1.01, places=2) - self.assertIsInstance(proj.matrix, numpy.ndarray) + self.assertIsInstance(proj.matrix, glm.mat4) self.assertIsInstance(proj.tobytes(), bytes) def test_update(self):