Beispiel #1
0
def show(molecule, width=500, height=500,
         show_bonds=True, bonds_method='radii', bonds_param=None,
         camera=None, title='mogli'):
    """
    Interactively show the given molecule with OpenGL. By default, bonds are
    drawn, if this is undesired the show_bonds parameter can be set to False.
    For information on the bond calculation, see Molecule.calculate_bonds.
    If you pass a tuple of camera position, center of view and an up vector to
    the camera parameter, the camera will be set accordingly. Otherwise the
    molecule will be viewed in the direction of the z axis, with the y axis
    pointing upward.
    """
    global _camera
    molecule.positions -= np.mean(molecule.positions, axis=0)
    max_atom_distance = np.max(la.norm(molecule.positions, axis=1))
    if show_bonds:
        molecule.calculate_bonds(bonds_method, bonds_param)

    # If GR3 was initialized earlier, it would use a different context, so
    # it will be terminated first.
    gr3.terminate()

    # Initialize GLFW and create an OpenGL context
    glfw.init()
    glfw.window_hint(glfw.SAMPLES, 16)
    window = glfw.create_window(width, height, title, None, None)
    glfw.make_context_current(window)
    glEnable(GL_MULTISAMPLE)

    # Set up the camera (it will be changed during mouse rotation)
    if camera is None:
        camera_distance = -max_atom_distance*2.5
        camera = ((0, 0, camera_distance),
                  (0, 0, 0),
                  (0, 1, 0))
    camera = np.array(camera)
    _camera = camera

    # Create the GR3 scene
    gr3.setbackgroundcolor(255, 255, 255, 0)
    _create_gr3_scene(molecule, show_bonds)
    # Configure GLFW
    glfw.set_cursor_pos_callback(window, _mouse_move_callback)
    glfw.set_mouse_button_callback(window, _mouse_click_callback)
    glfw.swap_interval(1)
    # Start the GLFW main loop
    while not glfw.window_should_close(window):
        glfw.poll_events()
        width, height = glfw.get_window_size(window)
        glViewport(0, 0, width, height)
        _set_gr3_camera()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        gr3.drawimage(0, width, 0, height,
                      width, height, gr3.GR3_Drawable.GR3_DRAWABLE_OPENGL)
        glfw.swap_buffers(window)
    glfw.terminate()
    gr3.terminate()
Beispiel #2
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)
Beispiel #3
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)
Beispiel #4
0
def _mouse_move_callback(window, x, y):
    """ Mouse move event handler for GLFW. """
    global _previous_mouse_position, _camera
    if _mouse_dragging and _camera is not None:
        width, height = glfw.get_window_size(window)
        dx = (x-_previous_mouse_position[0])/width
        dy = (y-_previous_mouse_position[1])/height
        rotation_intensity = la.norm((dx, dy)) * 2
        eye, center, up = _camera
        camera_distance = la.norm(center-eye)
        forward = (center-eye)/camera_distance
        right = np.cross(forward, up)
        rotation_axis = (up*dx+right*dy)
        rotation_matrix = _create_rotation_matrix(-rotation_intensity,
                                                  rotation_axis[0],
                                                  rotation_axis[1],
                                                  rotation_axis[2])
        forward = np.dot(rotation_matrix, forward)
        up = np.dot(rotation_matrix, up)
        eye = center-forward*camera_distance
        _camera = eye, center, up
        _previous_mouse_position = (x, y)
Beispiel #5
0
 def __init__(self, window):
     super(Client, self).__init__()
     self.window = window
     self.width, self.height = glfw.get_window_size(window)
     self.init()
Beispiel #6
0
    def process(self, path=False, vertices=False, indices=False, info= False):


        if path:
            vertices, element_dict, info = read_model(path)
            indices = element_dict["triangles"] 
            print(f"Reading {path}")
        else:
            assert (type(vertices) ==np.ndarray and type(indices) ==np.ndarray), "Define path or both vertices and indices"
        
        pre_box = indices.size
        
        bounding_rect_vertices, bounding_rect_indices = bounding_box(vertices,indices)

        vertices = np.append(vertices,bounding_rect_vertices)

        

        

        indices = np.append(indices,bounding_rect_indices)

        vertex_normals = pyrr.vector3.generate_vertex_normals(vertices.reshape((-1,3)), indices.reshape((-1,3)), normalize_result=True).flatten()

        
        
        vertices_final = np.append(vertices,vertex_normals)



        


       

        # initializing glfw library
        if not glfw.init():
            raise Exception("glfw can not be initialized!")

        # creating the window
        window = glfw.create_window(1280, 720, "My OpenGL window", None, None)

        input_handler = InputHandler(window)
        # check if window was created
        if not window:
            glfw.terminate()
            raise Exception("glfw window can not be created!")

        # set window's position
        glfw.set_window_pos(window, 400, 200)

        # set the callback function for window resize

        glfw.set_window_size_callback(window, self.window_resize)
        # make the context current

        glfw.make_context_current(window)

        

        

        as_points = vertices.reshape(-1, 3)

        barycenter = as_points.mean(axis=0)

        max_x, max_y, max_z = as_points.max(axis=0)
        min_x, min_y, min_z = as_points.min(axis=0)

        middle_point = np.array(
            [min_x + (max_x-min_x)/2, min_y + (max_y-min_y)/2, min_z + (max_z-min_z)/2])





        shader = shader_loader.compile_shader("src/shaders/vert.vs", "src/shaders/frag.fs")




        
        # Vertex Buffer Object
        VBO = glGenBuffers(1)
        VA0 = glGenVertexArrays(1)
        glBindBuffer(GL_ARRAY_BUFFER, VBO)
        glBufferData(GL_ARRAY_BUFFER, vertices_final.nbytes, vertices_final, GL_STATIC_DRAW)

      


        
        #positions
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*4, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)
        #normals
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*4, ctypes.c_void_p(4*len(vertices)))
        glEnableVertexAttribArray(1)
    





        # Element Buffer Object
        EBO = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)



   
        glUseProgram(shader)
        glClearColor(0, 0.1, 0.1, 1)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glEnable(GL_DEPTH_TEST)

        ## Shader matrices
        model_loc = glGetUniformLocation(shader, "model")

        self.proj_loc = glGetUniformLocation(shader, "projection")

        view_loc = glGetUniformLocation(shader, "view")

        color_loc = glGetUniformLocation(shader,"color")

        transform_loc = glGetUniformLocation(shader, "transform")


        light_loc = glGetUniformLocation(shader, "light")

        window_height = glfw.get_window_size(window)[1]
        window_width = glfw.get_window_size(window)[0]
        projection = pyrr.matrix44.create_perspective_projection_matrix(
            fovy=45, aspect=window_width/window_height, near=0.1, far=100)
        #projection = pyrr.matrix44.create_orthogonal_projection_matrix(0,1280,0,720,-1000,1000)

        scale = pyrr.matrix44.create_from_scale(pyrr.Vector3([1]*3))


        # eye pos , target, up
        view = pyrr.matrix44.create_look_at(pyrr.Vector3(
            [0, 0, 3]), pyrr.Vector3([0, 0, 0]), pyrr.Vector3([0, 1, 0]))
        proj_matrix = glGetUniformLocation(shader, "projection")


        initial_offset = middle_point
        translation = pyrr.matrix44.create_from_translation(
            pyrr.Vector3(-initial_offset))


    


        ## Input

        
        rotation = pyrr.matrix44.create_from_axis_rotation(np.array([0, 1, 0]), 0)

        glfw.set_key_callback(window, input_handler.keyboard_handler)
        glfw.set_scroll_callback(window, input_handler.scroll_handler)
        glfw.set_mouse_button_callback(window, input_handler.mouse_handler)


        previous_displacement = np.zeros(2)



        rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time() )

        glUniformMatrix4fv(transform_loc, 1, GL_FALSE, rot_y)

        
  



        glEnable(GL_LIGHTING)
        glEnable(GL_COLOR_MATERIAL)
        while not glfw.window_should_close(window):
            glfw.poll_events()

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

            if input_handler.right_key_pressed:
                current_cursor_position = glfw.get_cursor_pos(window)
                cursor_displacement = np.array(current_cursor_position) - np.array(
                    input_handler.start_cursor_position) - previous_displacement
                input_handler.rotation_list[0] += input_handler.rotations_per_screen_hor * \
                    cursor_displacement[0]/window_width
                input_handler.rotation_list[1] += input_handler.rotations_per_screen_vert * \
                    cursor_displacement[1]/window_height
                previous_displacement = cursor_displacement

            rot_x = pyrr.Matrix44.from_x_rotation(input_handler.rotation_list[1])

            rot_y = pyrr.Matrix44.from_y_rotation(input_handler.rotation_list[0])

            rotation = pyrr.matrix44.multiply(rot_x, rot_y)

            view = pyrr.matrix44.create_look_at(pyrr.Vector3(input_handler.eye), pyrr.Vector3(
                input_handler.target), pyrr.Vector3(input_handler.up))

            light = pyrr.matrix44.create_identity()
            glUniformMatrix4fv(light_loc, 1, GL_FALSE, light)
       
            model = pyrr.matrix44.multiply(scale, translation)
            model = pyrr.matrix44.multiply(model, rotation)

            glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
            glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)
            glUniformMatrix4fv(proj_matrix, 1, GL_FALSE, projection)

            default_RGB  = np.zeros(shape=(3,),dtype=np.float32) +1

            color = pyrr.Vector3(default_RGB)
            glUniform3fv(color_loc,1,color)


           
    

            if input_handler.mode == "default":
    
                glDrawElements(GL_TRIANGLES, pre_box, GL_UNSIGNED_INT, None)
            elif input_handler.mode == "point_cloud":
                
                glDrawElements(GL_POINTS, pre_box, GL_UNSIGNED_INT, None)
                
            elif input_handler.mode=="wireframe":
                glEnable(GL_POLYGON_OFFSET_FILL)
                glPolygonOffset(1.0, 2)
                glDrawElements(GL_TRIANGLES, pre_box, GL_UNSIGNED_INT, None)
                RGB = np.zeros(shape=(3,),dtype=np.float32) 
                color = pyrr.Vector3(RGB)
                glUniform3fv(color_loc,1,RGB)
                glDrawElements(GL_LINES, pre_box, GL_UNSIGNED_INT, None)
            elif input_handler.mode == "bounding_box":
                glDrawElements(GL_LINES, len(indices), GL_UNSIGNED_INT, None)
            else:
                raise Exception("Invalid Mode!")

   
          

            

            glfw.swap_buffers(window)

        # terminate glfw, free up allocated resources
        glfw.terminate()
Beispiel #7
0
 def height(self):
     return glfw.get_window_size(self.window)[1]
Beispiel #8
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)
Beispiel #9
0
def get_window_content_rect(window) -> _Rectangle:
    x, y = glfw.get_window_pos(window)
    w, h = glfw.get_window_size(window)
    return _Rectangle(x=x, y=y, width=w, height=h)
Beispiel #10
0
def main():
    init()

    window = glfw.create_window(800, 600, "Chapter6", None, None)
    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_CULL_FACE)
    glDepthFunc(GL_LESS)
    glClearColor(0.3, 0.3, 0.3, 1)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)
    program_id = load_shaders('res/glsl/chapter6.vs', 'res/glsl/chapter6.fs')
    tex = texture.load('res/texture/dice.png')
    texture_id = glGetUniformLocation(program_id, 'TextureSampler')

    res_x, res_y = glfw.get_window_size(window)
    #projection = camera.ortho(-4,4,-3,3,0.1,10.0)
    projection = camera.perspective(45.0, res_x/res_y, 0.1, 100.0)
    view = camera.look_at(
        np.matrix([2,2,2], dtype=np.float32),
        np.matrix([0,0,0], dtype=np.float32),
        np.matrix([0,1,0], dtype=np.float32))
    model = np.matrix(np.identity(4), dtype=np.float32)

    projection_id = glGetUniformLocation(program_id, 'projection')
    view_id = glGetUniformLocation(program_id, 'view')
    model_id = glGetUniformLocation(program_id, 'model')

    vertex = np.array([
        #back
        -1,-1,1,
        1,-1,1,
        1,1,1,
        -1,1,1,
        -1,-1,1,
        1,1,1,

        #bottom
        -1,-1,-1,
        1,-1,-1,
        1,-1,1,
        1,-1,1,
        -1,-1,1,
        -1,-1,-1,

        #right
        1,-1,1,
        1,-1,-1,
        1,1,-1,
        1,1,-1,
        1,1,1,
        1,-1,1,

        #left
        -1,-1,-1,
        -1,-1,1,
        -1,1,-1,
        -1,1,-1,
        -1,-1,1,
        -1,1,1,

        #top
        -1,1,1,
        1,1,1,
        1,1,-1,
        1,1,-1,
        -1,1,-1,
        -1,1,1,

        #front
        1,-1,-1,
        -1,-1,-1,
        -1,1,-1,
        -1,1,-1,
        1,1,-1,
        1,-1,-1,

        ], dtype=np.float32)

    uv = np.array([
        #back
        0.25, 0.5,
        0.5, 0.5,
        0.5, 0.25,
        0.25, 0.25,
        0.25, 0.5,
        0.5, 0.25,

        #bottom
        0.25, 0.25,
        0.5, 0.25,
        0.5, 0.0,
        0.5, 0.0,
        0.25, 0.0,
        0.25, 0.25,

        #right
        0.0, 0.5,
        0.25, 0.5,
        0.25, 0.25,
        0.25, 0.25,
        0.0, 0.25,
        0.0, 0.5,

        #left
        0.5, 0.5,
        0.75, 0.5,
        0.5, 0.25,
        0.5, 0.25,
        0.75, 0.5,
        0.75, 0.25,

        #top
        0.25, 0.75,
        0.5, 0.75,
        0.5, 0.5,
        0.5, 0.5,
        0.25, 0.5,
        0.25, 0.75,

        #front
        0.75,0.5,
        1.0,0.5,
        1.0,0.25,
        1.0,0.25,
        0.75,0.25,
        0.75,0.5,
        ], dtype=np.float32)

    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, vertex.nbytes, vertex, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, uv.nbytes, uv, GL_STATIC_DRAW)

    while not glfw.window_should_close(window) and glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glUseProgram(program_id)
        glUniformMatrix4fv(projection_id, 1, GL_FALSE, projection)
        glUniformMatrix4fv(view_id, 1, GL_FALSE, view)
        glUniformMatrix4fv(model_id, 1, GL_FALSE, model)

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glUniform1i(texture_id, 0)

        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, None)

        glDrawArrays(GL_TRIANGLES, 0, int(len(vertex)/3))

        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()
Beispiel #11
0
def demo():
    global quit
    quit = False

    # Callback functions
    def on_resize(window, w, h):
        h = max(h, 1)
        w = max(w, 1)
        hdpi_factor = (glfw.get_framebuffer_size(window)[0] /
                       glfw.get_window_size(window)[0])
        w, h = w * hdpi_factor, h * hdpi_factor
        gui.update_window(w, h)
        active_window = glfw.get_current_context()
        glfw.make_context_current(active_window)
        # norm_size = normalize((w,h),glfw.get_window_size(window))
        # fb_size = denormalize(norm_size,glfw.get_framebuffer_size(window))
        adjust_gl_view(w, h, window)
        glfw.make_context_current(active_window)

    def on_iconify(window, iconfied):
        pass

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

        if action == glfw.PRESS:
            if key == glfw.KEY_ESCAPE:
                on_close(window)
            if mods == glfw.MOD_SUPER:
                if key == 67:
                    # copy value to system clipboard
                    # ideally copy what is in our text input area
                    test_val = "copied text input"
                    glfw.set_clipboard_string(window, test_val)
                    print("set clipboard to: %s" % (test_val))
                if key == 86:
                    # copy from system clipboard
                    clipboard = glfw.get_clipboard_string(window)
                    print("pasting from clipboard: %s" % (clipboard))

    def on_char(window, char):
        gui.update_char(char)

    def on_button(window, button, action, mods):
        gui.update_button(button, action, mods)
        # pos = normalize(pos,glfw.get_window_size(window))
        # pos = denormalize(pos,(frame.img.shape[1],frame.img.shape[0]) ) # Position in img pixels

    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)

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

    def on_close(window):
        global quit
        quit = True
        logger.info("Process closing from window")

    # get glfw started
    glfw.init()

    window = glfw.create_window(width, height, "pyglui demo", None, None)
    if not window:
        exit()

    glfw.set_window_pos(window, 0, 0)
    # Register callbacks for the window
    glfw.set_window_size_callback(window, on_resize)
    glfw.set_window_close_callback(window, on_close)
    glfw.set_window_iconify_callback(window, on_iconify)
    glfw.set_key_callback(window, on_key)
    glfw.set_char_callback(window, on_char)
    glfw.set_mouse_button_callback(window, on_button)
    glfw.set_cursor_pos_callback(window, on_pos)
    glfw.set_scroll_callback(window, on_scroll)
    # test out new paste function

    glfw.make_context_current(window)
    init()
    basic_gl_setup()

    print(glGetString(GL_VERSION))

    class Temp(object):
        """Temp class to make objects"""
        def __init__(self):
            pass

    foo = Temp()
    foo.bar = 34
    foo.sel = "mi"
    foo.selection = ["€", "mi", u"re"]

    foo.mytext = "some text"
    foo.T = True
    foo.L = False

    def set_text_val(val):
        foo.mytext = val
        # print 'setting to :',val

    def pr():
        print("pyglui version: %s" % (ui.__version__))

    gui = ui.UI()
    gui.scale = 1.0
    thumbbar = ui.Scrolling_Menu("ThumbBar",
                                 pos=(-80, 0),
                                 size=(0, 0),
                                 header_pos="hidden")
    menubar = ui.Scrolling_Menu("MenueBar",
                                pos=(-500, 0),
                                size=(-90, 0),
                                header_pos="left")

    gui.append(menubar)
    gui.append(thumbbar)

    T = ui.Growing_Menu("T menu", header_pos="headline")
    menubar.append(T)
    L = ui.Growing_Menu("L menu", header_pos="headline")
    menubar.append(L)
    M = ui.Growing_Menu("M menu", header_pos="headline")
    menubar.append(M)

    def toggle_menu(collapsed, menu):
        menubar.collapsed = collapsed
        for m in menubar.elements:
            m.collapsed = True
        menu.collapsed = collapsed

    thumbbar.append(
        ui.Thumb(
            "collapsed",
            T,
            label="T",
            on_val=False,
            off_val=True,
            setter=lambda x: toggle_menu(x, T),
        ))
    thumbbar.append(
        ui.Thumb(
            "collapsed",
            L,
            label="L",
            on_val=False,
            off_val=True,
            setter=lambda x: toggle_menu(x, L),
        ))
    thumbbar.append(
        ui.Thumb(
            "collapsed",
            M,
            label="M",
            on_val=False,
            off_val=True,
            setter=lambda x: toggle_menu(x, M),
        ))

    # thumbbar.elements[-1].order = -10.0
    print("order" + str(thumbbar.elements[-1].order))
    T.append(ui.Button("T test", pr))
    T.append(
        ui.Info_Text(
            "T best finerfpiwnesdco'n wfo;ineqrfo;inwefo'qefr voijeqfr'p9qefrp'i 'iqefr'ijqfr eqrfiqerfn'ioer"
        ))
    L.append(ui.Button("L test", pr))
    L.append(ui.Button("L best", pr))
    M.append(ui.Button("M test", pr))
    M.append(ui.Button("M best", pr))
    MM = ui.Growing_Menu("MM menu", pos=(0, 0), size=(0, 400))
    M.append(MM)
    for x in range(20):
        MM.append(ui.Button("M test%s" % x, pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    M.append(ui.Button("M best", pr))
    # label = 'Ï'
    # label = 'R'
    # gui.append(
    import os
    import psutil

    pid = os.getpid()
    ps = psutil.Process(pid)
    ts = time.time()

    from pyglui import graph

    print(graph.__version__)
    cpu_g = graph.Line_Graph()
    cpu_g.pos = (50, 100)
    cpu_g.update_fn = ps.cpu_percent
    cpu_g.update_rate = 5
    cpu_g.label = "CPU %0.1f"

    fps_g = graph.Line_Graph()
    fps_g.pos = (50, 100)
    fps_g.update_rate = 5
    fps_g.label = "%0.0f FPS"
    fps_g.color[:] = 0.1, 0.1, 0.8, 0.9

    on_resize(window, *glfw.get_window_size(window))

    while not quit:
        gui.update()
        # print(T.collapsed,L.collapsed,M.collapsed)
        # T.collapsed = True
        # glfw.make_context_current(window)
        glfw.swap_buffers(window)
        glfw.poll_events()
        # adjust_gl_view(1280,720,window)
        glClearColor(0.3, 0.4, 0.1, 1)
        glClear(GL_COLOR_BUFFER_BIT)

    gui.terminate()
    glfw.terminate()
    logger.debug("Process done")
Beispiel #12
0
 def size(self):
     return glfw.get_window_size(self.window)
Beispiel #13
0
def main():
    glfw.init()
    window = glfw.create_window(640, 320, "Chip8", None, None)
    glfw.make_context_current(window)

    program = glCreateProgram()

    with open("vertex.glsl") as source:
        vertex = glCreateShader(GL_VERTEX_SHADER)
        glShaderSource(vertex, source.read())
        glCompileShader(vertex)
        glAttachShader(program, vertex)

    with open("fragment.glsl") as source:
        fragment = glCreateShader(GL_FRAGMENT_SHADER)
        glShaderSource(fragment, source.read())
        glCompileShader(fragment)
        glAttachShader(program, fragment)

    glLinkProgram(program)

    vbo = glGenBuffers(1)
    vao = glGenVertexArrays(1)

    glBindVertexArray(vao)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(0)

    glBindVertexArray(0)

    program_counter = 0x200
    index = 0

    display   = [[0] * 64 for _ in range(32)]
    memory    = [0] * 4096
    variables = [0] * 16
    stack     = [ ]

    delay_timer = 0
    sound_timer = 0

    memory[0: 80] = [
        0xF0, 0x90, 0x90, 0x90, 0xF0,  # 0
        0x20, 0x60, 0x20, 0x20, 0x70,  # 1
        0xF0, 0x10, 0xF0, 0x80, 0xF0,  # 2
        0xF0, 0x10, 0xF0, 0x10, 0xF0,  # 3
        0x90, 0x90, 0xF0, 0x10, 0x10,  # 4
        0xF0, 0x80, 0xF0, 0x10, 0xF0,  # 5
        0xF0, 0x80, 0xF0, 0x90, 0xF0,  # 6
        0xF0, 0x10, 0x20, 0x40, 0x40,  # 7
        0xF0, 0x90, 0xF0, 0x90, 0xF0,  # 8
        0xF0, 0x90, 0xF0, 0x10, 0xF0,  # 9
        0xF0, 0x90, 0xF0, 0x90, 0x90,  # A
        0xE0, 0x90, 0xE0, 0x90, 0xE0,  # B
        0xF0, 0x80, 0x80, 0x80, 0xF0,  # C
        0xE0, 0x90, 0x90, 0x90, 0xE0,  # D
        0xF0, 0x80, 0xF0, 0x80, 0xF0,  # E
        0xF0, 0x80, 0xF0, 0x80, 0x80  # F
    ]

    binary = open("roms/" + input("Program? :> ") + ".ch8", "rb")

    for i, byte in enumerate(binary.read()):
        memory[0x200 + i] = byte

    binary.close()

    timer_clock = time.time()
    cycle_clock = time.time()

    while not glfw.window_should_close(window):
        if time.time() - timer_clock >= 1 / 60:
            if sound_timer > 0:
                sound_timer -= 1
            if delay_timer > 0:
                delay_timer -= 1

            timer_clock = time.time()

        if time.time() - cycle_clock >= 1 / 500:
            glfw.poll_events()

            opcode = memory[program_counter] << 8 | memory[program_counter + 1]

            x   = (opcode & 0x0F00) >> 8
            y   = (opcode & 0x00F0) >> 4
            n   = (opcode & 0x000F)
            nn  = (opcode & 0x00FF)
            nnn = (opcode & 0x0FFF)

            if (opcode & 0xF00F) == 0x0000:
                display = [[0] * 64 for _ in range(32)]

            if (opcode & 0xF00F) == 0x000E:
                program_counter = stack.pop()

            if (opcode & 0xF000) == 0x1000:
                program_counter = nnn - 2

            if (opcode & 0xF000) == 0x2000:
                stack.append(program_counter)
                program_counter = nnn - 2

            if (opcode & 0xF000) == 0x3000:
                if variables[x] == nn:
                    program_counter += 2

            if (opcode & 0xF000) == 0x4000:
                if variables[x] != nn:
                    program_counter += 2

            if (opcode & 0xF000) == 0x5000:
                if variables[x] == variables[y]:
                    program_counter += 2

            if (opcode & 0xF000) == 0x6000:
                variables[x] = nn

            if (opcode & 0xF000) == 0x7000:
                variables[x] = (variables[x] + nn) % 256

            if (opcode & 0xF00F) == 0x8000:
                variables[x] = variables[y]

            if (opcode & 0xF00F) == 0x8001:
                variables[x] = variables[x] | variables[y]

            if (opcode & 0xF00F) == 0x8002:
                variables[x] = variables[x] & variables[y]

            if (opcode & 0xF00F) == 0x8003:
                variables[x] = variables[x] ^ variables[y]

            if (opcode & 0xF00F) == 0x8004:
                if variables[x] + variables[y] > 255:
                    variables[0xF] = 1
                else:
                    variables[0xF] = 0

                variables[x] = (variables[x] + variables[y]) % 256

            if (opcode & 0xF00F) == 0x8005:
                if variables[x] > variables[y]:
                    variables[0xF] = 1
                else:
                    variables[0xF] = 0

                variables[x] = (variables[x] - variables[y]) % 256

            if (opcode & 0xF00F) == 0x8006:
                variables[0xF] = variables[x] & 1
                variables[x] = variables[x] >> 1

            if (opcode & 0xF00F) == 0x8007:
                if variables[y] > variables[x]:
                    variables[0xF] = 1
                else:
                    variables[0xF] = 0

                variables[x] = (variables[y] - variables[x]) % 256

            if (opcode & 0xF00F) == 0x800E:
                variables[0xF] = variables[x] >> 7
                variables[x] = (variables[x] << 1) % 256

            if (opcode & 0xF000) == 0x9000:
                if variables[x] != variables[y]:
                    program_counter += 2

            if (opcode & 0xF000) == 0xA000:
                index = nnn

            if (opcode & 0xF000) == 0xB000:
                program_counter = nnn + variables[0] - 2

            if (opcode & 0xF000) == 0xC000:
                variables[x] = random.randint(0, 255) & nn

            if (opcode & 0xF000) == 0xD000:  # todo
                variables[0xF] = 0
                x_pos, y_pos = variables[x] % 64, variables[y] % 32
                sprite = memory[index: index + n]

                for y_sprite, row in enumerate(sprite):
                    for x_sprite, pixel in enumerate(bin(row)[2:].zfill(8)):
                        pixel_x = x_pos + x_sprite
                        pixel_y = y_pos + y_sprite

                        if pixel_x >= 64 or pixel_y >= 32:
                            continue

                        if display[pixel_y][pixel_x] == 1 and int(pixel) == 1:
                            variables[0xF] = 1

                        display[pixel_y][pixel_x] ^= int(pixel)

            if (opcode & 0xF00F) == 0xE00E:
                if keyboard(window)[variables[x]] == 1:
                    program_counter += 2

            if (opcode & 0xF00F) == 0xE001:
                if keyboard(window)[variables[x]] == 0:
                    program_counter += 2

            if opcode & 0xF0FF == 0xF007:
                variables[x] = delay_timer

            if opcode & 0xF0FF == 0xF00A:
                key_press = False

                while not key_press:
                    for key, value in keyboard(window).items():
                        if value == 1:
                            variables[x] = key
                            key_press = True
                            break

            if opcode & 0xF0FF == 0xF015:
                delay_timer = variables[x]

            if opcode & 0xF0FF == 0xF018:
                sound_timer = variables[x]

            if opcode & 0xF0FF == 0xF01E:
                index = variables[x] + index

            if opcode & 0xF0FF == 0xF029:
                index = variables[x] * 5

            if opcode & 0xF0FF == 0xF033:
                memory[index + 0] = (variables[x] // 100) % 10
                memory[index + 1] = (variables[x] // 10) % 10
                memory[index + 2] = (variables[x] // 1) % 10

            if opcode & 0xF0FF == 0xF055:
                memory[index: index + x + 1] = variables[:x + 1]

            if opcode & 0xF0FF == 0xF065:
                variables[:x + 1] = memory[index: index + x + 1]

            glClear(GL_COLOR_BUFFER_BIT)
            glUseProgram(program)

            width, height = glfw.get_window_size(window)
            matrix = glm.ortho(0, width, height, 0)

            location = glGetUniformLocation(program, "ortho_matrix")
            glUniformMatrix4fv(location, 1, GL_FALSE, glm.value_ptr(matrix))

            verticies = []
            for x in range(64):
                for y in range(32):
                    if display[y][x] == 1:
                        verticies.extend([
                            (x    ) * 10, (y    ) * 10,
                            (x + 1) * 10, (y    ) * 10,
                            (x    ) * 10, (y + 1) * 10,
                            (x + 1) * 10, (y + 1) * 10,
                            (x    ) * 10, (y + 1) * 10,
                            (x + 1) * 10, (y    ) * 10
                        ])

            verticies = numpy.array(verticies, dtype=numpy.float32)

            glBindVertexArray(vao)
            glBindBuffer(GL_ARRAY_BUFFER, vbo)
            glBufferData(GL_ARRAY_BUFFER, verticies.nbytes, verticies, GL_DYNAMIC_DRAW)

            glDrawArrays(GL_TRIANGLES, 0, len(verticies))

            glBindVertexArray(0)
            glUseProgram(0)

            glfw.swap_buffers(window)

            program_counter += 2
            cycle_clock = time.time()
    glfw.terminate()
    def __init__(self, width=640, height=480, name="Window"):

        glfw.window_hint(glfw.RESIZABLE, True)
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)

        self.width, self.height = width, height

        self.win = glfw.create_window(width, height, name, None, None)
        if not self.win:
            glfw.terminate()
            exit()

        glfw.make_context_current(self.win)

        glfw.set_key_callback(self.win, self.on_key)
        glfw.set_window_size_callback(self.win, self.window_resize)
        # glfw.set_input_mode(self.win, glfw.CURSOR, glfw.CURSOR_NORMAL)
        glfw.set_cursor_pos_callback(self.win, self.on_mouse)
        glfw.set_scroll_callback(self.win, self.on_scroll)
        glfw.set_mouse_button_callback(self.win, self.on_mouse_button)

        print('OpenGL', glGetString(GL_VERSION).decode() + ', GLSL',
              glGetString(GL_SHADING_LANGUAGE_VERSION).decode() +
              ', Renderer', glGetString(GL_RENDERER).decode(), '\n')

        glClearColor(0, 0, 0, 1)
        glEnable(GL_CULL_FACE)

        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_DEPTH_TEST)
        # glEnable(GL_ALPHA_TEST)
        glDepthFunc(GL_LEQUAL)
        # glDepthMask(GL_FALSE)


        self.elements = list()
        self.colored_elements = list()
        # self.colored_elements.append(Pyramid())

        self.camera = Camera(self.win)

        self.trackball = Trackball()
        winsize = glfw.get_window_size(self.win)
        self.projection = self.trackball.projection_matrix(winsize)

        self.mouse_picker = MousePicker(self.camera, self.projection)

        self.texture_shader = Shader("res/shaders/basicShader")
        self.color_shader = Shader("res/shaders/grid")
        self.shaders = {
            "color": self.color_shader,
            "texture": self.texture_shader
        }

        self.map_pointer = None
        self.keys = {
            "e": False
        }
        self.clicks = {}


        self.delta_time = 0
        self.last_frame = 0

        self.last_x = 400
        self    .last_y = 300
        self.first_mouse = True

        self.move_x = 0
        self.move_y = 0


        self.map = BasicMap(5)
        main_planet = MainPlanet(1.0)
        main_planet_pos = (0, 0)

        self.map.set_entity(main_planet_pos, main_planet)
        # Trying to enter the main planet at the launch
        # self.map.selected_tile = self.map.get_tile(main_planet_pos)
        # self.map_pointer = main_planet

        self.elements.append(self.map)

        self.elements.extend((
            Background(1, 20),
            Background(2, 20),
            Background(3, 20)))

        self.pyramid = Pyramid()
 def window_resize(self, _window, _width, _height):
     self.width, self.height = _width, _height
     glViewport(0, 0, _width, _height)
     winsize = glfw.get_window_size(self.win)
     self.projection = self.trackball.projection_matrix(winsize)
     self.mouse_picker.projection_matrix = self.projection
Beispiel #16
0
def main():
    init()

    window = glfw.create_window(800, 600, "Chapter7", None, None)
    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LESS)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glClearColor(0.3, 0.3, 0.3, 1)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)
    program_id = load_shaders('res/glsl/chapter7.vs', 'res/glsl/chapter7.fs')

    res_x, res_y = glfw.get_window_size(window)
    #projection = camera.ortho(-4,4,-3,3,0.1,5.0)
    projection = camera.perspective(45.0, res_x / res_y, 0.1, 100.0)
    view = camera.look_at(np.matrix([2, 2, 2], dtype=np.float32),
                          np.matrix([0, 0, 0], dtype=np.float32),
                          np.matrix([0, 1, 0], dtype=np.float32))
    model = np.matrix(np.identity(4), dtype=np.float32)

    projection_id = glGetUniformLocation(program_id, 'projection')
    view_id = glGetUniformLocation(program_id, 'view')
    model_id = glGetUniformLocation(program_id, 'model')

    vertex = np.array([
        -1,
        -1,
        -1,
        1,
        -1,
        -1,
        1,
        1,
        -1,
        -1,
        1,
        -1,
        -1,
        -1,
        1,
        1,
        -1,
        1,
        1,
        1,
        1,
        -1,
        1,
        1,
    ],
                      dtype=np.float32)

    color = np.array([
        0,
        0,
        0,
        1,
        0,
        0,
        1,
        1,
        0,
        1,
        0,
        1,
        0,
        1,
        0,
        0,
        1,
        1,
        0,
        0,
        1,
        1,
        1,
        1,
    ],
                     dtype=np.float32)

    index = np.array(
        [
            #top
            7,
            6,
            2,
            2,
            3,
            7,

            #bottom
            0,
            1,
            5,
            5,
            4,
            0,

            #left
            0,
            4,
            7,
            7,
            3,
            0,

            #right
            5,
            1,
            2,
            2,
            6,
            5,

            #front
            1,
            0,
            3,
            3,
            2,
            1,

            #back
            4,
            5,
            6,
            6,
            7,
            4,
        ],
        dtype=np.uint32)

    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, vertex.nbytes, vertex, GL_STATIC_DRAW)

    color_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, color_buffer)
    glBufferData(GL_ARRAY_BUFFER, color.nbytes, color, GL_STATIC_DRAW)

    element_buffer = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.nbytes, index, GL_STATIC_DRAW)

    while not glfw.window_should_close(window) and glfw.get_key(
            window, glfw.KEY_ESCAPE) != glfw.PRESS:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glUseProgram(program_id)
        glUniformMatrix4fv(projection_id, 1, GL_FALSE, projection)
        glUniformMatrix4fv(view_id, 1, GL_FALSE, view)
        glUniformMatrix4fv(model_id, 1, GL_FALSE, model)

        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, color_buffer)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer)
        glDrawElements(GL_TRIANGLES, index.nbytes, GL_UNSIGNED_INT, None)

        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()
Beispiel #17
0
    def render(self):
        rendertime = time.time()

        GL.glClearColor(0, 0, 0, 1)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        # active shader program
        GL.glUseProgram(self.window.shader)

        # Bind Texture
        GL.glBindTexture(GL.GL_TEXTURE_2D, self.window.texture);

        # Create transformations
        # transform = pyrr.Matrix44().identity()

        # Coordinates
        '''
        Local space (Object space)
        World space
        View space (Eye space)
        Clip space
        Screen space
        '''


        # Model Matrix
        #rad = numpy.radians(glfw.get_time() * -30.0)
        rad = numpy.radians(-50.0)
        model = pyrr.matrix44.create_from_axis_rotation([1.0, 0.0, 0.0], rad)
        loc = GL.glGetUniformLocation(self.window.shader, 'model')
        GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, model)

        # View Matrix
        view = pyrr.matrix44.create_from_translation([0.0, 0.0, -3.0])
        loc = GL.glGetUniformLocation(self.window.shader, 'view')
        GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, view)

        # Projection Matrix
        fovy = 45.0
        (width, height) = glfw.get_window_size(self.w)
        aspect_ratio = (width * 1.0) / height
        near = 0.1
        far = 100.0
        projection = pyrr.matrix44.create_perspective_projection_matrix(fovy, aspect_ratio, near, far)
        loc = GL.glGetUniformLocation(self.window.shader, 'projection')
        GL.glUniformMatrix4fv(loc, 1, GL.GL_FALSE, projection)


        try:
            GL.glBindVertexArray(self.VAO)
           
            # Draw a triangle
            # GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)

            # draw triangle, starting index of the vertex array, # of vertices (6 = indexData.size), 
            # EBO indexes remain the same (accounts for stride of extra data
            GL.glDrawElements(GL.GL_TRIANGLES, self.index_size, GL.GL_UNSIGNED_INT, None)
        finally:
            # Unbind when we finish
            GL.glBindVertexArray(0)
            GL.glUseProgram(0)

        self.rendertime = 1000 * (time.time() - rendertime)
Beispiel #18
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
Beispiel #19
0
 def _before_make_current(self, width, height):
     previous_context = glfw.get_current_context()
     glfw.make_context_current(self._context)
     if (width, height) != glfw.get_window_size(self._context):
         glfw.set_window_size(self._context, width, height)
     return previous_context
    if simulation_running:
        agents.step()

    if current_time - previous_time >= 1.0:
        title = "Crowd Simulation ( " + str(frame_count) + " FPS | Number Of Agents: " + str(
            len(agents.agent_list)) + " )" + " intensity: " + str(global_intensity)
        glfw.set_window_title(window, title)
        frame_count = 0
        previous_time = current_time

    glfw.poll_events()

    glClearColor(0.0, 0.0, 0.0, 1.0)
    glClear(GL_COLOR_BUFFER_BIT)

    w, h = glfw.get_window_size(window)

    if w != w_prev or h != h_prev:
        w_prev = w
        h_prev = h
        tile_size[0] = (w - 2 * (offset + 1)) / len(maze[0])
        tile_size[1] = (h - 2 * (offset + 1)) / len(maze)
        agents.set_client_tile_size(w, h, tile_size)
        mazeTexture.reconstruct(w, h, tile_size)

    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0, w, 0, h, -10, 10)

    glMatrixMode(GL_MODELVIEW)
Beispiel #21
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)
Beispiel #22
0
    glfw.set_mouse_button_callback(window, on_mouse_button)
    shader, VAO, texture, texture_locn = prepare_shader()

    imgui.set_window_focus()

    for j in range(19):
        add_fg_element(load_image('images/heli%d.png' % j), label='heli%d' % j)
    original_bg_im_data = np.copy(bg_im_data)
    active_fg_element = 0

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

        imgui.new_frame()
        curr_width, curr_height = glfw.get_window_size(window)
        if curr_width != width or curr_height != height:
            width, height = curr_width, curr_height

        timestep_changed = False
        if not hide_panel:
            # Timeline
            timeline_height = 80
            imgui.set_next_window_position(0, height - timeline_height)
            imgui.set_next_window_size(width, timeline_height)
            imgui.set_next_window_bg_alpha(0.8)
            imgui.begin('timeline', False,
                        imgui.WINDOW_NO_TITLE_BAR | imgui.WINDOW_NO_RESIZE)
            n_frames = max([len(t) for t in traces])
            timestep_changed, timestep = imgui.slider_int('timestep',
                                                          timestep,
Beispiel #23
0
vms = glfw.get_video_modes(pm)
print("Available video modes:\n%s\n" % "\n".join(map(str, vms)))
vm = glfw.get_video_mode(pm)
print("Desktop video mode:\n%s\n" % str(vm))
print("GLFW Version: %d.%d.%d" % glfw.get_version())

w = glfw.create_window(800, 600, 'test', None, None)

#print("OpenGL version: %d.%d.%d\n" % glfw.get_gl_version())

#glfw.ext.set_icons([(icon_data, icon_width, icon_height)])
glfw.set_window_title(w, "pyglfw test")
#glfw.disable(w, glfw.AUTO_POLL_EVENTS)
#glfw.enable(w, glfw.KEY_REPEAT)

center_x = int(vm[0][0] / 2 - glfw.get_window_size(w)[0] / 2)
center_y = int(vm[0][1] / 2 - glfw.get_window_size(w)[1] / 2)
print("new window position: {!s}, {!s}".format(center_x, center_y))
glfw.set_window_pos(w, center_x, center_y)

glfw.set_window_size_callback(w, on_resize)
glfw.set_window_close_callback(w, on_close)
glfw.set_window_refresh_callback(w, on_refresh)
glfw.set_key_callback(w, on_key)
glfw.set_char_callback(w, on_char)
glfw.set_mouse_button_callback(w, on_button)
glfw.set_cursor_pos_callback(w, on_pos)
glfw.set_scroll_callback(w, on_scroll)

while not glfw.window_should_close(w):
    glfw.poll_events()
    def run(self):
        # Loop until the user closes the window
        while not glfw.window_should_close(self.window):
            # Poll for and process events
            glfw.poll_events()

            # build gui.
            self.impl.process_inputs()

            w, h = glfw.get_window_size(self.window)
            glViewport(0, 0, w, h)

            imgui.new_frame()

            timeline_height = 35
            imgui.push_style_var(imgui.STYLE_WINDOW_ROUNDING, 0)
            imgui.push_style_var(imgui.STYLE_FRAME_ROUNDING, 0)

            imgui.set_next_window_position(0, h - timeline_height - 10)
            imgui.set_next_window_size(w, timeline_height)

            imgui.begin(
                "Timeline", False, imgui.WINDOW_NO_TITLE_BAR
                | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_SCROLLBAR)
            imgui.columns(1)
            imgui.same_line(0, 0)
            imgui.push_item_width(-50)
            changed, value = imgui.slider_int("", self.sliderValue, 0,
                                              self.num_scans - 1)
            if changed: self.sliderValue = value
            if self.sliderValue != self.currentTimestep:
                self.currentTimestep = self.sliderValue

            imgui.push_style_var(imgui.STYLE_FRAME_ROUNDING, 3)

            play_delay = 1
            refresh_rate = 0.05

            current_time = time.time()

            imgui.same_line(spacing=5)
            changed = imgui.button("<", 20)
            if self.currentTimestep > 0:
                # just a click
                if changed:
                    self.currentTimestep = self.sliderValue = self.currentTimestep - 1
                    self.lastUpdate = current_time

                # button pressed.
                if imgui.is_item_active() and not self.button_backward_hold:
                    self.hold_start = current_time
                    self.button_backward_hold = True

                if not imgui.is_item_active() and self.button_backward_hold:
                    self.button_backward_hold = False

                # start playback when button pressed long enough
                if self.button_backward_hold and (
                    (current_time - self.hold_start) > play_delay):
                    if (current_time - self.lastUpdate) > refresh_rate:
                        self.currentTimestep = self.sliderValue = self.currentTimestep - 1
                        self.lastUpdate = current_time

            imgui.same_line(spacing=2)
            changed = imgui.button(">", 20)

            if self.currentTimestep < self.num_scans - 1:
                # just a click
                if changed:
                    self.currentTimestep = self.sliderValue = self.currentTimestep + 1
                    self.lastUpdate = current_time

                # button pressed.
                if imgui.is_item_active() and not self.button_forward_hold:
                    self.hold_start = current_time
                    self.button_forward_hold = True

                if not imgui.is_item_active() and self.button_forward_hold:
                    self.button_forward_hold = False

                # start playback when button pressed long enough
                if self.button_forward_hold and (
                    (current_time - self.hold_start) > play_delay):
                    if (current_time - self.lastUpdate) > refresh_rate:
                        self.currentTimestep = self.sliderValue = self.currentTimestep + 1
                        self.lastUpdate = current_time

            imgui.pop_style_var(3)
            imgui.end()

            imgui.set_next_window_position(20, 20, imgui.FIRST_USE_EVER)
            imgui.set_next_window_size(200, 150, imgui.FIRST_USE_EVER)
            imgui.begin("Show Data")

            if len(self.subdirs) > 1:
                for i, subdir in enumerate(self.subdirs):
                    changed, value = imgui.checkbox(subdir,
                                                    self.current_subdir == i)
                    if i < len(self.subdirs) - 1: imgui.same_line()
                    if changed and value: self.current_subdir = i

            subdir = self.subdirs[self.current_subdir]

            data_available = "input" in self.availableData[subdir]
            if data_available:
                imgui.push_style_var(imgui.STYLE_ALPHA, 1.0)
            else:
                imgui.push_style_var(imgui.STYLE_ALPHA, 0.3)

            changed, value = imgui.checkbox("input", self.showInput)
            if changed and value and data_available:
                self.showInput = True
                self.showLabels = False

            imgui.pop_style_var()

            data_available = "labels" in self.availableData[subdir]
            if data_available:
                imgui.push_style_var(imgui.STYLE_ALPHA, 1.0)
            else:
                imgui.push_style_var(imgui.STYLE_ALPHA, 0.3)

            changed, value = imgui.checkbox("labels", self.showLabels)
            if changed and value and data_available:
                self.showInput = False
                self.showLabels = True

            imgui.pop_style_var()

            data_available = "invalid" in self.availableData[subdir]
            if data_available:
                imgui.push_style_var(imgui.STYLE_ALPHA, 1.0)
            else:
                imgui.push_style_var(imgui.STYLE_ALPHA, 0.3)

            changed, value = imgui.checkbox("invalid", self.showInvalid)
            if changed and data_available: self.showInvalid = value

            imgui.pop_style_var()

            data_available = "occluded" in self.availableData[subdir]
            if data_available:
                imgui.push_style_var(imgui.STYLE_ALPHA, 1.0)
            else:
                imgui.push_style_var(imgui.STYLE_ALPHA, 0.3)

            changed, value = imgui.checkbox("occluded", self.showOccluded)
            if changed and data_available: self.showOccluded = value

            imgui.pop_style_var()

            imgui.end()

            # imgui.show_demo_window()

            showData = []
            if self.showInput: showData.append("input")
            if self.showOccluded: showData.append("occluded")
            if self.showInvalid: showData.append("invalid")

            mvp = self.projection_ @ self.cam.matrix @ self.conversion_

            glClearColor(1.0, 1.0, 1.0, 1.0)

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            glBindVertexArray(self.vao)

            self.program.bind()
            self.program["mvp"] = mvp.transpose()
            self.program["view_mat"] = (
                self.cam.matrix @ self.conversion_).transpose()
            self.program["lightPos"] = glow.vec3(10, 10, 10)
            self.program["voxel_scale"] = 0.8
            self.program["voxel_alpha"] = 1.0
            self.program["use_label_colors"] = True

            self.label_colors.bind(0)

            if self.showLabels:
                self.setCurrentBufferData("labels", self.currentTimestep)
                glDrawArraysInstanced(GL_TRIANGLES, 0, 36, self.num_instances)

            self.program["use_label_colors"] = False
            self.program["voxel_color"] = glow.vec3(0.3, 0.3, 0.3)

            self.program["voxel_alpha"] = 0.5

            for data_name in showData:
                self.program["voxel_scale"] = 0.5
                if data_name == "input": self.program["voxel_scale"] = 0.8

                self.setCurrentBufferData(data_name, self.currentTimestep)
                glDrawArraysInstanced(GL_TRIANGLES, 0, 36, self.num_instances)

            self.program.release()
            self.label_colors.release(0)

            glBindVertexArray(self.vao_no_points)

            self.prgDrawPose.bind()
            self.prgDrawPose["mvp"] = mvp.transpose()
            self.prgDrawPose["pose"] = np.identity(4, dtype=np.float32)
            self.prgDrawPose["size"] = 1.0

            glDrawArrays(GL_POINTS, 0, 1)
            self.prgDrawPose.release()

            glBindVertexArray(0)

            # draw gui ontop.
            imgui.render()
            self.impl.render(imgui.get_draw_data())

            # Swap front and back buffers
            glfw.swap_buffers(self.window)
Beispiel #25
0
 def get_normalized_device_coords(self, mouse_x, mouse_y):
     width, height = glfw.get_window_size(self.camera.window)
     x = (2 * mouse_x) / width - 1
     y = -((2 * mouse_y) / height - 1)
     return vec(x, y)
Beispiel #26
0
vms = glfw.get_video_modes( pm )
print("Available video modes:\n%s\n" % "\n".join(map(str, vms)))
vm = glfw.get_video_mode( pm )
print( "Desktop video mode:\n%s\n" % str(vm) )
print( "GLFW Version: %d.%d.%d" % glfw.get_version() )

w = glfw.create_window(800, 600, 'test', None, None)

#print("OpenGL version: %d.%d.%d\n" % glfw.get_gl_version())

#glfw.ext.set_icons([(icon_data, icon_width, icon_height)])
glfw.set_window_title(w, "pyglfw test")
#glfw.disable(w, glfw.AUTO_POLL_EVENTS)
#glfw.enable(w, glfw.KEY_REPEAT)

center_x = int(vm[0][0] / 2 - glfw.get_window_size(w)[0] / 2)
center_y = int(vm[0][1] / 2 - glfw.get_window_size(w)[1] / 2)
print( "new window position: {!s}, {!s}".format(center_x, center_y) )
glfw.set_window_pos(w, center_x, center_y)

glfw.set_window_size_callback(w, on_resize)
glfw.set_window_close_callback(w, on_close)
glfw.set_window_refresh_callback(w, on_refresh)
glfw.set_key_callback(w, on_key)
glfw.set_char_callback(w, on_char)
glfw.set_mouse_button_callback(w, on_button)
glfw.set_cursor_pos_callback(w, on_pos)
glfw.set_scroll_callback(w, on_scroll)

while not glfw.window_should_close(w):
    glfw.poll_events()
Beispiel #27
0
 def width(self):
     return glfw.get_window_size(self.window)[0]
Beispiel #28
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
Beispiel #29
0
    def controller(self, window):
        if self.__last_time is None:
            self.__last_time = glfw.get_time()

        current_time = glfw.get_time()
        delta_time = current_time - self.__last_time
        width, height = glfw.get_window_size(window)
        self.__aspect = width / float(height)
        xpos, ypos = glfw.get_cursor_pos(window)

        if self.__last_xpos is None or self.__last_ypos is None:
            self.__last_xpos, self.__last_ypos = xpos, ypos

        self.__horizontal_angle += self.__mouse_speed * float(
            self.__last_xpos - xpos)
        self.__vertical_angle += self.__mouse_speed * float(self.__last_ypos -
                                                            ypos)

        # カメラの向いている方向:球面座標から直交座標への変換
        self.direction = np.matrix([
            np.cos(self.__vertical_angle) * np.sin(self.__horizontal_angle),
            np.sin(self.__vertical_angle),
            np.cos(self.__vertical_angle) * np.cos(self.__horizontal_angle)
        ],
                                   dtype=np.float32)

        # カメラの右方向
        right = np.matrix([
            np.sin(self.__horizontal_angle - np.pi / 2.0), 0,
            np.cos(self.__horizontal_angle - np.pi / 2.0)
        ],
                          dtype=np.float32)

        # カメラの上方向:右方向と正面方向の外積
        self.__up = np.cross(right, self.direction)

        if glfw.get_key(window, glfw.KEY_DOWN) is glfw.PRESS:
            self.position -= self.__up * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_UP) is glfw.PRESS:
            self.position += self.__up * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_S) is glfw.PRESS:
            self.position -= self.direction * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_W) is glfw.PRESS:
            self.position += self.direction * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_A) is glfw.PRESS:
            self.position -= right * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_D) is glfw.PRESS:
            self.position += right * delta_time * self.__speed
        if glfw.get_key(window, glfw.KEY_I) is glfw.PRESS and self.__fov > 1.0:
            self.__fov -= 1.0
        if glfw.get_key(window,
                        glfw.KEY_O) is glfw.PRESS and self.__fov < 180.0:
            self.__fov += 1.0

        self.__target = self.position + self.direction
        self.projection = perspective(self.__fov, self.__aspect, self.__near,
                                      self.__far)
        self.view = look_at(self.position, self.__target, self.__up)

        self.__last_xpos, self.__last_ypos = xpos, ypos
        self.__last_time = current_time
Beispiel #30
0
def main():
    init()

    window = glfw.create_window(800, 600, "Chapter8", None, None)
    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LESS)
    glClearColor(0.3, 0.3, 0.3, 1)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)
    program_id = load_shaders('res/glsl/chapter8.vs', 'res/glsl/chapter8.fs')
    tex = texture.load('res/texture/eye.bmp')
    #tex = texture.load('res/texture/earth.bmp')
    texture_id = glGetUniformLocation(program_id, 'TextureSampler')

    res_x, res_y = glfw.get_window_size(window)
    #projection = camera.ortho(-4,4,-3,3,0.1,5.0)
    projection = camera.perspective(45.0, res_x / res_y, 0.1, 100.0)
    view = camera.look_at(np.matrix([0, 0, 2], dtype=np.float32),
                          np.matrix([0, 0, 0], dtype=np.float32),
                          np.matrix([0, 1, 0], dtype=np.float32))
    model = np.matrix(np.identity(4), dtype=np.float32)

    projection_id = glGetUniformLocation(program_id, 'projection')
    view_id = glGetUniformLocation(program_id, 'view')
    model_id = glGetUniformLocation(program_id, 'model')

    scene = load('res/model/sphere.obj')
    mesh = scene.meshes[0]
    vertex = mesh.vertices
    uv = mesh.texturecoords
    normal = mesh.normals
    index = mesh.faces

    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, vertex.nbytes, vertex, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, uv.nbytes, uv, GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER, normal.nbytes, normal, GL_STATIC_DRAW)

    element_buffer = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.nbytes, index, GL_STATIC_DRAW)

    while not glfw.window_should_close(window) and glfw.get_key(
            window, glfw.KEY_ESCAPE) != glfw.PRESS:
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glUseProgram(program_id)
        glUniformMatrix4fv(projection_id, 1, GL_FALSE, projection)
        glUniformMatrix4fv(view_id, 1, GL_FALSE, view)
        glUniformMatrix4fv(model_id, 1, GL_FALSE, model)

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, tex)
        glUniform1i(texture_id, 0)

        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)

        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None)

        glEnableVertexAttribArray(2)
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, None)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer)
        glDrawElements(GL_TRIANGLES, index.nbytes, GL_UNSIGNED_INT, None)

        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
        glDisableVertexAttribArray(2)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glfw.terminate()
Beispiel #31
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)
Beispiel #32
0
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.")
Beispiel #33
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)
Beispiel #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()
Beispiel #35
0
 def on_scroll(self, win, _deltax, deltay):
     """ Scroll controls the camera distance to trackball center """
     self.zoom(deltay, glfw.get_window_size(win)[1])
Beispiel #36
0
def initialize(window):
    global cursorOnCowBoundingBox, floorTexID, cameraIndex, camModel, cow2wld, cowModel
    cursorOnCowBoundingBox=False;
    # Set up OpenGL state
    glShadeModel(GL_SMOOTH);         # Set Smooth Shading
    glEnable(GL_DEPTH_TEST);         # Enables Depth Testing
    glDepthFunc(GL_LEQUAL);          # The Type Of Depth Test To Do
    # Use perspective correct interpolation if available
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    # Initialize the matrix stacks
    width, height = glfw.get_window_size(window)
    reshape(window, width, height);
    # Define lighting for the scene
    lightDirection   = [1.0, 1.0, 1.0, 0];
    ambientIntensity = [0.1, 0.1, 0.1, 1.0];
    lightIntensity   = [0.9, 0.9, 0.9, 1.0];
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientIntensity);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightIntensity);
    glLightfv(GL_LIGHT0, GL_POSITION, lightDirection);
    glEnable(GL_LIGHT0);

    # initialize floor
    im = open('bricks.bmp')
    try:
        ix, iy, image = im.size[0], im.size[1], im.tobytes("raw", "RGB", 0, -1)
    except SystemError:
        ix, iy, image = im.size[0], im.size[1], im.tobytes("raw", "RGBX", 0, -1)

    # Make texture which is accessible through floorTexID. 
    floorTexID=glGenTextures( 1)
    glBindTexture(GL_TEXTURE_2D, floorTexID);		
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, ix, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    # initialize cow
    cowModel=OBJ.OBJrenderer("cow.obj")

    # initialize cow2wld matrix
    glPushMatrix();		        # Push the current matrix of GL into stack.
    glLoadIdentity();		        # Set the GL matrix Identity matrix.
    glTranslated(0,-cowModel.bbmin[1],-8);	# Set the location of cow.
    glRotated(-90, 0, 1, 0);		# Set the direction of cow. These information are stored in the matrix of GL.
    cow2wld=glGetDoublev(GL_MODELVIEW_MATRIX).T # convert column-major to row-major 
    glPopMatrix();			# Pop the matrix on stack to GL.


    # intialize camera model.
    camModel=OBJ.OBJrenderer("camera.obj")


    # initialize camera frame transforms.

    cameraCount=len(cameras)
    for i in range(cameraCount):
        # 'c' points the coordinate of i-th camera.
        c = cameras[i];										
        glPushMatrix();													# Push the current matrix of GL into stack.
        glLoadIdentity();												# Set the GL matrix Identity matrix.
        gluLookAt(c[0],c[1],c[2], c[3],c[4],c[5], c[6],c[7],c[8]);		# Setting the coordinate of camera.
        wld2cam.append(glGetDoublev(GL_MODELVIEW_MATRIX).T)
        glPopMatrix();													# Transfer the matrix that was pushed the stack to GL.
        cam2wld.append(np.linalg.inv(wld2cam[i]))
    cameraIndex = 0;
Beispiel #37
0
 def get_size(self):
     """获取窗口尺寸"""
     if self.window is None:
         return None
     return glfw.get_window_size(self.window)
Beispiel #38
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)