Пример #1
0
    def _read_pixels_as_in_window(self):
        # Reads pixels with markers and overlay from the same camera as screen.
        resolution = glfw.get_framebuffer_size(
            self.sim._render_context_window.window)

        resolution = np.array(resolution)
        resolution = resolution * min(1000 / np.min(resolution), 1)
        resolution = resolution.astype(np.int32)
        resolution -= resolution % 16
        if self.sim._render_context_offscreen is None:
            self.sim.render(resolution[0], resolution[1])
        offscreen_ctx = self.sim._render_context_offscreen
        window_ctx = self.sim._render_context_window
        # Save markers and overlay from offscreen.
        saved = [copy.deepcopy(offscreen_ctx._markers),
                 copy.deepcopy(offscreen_ctx._overlay),
                 rec_copy(offscreen_ctx.cam)]
        # Copy markers and overlay from window.
        offscreen_ctx._markers[:] = window_ctx._markers[:]
        offscreen_ctx._overlay.clear()
        offscreen_ctx._overlay.update(window_ctx._overlay)
        rec_assign(offscreen_ctx.cam, rec_copy(window_ctx.cam))

        img = self.sim.render(*resolution)
        img = img[::-1, :, :] # Rendered images are upside-down.
        # Restore markers and overlay to offscreen.
        offscreen_ctx._markers[:] = saved[0][:]
        offscreen_ctx._overlay.clear()
        offscreen_ctx._overlay.update(saved[1])
        rec_assign(offscreen_ctx.cam, saved[2])
        return img
Пример #2
0
    def _read_pixels_as_in_window(self):
        # Reads pixels with markers and overlay from the same camera as screen.
        resolution = glfw.get_framebuffer_size(
            self.sim._render_context_window.window)
        if self.sim._render_context_offscreen is None:
            self.sim.render(*resolution)
        offscreen_ctx = self.sim._render_context_offscreen
        window_ctx = self.sim._render_context_window
        # Save markers and overlay from offscreen.
        saved = [copy.deepcopy(offscreen_ctx._markers),
                 copy.deepcopy(offscreen_ctx._overlay),
                 rec_copy(offscreen_ctx.cam)]
        # Copy markers and overlay from window.
        offscreen_ctx._markers[:] = window_ctx._markers[:]
        offscreen_ctx._overlay.clear()
        offscreen_ctx._overlay.update(window_ctx._overlay)
        rec_assign(offscreen_ctx.cam, rec_copy(window_ctx.cam))

        img = self.sim.render(*resolution)
        # Restore markers and overlay to offscreen.
        offscreen_ctx._markers[:] = saved[0][:]
        offscreen_ctx._overlay.clear()
        offscreen_ctx._overlay.update(saved[1])
        rec_assign(offscreen_ctx.cam, saved[2])
        return img
Пример #3
0
    def _cursor_pos_callback(self, window, xpos, ypos):
        if not (self._button_left_pressed or self._button_right_pressed):
            return

        # Determine whether to move, zoom or rotate view
        mod_shift = (
            glfw.get_key(window, glfw.KEY_LEFT_SHIFT) == glfw.PRESS or
            glfw.get_key(window, glfw.KEY_RIGHT_SHIFT) == glfw.PRESS)
        if self._button_right_pressed:
            action = const.MOUSE_MOVE_H if mod_shift else const.MOUSE_MOVE_V
        elif self._button_left_pressed:
            action = const.MOUSE_ROTATE_H if mod_shift else const.MOUSE_ROTATE_V
        else:
            action = const.MOUSE_ZOOM

        # Determine
        dx = int(self._scale * xpos) - self._last_mouse_x
        dy = int(self._scale * ypos) - self._last_mouse_y
        width, height = glfw.get_framebuffer_size(window)

        with self._gui_lock:
            self.move_camera(action, dx / height, dy / height)

        self._last_mouse_x = int(self._scale * xpos)
        self._last_mouse_y = int(self._scale * ypos)
Пример #4
0
 def get_dimensions(self):
     """
     returns a tuple (width, height)
     """
     if self.window:
         return glfw.get_framebuffer_size(self.window)
     return (self.init_width, self.init_height)
Пример #5
0
 def renderLoop(self):
     self.initGL()
     while not glfw.window_should_close(self.window):
         w, h = glfw.get_framebuffer_size(self.window)
         self.renderFrame()
         glfw.swap_buffers(self.window)
         glfw.poll_events()
     self.destroyGL()
Пример #6
0
    def retrieve_mouse_data(self):
        window_size = glfw.get_framebuffer_size(self.window)
        window_center = [window_size[0] / 2, window_size[1] / 2]

        mouse_pos = [float(p - window_center[i]) / window_center[i] for i, p in enumerate(glfw.get_cursor_pos(self.window))]
        self.mouse_movement = (mouse_pos[0], mouse_pos[1])

        glfw.set_cursor_pos(self.window, *window_center)
Пример #7
0
 def autoscale(self):
     self.cam.lookat[0] = self.model.stat.center[0]
     self.cam.lookat[1] = self.model.stat.center[1]
     self.cam.lookat[2] = self.model.stat.center[2]
     self.cam.distance = 1.0 * self.model.stat.extent
     self.cam.camid = -1
     self.cam.trackbodyid = -1
     if self.window:
         width, height = glfw.get_framebuffer_size(self.window)
         mjlib.mjv_updateCameraPose(byref(self.cam), width*1.0/height)
Пример #8
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        if not glfw.init():
            raise ValueError("Failed to initialize glfw")

        # Configure the OpenGL context
        glfw.window_hint(glfw.CONTEXT_CREATION_API, glfw.NATIVE_CONTEXT_API)
        glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API)
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, self.gl_version[0])
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, self.gl_version[1])
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
        glfw.window_hint(glfw.RESIZABLE, self.resizable)
        glfw.window_hint(glfw.DOUBLEBUFFER, True)
        glfw.window_hint(glfw.DEPTH_BITS, 24)
        glfw.window_hint(glfw.SAMPLES, self.samples)

        monitor = None
        if self.fullscreen:
            # Use the primary monitors current resolution
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            self.width, self.height = mode.size.width, mode.size.height

            # Make sure video mode switching will not happen by
            # matching the desktops current video mode
            glfw.window_hint(glfw.RED_BITS, mode.bits.red)
            glfw.window_hint(glfw.GREEN_BITS, mode.bits.green)
            glfw.window_hint(glfw.BLUE_BITS, mode.bits.blue)
            glfw.window_hint(glfw.REFRESH_RATE, mode.refresh_rate)

        self.window = glfw.create_window(self.width, self.height, self.title, monitor, None)

        if not self.window:
            glfw.terminate()
            raise ValueError("Failed to create window")

        if not self.cursor:
            glfw.set_input_mode(self.window, glfw.CURSOR, glfw.CURSOR_DISABLED)

        self.buffer_width, self.buffer_height = glfw.get_framebuffer_size(self.window)
        glfw.make_context_current(self.window)

        if self.vsync:
            glfw.swap_interval(1)

        glfw.set_key_callback(self.window, self.key_event_callback)
        glfw.set_cursor_pos_callback(self.window, self.mouse_event_callback)
        glfw.set_mouse_button_callback(self.window, self.mouse_button_callback)
        glfw.set_window_size_callback(self.window, self.window_resize_callback)

        self.ctx = moderngl.create_context(require=self.gl_version_code)
        self.print_context_info()
        self.set_default_viewport()
Пример #9
0
    def start(self):
        if not glfw.init():
            return

        glfw.window_hint(glfw.SAMPLES, 4)

        # try stereo if refresh rate is at least 100Hz
        window = None
        stereo_available = False

        _, _, refresh_rate = glfw.get_video_mode(glfw.get_primary_monitor())
        if refresh_rate >= 100:
            glfw.window_hint(glfw.STEREO, 1)
            window = glfw.create_window(500, 500, "Simulate", None, None)
            if window:
                stereo_available = True

        # no stereo: try mono
        if not window:
            glfw.window_hint(glfw.STEREO, 0)
            window = glfw.create_window(500, 500, "Simulate", None, None)

        if not window:
            glfw.terminate()
            return

        self.running = True

        # Make the window's context current
        glfw.make_context_current(window)

        width, height = glfw.get_framebuffer_size(window)
        width1, height = glfw.get_window_size(window)
        self._scale = width * 1.0 / width1

        self.window = window

        mjlib.mjv_makeObjects(byref(self.objects), 1000)

        mjlib.mjv_defaultCamera(byref(self.cam))
        mjlib.mjv_defaultOption(byref(self.vopt))
        mjlib.mjr_defaultOption(byref(self.ropt))

        mjlib.mjr_defaultContext(byref(self.con))

        if self.model:
            mjlib.mjr_makeContext(self.model.ptr, byref(self.con), 150)
            self.autoscale()
        else:
            mjlib.mjr_makeContext(None, byref(self.con), 150)

        glfw.set_cursor_pos_callback(window, self.handle_mouse_move)
        glfw.set_mouse_button_callback(window, self.handle_mouse_button)
        glfw.set_scroll_callback(window, self.handle_scroll)
Пример #10
0
    def handle_scroll(self, window, x_offset, y_offset):
        # require model
        if not self.model:
            return

        # get current window size
        width, height = glfw.get_framebuffer_size(window)

        # scroll
        self.gui_lock.acquire()
        mjlib.mjv_moveCamera(MOUSE_ZOOM, 0, (-20*y_offset), byref(self.cam), width, height)
        self.gui_lock.release()
Пример #11
0
    def window_resize_callback(self, window, width, height):
        """
        Window resize callback for glfw

        Args:
            window: The window
            width: New width
            height: New height
        """
        self.width, self.height = width, height
        self.buffer_width, self.buffer_height = glfw.get_framebuffer_size(self.window)
        self.set_default_viewport()

        super().resize(self.buffer_width, self.buffer_height)
Пример #12
0
    def mouse_button_event(self, button, action, mods):
        """Called when a mouse button is pressed or released

        :param int button: The pressed/released mouse button
        :param int action: glfw.PRESS or glfw.RELEASE
        :param int mods: Bit field describing which modifier keys were held down.
        """
        if button == glfw.MOUSE_BUTTON_LEFT and action == glfw.PRESS:
            width, height = glfw.get_framebuffer_size(self.window)
            x, y = glfw.get_cursor_pos(self.window)  # integer positions relative to the upper left corner of the window
            x = x - (width / 2)
            y = (height / 2) - y
            self.heightmap.generate(game_core.Point(x, y))
            self.generate_texture(width, height)
Пример #13
0
def on_window_size(window, w, h):
    # get the frame buffer size and don't rely on the window
    # the window size and the framebuffer can vary on retina displays
    size_w, size_h = glfw.get_framebuffer_size(window)
    window_width = size_w
    window_height = size_h
    
    gl.glViewport(0, 0, window_width, window_height) #Reset The Current Viewport And Perspective Transformation

    gl.glMatrixMode(gl.GL_PROJECTION) #Select The Projection Matrix
    gl.glLoadIdentity() #Reset The Projection Matrix

    glu.gluPerspective(45.0,window_width/window_height,0.1,100.0) #Calculate The Aspect Ratio Of The Window
    gl.glMatrixMode(gl.GL_MODELVIEW) #Select The Modelview Matrix
Пример #14
0
    def handleResizeEvent(self, window):
        w, h = glfw.get_framebuffer_size(window)
        viewport = (int(max(1, w)), int(max(1, h)))

        if viewport != self.viewport:
            self.viewport = viewport
            self.updateMatrix(self.viewport)

            if self.useFramebuffers:
                self.initFramebuffers()
            if self.overlay:
                self.initOverlay()

            glViewport(0, 0, *self.viewport)
            self.redisplay = True
Пример #15
0
    def init(self):
        super(Window, self).init()

        # hide the cursor and lock it to this window. GLFW will then take care
        # of all the details of cursor re-centering and offset calculation and
        # providing the application with a virtual cursor position
        glfw.set_input_mode(self.window, glfw.CURSOR, glfw.CURSOR_DISABLED)

        self.cube = game_core.Mesh(smooth_cube.VERTICES, smooth_cube.NORMALS, smooth_cube.INDICES, smooth_cube.DRAW_METHOD)

        self.shaders = shaders.init()

        # set a default matrix for models, otherwise its nothing apparently
        self.light_direction = game_core.Vector(0.1, 1.0, 0.5)
        self.light_direction.normalize()
        model_mat = game_core.Matrix()
        for name, shader in self.shaders.iteritems():
            if 'modelToWorldMatrix' in shader.uniforms:
                with shader:
                    GL.glUniformMatrix4fv(
                        shader.uniforms['modelToWorldMatrix'],
                        1,
                        GL.GL_FALSE,
                        model_mat.tolist()
                    )
            if 'dirToLight' in shader.uniforms:
                with shader:
                    GL.glUniform4fv(shader.uniforms['dirToLight'], 1, list(self.light_direction))
            # if 'diffuseColor' in shader.uniforms:
            #     with shader:
            #         GL.glUniform4f(shader.uniforms['diffuseColor'], 0.5, 0.5, 0.5, 1.0)

        self.camera = Camera(position=[0.0, 32.0, 128.0])
        self.camera.init(*glfw.get_framebuffer_size(self.window))
        self._set_perspective_matrix()

        self.lod_tree = LodTestTree(size=64.0, max_depth=6)
        self.lod_tree.init()

        for depth in range(self.lod_tree.max_depth):
            fine_distance = self.lod_distances[depth]
            if depth == 0:
                coarse_distance = fine_distance * 2.0
            else:
                coarse_distance = self.lod_distances[depth - 1]
            with self.shaders['lod_test_{}'.format(depth)] as shader:
                GL.glUniform1f(shader.uniforms['fineDistance'], fine_distance)
                GL.glUniform1f(shader.uniforms['coarseDistance'], coarse_distance)
Пример #16
0
    def init(self):
        super(Window, self).init()

        # hide the cursor and lock it to this window. GLFW will then take care
        # of all the details of cursor re-centering and offset calculation and
        # providing the application with a virtual cursor position
        glfw.set_input_mode(self.window, glfw.CURSOR, glfw.CURSOR_DISABLED)

        # create a simple cube with smooth normals
        self.cube = game_core.Mesh(smooth_cube.VERTICES, smooth_cube.NORMALS, smooth_cube.INDICES, smooth_cube.DRAW_METHOD)

        # create a camera
        self.camera = game_core.AbstractCamera(position=[0.0, 0.0, 1.5])
        self.camera.init(*glfw.get_framebuffer_size(self.window))

        # compile a simple shader with MVP matrices
        frag_shader = compileShader(frag_shader_source, GL.GL_FRAGMENT_SHADER)
        vert_shader = compileShader(vert_shader_source, GL.GL_VERTEX_SHADER)
        self.shader = game_core.ShaderProgram(vert_shader, frag_shader)
        self.shader.store_uniform_location('modelToWorldMatrix')
        self.shader.store_uniform_location('worldToCameraMatrix')
        self.shader.store_uniform_location('cameraToClipMatrix')

        # populate the shader's MVP matrices and pull the "camera" back 1.5 units
        with self.shader:
            GL.glUniformMatrix4fv(
                self.shader.uniforms['cameraToClipMatrix'],
                1,
                GL.GL_FALSE,
                self.camera.projection_matrix.tolist(),
            )

            inverse_camera_matrix = self.camera.matrix.inverse()
            GL.glUniformMatrix4fv(
                self.shader.uniforms['worldToCameraMatrix'],
                1,
                GL.GL_FALSE,
                inverse_camera_matrix.tolist()
            )

            model_mat = game_core.Matrix()
            GL.glUniformMatrix4fv(
                self.shader.uniforms['modelToWorldMatrix'],
                1,
                GL.GL_FALSE,
                model_mat.tolist()
            )
Пример #17
0
   def init(self):
      # Initialize the renderer, set up the Window.
      glfw.init()
      glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
      glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
      glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)
      glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
      glfw.window_hint(glfw.DECORATED, gl.GL_TRUE)
      glfw.window_hint(glfw.DECORATED, gl.GL_TRUE)
      glfw.window_hint(glfw.RESIZABLE, gl.GL_FALSE)

      width = Config.windowWidth
      height = Config.windowHeight

      self.aspect = width/height

      # Initialize the window
      self.window = glfw.create_window(width, height, "Magic", None, None)
      glfw.make_context_current(self.window)
      self.renderer = Renderer()
      self.quad = []
      self.text = []

      # Set up camera
      self.viewMatrix = Matrix.identity()

      # Set up view transform. View is always 16 units high, and 16 * aspect units
      # wide. The extra space outside of a 4:3 ratio is unused, to make sure that
      # all the cards always fit in a 4:3 aspect monitor. 
      vHeight = 2
      vWidth = vHeight * self.aspect
      self.projectionMatrix = Matrix.ortho(-vWidth/2, vWidth/2, vHeight/2, -vHeight/2, -1, 1)
      self.viewProjectionMatrix = self.projectionMatrix * self.viewMatrix

      # Set up viewport
      fbWidth, fbHeight = glfw.get_framebuffer_size(self.window)
      gl.glViewport(0, 0, fbWidth, fbHeight)
      q = Quad(Texture('Images/Sen Triplets.jpg'))
      # Natural resolution of cards is 480x680
      cardAspect = 480/680
      q.x = 0
      q.y = 0
      q.height = .8
      q.width = q.height * cardAspect
      self.quad.append(q)
Пример #18
0
    def __init__(self, sim):
        super().__init__(sim)

        self._gui_lock = Lock()
        self._button_left_pressed = False
        self._button_right_pressed = False
        self._last_mouse_x = 0
        self._last_mouse_y = 0

        framebuffer_width, _ = glfw.get_framebuffer_size(self.window)
        window_width, _ = glfw.get_window_size(self.window)
        self._scale = framebuffer_width * 1.0 / window_width

        glfw.set_cursor_pos_callback(self.window, self._cursor_pos_callback)
        glfw.set_mouse_button_callback(
            self.window, self._mouse_button_callback)
        glfw.set_scroll_callback(self.window, self._scroll_callback)
        glfw.set_key_callback(self.window, self.key_callback)
Пример #19
0
def main():

    glfw.init()

    window = glfw.create_window( 640, 480, "glfw triangle", None, None )
    
    glfw.make_context_current( window )
    glfw.swap_interval( 1 )
    glfw.set_key_callback( window, on_key )

    while not glfw.window_should_close( window ):

        # set up model view
        width, height = glfw.get_framebuffer_size( window )
        ratio = width / float(height)
        gl.glViewport( 0, 0, width, height )
        gl.glClear( gl.GL_COLOR_BUFFER_BIT )
        gl.glMatrixMode( gl.GL_PROJECTION )
        gl.glLoadIdentity()
        gl.glOrtho( -ratio, ratio, -1.0, 1.0, 1.0, -1.0 )
        gl.glMatrixMode( gl.GL_MODELVIEW )
        gl.glLoadIdentity()
        gl.glRotatef( float(glfw.get_time()) * 50.0, 0.0, 0.0, 1.0 )

        # draw triangle
        gl.glBegin(gl.GL_TRIANGLES);
        gl.glColor3f( 1.0, 0.0, 0.0 )
        gl.glVertex3f( -0.6, -0.4, 0.0 )
        gl.glColor3f( 0.0, 1.0, 0.0 )
        gl.glVertex3f( 0.6, -0.4, 0.0 )
        gl.glColor3f( 0.0, 0.0, 1.0 )
        gl.glVertex3f( 0.0, 0.6, 0.0 )
        gl.glEnd()

        # swap buffers
        glfw.swap_buffers(window)

        # poll for events
        glfw.poll_events()
    
    glfw.destroy_window(window)
    glfw.terminate()
Пример #20
0
    def handle_mouse_move(self, window, xpos, ypos):

        # no buttons down: nothing to do
        if not self._button_left_pressed \
                and not self._button_middle_pressed \
                and not self._button_right_pressed:
            return

        # compute mouse displacement, save
        dx = int(self._scale * xpos) - self._last_mouse_x
        dy = int(self._scale * ypos) - self._last_mouse_y
        self._last_mouse_x = int(self._scale * xpos)
        self._last_mouse_y = int(self._scale * ypos)

        # require model
        if not self.model:
            return

        # get current window size
        width, height = glfw.get_framebuffer_size(self.window)

        # get shift key state
        mod_shift = glfw.get_key(window, glfw.KEY_LEFT_SHIFT) == glfw.PRESS \
                or glfw.get_key(window, glfw.KEY_RIGHT_SHIFT) == glfw.PRESS

        # determine action based on mouse button
        action = None
        if self._button_right_pressed:
            action = MOUSE_MOVE_H if mod_shift else MOUSE_MOVE_V
        elif self._button_left_pressed:
            action = MOUSE_ROTATE_H if mod_shift else MOUSE_ROTATE_V
        else:
            action = MOUSE_ZOOM

        self.gui_lock.acquire()

        mjlib.mjv_moveCamera(action, dx, dy, byref(self.cam), width, height)

        self.gui_lock.release()
Пример #21
0
    def __init__(self,
                 width=800,
                 height=600,
                 title="QLibs window",
                 swap_interval=1,
                 hint_conf=default_hint_conf,
                 resizable=True,
                 fullscreen=False,
                 transparent=False):
        self.width = width
        self.height = height
        self.resize_callback = None
        self.mouse_motion_callback = None
        self.mouse_button_callback = None
        self.scroll_callback = None
        self.key_callback = None
        self.spec_key_callback = None
        self.flip_mouse_y = False  #flipped relatively to usual math-y representation

        glfw.init()
        glfw.window_hint(glfw.RESIZABLE, resizable and not fullscreen)
        glfw.window_hint(glfw.TRANSPARENT_FRAMEBUFFER, transparent)
        for k, v in hint_conf.items():
            glfw.window_hint(k, v)
        monitor = None
        if fullscreen:
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            width = mode.size.width
            height = mode.size.height
            #width = 1920
            #height = 1080
            glfw.window_hint(glfw.RED_BITS, mode.bits.red)
            glfw.window_hint(glfw.GREEN_BITS, mode.bits.green)
            glfw.window_hint(glfw.BLUE_BITS, mode.bits.blue)
            glfw.window_hint(glfw.REFRESH_RATE, mode.refresh_rate)

        try:
            self.window = glfw.create_window(width, height, title, monitor,
                                             None)
        except glfw.GLFWError:
            logger.warn(
                "Provided config is unavailable, using fallback config")
            glfw.default_window_hints()
            for k, v in fallback_hint_conf.items():
                glfw.window_hint(k, v)
            self.window = glfw.create_window(width, height, title, None, None)

        if fullscreen:
            self.width, self.height = glfw.get_framebuffer_size(
                self.window)  #Required on windows

        glfw.set_window_user_pointer(self.window, id(self.window))
        glfw.make_context_current(self.window)
        glfw.swap_interval(swap_interval)
        #callbacks
        glfw.set_window_size_callback(self.window, self._on_resize)
        glfw.set_framebuffer_size_callback(self.window, self._update_viewport)
        glfw.set_cursor_pos_callback(self.window, self._on_mouse_motion)
        glfw.set_mouse_button_callback(self.window, self._on_mouse_button)
        glfw.set_char_mods_callback(self.window, self._on_key_press)
        glfw.set_key_callback(self.window, self._on_spec_key_press)
        glfw.set_scroll_callback(self.window, self._on_scroll)

        try:
            self.ctx = moderngl.create_context()
        except:
            self.ctx = moderngl.create_context(libgl='libGL.so.1')
Пример #22
0
def main():
    import os
    import sys
    os.chdir(os.path.dirname(__file__))

    import glfw
    import time
    from engine import Engine

    # Initialize the library
    if not glfw.init():
        sys.exit()

    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.SAMPLES, 16)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(640, 480, "Window Name", None, None)
    if not window:
        print "Couldn't initialize OpenGL. Check that your OpenGL version >4.3."
        glfw.terminate()
        sys.exit()

    # Make the window's context current
    glfw.make_context_current(window)

    # Get window size
    width, height = glfw.get_framebuffer_size(window)

    # Create engine
    engine = Engine(window)
    engine.setWindowHeight(height)
    engine.setWindowWidth(width)

    def on_resize(window, width, height):
        engine.setWindowWidth(width)
        engine.setWindowHeight(height)

    # Install a window size handler
    glfw.set_window_size_callback(window, on_resize)

    def on_key(window, key, scancode, action, mods):
        if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
            glfw.set_window_should_close(window, 1)

    # Install a key handler
    glfw.set_key_callback(window, on_key)

    def on_mouse(window, button, action, mods):
        if button == glfw.MOUSE_BUTTON_1 and action == glfw.PRESS:
            engine.shoot_on()
        if button == glfw.MOUSE_BUTTON_1 and action == glfw.RELEASE:
            engine.shoot_off()
        if button == glfw.MOUSE_BUTTON_2 and action == glfw.PRESS:
            engine.camera_switch()

    glfw.set_mouse_button_callback(window, on_mouse)

    def on_scroll(window, x, y):
        engine.camera_scroll(y)

    glfw.set_scroll_callback(window, on_scroll)

    old_time = time.time()
    elapsed_time = 0.0

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Calculate elapsed time
        elapsed_time = time.time() - old_time
        old_time = time.time()

        # Process
        engine.step(elapsed_time)

        # Swap front and back buffers
        glfw.swap_interval(1)
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

        # Don't be egoist :)
        time.sleep(0.01)

    glfw.terminate()
Пример #23
0
 def on_size(self, win, width, height):
     """ window size update => update viewport to new framebuffer size """
     GL.glViewport(0, 0, *glfw.get_framebuffer_size(win))
Пример #24
0

TARGET_FRAMERATE: int = 60

time_at_beginning_of_previous_frame: float = glfw.get_time()

while not glfw.window_should_close(window):
    while (
        glfw.get_time() < time_at_beginning_of_previous_frame + 1.0 / TARGET_FRAMERATE
    ):
        pass
    time_at_beginning_of_previous_frame = glfw.get_time()

    glfw.poll_events()

    width, height = glfw.get_framebuffer_size(window)
    glViewport(0, 0, width, height)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    draw_in_square_viewport()
    handle_inputs()

    axes_list = glfw.get_joystick_axes(glfw.JOYSTICK_1)
    if len(axes_list) >= 1 and axes_list[0]:
        if math.fabs(float(axes_list[0][0])) > 0.19:
            camera.position_worldspace.x += 10.0 * axes_list[0][0] * math.cos(camera.rot_y)
            camera.position_worldspace.z -= 10.0 * axes_list[0][0] * math.sin(camera.rot_y)
        if math.fabs(float(axes_list[0][1])) > 0.19:
            camera.position_worldspace.x += 10.0 * axes_list[0][1] * math.sin(camera.rot_y)
            camera.position_worldspace.z += 10.0 * axes_list[0][1] * math.cos(camera.rot_y)
Пример #25
0
def main():
    if not glfw.init():
        return

    window = glfw.create_window(WIDTH, HEIGHT, "Hello World", None, None)
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.window_hint(glfw.RESIZABLE, GL_FALSE)
    if not window:
        glfw.terminate()
        return -1
    glfw.make_context_current(window)

    (width, height) = glfw.get_framebuffer_size(window)
    glViewport(0, 0, width, height)

    glfw.set_key_callback(window, key_callback)

    glClearColor(0.2, 0.3, 0.2, 1.0)

    quad = [
        # coords            # colors        # texture
        -0.4,
        -0.5,
        0.0,
        1.0,
        0.0,
        0.0,
        0.0,
        0.0,
        0.4,
        -0.5,
        0.0,
        0.0,
        1.0,
        0.0,
        1.0,
        0.0,
        0.4,
        0.5,
        0.0,
        0.0,
        0.0,
        1.0,
        1.0,
        1.0,
        -0.4,
        0.5,
        0.0,
        1.0,
        1.0,
        1.0,
        0.0,
        1.0
    ]
    quad = numpy.array(quad, dtype=numpy.float32)
    indexes = [0, 1, 2, 0, 2, 3]
    indexes = numpy.array(indexes, dtype=numpy.uint32)

    ourShader = Shader('vertex_shader.vs', 'fragment_shader.frag')

    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)

    glBindVertexArray(VAO)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, quad.itemsize * len(quad), quad,
                 GL_STATIC_DRAW)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexes.itemsize * len(indexes),
                 indexes, GL_STATIC_DRAW)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(2)
    glBindVertexArray(0)

    texture1 = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture1)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    image = Image.open('../textures/wall.jpg')
    img_data = numpy.array(list(image.getdata()), numpy.uint8)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, img_data)
    glGenerateMipmap(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)

    texture2 = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture2)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    image = Image.open('../textures/container.jpg')
    img_data = numpy.array(list(image.getdata()), numpy.uint8)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB,
                 GL_UNSIGNED_BYTE, img_data)
    glGenerateMipmap(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)

    while not glfw.window_should_close(window):
        glfw.poll_events()

        glClear(GL_COLOR_BUFFER_BIT)

        ourShader.Use()

        dxLoc = glGetUniformLocation(ourShader.shader, "dx")
        glUniform1f(dxLoc, -0.5)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture1)
        glBindVertexArray(VAO)
        glDrawElements(GL_TRIANGLES, len(indexes), GL_UNSIGNED_INT, None)
        glBindVertexArray(0)

        glUniform1f(dxLoc, 0.5)
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture2)
        glBindVertexArray(VAO)
        glDrawElements(GL_TRIANGLES, len(indexes), GL_UNSIGNED_INT, None)
        glBindVertexArray(0)

        glfw.swap_buffers(window)

    glfw.terminate()
Пример #26
0
def player_drop(rec_dir, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir,
                app_version, debug):
    # general imports
    import logging

    # networking
    import zmq
    import zmq_tools
    from time import sleep

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.INFO)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    try:
        import glfw
        from gl_utils import GLFWErrorReporting

        GLFWErrorReporting.set_default()

        import gl_utils
        from OpenGL.GL import glClearColor
        from version_utils import parse_version
        from file_methods import Persistent_Dict
        from pyglui.pyfontstash import fontstash
        from pyglui.ui import get_roboto_font_path
        import player_methods as pm
        from pupil_recording import (
            assert_valid_recording_type,
            InvalidRecordingException,
        )
        from pupil_recording.update import update_recording

        process_was_interrupted = False

        def interrupt_handler(sig, frame):
            import traceback

            trace = traceback.format_stack(f=frame)
            logger.debug(f"Caught signal {sig} in:\n" + "".join(trace))
            nonlocal process_was_interrupted
            process_was_interrupted = True

        signal.signal(signal.SIGINT, interrupt_handler)

        def on_drop(window, paths):
            nonlocal rec_dir
            rec_dir = paths[0]

        if rec_dir:
            try:
                assert_valid_recording_type(rec_dir)
            except InvalidRecordingException as err:
                logger.error(str(err))
                rec_dir = None
        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(user_dir, "user_settings_player"))
        if parse_version(session_settings.get("version",
                                              "0.0")) != app_version:
            logger.info(
                "Session setting are from a  different version of this app. I will not use those."
            )
            session_settings.clear()
        w, h = session_settings.get("window_size", (1280, 720))

        glfw.init()
        glfw.window_hint(glfw.SCALE_TO_MONITOR, glfw.TRUE)
        glfw.window_hint(glfw.RESIZABLE, 0)
        window = glfw.create_window(w, h, "Pupil Player", None, None)
        glfw.window_hint(glfw.RESIZABLE, 1)

        glfw.make_context_current(window)

        window_position_manager = gl_utils.WindowPositionManager()
        window_pos = window_position_manager.new_window_position(
            window=window,
            default_position=window_position_default,
            previous_position=session_settings.get("window_position", None),
        )
        glfw.set_window_pos(window, window_pos[0], window_pos[1])

        glfw.set_drop_callback(window, on_drop)

        glfont = fontstash.Context()
        glfont.add_font("roboto", get_roboto_font_path())
        glfont.set_align_string(v_align="center", h_align="middle")
        glfont.set_color_float((0.2, 0.2, 0.2, 0.9))
        gl_utils.basic_gl_setup()
        glClearColor(0.5, 0.5, 0.5, 0.0)
        text = "Drop a recording directory onto this window."
        tip = "(Tip: You can drop a recording directory onto the app icon.)"

        # text = "Please supply a Pupil recording directory as first arg when calling Pupil Player."

        def display_string(string, font_size, center_y):
            x = w / 2 * content_scale
            y = center_y * content_scale

            glfont.set_size(font_size * content_scale)

            glfont.set_blur(10.5)
            glfont.set_color_float((0.0, 0.0, 0.0, 1.0))
            glfont.draw_text(x, y, string)

            glfont.set_blur(0.96)
            glfont.set_color_float((1.0, 1.0, 1.0, 1.0))
            glfont.draw_text(x, y, string)

        while not glfw.window_should_close(
                window) and not process_was_interrupted:

            fb_size = glfw.get_framebuffer_size(window)
            content_scale = gl_utils.get_content_scale(window)
            gl_utils.adjust_gl_view(*fb_size)

            if rec_dir:
                try:
                    assert_valid_recording_type(rec_dir)
                    logger.info(
                        "Starting new session with '{}'".format(rec_dir))
                    text = "Updating recording format."
                    tip = "This may take a while!"
                except InvalidRecordingException as err:
                    logger.error(str(err))
                    if err.recovery:
                        text = err.reason
                        tip = err.recovery
                    else:
                        text = "Invalid recording"
                        tip = err.reason
                    rec_dir = None

            gl_utils.clear_gl_screen()

            display_string(text, font_size=51, center_y=216)
            for idx, line in enumerate(tip.split("\n")):
                tip_font_size = 42
                center_y = 288 + tip_font_size * idx * 1.2
                display_string(line,
                               font_size=tip_font_size,
                               center_y=center_y)

            glfw.swap_buffers(window)

            if rec_dir:
                try:
                    update_recording(rec_dir)
                except AssertionError as err:
                    logger.error(str(err))
                    tip = "Oops! There was an error updating the recording."
                    rec_dir = None
                except InvalidRecordingException as err:
                    logger.error(str(err))
                    if err.recovery:
                        text = err.reason
                        tip = err.recovery
                    else:
                        text = "Invalid recording"
                        tip = err.reason
                    rec_dir = None
                else:
                    glfw.set_window_should_close(window, True)

            glfw.poll_events()

        session_settings["window_position"] = glfw.get_window_pos(window)
        session_settings.close()
        glfw.destroy_window(window)
        if rec_dir:
            ipc_pub.notify({
                "subject": "player_process.should_start",
                "rec_dir": rec_dir
            })

    except Exception:
        import traceback

        trace = traceback.format_exc()
        logger.error(
            "Process player_drop crashed with trace:\n{}".format(trace))

    finally:
        sleep(1.0)
Пример #27
0
 def get_rect(self):
     rect = mjcore.MJRRECT(0, 0, 0, 0)
     rect.width, rect.height = glfw.get_framebuffer_size(self.window)
     return rect
Пример #28
0
 def get_rect(self):
     rect = PyMjrRect()
     rect.width, rect.height = glfw.get_framebuffer_size(self.window)
     return rect
Пример #29
0
def main():
    if not glfw.init():
        return -1

    #configure glfw (using OpenGL 3.3 Core)
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    # create the window
    window = glfw.create_window(SCREEN_WIDTH, SCREEN_HEIGHT, "Hello World",
                                None, None)
    if not window:
        glfw.terminate()
        return -1
    glfw.make_context_current(window)
    # set callbacks
    glfw.set_window_size_callback(window, framebuffer_size_callback)
    glfw.set_key_callback(window, key_callback)

    # set the OpenGL viewport to the whole window
    (width, height) = glfw.get_framebuffer_size(window)
    glViewport(0, 0, width, height)

    # SHADERS #########################################################
    vertex_shader_source = """
    #version 330 core

    layout (location = 0) in vec3 position;
    layout (location = 1) in vec3 aColor;

    out vec3 vertexColor;

    void main()
    {
        gl_Position = vec4(position, 1.0f);
        vertexColor = aColor;
    }
    """

    fragment_shader_source = """
    #version 330 core

    in vec3 vertexColor;

    out vec4 FragColor;

    void main()
    {
        FragColor = vec4(vertexColor, 1.0f);
    }
    """

    vertex_shader = OpenGL.GL.shaders.compileShader(vertex_shader_source,
                                                    GL_VERTEX_SHADER)
    fragment_shader = OpenGL.GL.shaders.compileShader(fragment_shader_source,
                                                      GL_FRAGMENT_SHADER)
    shader = OpenGL.GL.shaders.compileProgram(vertex_shader, fragment_shader)
    # END SHADERS #########################################################

    # vertices data (a triangle)
    triangle = [
        # coords             # color
        -0.5,
        -0.5,
        0.0,
        1.0,
        0.0,
        0.0,
        0.5,
        -0.5,
        0.0,
        0.0,
        1.0,
        0.0,
        0.0,
        0.5,
        0.0,
        0.0,
        0.0,
        1.0
    ]
    triangle = numpy.array(triangle, dtype=numpy.float32)
    triangleIndices = [0, 1, 2]
    triangleIndices = numpy.array(triangleIndices, dtype=numpy.uint32)

    triangleVAO = glGenVertexArrays(1)
    triangleVBO = glGenBuffers(1)
    triangleEBO = glGenBuffers(1)

    glBindVertexArray(triangleVAO)
    glBindBuffer(GL_ARRAY_BUFFER, triangleVBO)
    glBufferData(GL_ARRAY_BUFFER, triangle.itemsize * len(triangle), triangle,
                 GL_STATIC_DRAW)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleEBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 triangleIndices.itemsize * len(triangleIndices),
                 triangleIndices, GL_STATIC_DRAW)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(ctypes.c_float),
                          ctypes.c_void_p(0))
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(ctypes.c_float),
                          ctypes.c_void_p(3 * sizeof(ctypes.c_float)))
    glEnableVertexAttribArray(0)
    glEnableVertexAttribArray(1)
    glBindVertexArray(0)

    # game loop
    while not glfw.window_should_close(window):
        # set the color buffer
        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(shader)
        glBindVertexArray(triangleVAO)
        glDrawElements(GL_TRIANGLES, len(triangleIndices), GL_UNSIGNED_INT,
                       None)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()
Пример #30
0
def main():
    global rotation_angle
    global d_x

    # Initialize the library
    if not glfw.init():
        print("library is not initialized")
        return
    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(640, 480, "Hello World", None, None)
    if not window:
        glfw.terminate()
        return

    # Make the window's context current
    glfw.make_context_current(window)

    print(glfw.__version__)



    glfw.set_key_callback(window, on_key)
    #glfw.set_mouse_button_callback(window, on_mouse)
    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here, e.g. using pyOpenGL

        width, height = glfw.get_framebuffer_size(window)
        ratio = width / float(height)

        rotation_angle += 0.1

        # Set viewport
        gl.glViewport(0, 0, width, height)
        # Clear color buffer
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        # Select and setup the projection matrix
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadIdentity()
        gl.glOrtho(-ratio, ratio, -1, 1, 1, -1)

        # Select and setup the modelview matrix
        gl.glMatrixMode(gl.GL_MODELVIEW)
        gl.glLoadIdentity()
        gl.glRotatef(rotation_angle, 0, 0, 1)
        gl.glBegin(gl.GL_POLYGON)
        gl.glColor3f(color.red, color.green, color.blue)
        gl.glVertex3f(-0.5 + d_x, -0.5, 0)
        gl.glColor3f(color.red, color.green, color.blue)
        gl.glVertex3f(-0.5 + d_x, +0.5, 0)
        gl.glColor3f(color.red, color.green, color.blue)
        gl.glVertex3f( 0.5 + d_x, +0.5, 0)
        gl.glColor3f(color.red, color.green, color.blue)
        gl.glVertex3f( 0.5 + d_x, -0.5, 0)
        gl.glEnd()

        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

    # terminating the whole proccess
    glfw.destroy_window(window)
    glfw.terminate()
Пример #31
0
 def on_pos(window, x, y):
     hdpi_factor = float(
         glfw.get_framebuffer_size(window)[0] /
         glfw.get_window_size(window)[0])
     x, y = x * hdpi_factor, y * hdpi_factor
     gui.update_mouse(x, y)
Пример #32
0
def main():
    if not glfw.init():
        return

    window = glfw.create_window(WIDTH, HEIGHT, "Hello World", None, None)
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.window_hint(glfw.RESIZABLE, GL_FALSE)
    if not window:
        glfw.terminate()
        return -1
    glfw.make_context_current(window)

    (width, height) = glfw.get_framebuffer_size(window)
    glViewport(0, 0, width, height)

    glfw.set_key_callback(window, key_callback)

    glClearColor(0.2, 0.3, 0.2, 1.0)

    triangle = [
        # coords            # colors
        -0.5,
        -0.5,
        0.0,
        1.0,
        0.0,
        0.0,
        0.5,
        -0.5,
        0.0,
        0.0,
        1.0,
        0.0,
        0.0,
        0.5,
        0.0,
        0.0,
        0.0,
        1.0
    ]
    triangle = numpy.array(triangle, dtype=numpy.float32)
    indexes = [0, 1, 2]
    indexes = numpy.array(indexes, dtype=numpy.uint32)

    vertex_shader_source = """
    #version 330 core

    layout (location = 0) in vec3 position;
    layout (location = 1) in vec3 color;

    out vec3 ourColor;

    void main()
    {
        gl_Position = vec4(position, 1.0f);
        ourColor = color;
    }
    """

    fragment_shader_source = """
    #version 330 core

    in vec3 ourColor;
    out vec4 color;

    void main()
    {
        color = vec4(ourColor, 1.0f);
    }
    """

    vertex_shader = OpenGL.GL.shaders.compileShader(vertex_shader_source,
                                                    GL_VERTEX_SHADER)
    fragment_shader = OpenGL.GL.shaders.compileShader(fragment_shader_source,
                                                      GL_FRAGMENT_SHADER)
    shader = OpenGL.GL.shaders.compileProgram(vertex_shader, fragment_shader)

    VAO = glGenVertexArrays(1)
    VBO = glGenBuffers(1)
    EBO = glGenBuffers(1)

    glBindVertexArray(VAO)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, triangle.itemsize * len(triangle), triangle,
                 GL_STATIC_DRAW)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexes.itemsize * len(indexes),
                 indexes, GL_STATIC_DRAW)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)
    glBindVertexArray(0)

    while not glfw.window_should_close(window):
        glfw.poll_events()

        glClear(GL_COLOR_BUFFER_BIT)

        glUseProgram(shader)
        glBindVertexArray(VAO)
        glDrawElements(GL_TRIANGLES, len(indexes), GL_UNSIGNED_INT, None)
        glBindVertexArray(0)

        glfw.swap_buffers(window)

    glfw.terminate()
Пример #33
0
    def __init__(
        self,
        width,
        height,
        caption,
        resizable=True,
        fullscreen=False,
        vsync=True,
        aspect_ratio=16 / 9,
        samples=4,
        cursor=True,
    ):

        self.vsync = vsync
        self.width = width
        self.cursor = cursor
        self.height = height
        self.samples = samples
        self.caption = caption
        self.resizable = resizable
        self.fullscreen = fullscreen
        self.aspect_ratio = aspect_ratio

        if not glfw.init():
            raise ValueError("Failed to initialize glfw")

        # Configure the OpenGL context
        glfw.window_hint(glfw.CONTEXT_CREATION_API, glfw.NATIVE_CONTEXT_API)
        glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API)
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, self.gl_version[0])
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, self.gl_version[1])
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
        glfw.window_hint(glfw.RESIZABLE, self.resizable)
        glfw.window_hint(glfw.DOUBLEBUFFER, True)
        glfw.window_hint(glfw.DEPTH_BITS, 24)
        glfw.window_hint(glfw.SAMPLES, self.samples)

        monitor = None
        if self.fullscreen:
            # Use the primary monitors current resolution
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            self.width, self.height = mode.size.width, mode.size.height

            # Make sure video mode switching will not happen by
            # matching the desktops current video mode
            glfw.window_hint(glfw.RED_BITS, mode.bits.red)
            glfw.window_hint(glfw.GREEN_BITS, mode.bits.green)
            glfw.window_hint(glfw.BLUE_BITS, mode.bits.blue)
            glfw.window_hint(glfw.REFRESH_RATE, mode.refresh_rate)

        self.window = glfw.create_window(self.width, self.height, self.caption,
                                         monitor, None)

        if not self.window:
            glfw.terminate()
            raise ValueError("Failed to create window")

        if not self.cursor:
            glfw.set_input_mode(self.window, glfw.CURSOR, glfw.CURSOR_DISABLED)

        self.buffer_width, self.buffer_height = glfw.get_framebuffer_size(
            self.window)
        glfw.make_context_current(self.window)

        if self.vsync:
            glfw.swap_interval(1)

        self.frames = 0
        glfw.set_key_callback(self.window, self.key_event_callback)
        glfw.set_cursor_pos_callback(self.window, self.mouse_event_callback)
        glfw.set_scroll_callback(self.window, self.scroll_callback)
        glfw.set_mouse_button_callback(self.window, self.mouse_button_callback)
        glfw.set_window_size_callback(self.window, self.window_resize_callback)

        self.setup()
Пример #34
0
def main():
    if not glfw.init():
        raise RuntimeError('Failed to initialize GLFW')

    version = glfw.get_version_string().decode('ASCII')
    print('GLFW', version)

    monitors = glfw.get_monitors()
    for i, monitor in enumerate(monitors):
        name = glfw.get_monitor_name(monitor)
        primary = (glfw.get_monitor_pos(monitor) ==
                   glfw.get_monitor_pos(glfw.get_primary_monitor()))
        print('Monitor #{}: {}{}'.format(i, name.decode('utf8'),
              ' (primary)' if primary else ''))
        width_mm, height_mm = glfw.get_monitor_physical_size(monitor)
        diag_mm = math.sqrt(width_mm*width_mm + height_mm*height_mm)
        print('Diagonal: {:.1f}"'.format(diag_mm / 25.4))
        mode = glfw.get_video_mode(monitor)
        print('Video mode: {}x{} {}Hz {}'.format(mode.size.width, mode.size.height,
              mode.refresh_rate, mode.bits))
        xscale, yscale = glfw.get_monitor_content_scale(monitor)
        print('Scale: {}|{}'.format(xscale, yscale))
        print('Virtual position:', glfw.get_monitor_pos(monitor))
        print('Work ares:', glfw.get_monitor_workarea(monitor))
        for mode in glfw.get_video_modes(monitor):
            print('Supported: {}x{} {}Hz {}'.format(mode.size.width, mode.size.height,
                mode.refresh_rate, mode.bits))
            print(mode)

        print()

    glfw.window_hint(glfw.RESIZABLE, True)
    glfw.window_hint(glfw.STENCIL_BITS, 8)
    glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API)
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6)
    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    monitor = glfw.get_primary_monitor()
    mode = glfw.get_video_mode(monitor)

    window = glfw.create_window(640, 480, 'Title', None, None)
    # window = glfw.create_window(mode.size.width, mode.size.height, 'Title', monitor, None)
    if window is None:
        glfw.terminate()
        raise RuntimeError('Failed to create a window')

    # glfw.set_window_monitor(window, monitor, 0, 0, mode.size.width, mode.size.height, mode.refresh_rate)

    width, height = glfw.get_window_size(window)
    print('Window size: {}x{}'.format(width, height))
    print('Frame size:', glfw.get_window_frame_size(window))
    width, height = glfw.get_framebuffer_size(window)
    print('Framebuffer size: {}x{}'.format(width, height))
    print('Client API:', glfw.get_window_attrib(window, glfw.CLIENT_API))
    version_major = glfw.get_window_attrib(window, glfw.CONTEXT_VERSION_MAJOR)
    version_minor = glfw.get_window_attrib(window, glfw.CONTEXT_VERSION_MINOR)
    revision = glfw.get_window_attrib(window, glfw.CONTEXT_REVISION)
    print('Version: {}.{} rev{}'.format(version_major, version_minor, revision))

    glfw.make_context_current(window)
    renderer = Renderer(window)

    while not glfw.window_should_close(window):
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        renderer.render()
        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()
Пример #35
0
    def start(self):
        logger.info('initializing glfw@%s', glfw.get_version())

        glfw.set_error_callback(_glfw_error_callback)

        if not glfw.init():
            raise Exception('glfw failed to initialize')

        window = None
        if self.visible:
            glfw.window_hint(glfw.SAMPLES, 4)
        else:
            glfw.window_hint(glfw.VISIBLE, 0);

        # try stereo if refresh rate is at least 100Hz
        stereo_available = False

        _, _, refresh_rate = glfw.get_video_mode(glfw.get_primary_monitor())
        if refresh_rate >= 100:
            glfw.window_hint(glfw.STEREO, 1)
            window = glfw.create_window(
                self.init_width, self.init_height, "Simulate", None, None)
            if window:
                stereo_available = True

        # no stereo: try mono
        if not window:
            glfw.window_hint(glfw.STEREO, 0)
            window = glfw.create_window(
                self.init_width, self.init_height, "Simulate", None, None)

        if not window:
            glfw.terminate()
            return

        self.running = True

        # Make the window's context current
        glfw.make_context_current(window)

        self._init_framebuffer_object()

        width, height = glfw.get_framebuffer_size(window)
        width1, height = glfw.get_window_size(window)
        self._scale = width * 1.0 / width1

        self.window = window

        mjlib.mjv_makeObjects(byref(self.objects), 1000)

        mjlib.mjv_defaultCamera(byref(self.cam))
        mjlib.mjv_defaultOption(byref(self.vopt))
        mjlib.mjr_defaultOption(byref(self.ropt))

        mjlib.mjr_defaultContext(byref(self.con))

        if self.model:
            mjlib.mjr_makeContext(self.model.ptr, byref(self.con), 150)
            self.autoscale()
        else:
            mjlib.mjr_makeContext(None, byref(self.con), 150)

        glfw.set_cursor_pos_callback(window, self.handle_mouse_move)
        glfw.set_mouse_button_callback(window, self.handle_mouse_button)
        glfw.set_scroll_callback(window, self.handle_scroll)
Пример #36
0
Файл: eye.py Проект: N-M-T/pupil
def eye(
    timebase,
    is_alive_flag,
    ipc_pub_url,
    ipc_sub_url,
    ipc_push_url,
    user_dir,
    version,
    eye_id,
    overwrite_cap_settings=None,
    hide_ui=False,
    debug=False,
    pub_socket_hwm=None,
    parent_application="capture",
):
    """reads eye video and detects the pupil.

    Creates a window, gl context.
    Grabs images from a capture.
    Streams Pupil coordinates.

    Reacts to notifications:
        ``eye_process.should_stop``: Stops the eye process
        ``recording.started``: Starts recording eye video
        ``recording.stopped``: Stops recording eye video
        ``frame_publishing.started``: Starts frame publishing
        ``frame_publishing.stopped``: Stops frame publishing
        ``start_eye_plugin``: Start plugins in eye process

    Emits notifications:
        ``eye_process.started``: Eye process started
        ``eye_process.stopped``: Eye process stopped

    Emits data:
        ``pupil.<eye id>``: Pupil data for eye with id ``<eye id>``
        ``frame.eye.<eye id>``: Eye frames with id ``<eye id>``
    """

    # We deferr the imports becasue of multiprocessing.
    # Otherwise the world process each process also loads the other imports.
    import zmq
    import zmq_tools

    zmq_ctx = zmq.Context()
    ipc_socket = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)
    pupil_socket = zmq_tools.Msg_Streamer(zmq_ctx, ipc_pub_url, pub_socket_hwm)
    notify_sub = zmq_tools.Msg_Receiver(zmq_ctx, ipc_sub_url, topics=("notify",))

    # logging setup
    import logging

    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.NOTSET)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    if is_alive_flag.value:
        # indicates eye process that this is a duplicated startup
        logger.warning("Aborting redundant eye process startup")
        return

    with Is_Alive_Manager(is_alive_flag, ipc_socket, eye_id, logger):
        # general imports
        import traceback
        import numpy as np
        import cv2

        from OpenGL.GL import GL_COLOR_BUFFER_BIT

        # display
        import glfw
        from gl_utils import GLFWErrorReporting

        GLFWErrorReporting.set_default()

        from pyglui import ui, graph, cygl
        from pyglui.cygl.utils import Named_Texture
        import gl_utils
        from gl_utils import basic_gl_setup, adjust_gl_view, clear_gl_screen
        from gl_utils import make_coord_system_pixel_based
        from gl_utils import make_coord_system_norm_based
        from gl_utils import is_window_visible, glViewport

        # monitoring
        import psutil

        # Plug-ins
        from plugin import Plugin_List

        # helpers/utils
        from uvc import get_time_monotonic
        from file_methods import Persistent_Dict
        from version_utils import parse_version
        from methods import normalize, denormalize, timer
        from av_writer import JPEG_Writer, MPEG_Writer, NonMonotonicTimestampError
        from ndsi import H264Writer
        from video_capture import source_classes, manager_classes
        from roi import Roi

        from background_helper import IPC_Logging_Task_Proxy
        from pupil_detector_plugins import available_detector_plugins, EVENT_KEY

        IPC_Logging_Task_Proxy.push_url = ipc_push_url

        def interrupt_handler(sig, frame):
            import traceback

            trace = traceback.format_stack(f=frame)
            logger.debug(f"Caught signal {sig} in:\n" + "".join(trace))
            # NOTE: Interrupt is handled in world/service/player which are responsible for
            # shutting down the eye process properly

        signal.signal(signal.SIGINT, interrupt_handler)

        # UI Platform tweaks
        if platform.system() == "Linux":
            scroll_factor = 10.0
            window_position_default = (600, 300 * eye_id + 30)
        elif platform.system() == "Windows":
            scroll_factor = 10.0
            window_position_default = (600, 90 + 300 * eye_id)
        else:
            scroll_factor = 1.0
            window_position_default = (600, 300 * eye_id)

        icon_bar_width = 50
        window_size = None
        content_scale = 1.0

        # g_pool holds variables for this process
        g_pool = SimpleNamespace()

        # make some constants avaiable
        g_pool.debug = debug
        g_pool.user_dir = user_dir
        g_pool.version = version
        g_pool.app = parent_application
        g_pool.eye_id = eye_id
        g_pool.process = f"eye{eye_id}"
        g_pool.timebase = timebase
        g_pool.camera_render_size = None

        g_pool.zmq_ctx = zmq_ctx
        g_pool.ipc_pub = ipc_socket
        g_pool.ipc_pub_url = ipc_pub_url
        g_pool.ipc_sub_url = ipc_sub_url
        g_pool.ipc_push_url = ipc_push_url

        def get_timestamp():
            return get_time_monotonic() - g_pool.timebase.value

        g_pool.get_timestamp = get_timestamp
        g_pool.get_now = get_time_monotonic

        def load_runtime_pupil_detection_plugins():
            from plugin import import_runtime_plugins
            from pupil_detector_plugins.detector_base_plugin import PupilDetectorPlugin

            plugins_path = os.path.join(g_pool.user_dir, "plugins")

            for plugin in import_runtime_plugins(plugins_path):
                if not isinstance(plugin, type):
                    continue
                if not issubclass(plugin, PupilDetectorPlugin):
                    continue
                if plugin is PupilDetectorPlugin:
                    continue
                yield plugin

        available_detectors = available_detector_plugins()
        runtime_detectors = list(load_runtime_pupil_detection_plugins())
        plugins = (
            manager_classes
            + source_classes
            + available_detectors
            + runtime_detectors
            + [Roi]
        )
        g_pool.plugin_by_name = {p.__name__: p for p in plugins}

        preferred_names = [
            f"Pupil Cam3 ID{eye_id}",
            f"Pupil Cam2 ID{eye_id}",
            f"Pupil Cam1 ID{eye_id}",
        ]
        if eye_id == 0:
            preferred_names += ["HD-6000"]

        default_capture_name = "UVC_Source"
        default_capture_settings = {
            "preferred_names": preferred_names,
            "frame_size": (192, 192),
            "frame_rate": 120,
        }

        default_plugins = [
            # TODO: extend with plugins
            (default_capture_name, default_capture_settings),
            ("UVC_Manager", {}),
            *[(p.__name__, {}) for p in available_detectors],
            ("NDSI_Manager", {}),
            ("HMD_Streaming_Manager", {}),
            ("File_Manager", {}),
            ("Roi", {}),
        ]

        def consume_events_and_render_buffer():
            glfw.make_context_current(main_window)
            clear_gl_screen()

            if all(c > 0 for c in g_pool.camera_render_size):
                glViewport(0, 0, *g_pool.camera_render_size)
                for p in g_pool.plugins:
                    p.gl_display()

            glViewport(0, 0, *window_size)
            # render graphs
            fps_graph.draw()
            cpu_graph.draw()

            # render GUI
            try:
                clipboard = glfw.get_clipboard_string(main_window).decode()
            except (AttributeError, glfw.GLFWError):
                # clipboard is None, might happen on startup
                clipboard = ""
            g_pool.gui.update_clipboard(clipboard)
            user_input = g_pool.gui.update()
            if user_input.clipboard != clipboard:
                # only write to clipboard if content changed
                glfw.set_clipboard_string(main_window, user_input.clipboard)

            for button, action, mods in user_input.buttons:
                x, y = glfw.get_cursor_pos(main_window)
                pos = gl_utils.window_coordinate_to_framebuffer_coordinate(
                    main_window, x, y, cached_scale=None
                )
                pos = normalize(pos, g_pool.camera_render_size)
                if g_pool.flip:
                    pos = 1 - pos[0], 1 - pos[1]
                # Position in img pixels
                pos = denormalize(pos, g_pool.capture.frame_size)

                for plugin in g_pool.plugins:
                    if plugin.on_click(pos, button, action):
                        break

            for key, scancode, action, mods in user_input.keys:
                for plugin in g_pool.plugins:
                    if plugin.on_key(key, scancode, action, mods):
                        break

            for char_ in user_input.chars:
                for plugin in g_pool.plugins:
                    if plugin.on_char(char_):
                        break

            # update screen
            glfw.swap_buffers(main_window)

        # Callback functions
        def on_resize(window, w, h):
            nonlocal window_size
            nonlocal content_scale

            is_minimized = bool(glfw.get_window_attrib(window, glfw.ICONIFIED))

            if is_minimized:
                return

            # Always clear buffers on resize to make sure that there are no overlapping
            # artifacts from previous frames.
            gl_utils.glClear(GL_COLOR_BUFFER_BIT)
            gl_utils.glClearColor(0, 0, 0, 1)

            active_window = glfw.get_current_context()
            glfw.make_context_current(window)
            content_scale = gl_utils.get_content_scale(window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(window)
            g_pool.gui.scale = content_scale
            window_size = w, h
            g_pool.camera_render_size = w - int(icon_bar_width * g_pool.gui.scale), h
            g_pool.gui.update_window(w, h)
            g_pool.gui.collect_menus()
            for g in g_pool.graphs:
                g.scale = content_scale
                g.adjust_window_size(w, h)
            adjust_gl_view(w, h)
            glfw.make_context_current(active_window)

            # Minimum window size required, otherwise parts of the UI can cause openGL
            # issues with permanent effects. Depends on the content scale, which can
            # potentially be dynamically modified, so we re-adjust the size limits every
            # time here.
            min_size = int(2 * icon_bar_width * g_pool.gui.scale / framebuffer_scale)
            glfw.set_window_size_limits(
                window,
                min_size,
                min_size,
                glfw.DONT_CARE,
                glfw.DONT_CARE,
            )

            # Needed, to update the window buffer while resizing
            consume_events_and_render_buffer()

        def on_window_key(window, key, scancode, action, mods):
            g_pool.gui.update_key(key, scancode, action, mods)

        def on_window_char(window, char):
            g_pool.gui.update_char(char)

        def on_iconify(window, iconified):
            g_pool.iconified = iconified

        def on_window_mouse_button(window, button, action, mods):
            g_pool.gui.update_button(button, action, mods)

        def on_pos(window, x, y):
            x, y = gl_utils.window_coordinate_to_framebuffer_coordinate(
                window, x, y, cached_scale=None
            )
            g_pool.gui.update_mouse(x, y)

            pos = x, y
            pos = normalize(pos, g_pool.camera_render_size)
            if g_pool.flip:
                pos = 1 - pos[0], 1 - pos[1]
            # Position in img pixels
            pos = denormalize(pos, g_pool.capture.frame_size)

            for p in g_pool.plugins:
                p.on_pos(pos)

        def on_scroll(window, x, y):
            g_pool.gui.update_scroll(x, y * scroll_factor)

        def on_drop(window, paths):
            for plugin in g_pool.plugins:
                if plugin.on_drop(paths):
                    break

        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(g_pool.user_dir, "user_settings_eye{}".format(eye_id))
        )
        if parse_version(session_settings.get("version", "0.0")) != g_pool.version:
            logger.info(
                "Session setting are from a different version of this app. I will not use those."
            )
            session_settings.clear()

        camera_is_physically_flipped = eye_id == 0
        g_pool.iconified = False
        g_pool.capture = None
        g_pool.flip = session_settings.get("flip", camera_is_physically_flipped)
        g_pool.display_mode = session_settings.get("display_mode", "camera_image")
        g_pool.display_mode_info_text = {
            "camera_image": "Raw eye camera image. This uses the least amount of CPU power",
            "roi": "Click and drag on the blue circles to adjust the region of interest. The region should be as small as possible, but large enough to capture all pupil movements.",
            "algorithm": "Algorithm display mode overlays a visualization of the pupil detection parameters on top of the eye video. Adjust parameters within the Pupil Detection menu below.",
        }

        def set_display_mode_info(val):
            g_pool.display_mode = val
            g_pool.display_mode_info.text = g_pool.display_mode_info_text[val]

        def toggle_general_settings(collapsed):
            # this is the menu toggle logic.
            # Only one menu can be open.
            # If no menu is open the menubar should collapse.
            g_pool.menubar.collapsed = collapsed
            for m in g_pool.menubar.elements:
                m.collapsed = True
            general_settings.collapsed = collapsed

        # Initialize glfw
        glfw.init()
        glfw.window_hint(glfw.SCALE_TO_MONITOR, glfw.TRUE)
        if hide_ui:
            glfw.window_hint(glfw.VISIBLE, 0)  # hide window
        title = "Pupil Capture - eye {}".format(eye_id)

        # Pupil Cam1 uses 4:3 resolutions. Pupil Cam2 and Cam3 use 1:1 resolutions.
        # As all Pupil Core and VR/AR add-ons are shipped with Pupil Cam2 and Cam3
        # cameras, we adjust the default eye window size to a 1:1 content aspect ratio.
        # The size of 500 was chosen s.t. the menu still fits.
        default_window_size = 500 + icon_bar_width, 500
        width, height = session_settings.get("window_size", default_window_size)

        main_window = glfw.create_window(width, height, title, None, None)

        window_position_manager = gl_utils.WindowPositionManager()
        window_pos = window_position_manager.new_window_position(
            window=main_window,
            default_position=window_position_default,
            previous_position=session_settings.get("window_position", None),
        )
        glfw.set_window_pos(main_window, window_pos[0], window_pos[1])

        glfw.make_context_current(main_window)
        cygl.utils.init()

        # gl_state settings
        basic_gl_setup()
        g_pool.image_tex = Named_Texture()
        g_pool.image_tex.update_from_ndarray(np.ones((1, 1), dtype=np.uint8) + 125)

        # setup GUI
        g_pool.gui = ui.UI()
        g_pool.menubar = ui.Scrolling_Menu(
            "Settings", pos=(-500, 0), size=(-icon_bar_width, 0), header_pos="left"
        )
        g_pool.iconbar = ui.Scrolling_Menu(
            "Icons", pos=(-icon_bar_width, 0), size=(0, 0), header_pos="hidden"
        )
        g_pool.gui.append(g_pool.menubar)
        g_pool.gui.append(g_pool.iconbar)

        general_settings = ui.Growing_Menu("General", header_pos="headline")

        def set_window_size():
            # Get current capture frame size
            f_width, f_height = g_pool.capture.frame_size
            # Eye camera resolutions are too small to be used as default window sizes.
            # We use double their size instead.
            frame_scale_factor = 2
            f_width *= frame_scale_factor
            f_height *= frame_scale_factor

            # Get current display scale factor
            content_scale = gl_utils.get_content_scale(main_window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(main_window)
            display_scale_factor = content_scale / framebuffer_scale

            # Scale the capture frame size by display scale factor
            f_width *= display_scale_factor
            f_height *= display_scale_factor

            # Increas the width to account for the added scaled icon bar width
            f_width += icon_bar_width * display_scale_factor

            # Set the newly calculated size (scaled capture frame size + scaled icon bar width)
            glfw.set_window_size(main_window, int(f_width), int(f_height))

        general_settings.append(ui.Button("Reset window size", set_window_size))
        general_settings.append(ui.Switch("flip", g_pool, label="Flip image display"))
        general_settings.append(
            ui.Selector(
                "display_mode",
                g_pool,
                setter=set_display_mode_info,
                selection=["camera_image", "roi", "algorithm"],
                labels=["Camera Image", "ROI", "Algorithm"],
                label="Mode",
            )
        )
        g_pool.display_mode_info = ui.Info_Text(
            g_pool.display_mode_info_text[g_pool.display_mode]
        )

        general_settings.append(g_pool.display_mode_info)

        g_pool.menubar.append(general_settings)
        icon = ui.Icon(
            "collapsed",
            general_settings,
            label=chr(0xE8B8),
            on_val=False,
            off_val=True,
            setter=toggle_general_settings,
            label_font="pupil_icons",
        )
        icon.tooltip = "General Settings"
        g_pool.iconbar.append(icon)

        plugins_to_load = session_settings.get("loaded_plugins", default_plugins)
        if overwrite_cap_settings:
            # Ensure that overwrite_cap_settings takes preference over source plugins
            # with incorrect settings that were loaded from session settings.
            plugins_to_load.append(overwrite_cap_settings)

        # Add runtime plugins to the list of plugins to load with default arguments,
        # if not already restored from session settings
        plugins_to_load_names = set(name for name, _ in plugins_to_load)
        for runtime_detector in runtime_detectors:
            runtime_name = runtime_detector.__name__
            if runtime_name not in plugins_to_load_names:
                plugins_to_load.append((runtime_name, {}))

        g_pool.plugins = Plugin_List(g_pool, plugins_to_load)

        if not g_pool.capture:
            # Make sure we always have a capture running. Important if there was no
            # capture stored in session settings.
            g_pool.plugins.add(
                g_pool.plugin_by_name[default_capture_name], default_capture_settings
            )

        toggle_general_settings(True)

        g_pool.writer = None
        g_pool.rec_path = None

        # Register callbacks main_window
        glfw.set_framebuffer_size_callback(main_window, on_resize)
        glfw.set_window_iconify_callback(main_window, on_iconify)
        glfw.set_key_callback(main_window, on_window_key)
        glfw.set_char_callback(main_window, on_window_char)
        glfw.set_mouse_button_callback(main_window, on_window_mouse_button)
        glfw.set_cursor_pos_callback(main_window, on_pos)
        glfw.set_scroll_callback(main_window, on_scroll)
        glfw.set_drop_callback(main_window, on_drop)

        # load last gui configuration
        g_pool.gui.configuration = session_settings.get("ui_config", {})
        # If previously selected plugin was not loaded this time, we will have an
        # expanded menubar without any menu selected. We need to ensure the menubar is
        # collapsed in this case.
        if all(submenu.collapsed for submenu in g_pool.menubar.elements):
            g_pool.menubar.collapsed = True

        # set up performance graphs
        pid = os.getpid()
        ps = psutil.Process(pid)
        ts = g_pool.get_timestamp()

        cpu_graph = graph.Bar_Graph()
        cpu_graph.pos = (20, 50)
        cpu_graph.update_fn = ps.cpu_percent
        cpu_graph.update_rate = 5
        cpu_graph.label = "CPU %0.1f"

        fps_graph = graph.Bar_Graph()
        fps_graph.pos = (140, 50)
        fps_graph.update_rate = 5
        fps_graph.label = "%0.0f FPS"
        g_pool.graphs = [cpu_graph, fps_graph]

        # set the last saved window size
        on_resize(main_window, *glfw.get_framebuffer_size(main_window))

        should_publish_frames = False
        frame_publish_format = "jpeg"
        frame_publish_format_recent_warning = False

        # create a timer to control window update frequency
        window_update_timer = timer(1 / 60)

        def window_should_update():
            return next(window_update_timer)

        logger.warning("Process started.")

        frame = None

        if platform.system() == "Darwin":
            # On macOS, calls to glfw.swap_buffers() deliberately take longer in case of
            # occluded windows, based on the swap interval value. This causes an FPS drop
            # and leads to problems when recording. To side-step this behaviour, the swap
            # interval is set to zero.
            #
            # Read more about window occlusion on macOS here:
            # https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/WorkWhenVisible.html
            glfw.swap_interval(0)

        # Event loop
        window_should_close = False
        while not window_should_close:

            if notify_sub.new_data:
                t, notification = notify_sub.recv()
                subject = notification["subject"]
                if subject.startswith("eye_process.should_stop"):
                    if notification["eye_id"] == eye_id:
                        break
                elif subject == "recording.started":
                    if notification["record_eye"] and g_pool.capture.online:
                        g_pool.rec_path = notification["rec_path"]
                        raw_mode = notification["compression"]
                        start_time_synced = notification["start_time_synced"]
                        logger.info(f"Will save eye video to: {g_pool.rec_path}")
                        video_path = os.path.join(
                            g_pool.rec_path, "eye{}.mp4".format(eye_id)
                        )
                        if raw_mode and frame and g_pool.capture.jpeg_support:
                            g_pool.writer = JPEG_Writer(video_path, start_time_synced)
                        elif hasattr(g_pool.capture._recent_frame, "h264_buffer"):
                            g_pool.writer = H264Writer(
                                video_path,
                                g_pool.capture.frame_size[0],
                                g_pool.capture.frame_size[1],
                                g_pool.capture.frame_rate,
                            )
                        else:
                            g_pool.writer = MPEG_Writer(video_path, start_time_synced)
                elif subject == "recording.stopped":
                    if g_pool.writer:
                        logger.info("Done recording.")
                        try:
                            g_pool.writer.release()
                        except RuntimeError:
                            logger.error("No eye video recorded")
                        else:
                            # TODO: wrap recording logic into plugin
                            g_pool.capture.intrinsics.save(
                                g_pool.rec_path, custom_name=f"eye{eye_id}"
                            )
                        finally:
                            g_pool.writer = None
                elif subject.startswith("meta.should_doc"):
                    ipc_socket.notify(
                        {
                            "subject": "meta.doc",
                            "actor": "eye{}".format(eye_id),
                            "doc": eye.__doc__,
                        }
                    )
                elif subject.startswith("frame_publishing.started"):
                    should_publish_frames = True
                    frame_publish_format = notification.get("format", "jpeg")
                elif subject.startswith("frame_publishing.stopped"):
                    should_publish_frames = False
                    frame_publish_format = "jpeg"
                elif (
                    subject.startswith("start_eye_plugin")
                    and notification["target"] == g_pool.process
                ):
                    try:
                        g_pool.plugins.add(
                            g_pool.plugin_by_name[notification["name"]],
                            notification.get("args", {}),
                        )
                    except KeyError as err:
                        logger.error(f"Attempt to load unknown plugin: {err}")
                elif (
                    subject.startswith("stop_eye_plugin")
                    and notification["target"] == g_pool.process
                ):
                    try:
                        plugin_to_stop = g_pool.plugin_by_name[notification["name"]]
                    except KeyError as err:
                        logger.error(f"Attempt to load unknown plugin: {err}")
                    else:
                        plugin_to_stop.alive = False
                        g_pool.plugins.clean()

                for plugin in g_pool.plugins:
                    plugin.on_notify(notification)

            event = {}
            for plugin in g_pool.plugins:
                plugin.recent_events(event)

            frame = event.get("frame")
            if frame:
                if should_publish_frames:
                    try:
                        if frame_publish_format == "jpeg":
                            data = frame.jpeg_buffer
                        elif frame_publish_format == "yuv":
                            data = frame.yuv_buffer
                        elif frame_publish_format == "bgr":
                            data = frame.bgr
                        elif frame_publish_format == "gray":
                            data = frame.gray
                        assert data is not None
                    except (AttributeError, AssertionError, NameError):
                        if not frame_publish_format_recent_warning:
                            frame_publish_format_recent_warning = True
                            logger.warning(
                                '{}s are not compatible with format "{}"'.format(
                                    type(frame), frame_publish_format
                                )
                            )
                    else:
                        frame_publish_format_recent_warning = False
                        pupil_socket.send(
                            {
                                "topic": "frame.eye.{}".format(eye_id),
                                "width": frame.width,
                                "height": frame.height,
                                "index": frame.index,
                                "timestamp": frame.timestamp,
                                "format": frame_publish_format,
                                "__raw_data__": [data],
                            }
                        )

                t = frame.timestamp
                dt, ts = t - ts, t
                try:
                    fps_graph.add(1.0 / dt)
                except ZeroDivisionError:
                    pass

                if g_pool.writer:
                    try:
                        g_pool.writer.write_video_frame(frame)
                    except NonMonotonicTimestampError as e:
                        logger.error(
                            "Recorder received non-monotonic timestamp!"
                            " Stopping the recording!"
                        )
                        logger.debug(str(e))
                        ipc_socket.notify({"subject": "recording.should_stop"})
                        ipc_socket.notify(
                            {"subject": "recording.should_stop", "remote_notify": "all"}
                        )

                for result in event.get(EVENT_KEY, ()):
                    pupil_socket.send(result)

            # GL drawing
            if window_should_update():
                cpu_graph.update()
                if is_window_visible(main_window):
                    consume_events_and_render_buffer()
                glfw.poll_events()
                window_should_close = glfw.window_should_close(main_window)

        # END while running

        # in case eye recording was still runnnig: Save&close
        if g_pool.writer:
            logger.info("Done recording eye.")
            g_pool.writer.release()
            g_pool.writer = None

        session_settings["loaded_plugins"] = g_pool.plugins.get_initializers()
        # save session persistent settings
        session_settings["flip"] = g_pool.flip
        session_settings["display_mode"] = g_pool.display_mode
        session_settings["ui_config"] = g_pool.gui.configuration
        session_settings["version"] = str(g_pool.version)

        if not hide_ui:
            glfw.restore_window(main_window)  # need to do this for windows os
            session_settings["window_position"] = glfw.get_window_pos(main_window)
            session_window_size = glfw.get_window_size(main_window)
            if 0 not in session_window_size:
                f_width, f_height = session_window_size
                if platform.system() in ("Windows", "Linux"):
                    # Store unscaled window size as the operating system will scale the
                    # windows appropriately during launch on Windows and Linux.
                    f_width, f_height = (
                        f_width / content_scale,
                        f_height / content_scale,
                    )
                session_settings["window_size"] = int(f_width), int(f_height)

        session_settings.close()

        for plugin in g_pool.plugins:
            plugin.alive = False
        g_pool.plugins.clean()

    glfw.destroy_window(main_window)
    g_pool.gui.terminate()
    glfw.terminate()
    logger.info("Process shutting down.")
Пример #37
0
 def window_size(self) -> T.Tuple[int, int]:
     if self.__gl_handle is not None:
         return glfw.get_framebuffer_size(self.__gl_handle)
     else:
         return (0, 0)
Пример #38
0
    def render(self):
        super(GatherViewer, self).render()
        ctx = MjRenderContext(self.env.wrapped_env.sim)
        scn = ctx.scn
        con = ctx.con
        functions.mjv_makeScene(scn, 1000)
        scn.camera[0].frustum_near = 0.05
        scn.camera[1].frustum_near = 0.05

        for obj in self.env.objects:
            x, y, typ = obj
            qpos = np.zeros_like(self.green_ball_sim.data.qpos)
            qpos[0] = x
            qpos[1] = y
            if typ == APPLE:
                self.green_ball_sim.data.qpos[:] = qpos
                self.green_ball_sim.forward()
                self.green_ball_renderer.render()
                self.green_ball_ctx = MjRenderContext(self.green_ball_sim)
                functions.mjv_addGeoms(self.green_ball_sim.model,
                                       self.green_ball_sim.data,
                                       self.green_ball_ctx.vopt,
                                       self.green_ball_ctx.pert, CAT_ALL, scn)
            else:
                self.red_ball_sim.data.qpos[:] = qpos
                self.red_ball_sim.forward()
                self.red_ball_renderer.render()
                self.red_ball_ctx = MjRenderContext(self.red_ball_sim)
                functions.mjv_addGeoms(self.red_ball_sim.model,
                                       self.red_ball_sim.data,
                                       self.red_ball_ctx.vopt,
                                       self.red_ball_ctx.pert, CAT_ALL, scn)

        functions.mjv_addGeoms(self.env.wrapped_env.sim.model,
                               self.env.wrapped_env.sim.data, ctx.vopt,
                               ctx.pert, CAT_ALL, scn)
        functions.mjr_render(self.green_ball_renderer.get_rect(), scn, con)

        try:
            import OpenGL.GL as GL
        except ImportError:
            return

        def draw_rect(x, y, width, height):
            # start drawing a rectangle
            GL.glBegin(GL.GL_QUADS)
            # bottom left point
            GL.glVertex2f(x, y)
            # bottom right point
            GL.glVertex2f(x + width, y)
            # top right point
            GL.glVertex2f(x + width, y + height)
            # top left point
            GL.glVertex2f(x, y + height)

        def refresh2d(width, height):
            GL.glViewport(0, 0, width, height)
            GL.glMatrixMode(GL.GL_PROJECTION)
            GL.glLoadIdentity()
            GL.glOrtho(0.0, width, 0.0, height, 0.0, 1.0)
            GL.glMatrixMode(GL.GL_MODELVIEW)
            GL.glLoadIdentity()

        GL.glBegin(GL.GL_QUADS)
        GL.glLoadIdentity()
        width, height = glfw.get_framebuffer_size(self.window)
        refresh2d(width, height)
        GL.glDisable(GL.GL_LIGHTING)
        GL.glEnable(GL.GL_BLEND)

        GL.glColor4f(0.0, 0.0, 0.0, 0.8)
        draw_rect(10, 10, 300, 100)

        apple_readings, bomb_readings = self.env.get_readings()
        for idx, reading in enumerate(apple_readings):
            if reading > 0:
                GL.glColor4f(0.0, 1.0, 0.0, reading)
                draw_rect(20 * (idx + 1), 10, 5, 50)
        for idx, reading in enumerate(bomb_readings):
            if reading > 0:
                GL.glColor4f(1.0, 0.0, 0.0, reading)
                draw_rect(20 * (idx + 1), 60, 5, 50)
Пример #39
0
    def open(
        self,
        gui_monitor: GUIMonitor,
        title: str,
        is_fullscreen: bool = False,
        size: T.Tuple[int, int] = None,
        position: T.Tuple[int, int] = None,
    ):
        if self.is_open:
            # TODO: Warn that the window is already open
            return

        if not gui_monitor.is_available:
            raise ValueError(f"Window requires an available monitor.")

        has_fixed_size = ((size is not None) and (len(size) == 2)
                          and (size[0] > 0) and (size[1] > 0))
        if is_fullscreen and has_fixed_size:
            raise ValueError(
                f"Fullscreen is mutually exclusive to having a fixed size.")

        if position is None:
            if platform.system() == "Windows":
                position = (8, 90)
            else:
                position = (0, 0)

        if is_fullscreen:
            size = gui_monitor.size

        # NOTE: Always creating windowed window here, even if in fullscreen mode. On
        # windows you might experience a black screen for up to 1 sec when creating
        # a blank window directly in fullscreen mode. By creating it windowed and
        # then switching to fullscreen it will stay white the entire time.
        self.__gl_handle = glfw.create_window(*size, title, None,
                                              glfw.get_current_context())

        if not is_fullscreen:
            glfw.set_window_pos(self.__gl_handle, *position)

        # Register callbacks
        glfw.set_framebuffer_size_callback(self.__gl_handle, self.on_resize)
        glfw.set_key_callback(self.__gl_handle, self.on_key)
        glfw.set_mouse_button_callback(self.__gl_handle, self.on_mouse_button)
        self.on_resize(self.__gl_handle,
                       *glfw.get_framebuffer_size(self.__gl_handle))

        # gl_state settings
        with self._switch_to_current_context():
            gl_utils.basic_gl_setup()
            glfw.swap_interval(0)

        if is_fullscreen:
            # Switch to full screen here. See NOTE above at glfw.create_window().
            glfw.set_window_monitor(
                self.__gl_handle,
                gui_monitor.unsafe_handle,
                0,
                0,
                *gui_monitor.size,
                gui_monitor.refresh_rate,
            )
Пример #40
0
def player(rec_dir, ipc_pub_url, ipc_sub_url, ipc_push_url, user_dir,
           app_version, debug):
    # general imports
    from time import sleep
    import logging
    from glob import glob
    from time import time, strftime, localtime

    # networking
    import zmq
    import zmq_tools

    import numpy as np

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)
    notify_sub = zmq_tools.Msg_Receiver(zmq_ctx,
                                        ipc_sub_url,
                                        topics=("notify", ))

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.NOTSET)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    try:
        from background_helper import IPC_Logging_Task_Proxy

        IPC_Logging_Task_Proxy.push_url = ipc_push_url

        from tasklib.background.patches import IPCLoggingPatch

        IPCLoggingPatch.ipc_push_url = ipc_push_url

        # imports
        from file_methods import Persistent_Dict, next_export_sub_dir

        from OpenGL.GL import GL_COLOR_BUFFER_BIT

        # display
        import glfw
        from gl_utils import GLFWErrorReporting

        GLFWErrorReporting.set_default()

        # check versions for our own depedencies as they are fast-changing
        from pyglui import __version__ as pyglui_version

        from pyglui import ui, cygl
        from pyglui.cygl.utils import Named_Texture, RGBA
        import gl_utils

        # capture
        from video_capture import File_Source

        # helpers/utils
        from version_utils import parse_version
        from methods import normalize, denormalize, delta_t, get_system_info
        import player_methods as pm
        from pupil_recording import PupilRecording
        from csv_utils import write_key_value_file
        from hotkey import Hotkey

        # Plug-ins
        from plugin import Plugin, Plugin_List, import_runtime_plugins
        from plugin_manager import Plugin_Manager
        from vis_circle import Vis_Circle
        from vis_cross import Vis_Cross
        from vis_polyline import Vis_Polyline
        from vis_light_points import Vis_Light_Points
        from vis_watermark import Vis_Watermark
        from vis_fixation import Vis_Fixation

        from seek_control import Seek_Control
        from surface_tracker import Surface_Tracker_Offline

        # from marker_auto_trim_marks import Marker_Auto_Trim_Marks
        from fixation_detector import Offline_Fixation_Detector
        from log_display import Log_Display
        from annotations import Annotation_Player
        from raw_data_exporter import Raw_Data_Exporter
        from log_history import Log_History
        from pupil_producers import (
            DisabledPupilProducer,
            Pupil_From_Recording,
            Offline_Pupil_Detection,
        )
        from gaze_producer.gaze_from_recording import GazeFromRecording
        from gaze_producer.gaze_from_offline_calibration import (
            GazeFromOfflineCalibration, )
        from pupil_detector_plugins.detector_base_plugin import PupilDetectorPlugin
        from system_graphs import System_Graphs
        from system_timelines import System_Timelines
        from blink_detection import Offline_Blink_Detection
        from audio_playback import Audio_Playback
        from video_export.plugins.imotions_exporter import iMotions_Exporter
        from video_export.plugins.eye_video_exporter import Eye_Video_Exporter
        from video_export.plugins.world_video_exporter import World_Video_Exporter
        from head_pose_tracker.offline_head_pose_tracker import (
            Offline_Head_Pose_Tracker, )
        from video_capture import File_Source
        from video_overlay.plugins import Video_Overlay, Eye_Overlay

        from pupil_recording import (
            assert_valid_recording_type,
            InvalidRecordingException,
        )

        assert parse_version(pyglui_version) >= parse_version(
            "1.29"), "pyglui out of date, please upgrade to newest version"

        process_was_interrupted = False

        def interrupt_handler(sig, frame):
            import traceback

            trace = traceback.format_stack(f=frame)
            logger.debug(f"Caught signal {sig} in:\n" + "".join(trace))
            nonlocal process_was_interrupted
            process_was_interrupted = True

        signal.signal(signal.SIGINT, interrupt_handler)

        runtime_plugins = import_runtime_plugins(
            os.path.join(user_dir, "plugins"))
        runtime_plugins = [
            p for p in runtime_plugins
            if not issubclass(p, PupilDetectorPlugin)
        ]
        system_plugins = [
            Log_Display,
            Seek_Control,
            Plugin_Manager,
            System_Graphs,
            System_Timelines,
            Audio_Playback,
        ]
        user_plugins = [
            Vis_Circle,
            Vis_Fixation,
            Vis_Polyline,
            Vis_Light_Points,
            Vis_Cross,
            Vis_Watermark,
            Eye_Overlay,
            Video_Overlay,
            Offline_Fixation_Detector,
            Offline_Blink_Detection,
            Surface_Tracker_Offline,
            Raw_Data_Exporter,
            Annotation_Player,
            Log_History,
            DisabledPupilProducer,
            Pupil_From_Recording,
            Offline_Pupil_Detection,
            GazeFromRecording,
            GazeFromOfflineCalibration,
            World_Video_Exporter,
            iMotions_Exporter,
            Eye_Video_Exporter,
            Offline_Head_Pose_Tracker,
        ] + runtime_plugins

        plugins = system_plugins + user_plugins

        def consume_events_and_render_buffer():
            gl_utils.glViewport(0, 0, *g_pool.camera_render_size)
            g_pool.capture.gl_display()
            for p in g_pool.plugins:
                p.gl_display()

            gl_utils.glViewport(0, 0, *window_size)

            try:
                clipboard = glfw.get_clipboard_string(main_window).decode()
            except (AttributeError, glfw.GLFWError):
                # clipbaord is None, might happen on startup
                clipboard = ""
            g_pool.gui.update_clipboard(clipboard)
            user_input = g_pool.gui.update()
            if user_input.clipboard and user_input.clipboard != clipboard:
                # only write to clipboard if content changed
                glfw.set_clipboard_string(main_window, user_input.clipboard)

            for b in user_input.buttons:
                button, action, mods = b
                x, y = glfw.get_cursor_pos(main_window)
                pos = gl_utils.window_coordinate_to_framebuffer_coordinate(
                    main_window, x, y, cached_scale=None)
                pos = normalize(pos, g_pool.camera_render_size)
                pos = denormalize(pos, g_pool.capture.frame_size)

                for plugin in g_pool.plugins:
                    if plugin.on_click(pos, button, action):
                        break

            for key, scancode, action, mods in user_input.keys:
                for plugin in g_pool.plugins:
                    if plugin.on_key(key, scancode, action, mods):
                        break

            for char_ in user_input.chars:
                for plugin in g_pool.plugins:
                    if plugin.on_char(char_):
                        break

            glfw.swap_buffers(main_window)

        # Callback functions
        def on_resize(window, w, h):
            nonlocal window_size
            nonlocal content_scale
            if w == 0 or h == 0:
                return

            # Always clear buffers on resize to make sure that there are no overlapping
            # artifacts from previous frames.
            gl_utils.glClear(GL_COLOR_BUFFER_BIT)
            gl_utils.glClearColor(0, 0, 0, 1)

            content_scale = gl_utils.get_content_scale(window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(window)
            g_pool.gui.scale = content_scale
            window_size = w, h
            g_pool.camera_render_size = w - int(
                icon_bar_width * g_pool.gui.scale), h
            g_pool.gui.update_window(*window_size)
            g_pool.gui.collect_menus()
            for p in g_pool.plugins:
                p.on_window_resize(window, *g_pool.camera_render_size)

            # Minimum window size required, otherwise parts of the UI can cause openGL
            # issues with permanent effects. Depends on the content scale, which can
            # potentially be dynamically modified, so we re-adjust the size limits every
            # time here.
            min_size = int(2 * icon_bar_width * g_pool.gui.scale /
                           framebuffer_scale)
            glfw.set_window_size_limits(
                window,
                min_size,
                min_size,
                glfw.DONT_CARE,
                glfw.DONT_CARE,
            )

            # Needed, to update the window buffer while resizing
            consume_events_and_render_buffer()

        def on_window_key(window, key, scancode, action, mods):
            g_pool.gui.update_key(key, scancode, action, mods)

        def on_window_char(window, char):
            g_pool.gui.update_char(char)

        def on_window_mouse_button(window, button, action, mods):
            g_pool.gui.update_button(button, action, mods)

        def on_pos(window, x, y):
            x, y = gl_utils.window_coordinate_to_framebuffer_coordinate(
                window, x, y, cached_scale=None)
            g_pool.gui.update_mouse(x, y)
            pos = x, y
            pos = normalize(pos, g_pool.camera_render_size)
            # Position in img pixels
            pos = denormalize(pos, g_pool.capture.frame_size)
            for p in g_pool.plugins:
                p.on_pos(pos)

        def on_scroll(window, x, y):
            g_pool.gui.update_scroll(x, y * scroll_factor)

        def on_drop(window, paths):
            for path in paths:
                try:
                    assert_valid_recording_type(path)
                    _restart_with_recording(path)
                    return
                except InvalidRecordingException as err:
                    logger.debug(str(err))

            for plugin in g_pool.plugins:
                if plugin.on_drop(paths):
                    break

        def _restart_with_recording(rec_dir):
            logger.debug("Starting new session with '{}'".format(rec_dir))
            ipc_pub.notify({
                "subject": "player_drop_process.should_start",
                "rec_dir": rec_dir
            })
            glfw.set_window_should_close(g_pool.main_window, True)

        tick = delta_t()

        def get_dt():
            return next(tick)

        recording = PupilRecording(rec_dir)
        meta_info = recording.meta_info

        # log info about Pupil Platform and Platform in player.log
        logger.info("Application Version: {}".format(app_version))
        logger.info("System Info: {}".format(get_system_info()))
        logger.debug(f"Debug flag: {debug}")

        icon_bar_width = 50
        window_size = None
        content_scale = 1.0

        # create container for globally scoped vars
        g_pool = SimpleNamespace()
        g_pool.app = "player"
        g_pool.process = "player"
        g_pool.zmq_ctx = zmq_ctx
        g_pool.ipc_pub = ipc_pub
        g_pool.ipc_pub_url = ipc_pub_url
        g_pool.ipc_sub_url = ipc_sub_url
        g_pool.ipc_push_url = ipc_push_url
        g_pool.plugin_by_name = {p.__name__: p for p in plugins}
        g_pool.camera_render_size = None

        video_path = recording.files().core().world().videos()[0].resolve()
        File_Source(
            g_pool,
            timing="external",
            source_path=video_path,
            buffered_decoding=True,
            fill_gaps=True,
        )

        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(user_dir, "user_settings_player"))
        if parse_version(session_settings.get("version",
                                              "0.0")) != app_version:
            logger.info(
                "Session setting are a different version of this app. I will not use those."
            )
            session_settings.clear()

        width, height = g_pool.capture.frame_size
        width += icon_bar_width
        width, height = session_settings.get("window_size", (width, height))

        window_name = f"Pupil Player: {meta_info.recording_name} - {rec_dir}"

        glfw.init()
        glfw.window_hint(glfw.SCALE_TO_MONITOR, glfw.TRUE)
        main_window = glfw.create_window(width, height, window_name, None,
                                         None)
        window_position_manager = gl_utils.WindowPositionManager()
        window_pos = window_position_manager.new_window_position(
            window=main_window,
            default_position=window_position_default,
            previous_position=session_settings.get("window_position", None),
        )
        glfw.set_window_pos(main_window, window_pos[0], window_pos[1])

        glfw.make_context_current(main_window)
        cygl.utils.init()
        g_pool.main_window = main_window

        g_pool.version = app_version
        g_pool.timestamps = g_pool.capture.timestamps
        g_pool.get_timestamp = lambda: 0.0
        g_pool.user_dir = user_dir
        g_pool.rec_dir = rec_dir
        g_pool.meta_info = meta_info
        g_pool.min_data_confidence = session_settings.get(
            "min_data_confidence", MIN_DATA_CONFIDENCE_DEFAULT)
        g_pool.min_calibration_confidence = session_settings.get(
            "min_calibration_confidence", MIN_CALIBRATION_CONFIDENCE_DEFAULT)

        # populated by producers
        g_pool.pupil_positions = pm.PupilDataBisector()
        g_pool.gaze_positions = pm.Bisector()
        g_pool.fixations = pm.Affiliator()
        g_pool.eye_movements = pm.Affiliator()

        def set_data_confidence(new_confidence):
            g_pool.min_data_confidence = new_confidence
            notification = {"subject": "min_data_confidence_changed"}
            notification["_notify_time_"] = time() + 0.8
            g_pool.ipc_pub.notify(notification)

        def do_export(_):
            left_idx = g_pool.seek_control.trim_left
            right_idx = g_pool.seek_control.trim_right
            export_range = left_idx, right_idx + 1  # exclusive range.stop
            export_ts_window = pm.exact_window(g_pool.timestamps,
                                               (left_idx, right_idx))

            export_dir = os.path.join(g_pool.rec_dir, "exports")
            export_dir = next_export_sub_dir(export_dir)

            os.makedirs(export_dir)
            logger.info('Created export dir at "{}"'.format(export_dir))

            export_info = {
                "Player Software Version":
                str(g_pool.version),
                "Data Format Version":
                meta_info.min_player_version,
                "Export Date":
                strftime("%d.%m.%Y", localtime()),
                "Export Time":
                strftime("%H:%M:%S", localtime()),
                "Frame Index Range:":
                g_pool.seek_control.get_frame_index_trim_range_string(),
                "Relative Time Range":
                g_pool.seek_control.get_rel_time_trim_range_string(),
                "Absolute Time Range":
                g_pool.seek_control.get_abs_time_trim_range_string(),
            }
            with open(os.path.join(export_dir, "export_info.csv"), "w") as csv:
                write_key_value_file(csv, export_info)

            notification = {
                "subject": "should_export",
                "range": export_range,
                "ts_window": export_ts_window,
                "export_dir": export_dir,
            }
            g_pool.ipc_pub.notify(notification)

        def reset_restart():
            logger.warning("Resetting all settings and restarting Player.")
            glfw.set_window_should_close(main_window, True)
            ipc_pub.notify({"subject": "clear_settings_process.should_start"})
            ipc_pub.notify({
                "subject": "player_process.should_start",
                "rec_dir": rec_dir,
                "delay": 2.0,
            })

        def toggle_general_settings(collapsed):
            # this is the menu toggle logic.
            # Only one menu can be open.
            # If no menu is open the menubar should collapse.
            g_pool.menubar.collapsed = collapsed
            for m in g_pool.menubar.elements:
                m.collapsed = True
            general_settings.collapsed = collapsed

        g_pool.gui = ui.UI()
        g_pool.menubar = ui.Scrolling_Menu("Settings",
                                           pos=(-500, 0),
                                           size=(-icon_bar_width, 0),
                                           header_pos="left")
        g_pool.iconbar = ui.Scrolling_Menu("Icons",
                                           pos=(-icon_bar_width, 0),
                                           size=(0, 0),
                                           header_pos="hidden")
        g_pool.timelines = ui.Container((0, 0), (0, 0), (0, 0))
        g_pool.timelines.horizontal_constraint = g_pool.menubar
        g_pool.user_timelines = ui.Timeline_Menu("User Timelines",
                                                 pos=(0.0, -150.0),
                                                 size=(0.0, 0.0),
                                                 header_pos="headline")
        g_pool.user_timelines.color = RGBA(a=0.0)
        g_pool.user_timelines.collapsed = True
        # add container that constaints itself to the seekbar height
        vert_constr = ui.Container((0, 0), (0, -50.0), (0, 0))
        vert_constr.append(g_pool.user_timelines)
        g_pool.timelines.append(vert_constr)

        def set_window_size():
            # Get current capture frame size
            f_width, f_height = g_pool.capture.frame_size

            # Get current display scale factor
            content_scale = gl_utils.get_content_scale(main_window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(main_window)
            display_scale_factor = content_scale / framebuffer_scale

            # Scale the capture frame size by display scale factor
            f_width *= display_scale_factor
            f_height *= display_scale_factor

            # Increas the width to account for the added scaled icon bar width
            f_width += icon_bar_width * display_scale_factor

            # Set the newly calculated size (scaled capture frame size + scaled icon bar width)
            glfw.set_window_size(main_window, int(f_width), int(f_height))

        general_settings = ui.Growing_Menu("General", header_pos="headline")
        general_settings.append(ui.Button("Reset window size",
                                          set_window_size))
        general_settings.append(
            ui.Info_Text(
                f"Minimum Player Version: {meta_info.min_player_version}"))
        general_settings.append(
            ui.Info_Text(f"Player Version: {g_pool.version}"))
        general_settings.append(
            ui.Info_Text(
                f"Recording Software: {meta_info.recording_software_name}"))
        general_settings.append(
            ui.Info_Text(
                f"Recording Software Version: {meta_info.recording_software_version}"
            ))

        general_settings.append(
            ui.Info_Text(
                "High level data, e.g. fixations, or visualizations only consider gaze data that has an equal or higher confidence than the minimum data confidence."
            ))
        general_settings.append(
            ui.Slider(
                "min_data_confidence",
                g_pool,
                setter=set_data_confidence,
                step=0.05,
                min=0.0,
                max=1.0,
                label="Minimum data confidence",
            ))

        general_settings.append(
            ui.Button("Restart with default settings", reset_restart))

        g_pool.menubar.append(general_settings)
        icon = ui.Icon(
            "collapsed",
            general_settings,
            label=chr(0xE8B8),
            on_val=False,
            off_val=True,
            setter=toggle_general_settings,
            label_font="pupil_icons",
        )
        icon.tooltip = "General Settings"
        g_pool.iconbar.append(icon)

        user_plugin_separator = ui.Separator()
        user_plugin_separator.order = 0.35
        g_pool.iconbar.append(user_plugin_separator)

        g_pool.quickbar = ui.Stretching_Menu("Quick Bar", (0, 100),
                                             (100, -100))
        g_pool.export_button = ui.Thumb(
            "export",
            label=chr(0xE2C5),
            getter=lambda: False,
            setter=do_export,
            hotkey=Hotkey.EXPORT_START_PLAYER_HOTKEY(),
            label_font="pupil_icons",
        )
        g_pool.quickbar.extend([g_pool.export_button])
        g_pool.gui.append(g_pool.menubar)
        g_pool.gui.append(g_pool.timelines)
        g_pool.gui.append(g_pool.iconbar)
        g_pool.gui.append(g_pool.quickbar)

        # we always load these plugins
        _pupil_producer_plugins = [
            # In priority order (first is default)
            ("Pupil_From_Recording", {}),
            ("Offline_Pupil_Detection", {}),
            ("DisabledPupilProducer", {}),
        ]
        _pupil_producer_plugins = list(reversed(_pupil_producer_plugins))
        _gaze_producer_plugins = [
            # In priority order (first is default)
            ("GazeFromRecording", {}),
            ("GazeFromOfflineCalibration", {}),
        ]
        _gaze_producer_plugins = list(reversed(_gaze_producer_plugins))
        default_plugins = [
            ("Plugin_Manager", {}),
            ("Seek_Control", {}),
            ("Log_Display", {}),
            ("Raw_Data_Exporter", {}),
            ("Vis_Polyline", {}),
            ("Vis_Circle", {}),
            ("System_Graphs", {}),
            ("System_Timelines", {}),
            ("World_Video_Exporter", {}),
            *_pupil_producer_plugins,
            *_gaze_producer_plugins,
            ("Audio_Playback", {}),
        ]
        _plugins_to_load = session_settings.get("loaded_plugins", None)
        if _plugins_to_load is None:
            # If no plugins are available from a previous session,
            # then use the default plugin list
            _plugins_to_load = default_plugins
        else:
            # If there are plugins available from a previous session,
            # then prepend plugins that are required, but might have not been available before
            _plugins_to_load = [
                *_pupil_producer_plugins,
                *_gaze_producer_plugins,
                *_plugins_to_load,
            ]

        g_pool.plugins = Plugin_List(g_pool, _plugins_to_load)

        # Manually add g_pool.capture to the plugin list
        g_pool.plugins._plugins.append(g_pool.capture)
        g_pool.plugins._plugins.sort(key=lambda p: p.order)
        g_pool.capture.init_ui()

        general_settings.insert(
            -1,
            ui.Text_Input(
                "rel_time_trim_section",
                getter=g_pool.seek_control.get_rel_time_trim_range_string,
                setter=g_pool.seek_control.set_rel_time_trim_range_string,
                label="Relative time range to export",
            ),
        )
        general_settings.insert(
            -1,
            ui.Text_Input(
                "frame_idx_trim_section",
                getter=g_pool.seek_control.get_frame_index_trim_range_string,
                setter=g_pool.seek_control.set_frame_index_trim_range_string,
                label="Frame index range to export",
            ),
        )

        # Register callbacks main_window
        glfw.set_framebuffer_size_callback(main_window, on_resize)
        glfw.set_key_callback(main_window, on_window_key)
        glfw.set_char_callback(main_window, on_window_char)
        glfw.set_mouse_button_callback(main_window, on_window_mouse_button)
        glfw.set_cursor_pos_callback(main_window, on_pos)
        glfw.set_scroll_callback(main_window, on_scroll)
        glfw.set_drop_callback(main_window, on_drop)

        toggle_general_settings(True)

        g_pool.gui.configuration = session_settings.get("ui_config", {})
        # If previously selected plugin was not loaded this time, we will have an
        # expanded menubar without any menu selected. We need to ensure the menubar is
        # collapsed in this case.
        if all(submenu.collapsed for submenu in g_pool.menubar.elements):
            g_pool.menubar.collapsed = True

        # gl_state settings
        gl_utils.basic_gl_setup()
        g_pool.image_tex = Named_Texture()

        # trigger on_resize
        on_resize(main_window, *glfw.get_framebuffer_size(main_window))

        def handle_notifications(n):
            subject = n["subject"]
            if subject == "start_plugin":
                g_pool.plugins.add(g_pool.plugin_by_name[n["name"]],
                                   args=n.get("args", {}))
            elif subject.startswith("meta.should_doc"):
                ipc_pub.notify({
                    "subject": "meta.doc",
                    "actor": g_pool.app,
                    "doc": player.__doc__
                })
                for p in g_pool.plugins:
                    if (p.on_notify.__doc__
                            and p.__class__.on_notify != Plugin.on_notify):
                        ipc_pub.notify({
                            "subject": "meta.doc",
                            "actor": p.class_name,
                            "doc": p.on_notify.__doc__,
                        })

        while not glfw.window_should_close(
                main_window) and not process_was_interrupted:

            # fetch newest notifications
            new_notifications = []
            while notify_sub.new_data:
                t, n = notify_sub.recv()
                new_notifications.append(n)

            # notify each plugin if there are new notifications:
            for n in new_notifications:
                handle_notifications(n)
                for p in g_pool.plugins:
                    p.on_notify(n)

            events = {}
            # report time between now and the last loop interation
            events["dt"] = get_dt()

            # pupil and gaze positions are added by their respective producer plugins
            events["pupil"] = []
            events["gaze"] = []

            # allow each Plugin to do its work.
            for p in g_pool.plugins:
                p.recent_events(events)

            # check if a plugin need to be destroyed
            g_pool.plugins.clean()

            glfw.make_context_current(main_window)
            glfw.poll_events()
            # render visual feedback from loaded plugins
            if gl_utils.is_window_visible(main_window):

                gl_utils.glViewport(0, 0, *g_pool.camera_render_size)
                g_pool.capture.gl_display()
                for p in g_pool.plugins:
                    p.gl_display()

                gl_utils.glViewport(0, 0, *window_size)

                try:
                    clipboard = glfw.get_clipboard_string(main_window).decode()
                except (AttributeError, glfw.GLFWError):
                    # clipbaord is None, might happen on startup
                    clipboard = ""
                g_pool.gui.update_clipboard(clipboard)
                user_input = g_pool.gui.update()
                if user_input.clipboard and user_input.clipboard != clipboard:
                    # only write to clipboard if content changed
                    glfw.set_clipboard_string(main_window,
                                              user_input.clipboard)

                for b in user_input.buttons:
                    button, action, mods = b
                    x, y = glfw.get_cursor_pos(main_window)
                    pos = gl_utils.window_coordinate_to_framebuffer_coordinate(
                        main_window, x, y, cached_scale=None)
                    pos = normalize(pos, g_pool.camera_render_size)
                    pos = denormalize(pos, g_pool.capture.frame_size)

                    for plugin in g_pool.plugins:
                        if plugin.on_click(pos, button, action):
                            break

                for key, scancode, action, mods in user_input.keys:
                    for plugin in g_pool.plugins:
                        if plugin.on_key(key, scancode, action, mods):
                            break

                for char_ in user_input.chars:
                    for plugin in g_pool.plugins:
                        if plugin.on_char(char_):
                            break

                # present frames at appropriate speed
                g_pool.seek_control.wait(events["frame"].timestamp)
                glfw.swap_buffers(main_window)

        session_settings["loaded_plugins"] = g_pool.plugins.get_initializers()
        session_settings["min_data_confidence"] = g_pool.min_data_confidence
        session_settings[
            "min_calibration_confidence"] = g_pool.min_calibration_confidence
        session_settings["ui_config"] = g_pool.gui.configuration
        session_settings["window_position"] = glfw.get_window_pos(main_window)
        session_settings["version"] = str(g_pool.version)

        session_window_size = glfw.get_window_size(main_window)
        if 0 not in session_window_size:
            f_width, f_height = session_window_size
            if platform.system() in ("Windows", "Linux"):
                f_width, f_height = (
                    f_width / content_scale,
                    f_height / content_scale,
                )
            session_settings["window_size"] = int(f_width), int(f_height)

        session_settings.close()

        # de-init all running plugins
        for p in g_pool.plugins:
            p.alive = False
        g_pool.plugins.clean()

        g_pool.gui.terminate()
        glfw.destroy_window(main_window)

    except Exception:
        import traceback

        trace = traceback.format_exc()
        logger.error("Process Player crashed with trace:\n{}".format(trace))
    finally:
        logger.info("Process shutting down.")
        ipc_pub.notify({"subject": "player_process.stopped"})
        sleep(1.0)
Пример #41
0
        sys.exit()

    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(500, 500, "Scene 1", None, None)
    if not window:
        glfw.terminate()
        sys.exit()

    # Make the window's context current
    glfw.make_context_current(window)

    # Get window size
    width, height = glfw.get_framebuffer_size(window)

    def on_resize(window, width, height):
        gui.setWindowHeight(height)
        gui.setWindowWidth(width)
        pass

    # Install a window size handler
    glfw.set_window_size_callback(window, on_resize)

    def on_mouse(window, button, action, mods):
        pass

    glfw.set_mouse_button_callback(window, on_mouse)

    old_time = time.time()
Пример #42
0
def runProgram(title,
               startWidth,
               startHeight,
               renderFrame,
               initResources=None,
               drawUi=None,
               update=None):
    global g_simpleShader
    global g_vertexArrayObject
    global g_vertexDataBuffer
    global g_mousePos
    global g_coordinateSystemModel
    global g_numMsaaSamples
    global g_currentMsaaSamples

    if not glfw.init():
        sys.exit(1)

    window, impl = initGlFwAndResources(title, startWidth, startHeight,
                                        initResources)

    currentTime = glfw.get_time()
    prevMouseX, prevMouseY = glfw.get_cursor_pos(window)

    while not glfw.window_should_close(window):
        prevTime = currentTime
        currentTime = glfw.get_time()
        dt = currentTime - prevTime

        keyStateMap = {}
        for name, id in g_glfwKeymap.items():
            keyStateMap[name] = glfw.get_key(window, id) == glfw.PRESS

        for name, id in g_glfwMouseMap.items():
            keyStateMap[name] = glfw.get_mouse_button(window, id) == glfw.PRESS

        mouseX, mouseY = glfw.get_cursor_pos(window)
        g_mousePos = [mouseX, mouseY]

        # Udpate 'game logic'
        if update:
            imIo = imgui.get_io()
            mouseDelta = [mouseX - prevMouseX, mouseY - prevMouseY]
            if imIo.want_capture_mouse:
                mouseDelta = [0, 0]
            update(dt, keyStateMap, mouseDelta)
        prevMouseX, prevMouseY = mouseX, mouseY

        width, height = glfw.get_framebuffer_size(window)

        imgui.new_frame()

        imgui.set_next_window_position(5.0, 5.0)
        imgui.set_next_window_size(400.0, 620.0, imgui.FIRST_USE_EVER)
        imgui.begin("UI", 0)

        if drawUi:
            drawUi(width, height)

        drawWidth = width
        uiWidth = 0

        drawWidth -= uiWidth

        renderFrame(uiWidth, drawWidth, height)

        #drawCoordinateSystem()

        #mgui.show_test_window()

        imgui.end()

        imgui.render()
        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()
        impl.process_inputs()

    glfw.terminate()
Пример #43
0
    def __init__(self, win, *args, **kwargs):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        Parameters
        ----------
        win : psychopy.visual.Window instance
            PsychoPy Window (usually not fully created yet).
        share : psychopy.visual.Window instance
            PsychoPy Window to share a context with
        bpc : array_like
            Bits per color (R, G, B).
        refreshHz : int
            Refresh rate in Hertz.
        depthBits : int,
            Framebuffer (back buffer) depth bits.
        stencilBits : int
            Framebuffer (back buffer) stencil bits.
        swapInterval : int
            Screen updates before swapping buffers.
        winTitle : str
            Optional window title string.
        *args
            Additional position arguments.
        **kwargs
            Additional keyword arguments.

        """
        BaseBackend.__init__(self, win)

        # window to share a context with
        share_win = kwargs.get('share', None)
        if share_win is not None:
            if share_win.winType == 'glfw':
                share_context = share_win.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.'
                )
                share_context = None
        else:
            share_context = None

        if sys.platform == 'darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        win.bpc = kwargs.get('bpc', (8, 8, 8))  # nearly all displays use 8 bpc
        win.refreshHz = int(kwargs.get('refreshHz', 60))
        win.depthBits = int(kwargs.get('depthBits', 8))
        win.stencilBits = int(kwargs.get('stencilBits', 8))

        # TODO - make waitBlanking set this too, independent right now
        win.swapInterval = int(kwargs.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        this_screen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        vidmode_is_supported = False
        for vidmode in glfw.get_video_modes(this_screen):
            _size, _bpc, _hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                has_size = _size == tuple(win.size)
                has_hz = _hz == win.refreshHz
            else:
                has_size = has_hz = True
            has_bpc = _bpc == tuple(win.bpc)
            if has_size and has_bpc and has_hz:
                vidmode_is_supported = True
                break

        _size, _bpc, _hz = glfw.get_video_mode(this_screen)
        if not vidmode_is_supported:
            # the requested video mode is not supported, use current
            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))
            logging.warning(
                ("Overriding user video settings: size {} -> {}, bpc {} -> "
                 "{}, refreshHz {} -> {}".format(tuple(win.size), _size,
                                                 tuple(win.bpc), _bpc,
                                                 win.refreshHz, _hz)))
            # change the window settings
            win.bpc = _bpc
            win.refreshHz = _hz
            win.size = _size

        if win._isFullScr:
            use_display = this_screen
        else:
            use_display = None

        # configure stereo
        use_stereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                use_stereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaa_samples = 0
        if win.multiSample:
            max_samples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, max_samples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > max_samples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaa_samples = win.numSamples
        win.multiSample = msaa_samples > 0

        # disable stencil buffer
        if win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, use_stereo)
        glfw.window_hint(glfw.SAMPLES, msaa_samples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window title
        title_text = str(kwargs.get('winTitle', "PsychoPy (GLFW)"))

        # create the window
        self.winHandle = glfw.create_window(width=win.size[0],
                                            height=win.size[1],
                                            title=title_text,
                                            monitor=use_display,
                                            share=share_context)

        # set the window icon
        glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the window size to the framebuffer size
        win.size = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle,
                                       event._onGLFWMouseButton)
        glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # enable vsync, GLFW has additional setting for this that might be
        # useful.
        glfw.swap_interval(win.swapInterval)

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)

        #glfw.set_window_size_callback(self.winHandle, _onResize)
        #self.winHandle.on_resize = _onResize  # avoid circular reference

        # TODO - handle window resizing

        # Set the position of the window if not fullscreen.
        if not win.pos:
            # work out where the centre should be
            win.pos = [(_size[0] - win.size[0]) / 2.0,
                       (_size[1] - win.size[1]) / 2.0]
        if not win._isFullScr:
            # get the virtual position of the monitor, apply offset to pos
            _px, _py = glfw.get_monitor_pos(this_screen)
            glfw.set_window_pos(self.winHandle, int(win.pos[0] + _px),
                                int(win.pos[1] + _py))
Пример #44
0
    def __init__(
        self,
        module,
        width,
        height,
        caption,
        scale,
        palette,
        fps,
        border_width,
        border_color,
    ):
        if glfw.get_version() < tuple(map(int, GLFW_VERSION.split("."))):
            raise RuntimeError(
                "glfw version is lower than {}".format(GLFW_VERSION))

        if width > APP_SCREEN_MAX_SIZE or height > APP_SCREEN_MAX_SIZE:
            raise ValueError("screen size is larger than {}x{}".format(
                APP_SCREEN_MAX_SIZE, APP_SCREEN_MAX_SIZE))

        self._module = module
        self._palette = palette[:]
        self._pil_palette = self._get_pil_palette(palette)
        self._fps = fps
        self._border_width = border_width
        self._border_color = border_color
        self._next_update_time = 0
        self._one_frame_time = 1 / fps
        self._key_state = {}
        self._update = None
        self._draw = None
        self._capture_start = 0
        self._capture_index = 0
        self._capture_images = [None] * APP_GIF_CAPTURE_COUNT

        self._perf_monitor_is_enabled = False
        self._perf_fps_count = 0
        self._perf_fps_start_time = 0
        self._perf_fps = 0
        self._perf_update_count = 0
        self._perf_update_total_time = 0
        self._perf_update_time = 0
        self._perf_draw_count = 0
        self._perf_draw_total_time = 0
        self._perf_draw_time = 0

        module.width = width
        module.height = height
        module.mouse_x = 0
        module.mouse_y = 0
        module.frame_count = 0

        # initialize window
        if not glfw.init():
            exit()

        monitor = glfw.get_primary_monitor()
        display_width, display_height = glfw.get_video_mode(monitor)[0]

        if scale == 0:
            scale = max(
                min(
                    (display_width // width) - APP_SCREEN_SCALE_CUTDOWN,
                    (display_height // height) - APP_SCREEN_SCALE_CUTDOWN,
                ),
                APP_SCREEN_SCALE_MINIMUM,
            )

        window_width = width * scale + border_width
        window_height = height * scale + border_width
        self._window = glfw.create_window(window_width, window_height, caption,
                                          None, None)

        if not self._window:
            glfw.terminate()
            exit()

        glfw.set_window_pos(
            self._window,
            (display_width - window_width) // 2,
            (display_height - window_height) // 2,
        )

        glfw.make_context_current(self._window)
        glfw.set_window_size_limits(self._window, width, height,
                                    glfw.DONT_CARE, glfw.DONT_CARE)
        self._hidpi_scale = (glfw.get_framebuffer_size(self._window)[0] /
                             glfw.get_window_size(self._window)[0])
        self._update_viewport()

        glfw.set_key_callback(self._window, self._key_callback)
        glfw.set_cursor_pos_callback(self._window, self._cursor_pos_callback)
        glfw.set_mouse_button_callback(self._window,
                                       self._mouse_button_callback)

        glfw.set_window_icon(self._window, 1, [self._get_icon_image()])

        # initialize renderer
        self._renderer = Renderer(width, height)

        # initialize audio player
        self._audio_player = AudioPlayer()

        # export module functions
        module.btn = self.btn
        module.btnp = self.btnp
        module.btnr = self.btnr
        module.run = self.run
        module.run_with_profiler = self.run_with_profiler
        module.quit = self.quit
        module.save = self.save
        module.load = self.load
        module.image = self._renderer.image
        module.tilemap = self._renderer.tilemap
        module.clip = self._renderer.draw_command.clip
        module.pal = self._renderer.draw_command.pal
        module.cls = self._renderer.draw_command.cls
        module.pix = self._renderer.draw_command.pix
        module.line = self._renderer.draw_command.line
        module.rect = self._renderer.draw_command.rect
        module.rectb = self._renderer.draw_command.rectb
        module.circ = self._renderer.draw_command.circ
        module.circb = self._renderer.draw_command.circb
        module.blt = self._renderer.draw_command.blt
        module.bltm = self._renderer.draw_command.bltm
        module.text = self._renderer.draw_command.text
        module.sound = self._audio_player.sound
        module.play = self._audio_player.play
        # module.playm = self._audio_player.playm
        module.stop = self._audio_player.stop
Пример #45
0
    def __init__(self):
        if not glfw.init():
            return

        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)

        window = glfw.create_window(self.WIDTH, self.HEIGHT, self.TITLE, None, None)
        glfw.set_window_size_limits(window, 320, 480, glfw.DONT_CARE, glfw.DONT_CARE)
        if not window:
            glfw.terminate()
            return

        glfw.make_context_current(window)
        glfw.set_key_callback(window, self.key_callback)
        glfw.set_window_size_callback(window, self.reshape)

        width, height = glfw.get_framebuffer_size(window)
        glViewport(0, 0, width, height)
        aspect_ratio = width / height

        glClearColor(0.2, 0.3, 0.2, 1.0)
        glEnable(GL_DEPTH_TEST)

        self.ball = Ball(TEXTILE_TEXTURE)
        ball_shader = Shader(BASE_VS, BASE_FS)
        self.ball.prep(ball_shader, aspect_ratio, 0.5, 85)

        self.platform = Platform(BUCKET_TEXTURE)
        shader = Shader(BASE_VS, BASE_FS)
        self.platform.prep(shader, aspect_ratio, 1.0, 85)

        self.hearts = []
        for i in range(0, self.MAX_FAIL):
            heart = LiveHeart([-3.0 + i * 0.5, 5.5, 0.0])
            heart_shader = Shader(HEART_VS, HEART_FS)
            heart.prep(heart_shader, aspect_ratio, 0.3, 85)
            self.hearts.append(heart)

        self.bg = Background(WOOD_TEXTURE)
        bg_shader = Shader(BASE_VS, BASE_FS)
        self.bg.prep(bg_shader, aspect_ratio, 11.0, 85)

        while not glfw.window_should_close(window):
            glClearColor(0.0, 0.3, 0.3, 1.0)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

            glDisable(GL_DEPTH_TEST)
            self.bg.draw()
            glEnable(GL_DEPTH_TEST)

            self.platform.draw(self.game_status_play)
            self.ball.draw(self.game_status_play)

            if self.collision_detect():
                if self.fails == self.MAX_FAIL:
                    self.game_status_play = False

            for heart in self.hearts:
                heart.draw()

            glfw.swap_buffers(window)
            glfw.poll_events()

        glfw.terminate()
Пример #46
0
    def __init__(self, module, width, height, caption, scale, palette, fps,
                 border_width, border_color):
        self._module = module
        self._palette = palette[:]
        self._pil_palette = self._get_pil_palette(palette)
        self._fps = fps
        self._border_width = border_width
        self._border_color = border_color
        self._next_update_time = 0
        self._one_frame_time = 1 / fps
        self._key_state = {}
        self._update = None
        self._draw = None
        self._capture_start = 0
        self._capture_index = 0
        self._capture_images = [None] * APP_SCREEN_CAPTURE_COUNT

        self._perf_monitor_is_enabled = False
        self._perf_fps_count = 0
        self._perf_fps_start_time = 0
        self._perf_fps = 0
        self._perf_update_count = 0
        self._perf_update_total_time = 0
        self._perf_update_time = 0
        self._perf_draw_count = 0
        self._perf_draw_total_time = 0
        self._perf_draw_time = 0

        module.width = width
        module.height = height
        module.mouse_x = 0
        module.mouse_y = 0
        module.frame_count = 0

        # initialize window
        if not glfw.init():
            exit()

        window_width = width * scale + border_width
        window_height = height * scale + border_width
        self._window = glfw.create_window(window_width, window_height, caption,
                                          None, None)

        if not self._window:
            glfw.terminate()
            exit()

        glfw.make_context_current(self._window)
        glfw.set_window_size_limits(self._window, width, height,
                                    glfw.DONT_CARE, glfw.DONT_CARE)
        self._hidpi_scale = (glfw.get_framebuffer_size(self._window)[0] /
                             glfw.get_window_size(self._window)[0])
        self._update_viewport()

        glfw.set_key_callback(self._window, self._key_callback)
        glfw.set_cursor_pos_callback(self._window, self._cursor_pos_callback)
        glfw.set_mouse_button_callback(self._window,
                                       self._mouse_button_callback)

        glfw.set_window_icon(self._window, 1, [self._get_icon_image()])

        # initialize renderer
        self._renderer = Renderer(width, height)

        # initialize audio player
        self._audio_player = AudioPlayer()

        # export module functions
        module.btn = self.btn
        module.btnp = self.btnp
        module.btnr = self.btnr
        module.run = self.run
        module.quit = self.quit
        module.image = self._renderer.image
        module.clip = self._renderer.draw_command.clip
        module.pal = self._renderer.draw_command.pal
        module.cls = self._renderer.draw_command.cls
        module.pix = self._renderer.draw_command.pix
        module.line = self._renderer.draw_command.line
        module.rect = self._renderer.draw_command.rect
        module.rectb = self._renderer.draw_command.rectb
        module.circ = self._renderer.draw_command.circ
        module.circb = self._renderer.draw_command.circb
        module.blt = self._renderer.draw_command.blt
        module.text = self._renderer.draw_command.text
        module.sound = self._audio_player.sound
        module.play = self._audio_player.play
        module.stop = self._audio_player.stop
Пример #47
0
 def get_physical_size(self):
     psize = glfw.get_framebuffer_size(self.__window)
     return int(psize[0]), int(psize[1])
Пример #48
0
def main():

    useLiveCamera = True

    #gc.disable()

    # # transform to convert the image to tensor
    # transform = transforms.Compose([
    #     transforms.ToTensor()
    # ])
    # # initialize the model
    # model = torchvision.models.detection.keypointrcnn_resnet50_fpn(pretrained=True,
    #                                                             num_keypoints=17)
    # # set the computation device
    # device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    # # load the modle on to the computation device and set to eval mode
    # model.to(device).eval()

    # initialize glfw
    if not glfw.init():
        return
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    #creating the window
    window = glfw.create_window(1600, 900, "PyGLFusion", None, None)
    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)

    imgui.create_context()
    impl = GlfwRenderer(window)

    # rendering
    glClearColor(0.2, 0.3, 0.2, 1.0)

    #           positions        texture coords
    quad = [
        -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, -1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0,
        1.0, 1.0, -1.0, 1.0, 0.0, 0.0, 1.0
    ]

    quad = np.array(quad, dtype=np.float32)

    indices = [0, 1, 2, 2, 3, 0]

    indices = np.array(indices, dtype=np.uint32)

    screenVertex_shader = (Path(__file__).parent /
                           'shaders/ScreenQuad.vert').read_text()

    screenFragment_shader = (Path(__file__).parent /
                             'shaders/ScreenQuad.frag').read_text()

    renderShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(screenVertex_shader, GL_VERTEX_SHADER),
        OpenGL.GL.shaders.compileShader(screenFragment_shader,
                                        GL_FRAGMENT_SHADER))

    # set up VAO and VBO for full screen quad drawing calls
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)

    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 80, quad, GL_STATIC_DRAW)

    EBO = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 24, indices, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 20, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)

    # shaders

    bilateralFilter_shader = (Path(__file__).parent /
                              'shaders/bilateralFilter.comp').read_text()
    bilateralFilterShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(bilateralFilter_shader,
                                        GL_COMPUTE_SHADER))

    alignDepthColor_shader = (Path(__file__).parent /
                              'shaders/alignDepthColor.comp').read_text()
    alignDepthColorShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(alignDepthColor_shader,
                                        GL_COMPUTE_SHADER))

    depthToVertex_shader = (Path(__file__).parent /
                            'shaders/depthToVertex.comp').read_text()
    depthToVertexShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(depthToVertex_shader,
                                        GL_COMPUTE_SHADER))

    vertexToNormal_shader = (Path(__file__).parent /
                             'shaders/vertexToNormal.comp').read_text()
    vertexToNormalShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(vertexToNormal_shader,
                                        GL_COMPUTE_SHADER))

    raycast_shader = (Path(__file__).parent /
                      'shaders/raycast.comp').read_text()
    raycastShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(raycast_shader, GL_COMPUTE_SHADER))

    integrate_shader = (Path(__file__).parent /
                        'shaders/integrate.comp').read_text()
    integrateShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(integrate_shader, GL_COMPUTE_SHADER))

    trackP2P_shader = (Path(__file__).parent /
                       'shaders/p2pTrack.comp').read_text()
    trackP2PShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(trackP2P_shader, GL_COMPUTE_SHADER))

    reduceP2P_shader = (Path(__file__).parent /
                        'shaders/p2pReduce.comp').read_text()
    reduceP2PShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(reduceP2P_shader, GL_COMPUTE_SHADER))

    trackP2V_shader = (Path(__file__).parent /
                       'shaders/p2vTrack.comp').read_text()
    trackP2VShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(trackP2V_shader, GL_COMPUTE_SHADER))

    reduceP2V_shader = (Path(__file__).parent /
                        'shaders/p2vReduce.comp').read_text()
    reduceP2VShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(reduceP2V_shader, GL_COMPUTE_SHADER))

    LDLT_shader = (Path(__file__).parent / 'shaders/LDLT.comp').read_text()
    LDLTShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(LDLT_shader, GL_COMPUTE_SHADER))

    # Splatter
    globalMapUpdate_shader = (Path(__file__).parent /
                              'shaders/GlobalMapUpdate.comp').read_text()
    globalMapUpdateShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(globalMapUpdate_shader,
                                        GL_COMPUTE_SHADER))

    indexMapGenVert_shader = (Path(__file__).parent /
                              'shaders/IndexMapGeneration.vert').read_text()

    indexMapGenFrag_shader = (Path(__file__).parent /
                              'shaders/IndexMapGeneration.frag').read_text()

    IndexMapGenerationShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(indexMapGenVert_shader,
                                        GL_VERTEX_SHADER),
        OpenGL.GL.shaders.compileShader(indexMapGenFrag_shader,
                                        GL_FRAGMENT_SHADER))

    SurfaceSplattingVert_shader = (
        Path(__file__).parent / 'shaders/SurfaceSplatting.vert').read_text()

    SurfaceSplattingFrag_shader = (
        Path(__file__).parent / 'shaders/SurfaceSplatting.frag').read_text()

    SurfaceSplattingShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(SurfaceSplattingVert_shader,
                                        GL_VERTEX_SHADER),
        OpenGL.GL.shaders.compileShader(SurfaceSplattingFrag_shader,
                                        GL_FRAGMENT_SHADER))

    UnnecessaryPointRemoval_shader = (
        Path(__file__).parent /
        'shaders/UnnecessaryPointRemoval.comp').read_text()
    UnnecessaryPointRemovalShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(UnnecessaryPointRemoval_shader,
                                        GL_COMPUTE_SHADER))

    # P2V
    expm_shader = (Path(__file__).parent / 'shaders/expm.comp').read_text()
    expmShader = OpenGL.GL.shaders.compileProgram(
        OpenGL.GL.shaders.compileShader(expm_shader, GL_COMPUTE_SHADER))

    d2c, c2d, K, invK, colK = camera.start(useLiveCamera)

    shaderDict = {
        'renderShader': renderShader,
        'bilateralFilterShader': bilateralFilterShader,
        'alignDepthColorShader': alignDepthColorShader,
        'depthToVertexShader': depthToVertexShader,
        'vertexToNormalShader': vertexToNormalShader,
        'raycastVolumeShader': raycastShader,
        'integrateVolumeShader': integrateShader,
        'trackP2PShader': trackP2PShader,
        'reduceP2PShader': reduceP2PShader,
        'trackP2VShader': trackP2VShader,
        'reduceP2VShader': reduceP2VShader,
        'LDLTShader': LDLTShader,
        'globalMapUpdate': globalMapUpdateShader,
        'indexMapGeneration': IndexMapGenerationShader,
        'surfaceSplatting': SurfaceSplattingShader,
        'unnecessaryPointRemoval': UnnecessaryPointRemovalShader,
        'expm': expmShader
    }

    bufferDict = {
        'p2pReduction': -1,
        'p2pRedOut': -1,
        'p2vReduction': -1,
        'p2vRedOut': -1,
        'test': -1,
        'outBuf': -1,
        'poseBuffer': -1,
        'globalMap0': -1,
        'globalMap1': -1,
        'atomic0': -1,
        'atomic1': -1
    }

    textureDict = {
        'rawColor': -1,
        'lastColor': -1,
        'nextColor': -1,
        'rawDepth': -1,
        'filteredDepth': -1,
        'lastDepth': -1,
        'nextDepth': -1,
        'refVertex': -1,
        'refNormal': -1,
        'virtualVertex': -1,
        'virtualNormal': -1,
        'virtualDepth': -1,
        'virtualColor': -1,
        'mappingC2D': -1,
        'mappingD2C': -1,
        'xyLUT': -1,
        'tracking': -1,
        'volume': -1,
        'indexMap': -1
    }

    fboDict = {'indexMap': -1, 'virtualFrame': -1}
    #        'iters' : (2, 5, 10),

    fusionConfig = {
        'volSize': (128, 128, 128),
        'volDim': (1.0, 1.0, 1.0),
        'iters': (2, 2, 2),
        'initOffset': (0, 0, 0),
        'maxWeight': 100.0,
        'distThresh': 0.05,
        'normThresh': 0.9,
        'nearPlane': 0.1,
        'farPlane': 4.0,
        'maxMapSize': 5000000,
        'c_stable': 10.0,
        'sigma': 0.6
    }

    cameraConfig = {
        'depthWidth': 640,
        'depthHeight': 576,
        'colorWidth': 1920,
        'colorHeight': 1080,
        'd2c': d2c,
        'c2d': c2d,
        'depthScale': 0.001,
        'K': K,
        'invK': invK,
        'colK': colK
    }

    textureDict = frame.generateTextures(textureDict, cameraConfig,
                                         fusionConfig)
    bufferDict = frame.generateBuffers(bufferDict, cameraConfig, fusionConfig)

    colorMat = np.zeros(
        (cameraConfig['colorHeight'], cameraConfig['colorWidth'], 3),
        dtype="uint8")
    useColorMat = False
    integrateFlag = True
    resetFlag = True
    initPose = glm.mat4()
    initPose[3, 0] = fusionConfig['volDim'][0] / 2.0
    initPose[3, 1] = fusionConfig['volDim'][1] / 2.0
    initPose[3, 2] = 0

    blankResult = np.array([0, 0, 0, 0, 0, 0], dtype='float32')

    glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferDict['poseBuffer'])
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 16 * 4,
                    glm.value_ptr(initPose))
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 16 * 4, 16 * 4,
                    glm.value_ptr(glm.inverse(initPose)))
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 16 * 4 * 2, 16 * 4,
                    glm.value_ptr(glm.mat4(1.0)))
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 16 * 4 * 3, 16 * 4,
                    glm.value_ptr(glm.mat4(1.0)))
    glBufferSubData(GL_SHADER_STORAGE_BUFFER, 16 * 4 * 4, 6 * 4, blankResult)
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0)

    mouseX, mouseY = 0, 0
    clickedPoint3D = glm.vec4(fusionConfig['volDim'][0] / 2.0,
                              fusionConfig['volDim'][1] / 2.0, 0, 0)
    sliderDim = fusionConfig['volDim'][0]

    #[32 64 128 256 512]
    currentSize = math.log2(fusionConfig['volSize'][0]) - 5
    volumeStatsChanged = False

    currPose = initPose

    # splatter stuff
    frameCount = 0
    fboDict = frame.generateFrameBuffers(fboDict, textureDict, cameraConfig)

    initAtomicCount = np.array([0], dtype='uint32')
    mapSize = np.array([0], dtype='uint32')

    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bufferDict['atomic0'])
    glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, initAtomicCount)
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0)

    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bufferDict['atomic1'])
    glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, 4, initAtomicCount)
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0)

    # aa = torch.tensor([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0], dtype=torch.float32, device=torch.device('cuda'))
    # bb = torch.tensor([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], dtype=torch.float32, device=torch.device('cuda'))

    # #setup pycuda gl interop needs to be after openGL is init
    # import pycuda.gl.autoinit
    # import pycuda.gl
    # cuda_gl = pycuda.gl
    # cuda_driver = pycuda.driver
    # from pycuda.compiler import SourceModule
    # import pycuda

    # pycuda_source_ssbo = cuda_gl.RegisteredBuffer(int(bufferDict['test']), cuda_gl.graphics_map_flags.NONE)

    # sm = SourceModule("""
    #     __global__ void simpleCopy(float *inputArray, float *outputArray) {
    #             unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;

    #             outputArray[x] = inputArray[x];
    #             inputArray[x] = 8008.135f;
    #     }
    # """)

    # cuda_function = sm.get_function("simpleCopy")

    # mappingObj = pycuda_source_ssbo.map()
    # data, size = mappingObj.device_ptr_and_size()

    # cuda_function(np.intp(aa.data_ptr()), np.intp(data), block=(8, 1, 1))

    # mappingObj.unmap()

    # glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferDict['test'])
    # tee = glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 32)
    # glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0)
    # teeData = np.frombuffer(tee, dtype=np.float32)
    # print(teeData)

    # modTensor = aa.cpu().data.numpy()
    # print(modTensor)

    #fusionConfig['initOffset'] = (initPose[3,0], initPose[3,1], initPose[3,2])

    # LUTs
    #createXYLUT(k4a, textureDict, cameraConfig) <-- bug in this

    person.init()

    while not glfw.window_should_close(window):

        glfw.poll_events()
        impl.process_inputs()
        imgui.new_frame()

        sTime = time.perf_counter()

        try:
            capture = camera.getFrames(useLiveCamera)

            if capture.color is not None:
                #if useLiveCamera == False:
                #if k4a.configuration["color_format"] == ImageFormat.COLOR_MJPG:
                #    colorMat = cv2.imdecode(capture.color, cv2.IMREAD_COLOR)
                #    useColorMat = True
                glActiveTexture(GL_TEXTURE0)
                glBindTexture(GL_TEXTURE_2D, textureDict['rawColor'])
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                                int(cameraConfig['colorWidth']),
                                int(cameraConfig['colorHeight']),
                                (GL_RGB, GL_RGBA)[useLiveCamera],
                                GL_UNSIGNED_BYTE,
                                (capture.color, colorMat)[useColorMat])

            if capture.depth is not None:
                glActiveTexture(GL_TEXTURE1)
                glBindTexture(GL_TEXTURE_2D, textureDict['rawDepth'])
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                                int(cameraConfig['depthWidth']),
                                int(cameraConfig['depthHeight']), GL_RED,
                                GL_UNSIGNED_SHORT, capture.depth)

        except EOFError:
            break

        # #smallMat = cv2.pyrDown(colorMat)
        # start_time = time.time()
        # rotMat = cv2.flip(colorMat, 0)

        # pil_image = Image.fromarray(rotMat).convert('RGB')
        # image = transform(pil_image)

        # image = image.unsqueeze(0).to(device)
        # end_time = time.time()
        # print((end_time - start_time) * 1000.0)

        # with torch.no_grad():
        #     outputs = model(image)

        # output_image = utils.draw_keypoints(outputs, rotMat)
        # cv2.imshow('Face detection frame', output_image)
        # if cv2.waitKey(1) & 0xFF == ord('q'):
        #     break

        person.getPose(textureDict, cameraConfig, capture.color)

        frame.bilateralFilter(shaderDict, textureDict, cameraConfig)
        frame.depthToVertex(shaderDict, textureDict, cameraConfig,
                            fusionConfig)
        frame.alignDepthColor(shaderDict, textureDict, cameraConfig,
                              fusionConfig)
        frame.vertexToNormal(shaderDict, textureDict, cameraConfig)

        frame.mipmapTextures(textureDict)

        #currPose = track.runP2P(shaderDict, textureDict, bufferDict, cameraConfig, fusionConfig, currPose, integrateFlag, resetFlag)
        currPose = track.runP2V(shaderDict, textureDict, bufferDict,
                                cameraConfig, fusionConfig, currPose,
                                integrateFlag, resetFlag)

        #mapSize = track.runSplatter(shaderDict, textureDict, bufferDict, fboDict, cameraConfig, fusionConfig, mapSize, frameCount, integrateFlag, resetFlag)
        frameCount += 1

        if resetFlag == True:
            resetFlag = False
            integrateFlag = True

        imgui.begin("Menu", True)
        if imgui.button("Reset"):
            fusionConfig['volSize'] = (1 << (currentSize + 5), 1 <<
                                       (currentSize + 5), 1 <<
                                       (currentSize + 5))
            fusionConfig['volDim'] = (sliderDim, sliderDim, sliderDim)
            currPose, integrateFlag, resetFlag = track.reset(
                textureDict, bufferDict, cameraConfig, fusionConfig,
                clickedPoint3D)
            volumeStatsChanged = False

        if imgui.button("Integrate"):
            integrateFlag = not integrateFlag
        imgui.same_line()
        imgui.checkbox("", integrateFlag)

        changedDim, sliderDim = imgui.slider_float("dim",
                                                   sliderDim,
                                                   min_value=0.01,
                                                   max_value=5.0)

        clickedSize, currentSize = imgui.combo(
            "size", currentSize, ["32", "64", "128", "256", "512"])

        if imgui.is_mouse_clicked():
            if not imgui.is_any_item_active():
                mouseX, mouseY = imgui.get_mouse_pos()
                w, h = glfw.get_framebuffer_size(window)
                xPos = ((mouseX % int(w / 3)) / (w / 3) *
                        cameraConfig['depthWidth'])
                yPos = (mouseY / (h)) * cameraConfig['depthHeight']
                clickedDepth = capture.depth[
                    int(yPos + 0.5),
                    int(xPos + 0.5)] * cameraConfig['depthScale']
                clickedPoint3D = clickedDepth * (
                    cameraConfig['invK'] * glm.vec4(xPos, yPos, 1.0, 0.0))
                volumeStatsChanged = True

        if changedDim or clickedSize:
            volumeStatsChanged = True

        imgui.end()

        graphics.render(VAO, window, shaderDict, textureDict)

        imgui.render()

        impl.render(imgui.get_draw_data())

        eTime = time.perf_counter()

        #print((eTime-sTime) * 1000, mapSize[0])

        glfw.swap_buffers(window)

    glfw.terminate()
    if useLiveCamera == True:
        camera.stop()
Пример #49
0
    def run(self):
        """Run the main game loop logic"""
        # Shorten the variables
        world = self.world
        rendering_system = self.rendering_system
        window = self.window

        impl = ImGuiGlfwRenderer(window)

        # set the variables from the world object
        world.terrain = Terrain()
        world.terrain.load("data/track_01_128.png", rendering_system)

        world.racer = Racer()
        world.racer.load("data/racer_02.obj", world.terrain)

        current_time = glfw.get_time()
        prev_mouse_x, prev_mouse_y = glfw.get_cursor_pos(window)

        while not glfw.window_should_close(window):
            prev_time = current_time
            current_time = glfw.get_time()
            dt = current_time - prev_time

            key_state_map = {}
            for item_name, item_id in GLFW_KEYMAP.items():
                key_state_map[item_name] = glfw.get_key(window,
                                                        item_id) == glfw.PRESS

            for item_name, item_id in GLFW_MOUSE_MAP.items():
                key_state_map[item_name] = glfw.get_mouse_button(
                    window, item_id) == glfw.PRESS

            imgui.new_frame()
            imgui.set_next_window_size(430.0, 450.0, imgui.FIRST_USE_EVER)
            imgui.begin("Tweak variables")

            mouse_x, mouse_y = glfw.get_cursor_pos(window)
            mouse_delta = [mouse_x - prev_mouse_x, mouse_y - prev_mouse_y]
            prev_mouse_x, prev_mouse_y = mouse_x, mouse_y

            # Update 'world logic'
            im_io = imgui.get_io()
            if im_io.want_capture_mouse:
                mouse_delta = [0, 0]
            update(world, rendering_system, dt, key_state_map, mouse_delta)

            width, height = glfw.get_framebuffer_size(window)

            renderFrame(world, rendering_system, width, height)

            # mgui.show_test_window()

            imgui.end()
            imgui.render()
            # Swap front and back buffers
            glfw.swap_buffers(window)

            # Poll for and process events
            glfw.poll_events()
            impl.process_inputs()

        # This is the end of the game. Do some cleanup
        glfw.destroy_window(window)
        glfw.terminate()
Пример #50
0
    def __init__(
        self,
        module,
        width,
        height,
        caption,
        scale,
        palette,
        fps,
        border_width,
        border_color,
    ):
        if glfw.get_version() < tuple(map(int, GLFW_VERSION.split("."))):
            raise RuntimeError(
                "glfw version is lower than {}".format(GLFW_VERSION))

        if width > APP_SCREEN_MAX_SIZE or height > APP_SCREEN_MAX_SIZE:
            raise ValueError("screen size is larger than {}x{}".format(
                APP_SCREEN_MAX_SIZE, APP_SCREEN_MAX_SIZE))

        global pyxel
        pyxel = module

        self._palette = palette[:]
        self._fps = fps
        self._border_width = border_width
        self._border_color = border_color
        self._next_update_time = 0
        self._one_frame_time = 1 / fps
        self._key_state = {}
        self._is_mouse_visible = False
        self._update = None
        self._draw = None
        self._capture_start = 0
        self._capture_count = 0
        self._capture_images = [None] * APP_GIF_CAPTURE_COUNT

        self._perf_monitor_is_enabled = False
        self._perf_fps_count = 0
        self._perf_fps_start_time = 0
        self._perf_fps = 0
        self._perf_update_count = 0
        self._perf_update_total_time = 0
        self._perf_update_time = 0
        self._perf_draw_count = 0
        self._perf_draw_total_time = 0
        self._perf_draw_time = 0

        # exports variables
        pyxel._app = self
        pyxel.width = width
        pyxel.height = height
        pyxel.mouse_x = 0
        pyxel.mouse_y = 0
        pyxel.frame_count = 0

        # initialize window
        if not glfw.init():
            exit()

        monitor = glfw.get_primary_monitor()
        display_width, display_height = glfw.get_video_mode(monitor)[0]

        if scale == 0:
            scale = max(
                min(
                    (display_width // width) - APP_SCREEN_SCALE_CUTDOWN,
                    (display_height // height) - APP_SCREEN_SCALE_CUTDOWN,
                ),
                APP_SCREEN_SCALE_MINIMUM,
            )

        window_width = width * scale + border_width
        window_height = height * scale + border_width
        self._window = glfw.create_window(window_width, window_height, caption,
                                          None, None)

        if not self._window:
            glfw.terminate()
            exit()

        glfw.set_window_pos(
            self._window,
            (display_width - window_width) // 2,
            (display_height - window_height) // 2,
        )

        glfw.make_context_current(self._window)
        glfw.set_window_size_limits(self._window, width, height,
                                    glfw.DONT_CARE, glfw.DONT_CARE)
        self._hidpi_scale = (glfw.get_framebuffer_size(self._window)[0] /
                             glfw.get_window_size(self._window)[0])
        self._update_viewport()

        glfw.set_key_callback(self._window, self._key_callback)
        glfw.set_mouse_button_callback(self._window,
                                       self._mouse_button_callback)

        glfw.set_window_icon(self._window, 1, [utilities.get_icon_image()])
        glfw.set_input_mode(self._window, glfw.CURSOR, glfw.CURSOR_HIDDEN)

        # initialize renderer
        self._renderer = Renderer(width, height)

        # initialize audio player
        self._audio_player = AudioPlayer()

        # export module functions
        pyxel.btn = self.btn
        pyxel.btnp = self.btnp
        pyxel.btnr = self.btnr
        pyxel.mouse = self.mouse
        pyxel.run = self.run
        pyxel.run_with_profiler = self.run_with_profiler
        pyxel.quit = self.quit
        pyxel.save = self.save
        pyxel.load = self.load
        pyxel.image = self._renderer.image
        pyxel.tilemap = self._renderer.tilemap
        pyxel.clip = self._renderer.draw_command.clip
        pyxel.pal = self._renderer.draw_command.pal
        pyxel.cls = self._renderer.draw_command.cls
        pyxel.pix = self._renderer.draw_command.pix
        pyxel.line = self._renderer.draw_command.line
        pyxel.rect = self._renderer.draw_command.rect
        pyxel.rectb = self._renderer.draw_command.rectb
        pyxel.circ = self._renderer.draw_command.circ
        pyxel.circb = self._renderer.draw_command.circb
        pyxel.blt = self._renderer.draw_command.blt
        pyxel.bltm = self._renderer.draw_command.bltm
        pyxel.text = self._renderer.draw_command.text
        pyxel.sound = self._audio_player.sound
        pyxel.music = self._audio_player.music
        pyxel.play = self._audio_player.play
        pyxel.playm = self._audio_player.playm
        pyxel.stop = self._audio_player.stop

        # initialize mouse cursor
        pyxel.image(3,
                    system=True).set(MOUSE_CURSOR_IMAGE_X,
                                     MOUSE_CURSOR_IMAGE_Y, MOUSE_CURSOR_DATA)
Пример #51
0
    def __init__(
        self,
        g_pool,
        window_size=window_size_default,
        window_position=None,
        gui_scale=1.0,
        ui_config={},
    ):
        super().__init__(g_pool)

        self.texture = np.zeros((1, 1, 3), dtype=np.uint8) + 128

        glfw.init()
        glfw.window_hint(glfw.SCALE_TO_MONITOR, glfw.TRUE)
        if g_pool.hide_ui:
            glfw.window_hint(glfw.VISIBLE, 0)  # hide window
        main_window = glfw.create_window(*window_size, "Pupil Service", None,
                                         None)

        window_position_manager = gl_utils.WindowPositionManager()
        window_position = window_position_manager.new_window_position(
            window=main_window,
            default_position=window_position_default,
            previous_position=window_position,
        )
        glfw.set_window_pos(main_window, *window_position)

        glfw.make_context_current(main_window)
        cygl.utils.init()
        g_pool.main_window = main_window

        g_pool.gui = ui.UI()
        g_pool.menubar = ui.Scrolling_Menu("Settings",
                                           pos=(0, 0),
                                           size=(0, 0),
                                           header_pos="headline")
        g_pool.gui.append(g_pool.menubar)

        # Callback functions
        def on_resize(window, w, h):
            # Always clear buffers on resize to make sure that there are no overlapping
            # artifacts from previous frames.
            gl_utils.glClear(gl_utils.GL_COLOR_BUFFER_BIT)
            gl_utils.glClearColor(0, 0, 0, 1)

            self.window_size = w, h
            self.content_scale = gl_utils.get_content_scale(window)
            g_pool.gui.scale = self.content_scale
            g_pool.gui.update_window(w, h)
            g_pool.gui.collect_menus()

            # Needed, to update the window buffer while resizing
            self.update_ui()

        def on_window_key(window, key, scancode, action, mods):
            g_pool.gui.update_key(key, scancode, action, mods)

        def on_window_char(window, char):
            g_pool.gui.update_char(char)

        def on_window_mouse_button(window, button, action, mods):
            g_pool.gui.update_button(button, action, mods)

        def on_pos(window, x, y):
            x, y = gl_utils.window_coordinate_to_framebuffer_coordinate(
                window, x, y, cached_scale=None)
            g_pool.gui.update_mouse(x, y)

        def on_scroll(window, x, y):
            g_pool.gui.update_scroll(x, y * scroll_factor)

        def set_window_size():
            # Get default window size
            f_width, f_height = window_size_default

            # Get current display scale factor
            content_scale = gl_utils.get_content_scale(main_window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(main_window)
            display_scale_factor = content_scale / framebuffer_scale

            # Scale the capture frame size by display scale factor
            f_width *= display_scale_factor
            f_height *= display_scale_factor

            # Set the newly calculated size (scaled capture frame size + scaled icon bar width)
            glfw.set_window_size(main_window, int(f_width), int(f_height))

        def reset_restart():
            logger.warning("Resetting all settings and restarting Capture.")
            glfw.set_window_should_close(main_window, True)
            self.notify_all({"subject": "clear_settings_process.should_start"})
            self.notify_all({
                "subject": "service_process.should_start",
                "delay": 2.0
            })

        g_pool.menubar.append(ui.Button("Reset window size", set_window_size))

        pupil_remote_addr = "{}:{}".format(
            socket.gethostbyname(socket.gethostname()),
            g_pool.preferred_remote_port)
        g_pool.menubar.append(
            ui.Text_Input(
                "pupil_remote_addr",
                getter=lambda: pupil_remote_addr,
                setter=lambda x: None,
                label="Pupil Remote address",
            ))
        g_pool.menubar.append(
            ui.Switch(
                "eye0_process",
                label="Detect eye 0",
                setter=lambda alive: self.start_stop_eye(0, alive),
                getter=lambda: g_pool.eye_procs_alive[0].value,
            ))
        g_pool.menubar.append(
            ui.Switch(
                "eye1_process",
                label="Detect eye 1",
                setter=lambda alive: self.start_stop_eye(1, alive),
                getter=lambda: g_pool.eye_procs_alive[1].value,
            ))

        g_pool.menubar.append(
            ui.Info_Text("Service Version: {}".format(g_pool.version)))

        g_pool.menubar.append(
            ui.Button("Restart with default settings", reset_restart))

        # Register callbacks main_window
        glfw.set_framebuffer_size_callback(main_window, on_resize)
        glfw.set_key_callback(main_window, on_window_key)
        glfw.set_char_callback(main_window, on_window_char)
        glfw.set_mouse_button_callback(main_window, on_window_mouse_button)
        glfw.set_cursor_pos_callback(main_window, on_pos)
        glfw.set_scroll_callback(main_window, on_scroll)
        g_pool.gui.configuration = ui_config
        gl_utils.basic_gl_setup()

        on_resize(g_pool.main_window, *glfw.get_framebuffer_size(main_window))
Пример #52
0
    def __init__(self, win, *args, **kwargs):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        Parameters
        ----------
        win : psychopy.visual.Window instance
            PsychoPy Window (usually not fully created yet).
        share : psychopy.visual.Window instance
            PsychoPy Window to share a context with
        bpc : array_like
            Bits per color (R, G, B).
        refreshHz : int
            Refresh rate in Hertz.
        depthBits : int,
            Framebuffer (back buffer) depth bits.
        swapInterval : int
            Swap interval for the current OpenGL context.
        stencilBits : int
            Framebuffer (back buffer) stencil bits.
        winTitle : str
            Optional window title string.
        *args
            Additional position arguments.
        **kwargs
            Additional keyword arguments.

        """
        BaseBackend.__init__(self, win)

        # window to share a context with
        shareWin = kwargs.get('share', None)
        if shareWin is not None:
            if shareWin.winType == 'glfw':
                shareContext = shareWin.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.')
                shareContext = None
        else:
            shareContext = None

        if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        win.bpc = kwargs.get('bpc', (8, 8, 8))  # nearly all displays use 8 bpc
        win.refreshHz = int(kwargs.get('refreshHz', 60))
        win.depthBits = int(kwargs.get('depthBits', 8))
        win.stencilBits = int(kwargs.get('stencilBits', 8))
        # win.swapInterval = int(kwargs.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        thisScreen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        isVidmodeSupported = False
        for vidmode in glfw.get_video_modes(thisScreen):
            size, bpc, hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                hasSize = size == tuple(win.size)
                hasHz = hz == win.refreshHz
            else:
                hasSize = hasHz = True
            hasBpc = bpc == tuple(win.bpc)
            if hasSize and hasBpc and hasHz:
                isVidmodeSupported = True
                break

        nativeVidmode = glfw.get_video_mode(thisScreen)
        if not isVidmodeSupported:
            # the requested video mode is not supported, use current

            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))
            logging.warning(
                ("Overriding user video settings: size {} -> {}, bpc {} -> "
                 "{}, refreshHz {} -> {}".format(
                    tuple(win.size),
                    nativeVidmode[0],
                    tuple(win.bpc),
                    nativeVidmode[1],
                    win.refreshHz,
                    nativeVidmode[2])))

            # change the window settings
            win.size, win.bpc, win.refreshHz = nativeVidmode

        if win._isFullScr:
            useDisplay = thisScreen
        else:
            useDisplay = None

        # configure stereo
        useStereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                useStereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaaSamples = 0
        if win.multiSample:
            maxSamples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > maxSamples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaaSamples = win.numSamples
        win.multiSample = msaaSamples > 0

        # disable stencil buffer
        if not win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, useStereo)
        glfw.window_hint(glfw.SAMPLES, msaaSamples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)

        # create the window
        self.winHandle = glfw.create_window(
            width=win.size[0],
            height=win.size[1],
            title=str(kwargs.get('winTitle', "PsychoPy (GLFW)")),
            monitor=useDisplay,
            share=shareContext)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the position of the window if not fullscreen
        if not win._isFullScr:
            # if no window position is specified, centre it on-screen
            if win.pos is None:
                size, bpc, hz = nativeVidmode
                win.pos = [(size[0] - win.size[0]) / 2.0,
                           (size[1] - win.size[1]) / 2.0]

            # get the virtual position of the monitor, apply offset to the
            # window position
            px, py = glfw.get_monitor_pos(thisScreen)
            glfw.set_window_pos(self.winHandle,
                                int(win.pos[0] + px),
                                int(win.pos[1] + py))

        elif win._isFullScr and win.pos is not None:
            logging.warn("Ignoring window 'pos' in fullscreen mode.")

        # set the window icon
        glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # set the window size to the framebuffer size
        win.size = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle, event._onGLFWMouseButton)
        glfw.set_scroll_callback(self.winHandle, event._onGLFWMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # set swap interval to manual setting, independent of waitBlanking
        self.setSwapInterval(int(kwargs.get('swapInterval', 1)))

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)
Пример #53
0
def demo():
    # Initialize the library
    if not glfw.init():
        sys.exit()

    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    # for osx
    glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, gl.GL_TRUE)

    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(1000, 1000, "pyNuklear demo - GLFW OpenGL3",
                                None, None)
    if not window:
        glfw.terminate()
        sys.exit()

    # Make the window's context current
    glfw.make_context_current(window)

    ctx = nkglfw3.glfw3_init(window, nkglfw3.GLFW3_INSTALL_CALLBACKS)
    nuklear = nk.NuklearContext(ctx)

    fontAtlas = nkglfw3.FontAtlas()
    nkglfw3.glfw3_font_stash_begin(ctypes.byref(fontAtlas))
    nkglfw3.glfw3_font_stash_end()

    # Install a key handler

    def on_key(window, key, scancode, action, mods):
        if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
            glfwSetWindowShouldClose(window, 1)

    glfw.set_key_callback(window, on_key)

    gl.glClearColor(0.1, 0.18, 0.24, 1.0)
    gl.glEnable(gl.GL_DEPTH_TEST)
    gl.glClearDepth(1.0)
    gl.glDepthFunc(gl.GL_LEQUAL)

    class Camera:
        def __init__(self):
            self.x = 0.0
            self.y = 0.0
            self.z = 10.0

            self.rotationX = 0.0
            self.rotationY = 0.0

    camera = Camera()

    triangle = Triangle()
    triangle.prepareToRender()

    # does python have static local variables?  this declaration is way too far away from use
    #property = ctypes.c_int(20)

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here

        # Poll for and process events
        glfw.poll_events()
        nkglfw3.glfw3_new_frame()

        width, height = glfw.get_framebuffer_size(window)
        gl.glViewport(0, 0, width, height)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

        ms.setToIdentityMatrix(ms.MatrixStack.model)
        ms.setToIdentityMatrix(ms.MatrixStack.view)
        ms.setToIdentityMatrix(ms.MatrixStack.projection)

        # set the projection matrix to be perspective
        ms.perspective(fov=45.0,
                       aspectRatio=width / height,
                       nearZ=0.1,
                       farZ=10000.0)

        # get input from keyboard for camera movement
        if not nuklear.item_is_any_active():
            # set up Camera
            if glfw.get_key(window, glfw.KEY_RIGHT) == glfw.PRESS:
                camera.rotationY -= 0.03

            if glfw.get_key(window, glfw.KEY_LEFT) == glfw.PRESS:
                camera.rotationY += 0.03

            if glfw.get_key(window, glfw.KEY_UP) == glfw.PRESS:
                camera.x -= math.sin(camera.rotationY)
                camera.z -= math.cos(camera.rotationY)

            if glfw.get_key(window, glfw.KEY_DOWN) == glfw.PRESS:
                camera.x += math.sin(camera.rotationY)
                camera.z += math.cos(camera.rotationY)

        # move the camera to the correct position, which means
        # updating the view stack
        ms.rotateX(ms.MatrixStack.view, camera.rotationX)
        ms.rotateY(ms.MatrixStack.view, -camera.rotationY)
        ms.translate(ms.MatrixStack.view, -camera.x, -camera.y, -camera.z)

        # render the models

        triangle.render()

        MAX_VERTEX_BUFFER = 512 * 1024
        MAX_ELEMENT_BUFFER = 128 * 1024

        if (nuklear.begin(title="Demonstration",
                          bounds=nk.Rect(10.0, 10.0, 230.0, 250.0),
                          flags=nk.PanelFlags.WINDOW_BORDER.value
                          | nk.PanelFlags.WINDOW_MOVABLE.value
                          | nk.PanelFlags.WINDOW_SCALABLE.value
                          | nk.PanelFlags.WINDOW_MINIMIZABLE.value
                          | nk.PanelFlags.WINDOW_TITLE.value)):

            nuklear.layout_row_static(height=30.0, item_width=80, columns=5)
            if nuklear.button_label(title="button"):
                print('button pressed')

            nuklear.layout_row_dynamic(height=30.0, columns=2)

            try:
                op
            except Exception:
                op = 0

            if nuklear.option_label(label="easy", active=op == 0):
                op = 0
            if nuklear.option_label(label="hard", active=op == 1):
                op = 1

            nuklear.layout_row_dynamic(height=25.0, columns=1)

            try:
                prop
            except Exception:
                prop = 20

            prop = nuklear.property_int(name="Compression:",
                                        minV=0,
                                        val=prop,
                                        maxV=100,
                                        step=10,
                                        inc_per_pixel=1)

            nuklear.layout_row_dynamic(height=20.0, columns=1)
            nuklear.label(text="background:", alignment=nk.TextAlign.TEXT_LEFT)

            try:
                background
            except Exception:
                background = nk.ColorF(r=0.10, g=0.18, b=0.24, a=1.0)

            nuklear.layout_row_dynamic(height=25.0, columns=1)
            if nuklear.combo_begin_color(color=nuklear.rgb_cf(background),
                                         size=nk.Vec2(nuklear.widget_width(),
                                                      400)):
                nuklear.layout_row_dynamic(height=120.0, columns=1)
                background = nuklear.color_picker(color=background,
                                                  format=nk.ColorFormat.RGBA)

                nuklear.layout_row_dynamic(height=25.0, columns=1)
                background.r = nuklear.propertyf(name="#R:",
                                                 minVal=0.0,
                                                 val=background.r,
                                                 maxVal=1.0,
                                                 step=0.01,
                                                 inc_per_pixel=0.005)
                background.g = nuklear.propertyf(name="#G:",
                                                 minVal=0.0,
                                                 val=background.g,
                                                 maxVal=1.0,
                                                 step=0.01,
                                                 inc_per_pixel=0.005)
                background.b = nuklear.propertyf(name="#B:",
                                                 minVal=0.0,
                                                 val=background.b,
                                                 maxVal=1.0,
                                                 step=0.01,
                                                 inc_per_pixel=0.005)
                background.a = nuklear.propertyf(name="#A:",
                                                 minVal=0.0,
                                                 val=background.a,
                                                 maxVal=1.0,
                                                 step=0.01,
                                                 inc_per_pixel=0.005)

                gl.glClearColor(background.r, background.g, background.b,
                                background.a)

                nuklear.combo_end()

        nuklear.end()

        overview(nuklear)

        nkglfw3.glfw3_render(nk.AntiAliasing.ON.value, MAX_VERTEX_BUFFER,
                             MAX_ELEMENT_BUFFER)

        # done with frame, flush and swap buffers
        # Swap front and back buffers
        glfw.swap_buffers(window)

    glfw.terminate()
Пример #54
0
    def __init__(self, win, backendConf=None):
        """Set up the backend window according the params of the PsychoPy win

        Before PsychoPy 1.90.0 this code was executed in Window._setupPygame()

        Parameters
        ----------
        win : `psychopy.visual.Window` instance
            PsychoPy Window (usually not fully created yet).
        backendConf : `dict` or `None`
            Backend configuration options. Options are specified as a dictionary
            where keys are option names and values are settings. For this
            backend the following options are available:

            * `share` (`psychopy.visual.Window instance`) PsychoPy Window to
              share a context with.
            * `refreshHz` (`int`) Refresh rate in Hertz.
            * `bpc` (`array_like`) Bits per color (R, G, B).
            * `swapInterval` (`int`) Swap interval for the current OpenGL
              context.
            * `depthBits` (`int`) Framebuffer (back buffer) depth bits.
            * `stencilBits` (`int`) Framebuffer (back buffer) stencil bits.
            * `winTitle` (`str`) Optional window title string.

        Examples
        --------
        Create a window using the GLFW backend and specify custom options::

            import psychopy.visual as visual

            options = {'bpc': (8, 8, 8), 'depthBits': 24, 'stencilBits': 8}
            win = visual.Window(winType='glfw', backendOptions=options)

        """
        BaseBackend.__init__(self, win)

        # if `None`, change to `dict` to extract options
        backendConf = backendConf if backendConf is not None else {}

        if not isinstance(backendConf, dict):  # type check on options
            raise TypeError(
                'Object passed to `backendConf` must be type `dict`.')

        # window to share a context with
        shareWin = backendConf.get('share', None)
        if shareWin is not None:
            if shareWin.winType == 'glfw':
                shareContext = shareWin.winHandle
            else:
                logging.warning(
                    'Cannot share a context with a non-GLFW window. Disabling.')
                shareContext = None
        else:
            shareContext = None

        if sys.platform=='darwin' and not win.useRetina and pyglet.version >= "1.3":
            raise ValueError("As of PsychoPy 1.85.3 OSX windows should all be "
                             "set to useRetina=True (or remove the argument). "
                             "Pyglet 1.3 appears to be forcing "
                             "us to use retina on any retina-capable screen "
                             "so setting to False has no effect.")

        # window framebuffer configuration
        bpc = backendConf.get('bpc', (8, 8, 8))
        if isinstance(bpc, int):
            win.bpc = (bpc, bpc, bpc)
        else:
            win.bpc = bpc

        win.refreshHz = int(backendConf.get('refreshHz', 60))
        win.depthBits = int(backendConf.get('depthBits', 8))
        win.stencilBits = int(backendConf.get('stencilBits', 8))
        # win.swapInterval = int(backendConf.get('swapInterval', 1))  # vsync ON if 1

        # get monitors, with GLFW the primary display is ALWAYS at index 0
        allScrs = glfw.get_monitors()
        if len(allScrs) < int(win.screen) + 1:
            logging.warn("Requested an unavailable screen number - "
                         "using first available.")
            win.screen = 0

        thisScreen = allScrs[win.screen]
        if win.autoLog:
            logging.info('configured GLFW screen %i' % win.screen)

        # find a matching video mode (can we even support this configuration?)
        isVidmodeSupported = False
        for vidmode in glfw.get_video_modes(thisScreen):
            size, bpc, hz = vidmode
            if win._isFullScr:  # size and refresh rate are ignored if windowed
                hasSize = size == tuple(win.size)
                hasHz = hz == win.refreshHz
            else:
                hasSize = hasHz = True
            hasBpc = bpc == tuple(win.bpc)
            if hasSize and hasBpc and hasHz:
                isVidmodeSupported = True
                break

        nativeVidmode = glfw.get_video_mode(thisScreen)
        if not isVidmodeSupported:
            # the requested video mode is not supported, use current

            logging.warning(
                ("The specified video mode is not supported by this display, "
                 "using native mode ..."))

            actualWidth, actualHeight = nativeVidmode.size
            redBits, greenBits, blueBits = nativeVidmode.bits
            # change the window settings
            if win._isFullScr:
                logging.warning(
                    ("Overriding user video settings: size {} -> {}, bpc {} -> "
                     "{}, refreshHz {} -> {}".format(
                        tuple(win.size),
                        (actualWidth, actualHeight),
                        tuple(win.bpc),
                        (redBits, greenBits, blueBits),
                        win.refreshHz,
                        nativeVidmode.refresh_rate)))

                win.clientSize = np.array((actualWidth, actualHeight), int)
            else:
                logging.warning(
                    ("Overriding user video settings: bpc {} -> "
                     "{}, refreshHz {} -> {}".format(
                        tuple(win.bpc),
                        (redBits, greenBits, blueBits),
                        win.refreshHz,
                        nativeVidmode.refresh_rate)))

            win.bpc = (redBits, greenBits, blueBits)
            win.refreshHz = nativeVidmode.refresh_rate

        if win._isFullScr:
            useDisplay = thisScreen
        else:
            useDisplay = None

        # configure stereo
        useStereo = 0
        if win.stereo:
            # provide warning if stereo buffers are requested but unavailable
            if not glfw.extension_supported('GL_STEREO'):
                logging.warning(
                    'A stereo window was requested but the graphics '
                    'card does not appear to support GL_STEREO')
                win.stereo = False
            else:
                useStereo = 1

        # setup multisampling
        # This enables multisampling on the window backbuffer, not on other
        # framebuffers.
        msaaSamples = 0
        if win.multiSample:
            maxSamples = (GL.GLint)()
            GL.glGetIntegerv(GL.GL_MAX_SAMPLES, maxSamples)
            if (win.numSamples & (win.numSamples - 1)) != 0:
                # power of two?
                logging.warning(
                    'Invalid number of MSAA samples provided, must be '
                    'power of two. Disabling.')
            elif 0 > win.numSamples > maxSamples.value:
                # check if within range
                logging.warning(
                    'Invalid number of MSAA samples provided, outside of valid '
                    'range. Disabling.')
            else:
                msaaSamples = win.numSamples
        win.multiSample = msaaSamples > 0

        # disable stencil buffer
        if not win.allowStencil:
            win.stencilBits = 0

        # set buffer configuration hints
        glfw.window_hint(glfw.RED_BITS, win.bpc[0])
        glfw.window_hint(glfw.GREEN_BITS, win.bpc[1])
        glfw.window_hint(glfw.BLUE_BITS, win.bpc[2])
        glfw.window_hint(glfw.REFRESH_RATE, win.refreshHz)
        glfw.window_hint(glfw.STEREO, useStereo)
        glfw.window_hint(glfw.SAMPLES, msaaSamples)
        glfw.window_hint(glfw.STENCIL_BITS, win.stencilBits)
        glfw.window_hint(glfw.DEPTH_BITS, win.depthBits)
        glfw.window_hint(glfw.AUTO_ICONIFY, 0)

        # window appearance and behaviour hints
        if not win.allowGUI:
            glfw.window_hint(glfw.DECORATED, 0)

        # create the window
        self.winHandle = glfw.create_window(
            width=win.clientSize[0],
            height=win.clientSize[1],
            title=str(backendConf.get('winTitle', "PsychoPy (GLFW)")),
            monitor=useDisplay,
            share=shareContext)

        # The window's user pointer maps the Python Window object to its GLFW
        # representation.
        glfw.set_window_user_pointer(self.winHandle, win)
        glfw.make_context_current(self.winHandle)  # ready to use

        # set the position of the window if not fullscreen
        if not win._isFullScr:
            # if no window position is specified, centre it on-screen
            if win.pos is None:
                size, bpc, hz = nativeVidmode
                win.pos = [(size[0] - win.clientSize[0]) / 2.0,
                           (size[1] - win.clientSize[1]) / 2.0]

            # get the virtual position of the monitor, apply offset to the
            # window position
            px, py = glfw.get_monitor_pos(thisScreen)
            glfw.set_window_pos(self.winHandle,
                                int(win.pos[0] + px),
                                int(win.pos[1] + py))

        elif win._isFullScr and win.pos is not None:
            logging.warn("Ignoring window 'pos' in fullscreen mode.")

        # set the window icon
        if hasattr(glfw, 'set_window_icon'):
            glfw.set_window_icon(self.winHandle, 1, _WINDOW_ICON_)

        # set the window size to the framebuffer size
        self._frameBufferSize = np.array(glfw.get_framebuffer_size(self.winHandle))

        if win.useFBO:  # check for necessary extensions
            if not glfw.extension_supported('GL_EXT_framebuffer_object'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_EXT_framebuffer_object is not supported. Disabled")
                logging.warn(msg)
                win.useFBO = False
            if not glfw.extension_supported('GL_ARB_texture_float'):
                msg = ("Trying to use a framebuffer object but "
                       "GL_ARB_texture_float is not supported. Disabling")
                logging.warn(msg)
                win.useFBO = False

        # Assign event callbacks, these are dispatched when 'poll_events' is
        # called.
        glfw.set_mouse_button_callback(self.winHandle, self.onMouseButton)
        glfw.set_cursor_pos_callback(self.winHandle, self.onMouseMove)
        glfw.set_cursor_enter_callback(self.winHandle, self.onMouseEnter)
        glfw.set_scroll_callback(self.winHandle, self.onMouseScroll)
        glfw.set_key_callback(self.winHandle, event._onGLFWKey)
        glfw.set_char_mods_callback(self.winHandle, event._onGLFWText)

        # set swap interval to manual setting, independent of waitBlanking
        self.setSwapInterval(int(backendConf.get('swapInterval', 1)))

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)
Пример #55
0
 def size(self):
     return glfw.get_framebuffer_size(self._wnd)
Пример #56
0
def world(
    timebase,
    eye_procs_alive,
    ipc_pub_url,
    ipc_sub_url,
    ipc_push_url,
    user_dir,
    version,
    preferred_remote_port,
    hide_ui,
    debug,
):
    """Reads world video and runs plugins.

    Creates a window, gl context.
    Grabs images from a capture.
    Maps pupil to gaze data
    Can run various plug-ins.

    Reacts to notifications:
        ``eye_process.started``
        ``start_plugin``
        ``should_stop``

    Emits notifications:
        ``eye_process.should_start``
        ``eye_process.should_stop``
        ``world_process.started``
        ``world_process.stopped``
        ``recording.should_stop``: Emits on camera failure
        ``launcher_process.should_stop``

    Emits data:
        ``gaze``: Gaze data from current gaze mapping plugin.``
        ``*``: any other plugin generated data in the events
               that it not [dt,pupil,gaze].
    """

    # We defer the imports because of multiprocessing.
    # Otherwise the world process each process also loads the other imports.
    # This is not harmful but unnecessary.

    # general imports
    from time import sleep
    import logging

    # networking
    import zmq
    import zmq_tools

    # zmq ipc setup
    zmq_ctx = zmq.Context()
    ipc_pub = zmq_tools.Msg_Dispatcher(zmq_ctx, ipc_push_url)
    notify_sub = zmq_tools.Msg_Receiver(zmq_ctx, ipc_sub_url, topics=("notify",))

    # log setup
    logging.getLogger("OpenGL").setLevel(logging.ERROR)
    logger = logging.getLogger()
    logger.handlers = []
    logger.setLevel(logging.NOTSET)
    logger.addHandler(zmq_tools.ZMQ_handler(zmq_ctx, ipc_push_url))
    # create logger for the context of this function
    logger = logging.getLogger(__name__)

    def launch_eye_process(eye_id, delay=0):
        n = {
            "subject": "eye_process.should_start.{}".format(eye_id),
            "eye_id": eye_id,
            "delay": delay,
        }
        ipc_pub.notify(n)

    def stop_eye_process(eye_id):
        n = {
            "subject": "eye_process.should_stop.{}".format(eye_id),
            "eye_id": eye_id,
            "delay": 0.2,
        }
        ipc_pub.notify(n)

    def start_stop_eye(eye_id, make_alive):
        if make_alive:
            launch_eye_process(eye_id)
        else:
            stop_eye_process(eye_id)

    def detection_enabled_getter() -> bool:
        return g_pool.pupil_detection_enabled

    def detection_enabled_setter(is_on: bool):
        g_pool.pupil_detection_enabled = is_on
        n = {"subject": "set_pupil_detection_enabled", "value": is_on}
        ipc_pub.notify(n)

    try:
        from background_helper import IPC_Logging_Task_Proxy

        IPC_Logging_Task_Proxy.push_url = ipc_push_url

        from tasklib.background.patches import IPCLoggingPatch

        IPCLoggingPatch.ipc_push_url = ipc_push_url

        from OpenGL.GL import GL_COLOR_BUFFER_BIT

        # display
        import glfw

        glfw.ERROR_REPORTING = "raise"

        from version_utils import parse_version
        from pyglui import ui, cygl, __version__ as pyglui_version

        assert parse_version(pyglui_version) >= parse_version(
            "1.27"
        ), "pyglui out of date, please upgrade to newest version"
        from pyglui.cygl.utils import Named_Texture
        import gl_utils

        # helpers/utils
        from file_methods import Persistent_Dict
        from methods import normalize, denormalize, delta_t, get_system_info, timer
        from uvc import get_time_monotonic

        logger.info("Application Version: {}".format(version))
        logger.info("System Info: {}".format(get_system_info()))
        logger.debug(f"Debug flag: {debug}")

        import audio

        # Plug-ins
        from plugin import (
            Plugin,
            System_Plugin_Base,
            Plugin_List,
            import_runtime_plugins,
        )
        from plugin_manager import Plugin_Manager
        from calibration_choreography import (
            available_calibration_choreography_plugins,
            CalibrationChoreographyPlugin,
            patch_loaded_plugins_with_choreography_plugin,
        )

        available_choreography_plugins = available_calibration_choreography_plugins()

        from gaze_mapping import registered_gazer_classes
        from gaze_mapping.gazer_base import GazerBase
        from pupil_detector_plugins.detector_base_plugin import PupilDetectorPlugin
        from fixation_detector import Fixation_Detector
        from recorder import Recorder
        from display_recent_gaze import Display_Recent_Gaze
        from time_sync import Time_Sync
        from network_api import NetworkApiPlugin
        from pupil_groups import Pupil_Groups
        from surface_tracker import Surface_Tracker_Online
        from log_display import Log_Display
        from annotations import Annotation_Capture
        from log_history import Log_History
        from blink_detection import Blink_Detection
        from video_capture import (
            source_classes,
            manager_classes,
            Base_Manager,
            Base_Source,
        )
        from pupil_data_relay import Pupil_Data_Relay
        from remote_recorder import Remote_Recorder
        from accuracy_visualizer import Accuracy_Visualizer

        from system_graphs import System_Graphs
        from camera_intrinsics_estimation import Camera_Intrinsics_Estimation
        from hololens_relay import Hololens_Relay
        from head_pose_tracker.online_head_pose_tracker import Online_Head_Pose_Tracker

        # UI Platform tweaks
        if platform.system() == "Linux":
            scroll_factor = 10.0
            window_position_default = (30, 30)
        elif platform.system() == "Windows":
            scroll_factor = 10.0
            window_position_default = (8, 90)
        else:
            scroll_factor = 1.0
            window_position_default = (0, 0)

        process_was_interrupted = False

        def interrupt_handler(sig, frame):
            import traceback

            trace = traceback.format_stack(f=frame)
            logger.debug(f"Caught signal {sig} in:\n" + "".join(trace))
            nonlocal process_was_interrupted
            process_was_interrupted = True

        signal.signal(signal.SIGINT, interrupt_handler)

        icon_bar_width = 50
        window_size = None
        camera_render_size = None
        content_scale = 1.0

        # g_pool holds variables for this process they are accessible to all plugins
        g_pool = SimpleNamespace()
        g_pool.debug = debug
        g_pool.app = "capture"
        g_pool.process = "world"
        g_pool.user_dir = user_dir
        g_pool.version = version
        g_pool.timebase = timebase
        g_pool.zmq_ctx = zmq_ctx
        g_pool.ipc_pub = ipc_pub
        g_pool.ipc_pub_url = ipc_pub_url
        g_pool.ipc_sub_url = ipc_sub_url
        g_pool.ipc_push_url = ipc_push_url
        g_pool.eye_procs_alive = eye_procs_alive
        g_pool.preferred_remote_port = preferred_remote_port

        def get_timestamp():
            return get_time_monotonic() - g_pool.timebase.value

        g_pool.get_timestamp = get_timestamp
        g_pool.get_now = get_time_monotonic

        # manage plugins
        runtime_plugins = import_runtime_plugins(
            os.path.join(g_pool.user_dir, "plugins")
        )
        runtime_plugins = [
            p for p in runtime_plugins if not issubclass(p, PupilDetectorPlugin)
        ]
        user_plugins = [
            Pupil_Groups,
            NetworkApiPlugin,
            Time_Sync,
            Surface_Tracker_Online,
            Annotation_Capture,
            Log_History,
            Fixation_Detector,
            Blink_Detection,
            Remote_Recorder,
            Accuracy_Visualizer,
            Camera_Intrinsics_Estimation,
            Hololens_Relay,
            Online_Head_Pose_Tracker,
        ]

        system_plugins = (
            [
                Log_Display,
                Display_Recent_Gaze,
                Recorder,
                Pupil_Data_Relay,
                Plugin_Manager,
                System_Graphs,
            ]
            + manager_classes
            + source_classes
        )
        plugins = (
            system_plugins
            + user_plugins
            + runtime_plugins
            + available_choreography_plugins
            + registered_gazer_classes()
        )
        user_plugins += [
            p
            for p in runtime_plugins
            if not isinstance(
                p,
                (
                    Base_Manager,
                    Base_Source,
                    System_Plugin_Base,
                    CalibrationChoreographyPlugin,
                    GazerBase,
                ),
            )
        ]
        g_pool.plugin_by_name = {p.__name__: p for p in plugins}

        default_capture_name = "UVC_Source"
        default_capture_settings = {
            "preferred_names": [
                "Pupil Cam1 ID2",
                "Logitech Camera",
                "(046d:081d)",
                "C510",
                "B525",
                "C525",
                "C615",
                "C920",
                "C930e",
            ],
            "frame_size": (1280, 720),
            "frame_rate": 30,
        }

        default_plugins = [
            (default_capture_name, default_capture_settings),
            ("Pupil_Data_Relay", {}),
            ("UVC_Manager", {}),
            ("NDSI_Manager", {}),
            ("HMD_Streaming_Manager", {}),
            ("File_Manager", {}),
            ("Log_Display", {}),
            ("Dummy_Gaze_Mapper", {}),
            ("Display_Recent_Gaze", {}),
            # Calibration choreography plugin is added below by calling
            # patch_loaded_plugins_with_choreography_plugin
            ("Recorder", {}),
            ("NetworkApiPlugin", {}),
            ("Fixation_Detector", {}),
            ("Blink_Detection", {}),
            ("Accuracy_Visualizer", {}),
            ("Plugin_Manager", {}),
            ("System_Graphs", {}),
        ]

        def consume_events_and_render_buffer():
            gl_utils.glViewport(0, 0, *camera_render_size)
            for p in g_pool.plugins:
                p.gl_display()

            gl_utils.glViewport(0, 0, *window_size)
            try:
                clipboard = glfw.get_clipboard_string(main_window).decode()
            except (AttributeError, glfw.GLFWError):
                # clipboard is None, might happen on startup
                clipboard = ""
            g_pool.gui.update_clipboard(clipboard)
            user_input = g_pool.gui.update()
            if user_input.clipboard != clipboard:
                # only write to clipboard if content changed
                glfw.set_clipboard_string(main_window, user_input.clipboard)

            for button, action, mods in user_input.buttons:
                x, y = glfw.get_cursor_pos(main_window)
                pos = gl_utils.window_coordinate_to_framebuffer_coordinate(
                    main_window, x, y, cached_scale=None
                )
                pos = normalize(pos, camera_render_size)
                # Position in img pixels
                pos = denormalize(pos, g_pool.capture.frame_size)

                for plugin in g_pool.plugins:
                    if plugin.on_click(pos, button, action):
                        break

            for key, scancode, action, mods in user_input.keys:
                for plugin in g_pool.plugins:
                    if plugin.on_key(key, scancode, action, mods):
                        break

            for char_ in user_input.chars:
                for plugin in g_pool.plugins:
                    if plugin.on_char(char_):
                        break

            glfw.swap_buffers(main_window)

        # Callback functions
        def on_resize(window, w, h):
            nonlocal window_size
            nonlocal camera_render_size
            nonlocal content_scale
            if w == 0 or h == 0:
                return

            # Always clear buffers on resize to make sure that there are no overlapping
            # artifacts from previous frames.
            gl_utils.glClear(GL_COLOR_BUFFER_BIT)
            gl_utils.glClearColor(0, 0, 0, 1)

            content_scale = gl_utils.get_content_scale(window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(window)
            g_pool.gui.scale = content_scale
            window_size = w, h
            camera_render_size = w - int(icon_bar_width * g_pool.gui.scale), h
            g_pool.gui.update_window(*window_size)
            g_pool.gui.collect_menus()

            for p in g_pool.plugins:
                p.on_window_resize(window, *camera_render_size)

            # Minimum window size required, otherwise parts of the UI can cause openGL
            # issues with permanent effects. Depends on the content scale, which can
            # potentially be dynamically modified, so we re-adjust the size limits every
            # time here.
            min_size = int(2 * icon_bar_width * g_pool.gui.scale / framebuffer_scale)
            glfw.set_window_size_limits(
                window,
                min_size,
                min_size,
                glfw.DONT_CARE,
                glfw.DONT_CARE,
            )

            # Needed, to update the window buffer while resizing
            consume_events_and_render_buffer()

        def on_window_key(window, key, scancode, action, mods):
            g_pool.gui.update_key(key, scancode, action, mods)

        def on_window_char(window, char):
            g_pool.gui.update_char(char)

        def on_window_mouse_button(window, button, action, mods):
            g_pool.gui.update_button(button, action, mods)

        def on_pos(window, x, y):
            x, y = gl_utils.window_coordinate_to_framebuffer_coordinate(
                window, x, y, cached_scale=None
            )
            g_pool.gui.update_mouse(x, y)
            pos = x, y
            pos = normalize(pos, camera_render_size)
            # Position in img pixels
            pos = denormalize(pos, g_pool.capture.frame_size)
            for p in g_pool.plugins:
                p.on_pos(pos)

        def on_scroll(window, x, y):
            g_pool.gui.update_scroll(x, y * scroll_factor)

        def on_drop(window, paths):
            for plugin in g_pool.plugins:
                if plugin.on_drop(paths):
                    break

        tick = delta_t()

        def get_dt():
            return next(tick)

        # load session persistent settings
        session_settings = Persistent_Dict(
            os.path.join(g_pool.user_dir, "user_settings_world")
        )
        if parse_version(session_settings.get("version", "0.0")) != g_pool.version:
            logger.info(
                "Session setting are from a different version of this app. I will not use those."
            )
            session_settings.clear()

        g_pool.min_data_confidence = 0.6
        g_pool.min_calibration_confidence = session_settings.get(
            "min_calibration_confidence", 0.8
        )
        g_pool.pupil_detection_enabled = session_settings.get(
            "pupil_detection_enabled", True
        )
        g_pool.active_gaze_mapping_plugin = None
        g_pool.capture = None

        audio.set_audio_mode(
            session_settings.get("audio_mode", audio.get_default_audio_mode())
        )

        def handle_notifications(noti):
            subject = noti["subject"]
            if subject == "set_pupil_detection_enabled":
                g_pool.pupil_detection_enabled = noti["value"]
            elif subject == "start_plugin":
                try:
                    g_pool.plugins.add(
                        g_pool.plugin_by_name[noti["name"]], args=noti.get("args", {})
                    )
                except KeyError as err:
                    logger.error(f"Attempt to load unknown plugin: {err}")
            elif subject == "stop_plugin":
                for p in g_pool.plugins:
                    if p.class_name == noti["name"]:
                        p.alive = False
                        g_pool.plugins.clean()
            elif subject == "eye_process.started":
                noti = {
                    "subject": "set_pupil_detection_enabled",
                    "value": g_pool.pupil_detection_enabled,
                }
                ipc_pub.notify(noti)
            elif subject == "set_min_calibration_confidence":
                g_pool.min_calibration_confidence = noti["value"]
            elif subject.startswith("meta.should_doc"):
                ipc_pub.notify(
                    {"subject": "meta.doc", "actor": g_pool.app, "doc": world.__doc__}
                )
                for p in g_pool.plugins:
                    if (
                        p.on_notify.__doc__
                        and p.__class__.on_notify != Plugin.on_notify
                    ):
                        ipc_pub.notify(
                            {
                                "subject": "meta.doc",
                                "actor": p.class_name,
                                "doc": p.on_notify.__doc__,
                            }
                        )
            elif subject == "world_process.adapt_window_size":
                set_window_size()
            elif subject == "world_process.should_stop":
                glfw.set_window_should_close(main_window, True)

        width, height = session_settings.get(
            "window_size", (1280 + icon_bar_width, 720)
        )

        # window and gl setup
        glfw.init()
        glfw.window_hint(glfw.SCALE_TO_MONITOR, glfw.TRUE)
        if hide_ui:
            glfw.window_hint(glfw.VISIBLE, 0)  # hide window
        main_window = glfw.create_window(
            width, height, "Pupil Capture - World", None, None
        )

        window_position_manager = gl_utils.WindowPositionManager()
        window_pos = window_position_manager.new_window_position(
            window=main_window,
            default_position=window_position_default,
            previous_position=session_settings.get("window_position", None),
        )
        glfw.set_window_pos(main_window, window_pos[0], window_pos[1])

        glfw.make_context_current(main_window)
        cygl.utils.init()
        g_pool.main_window = main_window

        def reset_restart():
            logger.warning("Resetting all settings and restarting Capture.")
            glfw.set_window_should_close(main_window, True)
            ipc_pub.notify({"subject": "clear_settings_process.should_start"})
            ipc_pub.notify({"subject": "world_process.should_start", "delay": 2.0})

        def toggle_general_settings(collapsed):
            # this is the menu toggle logic.
            # Only one menu can be open.
            # If no menu is opened, the menubar should collapse.
            g_pool.menubar.collapsed = collapsed
            for m in g_pool.menubar.elements:
                m.collapsed = True
            general_settings.collapsed = collapsed

        # setup GUI
        g_pool.gui = ui.UI()
        g_pool.menubar = ui.Scrolling_Menu(
            "Settings", pos=(-400, 0), size=(-icon_bar_width, 0), header_pos="left"
        )
        g_pool.iconbar = ui.Scrolling_Menu(
            "Icons", pos=(-icon_bar_width, 0), size=(0, 0), header_pos="hidden"
        )
        g_pool.quickbar = ui.Stretching_Menu("Quick Bar", (0, 100), (120, -100))
        g_pool.gui.append(g_pool.menubar)
        g_pool.gui.append(g_pool.iconbar)
        g_pool.gui.append(g_pool.quickbar)

        general_settings = ui.Growing_Menu("General", header_pos="headline")

        def set_window_size():
            # Get current capture frame size
            f_width, f_height = g_pool.capture.frame_size

            # Get current display scale factor
            content_scale = gl_utils.get_content_scale(main_window)
            framebuffer_scale = gl_utils.get_framebuffer_scale(main_window)
            display_scale_factor = content_scale / framebuffer_scale

            # Scale the capture frame size by display scale factor
            f_width *= display_scale_factor
            f_height *= display_scale_factor

            # Increas the width to account for the added scaled icon bar width
            f_width += icon_bar_width * display_scale_factor

            # Set the newly calculated size (scaled capture frame size + scaled icon bar width)
            glfw.set_window_size(main_window, int(f_width), int(f_height))

        general_settings.append(ui.Button("Reset window size", set_window_size))
        general_settings.append(
            ui.Selector(
                "Audio mode",
                None,
                getter=audio.get_audio_mode,
                setter=audio.set_audio_mode,
                selection=audio.get_audio_mode_list(),
            )
        )

        general_settings.append(
            ui.Switch(
                "pupil_detection_enabled",
                label="Pupil detection",
                getter=detection_enabled_getter,
                setter=detection_enabled_setter,
            )
        )
        general_settings.append(
            ui.Switch(
                "eye0_process",
                label="Detect eye 0",
                setter=lambda alive: start_stop_eye(0, alive),
                getter=lambda: eye_procs_alive[0].value,
            )
        )
        general_settings.append(
            ui.Switch(
                "eye1_process",
                label="Detect eye 1",
                setter=lambda alive: start_stop_eye(1, alive),
                getter=lambda: eye_procs_alive[1].value,
            )
        )

        general_settings.append(
            ui.Info_Text("Capture Version: {}".format(g_pool.version))
        )
        general_settings.append(
            ui.Button("Restart with default settings", reset_restart)
        )

        g_pool.menubar.append(general_settings)
        icon = ui.Icon(
            "collapsed",
            general_settings,
            label=chr(0xE8B8),
            on_val=False,
            off_val=True,
            setter=toggle_general_settings,
            label_font="pupil_icons",
        )
        icon.tooltip = "General Settings"
        g_pool.iconbar.append(icon)

        user_plugin_separator = ui.Separator()
        user_plugin_separator.order = 0.35
        g_pool.iconbar.append(user_plugin_separator)

        loaded_plugins = session_settings.get("loaded_plugins", default_plugins)

        # Resolve the active calibration choreography plugin
        loaded_plugins = patch_loaded_plugins_with_choreography_plugin(
            loaded_plugins, app=g_pool.app
        )
        session_settings["loaded_plugins"] = loaded_plugins

        # plugins that are loaded based on user settings from previous session
        g_pool.plugins = Plugin_List(g_pool, loaded_plugins)

        if not g_pool.capture:
            # Make sure we always have a capture running. Important if there was no
            # capture stored in session settings.
            g_pool.plugins.add(
                g_pool.plugin_by_name[default_capture_name], default_capture_settings
            )

        # Register callbacks main_window
        glfw.set_framebuffer_size_callback(main_window, on_resize)
        glfw.set_key_callback(main_window, on_window_key)
        glfw.set_char_callback(main_window, on_window_char)
        glfw.set_mouse_button_callback(main_window, on_window_mouse_button)
        glfw.set_cursor_pos_callback(main_window, on_pos)
        glfw.set_scroll_callback(main_window, on_scroll)
        glfw.set_drop_callback(main_window, on_drop)

        # gl_state settings
        gl_utils.basic_gl_setup()
        g_pool.image_tex = Named_Texture()

        toggle_general_settings(True)

        # now that we have a proper window we can load the last gui configuration
        g_pool.gui.configuration = session_settings.get("ui_config", {})
        # If previously selected plugin was not loaded this time, we will have an
        # expanded menubar without any menu selected. We need to ensure the menubar is
        # collapsed in this case.
        if all(submenu.collapsed for submenu in g_pool.menubar.elements):
            g_pool.menubar.collapsed = True

        # create a timer to control window update frequency
        window_update_timer = timer(1 / 60)

        def window_should_update():
            return next(window_update_timer)

        # trigger setup of window and gl sizes
        on_resize(main_window, *glfw.get_framebuffer_size(main_window))

        if session_settings.get("eye1_process_alive", True):
            launch_eye_process(1, delay=0.6)
        if session_settings.get("eye0_process_alive", True):
            launch_eye_process(0, delay=0.3)

        ipc_pub.notify({"subject": "world_process.started"})
        logger.warning("Process started.")

        if platform.system() == "Darwin":
            # On macOS, calls to glfw.swap_buffers() deliberately take longer in case of
            # occluded windows, based on the swap interval value. This causes an FPS drop
            # and leads to problems when recording. To side-step this behaviour, the swap
            # interval is set to zero.
            #
            # Read more about window occlusion on macOS here:
            # https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/WorkWhenVisible.html
            glfw.swap_interval(0)

        # Event loop
        while not glfw.window_should_close(main_window) and not process_was_interrupted:

            # fetch newest notifications
            new_notifications = []
            while notify_sub.new_data:
                t, n = notify_sub.recv()
                new_notifications.append(n)

            # notify each plugin if there are new notifications:
            for n in new_notifications:
                handle_notifications(n)
                for p in g_pool.plugins:
                    p.on_notify(n)

            # a dictionary that allows plugins to post and read events
            events = {}
            # report time between now and the last loop interation
            events["dt"] = get_dt()

            # allow each Plugin to do its work.
            for p in g_pool.plugins:
                p.recent_events(events)

            # check if a plugin need to be destroyed
            g_pool.plugins.clean()

            # "blacklisted" events that were already sent
            del events["pupil"]
            del events["gaze"]
            # delete if exists. More expensive than del, so only use it when key might not exist
            events.pop("annotation", None)

            # send new events to ipc:
            if "frame" in events:
                del events["frame"]  # send explicitly with frame publisher
            if "depth_frame" in events:
                del events["depth_frame"]
            if "audio_packets" in events:
                del events["audio_packets"]
            del events["dt"]  # no need to send this
            for data in events.values():
                assert isinstance(data, (list, tuple))
                for d in data:
                    ipc_pub.send(d)

            glfw.make_context_current(main_window)
            # render visual feedback from loaded plugins
            glfw.poll_events()
            if window_should_update() and gl_utils.is_window_visible(main_window):

                gl_utils.glViewport(0, 0, *camera_render_size)
                for p in g_pool.plugins:
                    p.gl_display()

                gl_utils.glViewport(0, 0, *window_size)
                try:
                    clipboard = glfw.get_clipboard_string(main_window).decode()
                except (AttributeError, glfw.GLFWError):
                    # clipboard is None, might happen on startup
                    clipboard = ""
                g_pool.gui.update_clipboard(clipboard)
                user_input = g_pool.gui.update()
                if user_input.clipboard != clipboard:
                    # only write to clipboard if content changed
                    glfw.set_clipboard_string(main_window, user_input.clipboard)

                for button, action, mods in user_input.buttons:
                    x, y = glfw.get_cursor_pos(main_window)
                    pos = gl_utils.window_coordinate_to_framebuffer_coordinate(
                        main_window, x, y, cached_scale=None
                    )
                    pos = normalize(pos, camera_render_size)
                    # Position in img pixels
                    pos = denormalize(pos, g_pool.capture.frame_size)

                    for plugin in g_pool.plugins:
                        if plugin.on_click(pos, button, action):
                            break

                for key, scancode, action, mods in user_input.keys:
                    for plugin in g_pool.plugins:
                        if plugin.on_key(key, scancode, action, mods):
                            break

                for char_ in user_input.chars:
                    for plugin in g_pool.plugins:
                        if plugin.on_char(char_):
                            break

                glfw.swap_buffers(main_window)

        session_settings["loaded_plugins"] = g_pool.plugins.get_initializers()
        session_settings["ui_config"] = g_pool.gui.configuration
        session_settings["version"] = str(g_pool.version)
        session_settings["eye0_process_alive"] = eye_procs_alive[0].value
        session_settings["eye1_process_alive"] = eye_procs_alive[1].value
        session_settings[
            "min_calibration_confidence"
        ] = g_pool.min_calibration_confidence
        session_settings["pupil_detection_enabled"] = g_pool.pupil_detection_enabled
        session_settings["audio_mode"] = audio.get_audio_mode()

        if not hide_ui:
            glfw.restore_window(main_window)  # need to do this for windows os
            session_settings["window_position"] = glfw.get_window_pos(main_window)
            session_window_size = glfw.get_window_size(main_window)
            if 0 not in session_window_size:
                f_width, f_height = session_window_size
                if platform.system() in ("Windows", "Linux"):
                    f_width, f_height = (
                        f_width / content_scale,
                        f_height / content_scale,
                    )
                session_settings["window_size"] = int(f_width), int(f_height)

        session_settings.close()

        # de-init all running plugins
        for p in g_pool.plugins:
            p.alive = False
        g_pool.plugins.clean()

        g_pool.gui.terminate()
        glfw.destroy_window(main_window)
        glfw.terminate()

    except Exception:
        import traceback

        trace = traceback.format_exc()
        logger.error("Process Capture crashed with trace:\n{}".format(trace))

    finally:
        # shut down eye processes:
        stop_eye_process(0)
        stop_eye_process(1)

        logger.info("Process shutting down.")
        ipc_pub.notify({"subject": "world_process.stopped"})
        sleep(1.0)
Пример #57
0
	def start(self):

		if not glfw.init():
			print("Could not initialize OpenGL context")
			exit(1)

		glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
		glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3)
		glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
		glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

		#glfw.window_hint(glfw.RESIZABLE, self.resizable)
		glfw.window_hint(glfw.DOUBLEBUFFER, True)
		glfw.window_hint(glfw.DEPTH_BITS, 24)
		#glfw.window_hint(glfw.SAMPLES, 1)

		glfw.window_hint(glfw.DECORATED, False)

		monitor = None
		
		'''
		if self.fullscreen:
			# Use the primary monitors current resolution
			monitor = glfw.get_primary_monitor()
			self.width, self.height = mode.size.width, mode.size.height
			mode = glfw.get_video_mode(monitor)
		'''

		self.window = glfw.create_window(self.width, self.height, self.window_name, monitor, None)
		
		if not self.window:
			glfw.terminate()
			raise ValueError("Failed to create window")
		
		'''
		if not self.cursor:
			glfw.set_input_mode(self.window, glfw.CURSOR, glfw.CURSOR_DISABLED)
		'''

		glfw.set_window_pos(self.window, 40, 40)

		# Get the actual buffer size of the window
		# This is important for some displays like Apple's Retina as reported window sizes are virtual
		self.buffer_width, self.buffer_height = glfw.get_framebuffer_size(self.window)
		#print("Frame buffer size:", self.buffer_width, self.buffer_height)
		#print("Actual window size:", glfw.get_window_size(self.window))

		glfw.make_context_current(self.window)

		# The number of screen updates to wait from the time glfwSwapBuffers
		# was called before swapping the buffers and returning
		if self.bVsync:
			glfw.swap_interval(1)

		glfw.set_key_callback(self.window, self.key_event_callback)
		#glfw.set_cursor_pos_callback(self.window, self.mouse_event_callback)
		#glfw.set_window_size_callback(self.window, self.window_resize_callback)

		# Create mederngl context from existing context
		self.ctx = moderngl.create_context(require=330)
		self.fbo = self.ctx.screen

		#self.ctx.viewport = self.window.viewport
		#self.set_default_viewport()
		#print("Wow ! GL_SHADING_LANGUAGE_VERSION :", gl.glGetString(gl.GL_SHADING_LANGUAGE_VERSION))

		'''
		self.proj = Matrix44.perspective_projection(45.0, float(self.width)/float(self.height), 0.1, 1000.0)
		self.lookat = Matrix44.look_at(
			(0.0, 0.0, 10.0),
			(0.0, 0.0, 0.0),
			(0.0, -1.0, 0.0),
		)
		'''
		
		left = 0 #-float(self.width)
		right = float(self.width)
		top = 0 #float(self.height) 
		bottom = -float(self.height) 
		near = 1.0
		far = 1000.0
		self.proj = Matrix44.orthogonal_projection(left, right, bottom, top, near, far)
		self.lookat = Matrix44.look_at(
			(0.0, 0.0, -10.0),
			(0.0, 0.0, 0.0),
			(0.0, -1.0, 0.0),
		)

		self.prog = self.ctx.program(
			vertex_shader='''
				#version 330

				uniform mat4 MVP;

				//in vec3 in_vert;
				in vec2 in_vert;
				in vec2 in_text;

				out vec2 v_text;

				void main() 
				{
					//gl_Position = MVP * vec4(in_vert, 1.0);
					gl_Position = MVP * vec4(in_vert, 0.0, 1.0);
					v_text = in_text;
				}
			''',
			fragment_shader='''
				#version 330
				
				uniform sampler2D Texture;

				in vec2 v_text;

				out vec4 f_color;

				void main() 
				{
					//f_color = vec4(0.3, 0.5, 1.0, 1.0);
					f_color = vec4(texture(Texture, v_text).rgb, 1.0);
				}
			''',
		)
		
		self.mvp = self.prog['MVP']

		img_left = Image.open(local('assets', 'l.png')).convert('RGB')
		self.texture_left = self.ctx.texture(img_left.size, 3, img_left.tobytes())
		#self.texture_left.build_mipmaps()

		#img_right = Image.open(local('assets', 'r.png')).convert('RGB')
		#self.texture_right = self.ctx.texture(img_right.size, 3, img_right.tobytes())
		#self.texture_right.build_mipmaps()

		texSize = (1024,1024)

		self.texture_left = self.ctx.texture((1024,1024), 3)
		depth_attachment_left = self.ctx.depth_renderbuffer(texSize)
		self.fbo_left = self.ctx.framebuffer(self.texture_left, depth_attachment_left)

		self.texture_right = self.ctx.texture((1024,1024), 3)
		depth_attachment_right = self.ctx.depth_renderbuffer(texSize)
		self.fbo_right = self.ctx.framebuffer(self.texture_right, depth_attachment_right)

		vertices_left_quad = np.array([
			0.0, 0.0,					0.0,1.0,
			0.0, self.height,			0.0,0.0,
			self.width/2, 0.0,			1.0,1.0,
			self.width/2, self.height,	1.0,0.0
		])
		self.vbo_left_quad = self.ctx.buffer(vertices_left_quad.astype('f4').tobytes())
		self.vao_left_quad = self.ctx.simple_vertex_array(self.prog, self.vbo_left_quad, 'in_vert', 'in_text')
		
		vertices_right_quad = np.array([
			self.width/2, 0.0,			0.0,1.0,
			self.width/2, self.height,	0.0,0.0,
			self.width, 0.0,			1.0,1.0,
			self.width, self.height, 	1.0,0.0
		])
		self.vbo_right_quad = self.ctx.buffer(vertices_right_quad.astype('f4').tobytes())
		self.vao_right_quad = self.ctx.simple_vertex_array(self.prog, self.vbo_right_quad, 'in_vert', 'in_text')

		#####

		# Persp scene

		self.proj_sample = Matrix44.perspective_projection(45.0, self.width / self.height, 0.1, 1000.0)

		self.proj_sample_stereo = Matrix44.perspective_projection(45.0, (self.width/2) / self.height, 0.1, 1000.0)

		self.lookat_sample = Matrix44.look_at(
			(50.0, 20.0, 30.0),
			(0.0, 0.0, 10.0),
			(0.0, 0.0, 1.0),
		)
		
		self.prog_sample = self.ctx.program(
			vertex_shader='''
				#version 330

				uniform mat4 MVP;

				in vec3 in_vert;
				in vec3 in_norm;
				in vec2 in_text;

				out vec3 v_vert;
				out vec3 v_norm;
				out vec2 v_text;

				void main() {
					gl_Position = MVP * vec4(in_vert, 1.0);
					v_vert = in_vert;
					v_norm = in_norm;
					v_text = in_text;
				}
			''',
			fragment_shader='''
				#version 330

				uniform vec3 Light;
				uniform vec3 Color;
				uniform bool UseTexture;
				uniform sampler2D Texture;

				in vec3 v_vert;
				in vec3 v_norm;
				in vec2 v_text;

				out vec4 f_color;

				void main() {
					float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
					if (UseTexture) {
						f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
					} else {
						f_color = vec4(Color * lum, 1.0);
					}
				}
			''',
		)
		
		self.objects = {}

		for name in ['ground', 'grass', 'billboard', 'billboard-holder', 'billboard-image']:
			obj = Obj.open(local('assets', 'scene-1-%s.obj' % name))
			vbo = self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))
			vao = self.ctx.simple_vertex_array(self.prog_sample, vbo, 'in_vert', 'in_norm', 'in_text')
			self.objects[name] = vao

		img = Image.open(local('assets', 'infographic-1.jpg')).transpose(Image.FLIP_TOP_BOTTOM).convert('RGB')
		self.texture_sample = self.ctx.texture(img.size, 3, img.tobytes())
		self.texture_sample.build_mipmaps()

		self.mvp_sample = self.prog_sample['MVP']
		self.bUseTexture_sample = self.prog_sample['UseTexture']
		self.light_sample = self.prog_sample['Light']
		self.color_sample = self.prog_sample['Color']