Source code for yt_idv.rendering_contexts.pyglet_context

import numpy as np
import pyglet
from yt import write_bitmap

from yt_idv.simple_gui import SimpleGUI

from .base_context import BaseContext


[docs]class PygletRenderingContext(pyglet.window.Window, BaseContext): """ Basic rendering context for IDV using GLFW3, that handles the main window event loop Parameters ---------- width : int, optional The width of the Interactive Data Visualization window. For performance reasons it is recommended to use values that are natural powers of 2. height : int, optional The height of the Interactive Data Visualization window. For performance reasons it is recommended to use values that are natural powers of 2. title : str, optional The title of the Interactive Data Visualization window. position : tuple of ints, optional What position should the window be moved to? (Upper left) If not specified, default to center. """ _do_update = True def __init__( self, width=1024, height=1024, title="vol_render", position=None, visible=True, gui=True, scene=None, ): self.offscreen = not visible config = pyglet.gl.Config( major_version=3, minor_version=3, forward_compat=True, double_buffer=True, depth_size=24, ) super().__init__( width, height, config=config, visible=visible, caption=title, resizable=True ) if position is None: self.center_window() else: # self.set_position(*position) self.set_location(*position) if gui: gui = SimpleGUI(self) self.gui = gui self.scene = scene
[docs] def on_draw(self): self.switch_to() if self._do_update and self.scene: self._do_update = False self.clear() if self.scene is not None: # This should check if the scene is actually dirty, and only # redraw the FB if it's not; this might need another flag self.scene.render() if self.image_widget is not None: self.image_widget.value = write_bitmap( self.scene.image[:, :, :3], None ) if self.gui: self.switch_to() self.gui.render(self.scene)
[docs] def on_resize(self, width, height): super().on_resize(width, height) self.scene.reset_framebuffers() self.scene.camera.aspect_ratio = width / height self.scene.camera._update_matrices() self._do_update = True
[docs] def set_position(self, xpos, ypos): if xpos < 0 or ypos < 0: raise RuntimeError max_width = self.screen.width max_height = self.screen.height win_width, win_height = self.width, self.height if 0 < xpos < 1: # We're being fed relative coords. We offset these for the window # center. xpos = max(self.screen.x + xpos * max_width - 0.5 * win_width, 0) if 0 < ypos < 1: # We're being fed relative coords. We offset these for the window # center. ypos = max(self.screen.y + ypos * max_height - 0.5 * win_height, 0) print("Setting position", xpos, ypos) self.set_location(int(xpos), int(ypos))
[docs] def center_window(self): self.set_position(0.5, 0.5)
[docs] def on_mouse_press(self, x, y, button, modifiers): self._do_update = True
[docs] def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers): if self.gui and self.gui.mouse_event_handled: self._do_update = True return start_x = -1.0 + 2.0 * x / self.width end_x = -1.0 + 2.0 * (x - dx) / self.width start_y = -1.0 + 2.0 * y / self.height end_y = -1.0 + 2.0 * (y + dy) / self.height self.scene.camera.update_orientation(start_x, start_y, end_x, end_y) self._do_update = True
[docs] def on_mouse_scroll(self, x, y, scroll_x, scroll_y): # captures mouse scrolling as zoom in/out if self.gui and self.gui.mouse_event_handled: self._do_update = True return camera = self.scene.camera # current camera dpos = ( 0.1 * (camera.position - camera.focus) / np.linalg.norm(camera.position - camera.focus) ) # wheel scroll comes in the scroll_y parameter with a value +/- 1 # +1 when scrolling "down", -1 when scrolling "up", so # flip it so scrolling "down" zooms out: zoom_inout = -1 * scroll_y self.scene.camera.offset_position(zoom_inout * dpos) self._do_update = True
[docs] def on_key_press(self, symbol, modifiers): # skeleton for capturing key presses! # potential navigation keys if symbol in [pyglet.window.key.LEFT, pyglet.window.key.A]: pass if symbol in [pyglet.window.key.RIGHT, pyglet.window.key.D]: pass if symbol in [pyglet.window.key.UP, pyglet.window.key.W]: pass if symbol in [pyglet.window.key.DOWN, pyglet.window.key.S]: pass
[docs] def run(self): pyglet.app.run()