マウスをグリグリするとカメラがある点を注視しながら移動するOrbitCamera
を実装する.結論,ModernGLが用意しているクラスを使えばいいだけなので,とても簡単.
コード
ベースになっているコードは以下の回のもの.
今回はそこに,OrbitCamera
とそれをマウス操作するためのコールバック関数を追加した.
尚,self.window.mouse_exclusivity = True
(50行目)を指定しておくと,マウスポインタが見えなくなり,どこまでもスクロールし続けられるようになる.
# glfw_òrbitcamera.py from pathlib import Path import numpy as np import moderngl as mgl import moderngl_window as mglw from moderngl_window.conf import settings from moderngl_window import resources from moderngl_window.resources import programs, scenes from moderngl_window.meta import ProgramDescription, SceneDescription from moderngl_window.scene.camera import OrbitCamera class App: def __init__(self, width=512, height=512) -> None: # Window # create a gl window: https://moderngl-window.readthedocs.io/en/latest/reference/settings.conf.settings.html#moderngl_window.conf.Settings.WINDOW settings.WINDOW["class"] = "moderngl_window.context.glfw.Window" settings.WINDOW["gl_version"] = (4, 1) settings.WINDOW["size"] = (width, height) settings.WINDOW["aspect_ratio"] = width / height self.window = mglw.create_window_from_settings() self.window.print_context_info() # Resources self.resource_dir = Path(__file__).parent.resolve() / "resources" ## shaders resources.register_program_dir((self.resource_dir / "shaders").resolve()) self.program = programs.load( ProgramDescription( vertex_shader="test_vs.glsl", fragment_shader="test_fs.glsl", ) ) ## meshes resources.register_scene_dir((self.resource_dir / "models").resolve()) self.scene = scenes.load(SceneDescription(path="bunny/bunny.obj")) for mesh in self.scene.meshes: print(">> mesh.attributes:", mesh.attributes) print(">> len(self.scene.meshes):", len(self.scene.meshes)) # Camera self.camera = OrbitCamera( aspect_ratio=width / height, radius=0.5, near=0.01, far=100.0) self.camera.mouse_sensitivity = 0.75 # Set key and mouse callback ## Ref: https://github.com/moderngl/moderngl-window/blob/master/examples/custom_config_class.py self.window.mouse_position_event_func = self.mouse_position_event self.window.mouse_scroll_event_func = self.mouse_scroll_event self.window.mouse_exclusivity = True def mouse_position_event(self, x, y, dx, dy) -> None: #print("Mouse position pos={} {} delta={} {}".format(x, y, dx, dy)) self.camera.rot_state(dx, dy) def mouse_scroll_event(self, x_offset, y_offset) -> None: #print("mouse_scroll_event", x_offset, y_offset) self.camera.zoom_state(y_offset) def run(self) -> None: while not self.window.is_closing: self.window.ctx.enable_only(mgl.DEPTH_TEST | mgl.CULL_FACE) self.window.ctx.clear(1, 0, 0, 0) self.program["M"].write(np.identity(4, dtype="float32")) self.program["V"].write(self.camera.matrix) self.program["P"].write(self.camera.projection.matrix) self.scene.root_nodes[0].mesh.material.mat_texture.texture.use(0) self.scene.root_nodes[0].mesh.vao.render(self.program) self.window.swap_buffers() if __name__ == "__main__": app = App() app.run()
結果
マウスをグリグリするとStanford Bunnyがグリグリ周る!