Beispiel #1
0
    def _view(self, meshes=None, window_size=(800,600)):
        if meshes is None:
            meshes = []
        title = traceback.extract_stack(None, 2)[0][2]
        window, renderer = setup_glfw(width=window_size[0], height=window_size[1], double_buffered=True,
                                      title=title)
        camera_world_matrix = renderer.camera_matrix
        camera_position = camera_world_matrix[3,:3]
        gl.glViewport(0, 0, window_size[0], window_size[1])
        gl.glClearColor(*BG_COLOR)
        gl.glEnable(gl.GL_DEPTH_TEST)
        for mesh in meshes:
            mesh.init_gl(force=True)
        def on_resize(window, width, height):
            gl.glViewport(0, 0, width, height)
            renderer.window_size = (width, height)
            renderer.update_projection_matrix()
        glfw.SetWindowSizeCallback(window, on_resize)
        process_keyboard_input = init_keyboard(window)

        _logger.info('entering render loop...')
        stdout.flush()

        nframes = 0
        max_frame_time = 0.0
        lt = glfw.GetTime()
        while not glfw.WindowShouldClose(window):
            t = glfw.GetTime()
            dt = t - lt
            lt = t
            glfw.PollEvents()
            renderer.process_input()
            process_keyboard_input(dt, camera_world_matrix)
            with renderer.render(meshes=meshes):
                pass
            max_frame_time = max(max_frame_time, dt)
            if nframes == 0:
                st = glfw.GetTime()
            nframes += 1
            glfw.SwapBuffers(window)

        _logger.info('...exited render loop: average FPS: %f, maximum frame time: %f',
                     (nframes - 1) / (t - st), max_frame_time)

        renderer.shutdown()
        _logger.info('...shut down renderer')
        glfw.DestroyWindow(window)
        glfw.Terminate()
Beispiel #2
0
    def __init__(self,
                 width,
                 height,
                 title='',
                 samples=1,
                 monitor=0,
                 fullscreen=False):
        self._width = width
        self._height = height
        self._title = title

        if not glfw.Init():
            log.error('Glfw Init failed!')
            raise RuntimeError('Glfw Init failed!')
        else:
            log.debug('Glfw Initialized.')

        glfw.WindowHint(glfw.SAMPLES, samples)

        self._window = glfw.CreateWindow(
            self._width, self._height, self._title,
            glfw.GetMonitors()[monitor] if fullscreen else None, None)

        glfw.MakeContextCurrent(self._window)
        if not glInitBindlessTextureNV():
            log.error('Bindless textures not supported!')
            raise RuntimeError('Bindless textures not supported!')
        else:
            log.debug('Bindless textures supported.')

        self.center_pos(monitor)

        self._previous_second = glfw.GetTime()
        self._frame_count = 0.0
Beispiel #3
0
    def __init__(self, window_width, window_height, samples, window_title):
        self.window_title = window_title
        assert glfw.Init(), 'Glfw Init failed!'
        glfw.WindowHint(glfw.SAMPLES, samples)
        self.windowID = glfw.CreateWindow(window_width, window_height,
                                          self.window_title, None)
        assert self.windowID, 'Could not create Window!'
        glfw.MakeContextCurrent(self.windowID)
        assert glInitBindlessTextureNV(), 'Bindless Textures not supported!'
        self.framebuf_width, self.framebuf_height = glfw.GetFramebufferSize(
            self.windowID)

        def framebuffer_size_callback(window, w, h):
            self.framebuf_width, self.framebuf_height = w, h

        glfw.SetFramebufferSizeCallback(self.windowID,
                                        framebuffer_size_callback)

        def key_callback(window, key, scancode, action, mode):
            if action == glfw.PRESS:
                if key == glfw.KEY_ESCAPE:
                    glfw.SetWindowShouldClose(window, True)

        glfw.SetKeyCallback(self.windowID, key_callback)

        self.previous_second = glfw.GetTime()
        self.frame_count = 0.0

        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
        glDisable(GL_STENCIL_TEST)
        glDisable(GL_BLEND)
        glDisable(GL_CULL_FACE)
        glClearColor(0.0, 0.0, 0.0, 1.0)
        glEnable(GL_LINE_SMOOTH)
        glEnable(GL_POLYGON_SMOOTH)
 def update_fps_counter(self):
     current_second = glfw.GetTime()
     elapsed_seconds = current_second - self.previous_second
     if elapsed_seconds > 1.0:
         self.previous_second = current_second
         self._fps = float(self.frame_count) / float(elapsed_seconds)
         self.frame_count = 0.0
     self.frame_count += 1.0
    def __init__(self):
        assert glfw.Init(), 'Glfw Init failed!'
        glfw.WindowHint(glfw.VISIBLE, False);
        self._offscreen_context = glfw.CreateWindow(1, 1, "", None)
        assert self._offscreen_context, 'Could not create Offscreen Context!'
        glfw.MakeContextCurrent(self._offscreen_context)

        self.previous_second = glfw.GetTime()
        self.frame_count = 0.0
        self._fps = 0.0
def update_fps_counter():
    global previous_second, frame_count
    current_second = glfw.GetTime()
    elapsed_seconds = current_second - previous_second
    if elapsed_seconds > 0.25:
        previous_second = current_second
        fps = float(frame_count) / float(elapsed_seconds)
        glfw.SetWindowTitle(window, '%s @ FPS: %.2f' % (window_title, fps))
        frame_count = 0.0
    frame_count += 1.0
Beispiel #7
0
 def update_fps_counter(self):
     current_second = glfw.GetTime()
     elapsed_seconds = current_second - self._previous_second
     if elapsed_seconds > 0.25:
         self._previous_second = current_second
         fps = float(self._frame_count) / float(elapsed_seconds)
         new_title = '{} @ FPS: {:.2f}'.format(self._title, fps)
         glfw.SetWindowTitle(self._window, new_title)
         self._frame_count = 0.0
     self._frame_count += 1.0
Beispiel #8
0
def vr_render_loop(vr_renderer=None, process_input=None,
                   window=None, window_size=None,
                   gltf=None, nodes=None):
    _nframes = 0
    dt_max = 0.0
    st = lt = glfw.GetTime()
    while not glfw.WindowShouldClose(window):
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        process_input(dt)
        vr_renderer.process_input()
        vr_renderer.render(gltf, nodes, window_size)
        dt_max = max(dt, dt_max)
        _nframes += 1
        glfw.SwapBuffers(window)
    return {'NUM FRAMES RENDERER': _nframes,
            'AVERAGE FPS': _nframes / (t - st),
            'MAX FRAME RENDER TIME': dt_max}
Beispiel #9
0
 def update_fps_counter(self):
     current_second = glfw.GetTime()
     elapsed_seconds = current_second - self.previous_second
     if elapsed_seconds > 1.0:
         self.previous_second = current_second
         fps = float(self.frame_count) / float(elapsed_seconds)
         glfw.SetWindowTitle(self.windowID,
                             '%s @ FPS: %.2f' % (self.window_title, fps))
         self.frame_count = 0.0
     self.frame_count += 1.0
Beispiel #10
0
    def run_window(self):
        last_time = glfw.GetTime()
        frames = 0
        while glfw.GetKey(
                self.window,
                glfw.KEY_ESCAPE) != glfw.PRESS and not glfw.WindowShouldClose(
                    self.window):

            current_time = glfw.GetTime()
            if current_time - last_time >= 1.0:
                glfw.SetWindowTitle(self.window,
                                    "Loaded! Running at FPS: %d" % (frames))
                frames = 0
                last_time = current_time
            self.render()
            frames += 1

        for object in self._render_objects:
            object.delete()
        glDeleteProgram(self._mapping['program_id'])
        glDeleteVertexArrays(1, [self._mapping['vertex_array_id']])
        glfw.Terminate()
    def processPlayerInput(self, window):
        currentTime = glfw.GetTime()
        deltaTime = float(currentTime - self.lastUpdateTime)
        self.lastUpdateTime = currentTime

        # print 'self.pos', self.pos
        # print 'self.sphericalDir', self.sphericalDir

        self.processMoveInput(window, deltaTime)
        self.processLookInput(window, deltaTime)

        dir = sphericalToCartesian(self.sphericalDir)
        self.updateMatrix(self.f, self.framebufferSize, self.pos, dir, self.up)
Beispiel #12
0
    def inputhook_glfw():
        # We need to protect against a user pressing Control-C when IPython is
        # idle and this is running. We trap KeyboardInterrupt and pass.
        import cyglfw3 as glfw
        try:
            t = glfw.GetTime()
            while not stdin_ready():
                render_loop.next()

                used_time = glfw.GetTime() - t
                if used_time > 10.0:
                    # print 'Sleep for 1 s'  # dbg
                    time.sleep(1.0)
                elif used_time > 0.1:
                    # Few GUI events coming in, so we can sleep longer
                    # print 'Sleep for 0.05 s'  # dbg
                    time.sleep(0.05)
                else:
                    # Many GUI events coming in, so sleep only very little
                    time.sleep(0.001)
        except KeyboardInterrupt:
            pass
        return 0
Beispiel #13
0
def render_loop(process_input=None, window=None, window_size=None,
                gltf=None, nodes=None,
                camera_world_matrix=None, projection_matrix=None,
                nframes=None,
                display_fps=False, text_renderer=None):
    _nframes = 0
    dt_max = 0.0
    lt = st = glfw.GetTime()
    while not glfw.WindowShouldClose(window) and _nframes != nframes:
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        dt_max = max(dt, dt_max)
        process_input(dt)
        render(gltf, nodes, window_size,
               camera_world_matrix=camera_world_matrix,
               projection_matrix=projection_matrix)
        _draw_text(fps=1/dt, display_fps=display_fps, text_renderer=text_renderer)
        _nframes += 1
        glfw.SwapBuffers(window)
    return {'NUM FRAMES RENDERED': _nframes,
            'AVERAGE FPS': _nframes / (t - st),
            'MAX FRAME RENDER TIME': dt_max}
Beispiel #14
0
 def OnInit(self):
     #start main loop
     self.colorInc = 0.000
     self.radInc = 0.0001
     t = 0
     radStep = 0
     colorStep = 0
     while not glfw.WindowShouldClose(self.win) and not self.exitNow:
         currT = glfw.GetTime()
         if currT - t > 1 / 60.0:
             colorStep += self.colorInc
             radStep += self.radInc
             t = currT
             self.logic()
             self.draw(colorStep, radStep)
             glfw.PollEvents()
Beispiel #15
0
 def __init__(self, window_size, title=None):
     self.window = None
     self._window_size = window_size
     if title:
         self._title = title
     else:
         self._title = 'TSDF renderer'
     self._mapping = {}
     self._render_objects = []
     self._org_camera_position = vec3(0.5, -0.5, 3)
     self._camera_position = self._org_camera_position.copy()
     self._org_angle = (3.14, 0.0)
     self._horizontalAngle = self._org_angle[0]
     self._verticalAngle = self._org_angle[1]
     self._focus = False
     self._lastTime = None
     self._last_key_pressed = glfw.GetTime()
Beispiel #16
0
        def key_callback(window, key, scancode, action, mods):
            if (key == glfw.KEY_ESCAPE and action == glfw.PRESS):
                glfw.SetWindowShouldClose(window, True)

            if (action == glfw.PRESS and key == glfw.KEY_L):
                self.cameraLocked = not self.cameraLocked
                print 'cameraLocked:', self.cameraLocked

                glfw.SetInputMode(window, glfw.CURSOR, glfw.CURSOR_NORMAL if self.cameraLocked else glfw.CURSOR_DISABLED)

                # if not self.cameraLocked:
                # Ensure that locking/unlocking doesn't move the view:
                windowWidth, windowHeight = glfw.GetWindowSize(window)
                glfw.SetCursorPos(window, windowWidth / 2, windowHeight / 2)
                self.currentCamera.lastCursor = np.array(glfw.GetCursorPos(window), np.float32)
                self.currentCamera.lastUpdateTime = glfw.GetTime()

            if (action == glfw.PRESS and key == glfw.KEY_R):
                self.mainRender.renderCairo(self.playerCamera, self.cairoSavePath)

            pass
Beispiel #17
0
    def __init__(self,
                 window_width,
                 window_height,
                 samples=1,
                 window_title="",
                 monitor=1,
                 show_at_center=True,
                 offscreen=False):
        self.window_title = window_title
        assert glfw.Init(), "Glfw Init failed!"
        glfw.WindowHint(glfw.SAMPLES, samples)
        if offscreen:
            glfw.WindowHint(glfw.VISIBLE, False)
        mon = glfw.GetMonitors()[monitor] if monitor != None else None
        self.windowID = glfw.CreateWindow(window_width, window_height,
                                          self.window_title, mon)
        assert self.windowID, "Could not create Window!"
        glfw.MakeContextCurrent(self.windowID)

        if not glInitBindlessTextureNV():
            raise RuntimeError("Bindless Textures not supported")

        self.framebuf_width, self.framebuf_height = glfw.GetFramebufferSize(
            self.windowID)
        self.framebuffer_size_callback = []

        def framebuffer_size_callback(window, w, h):
            self.framebuf_width, self.framebuf_height = w, h
            for callback in self.framebuffer_size_callback:
                callback(w, h)

        glfw.SetFramebufferSizeCallback(self.windowID,
                                        framebuffer_size_callback)

        self.key_callback = []

        def key_callback(window, key, scancode, action, mode):
            if action == glfw.PRESS:
                if key == glfw.KEY_ESCAPE:
                    glfw.SetWindowShouldClose(window, True)
            for callback in self.key_callback:
                callback(key, scancode, action, mode)

        glfw.SetKeyCallback(self.windowID, key_callback)

        self.mouse_callback = []

        def mouse_callback(window, xpos, ypos):
            for callback in self.mouse_callback:
                callback(xpos, ypos)

        glfw.SetCursorPosCallback(self.windowID, mouse_callback)

        self.mouse_button_callback = []

        def mouse_button_callback(window, button, action, mods):
            for callback in self.mouse_button_callback:
                callback(button, action, mods)

        glfw.SetMouseButtonCallback(self.windowID, mouse_button_callback)

        self.scroll_callback = []

        def scroll_callback(window, xoffset, yoffset):
            for callback in self.scroll_callback:
                callback(xoffset, yoffset)

        glfw.SetScrollCallback(self.windowID, scroll_callback)

        self.previous_second = glfw.GetTime()
        self.frame_count = 0.0

        if show_at_center:
            monitors = glfw.GetMonitors()
            assert monitor >= 0 and monitor < len(
                monitors), "Invalid monitor selected."
            vidMode = glfw.GetVideoMode(monitors[monitor])
            glfw.SetWindowPos(
                self.windowID,
                vidMode.width / 2 - self.framebuf_width / 2,
                vidMode.height / 2 - self.framebuf_height / 2,
            )
Beispiel #18
0
                 dtype=np.float32))
    return mat.transpose().reshape(-1)


objectData = packObjectData()
objectUBO = np.empty(1, dtype=np.uint32)
glCreateBuffers(len(objectUBO), objectUBO)
glNamedBufferStorage(
    objectUBO[0], objectData.nbytes, objectData,
    GL_DYNAMIC_STORAGE_BIT | GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT)
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, objectUBO[0], 0,
                  objectData.nbytes)

while not glfw.WindowShouldClose(window.windowID):
    glfw.PollEvents()
    t = glfw.GetTime()

    sceneData = packSceneData()
    glNamedBufferSubData(sceneUBO, 0, sceneData.nbytes, sceneData)

    objectData = packObjectData()
    glNamedBufferSubData(objectUBO, 0, objectData.nbytes, objectData)

    window.update_fps_counter()
    tex.update(webcam_image)

    glViewport(0, 0, window.framebuf_width, window.framebuf_height)
    glClearColor(0.0, 0.0, 0.0, 1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    screen_shader.use()
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
glfw.WindowHint(glfw.SAMPLES, 16)

window = glfw.CreateWindow(W, H, window_title, None, None)
glfw.MakeContextCurrent(window)

def center_pos(monitor_id, W, H):
    # W, H: window dimensions
    mon = glfw.GetMonitors()
    xpos = glfw.GetMonitorPos(mon[monitor_id])[0]+glfw.GetVideoMode(mon[monitor_id]).width/2-W/2
    ypos = glfw.GetMonitorPos(mon[monitor_id])[1]+glfw.GetVideoMode(mon[monitor_id]).height/2-H/2
    glfw.SetWindowPos(window, xpos, ypos)

center_pos(monitor, W, H)

previous_second = glfw.GetTime()
frame_count = 0.0

def update_fps_counter():
    global previous_second, frame_count
    current_second = glfw.GetTime()
    elapsed_seconds = current_second - previous_second
    if elapsed_seconds > 0.25:
        previous_second = current_second
        fps = float(frame_count) / float(elapsed_seconds)
        glfw.SetWindowTitle(window, '%s @ FPS: %.2f' % (window_title, fps))
        frame_count = 0.0
    frame_count += 1.0

def add_shader(program, file, type):
    shader = glCreateShader(type)
Beispiel #20
0
def main(window_size=(800, 600),
         novr=False,
         ball_collision_model='simple',
         use_ode=False,
         multisample=0,
         fullscreen=False,
         cube_map=None,
         speed=1.0,
         glyphs=False,
         balls_on_table=None,
         use_quartic_solver=False,
         render_method='raycast',
         **kwargs):
    """
    The main routine.

    Performs initializations/setups; starts the render loop; performs shutdowns on exit.
    """
    _logger.debug(
        'configuration:\n%s',
        '\n'.join('%s: %s' % it
                  for it in chain(dict(locals()).items(), kwargs.items())))
    window, fallback_renderer = setup_glfw(window_size=window_size,
                                           double_buffered=novr,
                                           multisample=multisample,
                                           fullscreen=fullscreen)
    if not novr and OpenVRRenderer is not None:
        try:
            renderer = OpenVRRenderer(window_size=window_size,
                                      multisample=multisample)
            renderer.init_gl()
            global _window_renderer
            _window_renderer = renderer
        except Exception as err:
            renderer = fallback_renderer
            _logger.error('could not initialize OpenVRRenderer: %s', err)
    else:
        renderer = fallback_renderer

    init_sound()

    table = PoolTable()
    if use_ode:
        try:
            from .ode_physics import ODEPoolPhysics
            physics = ODEPoolPhysics(num_balls=16,
                                     table=table,
                                     balls_on_table=balls_on_table)
        except ImportError as err:
            _logger.error('could not import ode_physics:\n%s', err)
            ODEPoolPhysics = None
            physics = PoolPhysics(num_balls=16,
                                  table=table,
                                  ball_collision_model=ball_collision_model,
                                  enable_sanity_check=False,
                                  enable_occlusion=True,
                                  balls_on_table=balls_on_table,
                                  use_quartic_solver=use_quartic_solver,
                                  **kwargs)
    else:
        physics = PoolPhysics(num_balls=16,
                              table=table,
                              ball_collision_model=ball_collision_model,
                              enable_sanity_check=False,
                              enable_occlusion=True,
                              balls_on_table=balls_on_table,
                              use_quartic_solver=use_quartic_solver,
                              **kwargs)
    game = PoolGame(table=table, physics=physics)
    cue = PoolCue()
    game.physics.add_cue(cue)
    game.reset(balls_on_table=balls_on_table)
    table_mesh = game.table.export_mesh(surface_technique=LAMBERT_TECHNIQUE,
                                        cushion_technique=LAMBERT_TECHNIQUE)
    ball_meshes = game.table.export_ball_meshes(
        technique=LAMBERT_TECHNIQUE,
        use_bb_particles=render_method == 'billboards')
    # textured_text = TexturedText()
    # if use_bb_particles:

    if render_method == 'billboards':
        billboard_particles = ball_meshes[0]
        ball_mesh_positions = billboard_particles.primitive.attributes[
            'translate']
        ball_mesh_rotations = np.array(game.num_balls * [np.eye(3)])
        meshes = [floor_mesh, table_mesh
                  ] + ball_meshes + [cue.shadow_mesh, cue]

    elif render_method == 'raycast':
        ball_mesh_positions = np.zeros((game.num_balls, 3), dtype=np.float32)
        ball_quaternions = np.zeros((game.num_balls, 4), dtype=np.float32)
        ball_quaternions[:, 3] = 1
        from poolvr.gl_rendering import FragBox

        def on_use(material,
                   camera_matrix=None,
                   znear=None,
                   projection_lrbt=None,
                   window_size=None,
                   **frame_data):
            material.values['u_camera'] = camera_matrix
            material.values['u_projection_lrbt'] = projection_lrbt
            material.values['u_znear'] = znear
            material.values['iResolution'] = window_size

        import poolvr
        fragbox = FragBox(os.path.join(os.path.dirname(poolvr.__file__),
                                       'shaders', 'sphere_projection_fs.glsl'),
                          on_use=on_use)
        fragbox.material.values['ball_positions'] = ball_mesh_positions
        fragbox.material.values['ball_quaternions'] = ball_quaternions
        fragbox.material.values['cue_world_matrix'] = cue.world_matrix
        fragbox.material.values['cue_length'] = cue.length
        fragbox.material.values['cue_radius'] = cue.radius
        meshes = [table_mesh, fragbox]

    else:
        ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes]
        ball_mesh_positions = [
            mesh.world_matrix[3, :3] for mesh in ball_meshes
        ]
        ball_mesh_rotations = [
            mesh.world_matrix[:3, :3].T for mesh in ball_meshes
        ]
        ball_shadow_mesh_positions = [
            mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes
        ]
        meshes = [
            floor_mesh, table_mesh
        ] + ball_meshes + ball_shadow_meshes + [cue.shadow_mesh, cue]
        if cube_map:
            from .room import skybox_mesh
            meshes.insert(0, skybox_mesh)

    for mesh in meshes:
        mesh.init_gl()
    cue.shadow_mesh.update(c=table.H + 0.001)
    cue.position[1] = game.table.H + 0.001
    cue.position[2] += game.table.L * 0.1
    for i, mesh in enumerate(ball_meshes):
        if i not in balls_on_table:
            mesh.visible = False
            ball_shadow_meshes[i].visible = False
    camera_world_matrix = fallback_renderer.camera_matrix
    camera_position = camera_world_matrix[3, :3]
    camera_position[1] = game.table.H + 0.6
    camera_position[2] = game.table.L - 0.1
    last_contact_t = float('-inf')

    def reset():
        nonlocal last_contact_t
        nonlocal balls_on_table
        game.reset(balls_on_table=balls_on_table)
        last_contact_t = float('-inf')
        cue.position[0] = 0
        cue.position[1] = game.table.H + 0.001
        cue.position[2] = game.table.L * 0.3

    process_mouse_input = init_mouse(window)
    init_keyboard(window)

    def on_keydown(window, key, scancode, action, mods):
        if key == glfw.KEY_R and action == glfw.PRESS:
            reset()

    set_on_keydown_callback(window, on_keydown)
    theta = 0.0

    def process_keyboard_input(dt, camera_world_matrix):
        nonlocal theta
        theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] -
                                       key_state[KEY_RIGHT])
        sin, cos = np.sin(theta), np.cos(theta)
        camera_world_matrix[0, 0] = cos
        camera_world_matrix[0, 2] = -sin
        camera_world_matrix[2, 0] = sin
        camera_world_matrix[2, 2] = cos
        dist = dt * KB_MOVE_SPEED
        camera_world_matrix[3,:3] += \
            dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \
          + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \
          + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3]

    def process_input(dt):
        glfw.PollEvents()
        process_keyboard_input(dt, camera_world_matrix)
        process_mouse_input(dt, cue)

    if isinstance(renderer, OpenVRRenderer):
        from .vr_input import calc_cue_transformation, calc_cue_contact_velocity, axis_callbacks, button_press_callbacks
        button_press_callbacks[openvr.k_EButton_ApplicationMenu] = reset
        if use_ode and ODEPoolPhysics is not None:

            def on_cue_ball_collision(renderer=renderer,
                                      game=game,
                                      physics=physics,
                                      impact_speed=None):
                if impact_speed > 0.0015:
                    renderer.vr_system.triggerHapticPulse(
                        renderer._controller_indices[0], 0,
                        int(
                            max(0.8, impact_speed**2 / 4.0 +
                                impact_speed**3 / 16.0) * 2750))

            physics.set_cue_ball_collision_callback(on_cue_ball_collision)
            # def on_cue_surface_collision(renderer=renderer, game=game, physics=physics, impact_speed=None):
            #     if impact_speed > 0.003:
            #         renderer.vr_system.triggerHapticPulse(renderer._controller_indices[0], 0,
            #                                               int(max(0.75, 0.2*impact_speed**2 + 0.07*impact_speed**3) * 2500))
            # physics.set_cue_surface_collision_callback(on_cue_surface_collision)

    _logger.info('entering render loop...')
    sys.stdout.flush()
    import gc
    gc.collect()

    last_contact_t = float('-inf')
    contact_last_frame = False
    nframes = 0
    max_frame_time = 0.0
    lt = glfw.GetTime()
    glyph_meshes = []
    while not glfw.WindowShouldClose(window):
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        process_input(dt)
        if glyphs:
            glyph_meshes = physics.glyph_meshes(game.t)
        with renderer.render(meshes=meshes + glyph_meshes) as frame_data:
            if isinstance(renderer, OpenVRRenderer) and frame_data:
                renderer.process_input(
                    dt,
                    button_press_callbacks=button_press_callbacks,
                    axis_callbacks=axis_callbacks)
                hmd_pose = frame_data['hmd_pose']
                camera_position[:] = hmd_pose[:, 3]
                controller_poses = frame_data['controller_poses']
                if len(controller_poses) > 0:
                    if len(controller_poses) == 2:
                        pose_0, pose_1 = controller_poses
                    else:
                        controller_indices = frame_data['controller_indices']
                        if controller_indices[0] == 0:
                            pose_0 = controller_poses[0]
                            pose_1 = np.zeros((3, 4), dtype=np.float64)
                            pose_1[0, 0] = pose_1[1, 1] = pose_1[2, 2] = 1
                        else:
                            pose_0 = np.zeros((3, 4), dtype=np.float64)
                            pose_0[0, 0] = pose_0[1, 1] = pose_0[2, 2] = 1
                            pose_1 = controller_poses[0]
                    calc_cue_transformation(pose_0,
                                            pose_1,
                                            out=cue.world_matrix)
                    cue.velocity = frame_data['controller_velocities'][0]
                    cue.angular_velocity = frame_data[
                        'controller_angular_velocities'][0]
                    if use_ode and isinstance(physics, ODEPoolPhysics):
                        set_quaternion_from_matrix(pose_0[:, :3],
                                                   cue.quaternion)
            elif isinstance(renderer, OpenGLRenderer):
                if use_ode and isinstance(physics, ODEPoolPhysics):
                    set_quaternion_from_matrix(
                        cue.rotation.dot(cue.world_matrix[:3, :3].T),
                        cue.quaternion)
            if render_method == 'billboards':
                billboard_particles.update_gl()
            elif render_method == 'raycast':
                for i, (pos, quat) in enumerate(
                        zip(game.ball_positions, game.ball_quaternions)):
                    ball_mesh_positions[i][:] = pos
                    ball_quaternions[i][:] = quat
            else:
                for i, (pos, quat) in enumerate(
                        zip(game.ball_positions, game.ball_quaternions)):
                    ball_mesh_positions[i][:] = pos
                    ball_shadow_mesh_positions[i][0::2] = pos[0::2]
                    set_matrix_from_quaternion(quat, ball_mesh_rotations[i])
                cue.shadow_mesh.update()
            # sdf_text.set_text("%9.3f" % dt)
            # sdf_text.update_gl()

        if not contact_last_frame:
            if game.t - last_contact_t >= 2:
                for i, position in cue.aabb_check(game.ball_positions[:1],
                                                  physics.ball_radius):
                    r_c = cue.contact(position, physics.ball_radius)
                    if r_c is not None:
                        if isinstance(renderer,
                                      OpenVRRenderer) and frame_data and len(
                                          frame_data['controller_poses']) == 2:
                            pose_0, pose_1 = frame_data['controller_poses']
                            r_0, r_1 = pose_0[:, 3], pose_1[:, 3]
                            v_0, v_1 = frame_data['controller_velocities']
                            v_c = calc_cue_contact_velocity(
                                r_c, r_0, r_1, v_0, v_1)
                        else:
                            v_c = cue.velocity
                        physics.strike_ball(game.t, i, game.ball_positions[i],
                                            r_c, v_c, cue.mass)
                        last_contact_t = game.t
                        contact_last_frame = True
                        if isinstance(renderer, OpenVRRenderer):
                            renderer.vr_system.triggerHapticPulse(
                                renderer._controller_indices[0], 0,
                                int(
                                    np.linalg.norm(cue.velocity)**2 / 1.7 *
                                    2700))
                        break
        else:
            contact_last_frame = False

        game.step(speed * dt)

        max_frame_time = max(max_frame_time, dt)
        if nframes == 0:
            st = glfw.GetTime()
        nframes += 1
        glfw.SwapBuffers(window)

    if nframes > 1:
        _logger.info(
            '...exited render loop: average FPS: %f, maximum frame time: %f, average frame time: %f',
            (nframes - 1) / (t - st), max_frame_time, (t - st) / (nframes - 1))

    from .physics.events import PhysicsEvent
    _logger.debug(PhysicsEvent.events_str(physics.events))

    renderer.shutdown()
    _logger.info('...shut down renderer')
    glfw.DestroyWindow(window)
    glfw.Terminate()
    _logger.info('GOODBYE')
window = glfw.CreateWindow(window_width, window_height, window_title, None)
assert window, 'Could not create Window!'
glfw.MakeContextCurrent(window)
assert glInitBindlessTextureNV(), 'Bindless Textures not supported!'
framebuf_width, framebuf_height = glfw.GetFramebufferSize(window)
def framebuffer_size_callback(window, w, h):
    global framebuf_width, framebuf_height
    framebuf_width, framebuf_height = w, h
glfw.SetFramebufferSizeCallback(window, framebuffer_size_callback)
def key_callback(window, key, scancode, action, mode):
    if action == glfw.PRESS:
        if key == glfw.KEY_ESCAPE:
            glfw.SetWindowShouldClose(window, True)
glfw.SetKeyCallback(window, key_callback)

previous_second = glfw.GetTime(); frame_count = 0.0
def update_fps_counter(window):
    global previous_second, frame_count
    current_second = glfw.GetTime()
    elapsed_seconds = current_second - previous_second
    if elapsed_seconds > 1.0:
        previous_second = current_second
        fps = float(frame_count) / float(elapsed_seconds)
        glfw.SetWindowTitle(window, '%s @ FPS: %.2f' % (window_title, fps))
        frame_count = 0.0
    frame_count += 1.0

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
glDisable(GL_STENCIL_TEST)
glDisable(GL_BLEND)
glDisable(GL_CULL_FACE)
Beispiel #22
0
#!/usr/bin/env python3
import numpy as np
from OpenGL.arrays import ArrayDatatype
from OpenGL.GL import *
from OpenGL.GLUT import *
import glm
import sys
from ShaderProgram import ShaderProgram
import cyglfw3 as glfw
import math

camera_pos = glm.vec3(0.0, 0.0, 3.0)
camera_target = glm.vec3(0.0, 0.0, 0.0)
camera_direction = glm.normalize(camera_pos - camera_target)

up = glm.vec3(0.0, 1.0, 0.0)
camera_right = glm.normalize(glm.cross(up, camera_direction))

camera_up = glm.cross(camera_direction, camera_right)

view = glm.lookAt(glm.vec3(0.0, 0.0, 3.0), glm.vec3(0.0, 0.0, 0.0),
                  glm.vec3(0.0, 1.0, 0.0))

print(help(glfw))
radius = 10.0
camX = math.sin(glfw.GetTime()) * radius
camZ = math.cos(glfw.GetTime()) * radius
view = glm.lookAt(glm.vec3(camX, 0.0, camZ), glm.vec3(0.0, 0.0, 0.0),
                  glm.vec3(0.0, 1.0, 0.0))
Beispiel #23
0
            glfw.SetWindowShouldClose(window, gl.GL_TRUE)

    glfw.SetKeyCallback(window, on_keydown)

    def on_resize(window, width, height):
        gl.glViewport(0, 0, width, height)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        text_drawer.set_screen_size((width, height))

    glfw.SetWindowSizeCallback(window, on_resize)
    on_resize(window, w, h)
    _logger.debug('starting render loop...')
    nframes = 0
    dt = float('inf')
    avg_fps = 0.0
    t = lt = st = glfw.GetTime()
    while not glfw.WindowShouldClose(window):
        glfw.PollEvents()
        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        text_drawer.draw_text('TESTING123', screen_position=(0.5, 0.5))
        text_drawer.draw_text('fps: %f' % (1.0 / dt),
                              screen_position=(abs(np.sin(0.01 * (t - st))),
                                               abs(np.sin(0.1 * (t - st)))))
        text_drawer.draw_text('avg fps: %f' % avg_fps,
                              screen_position=(abs(np.sin(0.07 * (t - st))),
                                               abs(np.cos(0.3 * (t - st)))),
                              color=(1.0, 0.0, 0.0, 0.0))
        glfw.SwapBuffers(window)
        t = glfw.GetTime()
        dt = t - lt
        lt = t
def view_gltf(gltf, uri_path, scene_name=None, openvr=False, window_size=None):
    if scene_name is None:
        scene_name = gltf['scene']
    if window_size is None:
        window_size = [800, 600]
    window = setup_glfw(width=window_size[0], height=window_size[1],
                        double_buffered=not openvr)
    def on_resize(window, width, height):
        window_size[0], window_size[1] = width, height
    glfw.SetWindowSizeCallback(window, on_resize)
    if openvr and OpenVRRenderer is not None:
        vr_renderer = OpenVRRenderer()
    # text_drawer = TextDrawer()

    gl.glClearColor(0.01, 0.01, 0.17, 1.0);

    shader_ids = gltfu.setup_shaders(gltf, uri_path)
    gltfu.setup_programs(gltf, shader_ids)
    gltfu.setup_textures(gltf, uri_path)
    gltfu.setup_buffers(gltf, uri_path)

    scene = gltf.scenes[scene_name]
    nodes = [gltf.nodes[n] for n in scene.nodes]
    for node in nodes:
        gltfu.update_world_matrices(node, gltf)

    camera_world_matrix = np.eye(4, dtype=np.float32)
    projection_matrix = np.array(matrix44.create_perspective_projection_matrix(np.rad2deg(55), window_size[0]/window_size[1], 0.1, 1000),
                                 dtype=np.float32)

    for node in nodes:
        if 'camera' in node:
            camera = gltf['cameras'][node['camera']]
            if 'perspective' in camera:
                perspective = camera['perspective']
                projection_matrix = np.array(matrix44.create_perspective_projection_matrix(np.rad2deg(perspective['yfov']), perspective['aspectRatio'],
                                                                                           perspective['znear'], perspective['zfar']),
                                             dtype=np.float32)
            elif 'orthographic' in camera:
                raise Exception('TODO')
            camera_world_matrix = node['world_matrix']
            break
    camera_position = camera_world_matrix[3, :3]
    camera_rotation = camera_world_matrix[:3, :3]
    dposition = np.zeros(3, dtype=np.float32)
    rotation = np.eye(3, dtype=np.float32)

    key_state = defaultdict(bool)

    def on_keydown(window, key, scancode, action, mods):
        if key == glfw.KEY_ESCAPE and action == glfw.PRESS:
            glfw.SetWindowShouldClose(window, gl.GL_TRUE)
        elif action == glfw.PRESS:
            key_state[key] = True
        elif action == glfw.RELEASE:
            key_state[key] = False

    glfw.SetKeyCallback(window, on_keydown)

    def on_mousedown(window, button, action, mods):
        pass
    glfw.SetMouseButtonCallback(window, on_mousedown)

    move_speed = 2.0
    turn_speed = 0.5

    def process_input(dt):
        glfw.PollEvents()
        dposition[:] = 0.0
        if key_state[glfw.KEY_W]:
            dposition[2] -= dt * move_speed
        if key_state[glfw.KEY_S]:
            dposition[2] += dt * move_speed
        if key_state[glfw.KEY_A]:
            dposition[0] -= dt * move_speed
        if key_state[glfw.KEY_D]:
            dposition[0] += dt * move_speed
        if key_state[glfw.KEY_Q]:
            dposition[1] += dt * move_speed
        if key_state[glfw.KEY_Z]:
            dposition[1] -= dt * move_speed
        theta = 0.0
        if key_state[glfw.KEY_LEFT]:
            theta -= dt * turn_speed
        if key_state[glfw.KEY_RIGHT]:
            theta += dt * turn_speed
        rotation[0,0] = np.cos(theta)
        rotation[2,2] = rotation[0,0]
        rotation[0,2] = np.sin(theta)
        rotation[2,0] = -rotation[0,2]
        camera_rotation[...] = rotation.dot(camera_world_matrix[:3,:3])
        camera_position[:] += camera_rotation.T.dot(dposition)

    # sort nodes from front to back to avoid overdraw (assuming opaque objects):
    nodes = sorted(nodes, key=lambda node: np.linalg.norm(camera_position - node['world_matrix'][3, :3]))

    _logger.info('starting render loop...')
    sys.stdout.flush()
    gltfu.num_draw_calls = 0
    nframes = 0
    lt = glfw.GetTime()
    dt_max = 0.0
    while not glfw.WindowShouldClose(window):
        t = glfw.GetTime()
        dt = t - lt
        dt_max = max(dt, dt_max)
        lt = t
        process_input(dt)
        if openvr:
            vr_renderer.process_input()
            vr_renderer.render(gltf, nodes, window_size)
        else:
            gl.glViewport(0, 0, window_size[0], window_size[1])
            gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
            view_matrix = np.linalg.inv(camera_world_matrix)
            gltfu.set_material_state.current_material = None
            gltfu.set_technique_state.current_technique = None
            for node in nodes:
                gltfu.draw_node(node, gltf,
                                projection_matrix=projection_matrix,
                                view_matrix=view_matrix)
            # text_drawer.draw_text("%f" % dt, color=(1.0, 1.0, 0.0, 0.0),
            #                       view_matrix=view_matrix,
            #                       projection_matrix=projection_matrix)
        if nframes == 0:
            _logger.info("num draw calls per frame: %d", gltfu.num_draw_calls)
            sys.stdout.flush()
            gltfu.num_draw_calls = 0
            st = glfw.GetTime()
        nframes += 1
        glfw.SwapBuffers(window)
    _logger.info('FPS (avg): %f', ((nframes - 1) / (t - st)))
    _logger.info('MAX FRAME RENDER TIME: %f', dt_max)
    sys.stdout.flush()

    if openvr:
        vr_renderer.shutdown()
    glfw.DestroyWindow(window)
    glfw.Terminate()
Beispiel #25
0
def show(game,
         title='poolvr.py   ***   GLViewer',
         window_size=(800, 600),
         gl_clear_color=(0.24, 0.18, 0.08, 0.0),
         before_frame_cb=None,
         after_frame_cb=None,
         double_buffered=True,
         playback_rate=1.0,
         screenshots_dir='',
         use_billboards=False):
    if not glfw.Init():
        raise Exception('failed to initialize glfw')
    if not double_buffered:
        glfw.WindowHint(glfw.DOUBLEBUFFER, False)
        glfw.SwapInterval(0)
    window = glfw.CreateWindow(window_size[0], window_size[1], title)
    if not window:
        raise Exception('failed to create glfw window')
    glfw.MakeContextCurrent(window)
    _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION))
    renderer = OpenGLRenderer(window_size=window_size, znear=0.1, zfar=1000)

    def on_resize(window, width, height):
        gl.glViewport(0, 0, width, height)
        renderer.window_size = (width, height)
        renderer.update_projection_matrix()

    glfw.SetWindowSizeCallback(window, on_resize)

    table = game.table
    physics = game.physics
    ball_meshes = table.setup_balls(game.ball_radius,
                                    game.ball_colors[:9],
                                    game.ball_positions,
                                    striped_balls=set(range(9,
                                                            game.num_balls)),
                                    use_bb_particles=use_billboards)
    ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes]
    camera_world_matrix = renderer.camera_matrix
    camera_position = camera_world_matrix[3, :3]
    camera_position[1] = table.height + 0.19
    camera_position[2] = 0.183 * table.length
    cue = PoolCue()
    cue.position[1] = table.height + 0.1

    process_keyboard_input = init_keyboard(window)

    meshes = [table.mesh, floor_mesh, skybox_mesh] + ball_meshes  #+ [cue]
    for mesh in meshes:
        mesh.init_gl(force=True)

    ball_positions = game.ball_positions
    ball_quaternions = game.ball_quaternions
    ball_mesh_positions = [mesh.world_matrix[3, :3] for mesh in ball_meshes]
    ball_mesh_rotations = [mesh.world_matrix[:3, :3].T for mesh in ball_meshes]
    ball_shadow_mesh_positions = [
        mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes
    ]
    gl.glViewport(0, 0, window_size[0], window_size[1])
    gl.glClearColor(*gl_clear_color)
    gl.glEnable(gl.GL_DEPTH_TEST)

    _logger.info('entering render loop...')
    stdout.flush()

    nframes = 0
    max_frame_time = 0.0
    lt = glfw.GetTime()
    t0 = physics.events[0].t
    t1 = physics.events[-1].t + min(2.0, physics.events[-1].T)
    pt = t0

    while not glfw.WindowShouldClose(window) and pt <= t1:

        t = glfw.GetTime()
        dt = t - lt
        lt = t
        glfw.PollEvents()
        process_keyboard_input(dt, camera_world_matrix, cue=cue)
        renderer.process_input()

        with renderer.render(meshes=meshes) as frame_data:
            camera_position = frame_data.get('camera_position',
                                             renderer.camera_position)
            physics.eval_positions(pt, out=ball_positions)
            physics.eval_quaternions(pt, out=ball_quaternions)
            ball_positions[
                ~physics.
                on_table] = camera_position  # hacky way to only show balls that are on table
            for i, pos in enumerate(ball_positions):
                ball_mesh_positions[i][:] = pos
                ball_shadow_mesh_positions[i][0::2] = pos[0::2]
            for i, quat in enumerate(ball_quaternions):
                set_matrix_from_quaternion(quat, ball_mesh_rotations[i])

        physics.step(dt)

        max_frame_time = max(max_frame_time, dt)
        if nframes == 0:
            st = glfw.GetTime()
        nframes += 1
        pt += dt * playback_rate
        glfw.SwapBuffers(window)

    _logger.info(
        '...exited render loop: average FPS: %f, maximum frame time: %f',
        (nframes - 1) / (t - st), max_frame_time)

    mWidth, mHeight = glfw.GetWindowSize(window)
    gl.glPixelStorei(gl.GL_PACK_ALIGNMENT, 1)
    pixels = gl.glReadPixels(0, 0, mWidth, mHeight, gl.GL_RGB,
                             gl.GL_UNSIGNED_BYTE)
    pil_image = PIL.Image.frombytes('RGB', (mWidth, mHeight), pixels)
    pil_image = pil_image.transpose(PIL.Image.FLIP_TOP_BOTTOM)
    filename = title.replace(' ', '_') + '-screenshot.png'
    filepath = os.path.join(screenshots_dir, filename)
    pil_image.save(filepath)
    _logger.info('..saved screen capture to "%s"', filepath)

    try:
        renderer.shutdown()
        _logger.info('...shut down renderer')
    except Exception as err:
        _logger.error(err)

    glfw.DestroyWindow(window)
    glfw.Terminate()
Beispiel #26
0
def view_gltf(gltf, uri_path, scene_name=None,
              openvr=False,
              window_size=None,
              clear_color=(0.01, 0.01, 0.013, 0.0),
              multisample=None,
              nframes=None,
              screenshot=None,
              camera_position=None, camera_rotation=None,
              zfar=1000.0, znear=0.01, yfov=0.660593,
              window_title='gltfview',
              screen_capture_prefix=None,
              display_fps=False,
              move_speed=None):
    _t0 = time.time()
    if window_size is None:
        window_size = [800, 600]
    else:
        window_size = list(window_size)
    window = setup_glfw(width=window_size[0], height=window_size[1],
                        double_buffered=not openvr, multisample=multisample,
                        window_title=window_title)

    gl.glClearColor(*clear_color)

    camera = {'type': 'perspective',
              'perspective': {"aspectRatio": window_size[0]/window_size[1],
                              "yfov": yfov, "zfar": zfar, "znear": znear}}
    projection_matrix = np.zeros((4,4), dtype=np.float32)

    def on_resize(window, width, height):
        window_size[:] = width, height
        gl.glViewport(0, 0, window_size[0], window_size[1])
        gltfu.calc_projection_matrix(camera, out=projection_matrix,
                                     aspectRatio=window_size[0] / max(5, window_size[1]))
    glfw.SetWindowSizeCallback(window, on_resize)

    scene = gltfu.init_scene(gltf, uri_path, scene_name=scene_name)
    scene_bounds = gltfu.find_scene_bounds(scene, gltf)
    _logger.debug('scene bounds:\n%s', '\n'.join(['%20s: min = %s , max = %s' % (semantic, bounds[0], bounds[1])
                                                  for semantic, bounds in scene_bounds.items()]))

    root_nodes = [gltf['nodes'][n] for n in scene.get('nodes', [])]
    nodes = gltfu.flatten_nodes(root_nodes, gltf)

    camera_node = next((node for node in nodes if 'camera' in node), None)
    if camera_node is not None:
        camera = gltf['cameras'][camera_node['camera']]
        _logger.info('found camera: %s', camera)
        camera_world_matrix = camera_node['world_matrix']
    else:
        _logger.info('no camera specified, using default')
        camera_world_matrix = np.eye(4, dtype=np.float32)

    if camera_position is not None:
        _logger.info('setting camera position to %s', camera_position)
        camera_world_matrix[3, :3] = camera_position
    camera_position = camera_world_matrix[3, :3]

    if camera_node is None and 'POSITION' in scene_bounds:
        bounds = scene_bounds['POSITION']
        centroid = 0.5 * (bounds[0] + bounds[1])
        r_max = max(np.linalg.norm(bounds[0] - centroid), np.linalg.norm(bounds[1] - centroid))
        camera_position[:] = centroid
        camera_position[2] += r_max / np.tan(0.5*camera['perspective']['yfov'])
        _logger.debug('camera_position = %s', camera_position)

    if camera_rotation is not None:
        if camera_rotation[1]:
            s, c = np.sin(camera_rotation[1]), np.cos(camera_rotation[1])
            r = np.array([[c, -s],
                          [s,  c]], dtype=np.float32)
            camera_world_matrix[:3:2,:3:2] = camera_world_matrix[:3:2,:3:2].dot(r.T)

    # sort nodes from front to back to avoid overdraw (assuming opaque objects):
    nodes = sorted(nodes, key=lambda node: np.linalg.norm(camera_world_matrix[3, :3] - node['world_matrix'][3, :3]))

    on_resize(window, window_size[0], window_size[1])

    if 'POSITION' in scene_bounds:
        bounds = scene_bounds['POSITION']
        scene_centroid = 0.5 * (bounds[0] + bounds[1])
        move_speed = 0.125 * max(np.linalg.norm(bounds[0] - scene_centroid),
                                 np.linalg.norm(bounds[1] - scene_centroid))

    process_input = setup_controls(camera_world_matrix=camera_world_matrix, window=window,
                                   screen_capture_prefix=screen_capture_prefix, move_speed=move_speed)

    text_renderer = None
    if display_fps:
        text_renderer = TextRenderer()
        text_renderer.init_gl()

    _t1 = time.time()
    _logger.info('''...INITIALIZATION COMPLETE (took %s seconds)''', _t1 - _t0);

    # BURNER FRAME:
    gltfu.num_draw_calls = 0
    process_input(0.0)
    lt = glfw.GetTime()
    render(gltf, nodes, window_size,
           camera_world_matrix=camera_world_matrix,
           projection_matrix=projection_matrix)
    num_draw_calls_per_frame = gltfu.num_draw_calls
    _logger.info("NUM DRAW CALLS PER FRAME: %d", num_draw_calls_per_frame)
    _draw_text(fps=1/(glfw.GetTime()-lt), display_fps=display_fps, text_renderer=text_renderer)
    if screenshot:
        save_screen(window, screenshot)

    _logger.info('''STARTING RENDER LOOP...''')
    if nframes:
        _logger.info(""" * * * WILL RENDER %s FRAMES * * * """, nframes)
    stdout.flush()

    import gc; gc.collect() # does it do anything?

    if openvr and OpenVRRenderer is not None:
        vr_renderer = OpenVRRenderer(multisample=multisample, poll_tracked_device_frequency=90)
        setup_vr_controls()
        render_stats = vr_render_loop(vr_renderer=vr_renderer, process_input=process_input,
                                      window=window, window_size=window_size,
                                      gltf=gltf, nodes=nodes)
        vr_renderer.shutdown()
    else:
        render_stats = render_loop(process_input=process_input,
                                   window=window, window_size=window_size,
                                   gltf=gltf, nodes=nodes,
                                   camera_world_matrix=camera_world_matrix,
                                   projection_matrix=projection_matrix,
                                   nframes=nframes,
                                   display_fps=display_fps, text_renderer=text_renderer)
    _logger.info('''QUITING...

%s
''', '\n'.join('  %21s: %s' % (k, v) for k, v in render_stats.items()))
    glfw.DestroyWindow(window)
    glfw.Terminate()
Beispiel #27
0
def gl_rendering(pool_physics, pool_table, request, meshes):
    should_render = request.config.getoption('--render')
    should_screenshot = request.config.getoption('--screenshot')
    if not (should_render or should_screenshot):
        yield
        return
    xres, yres = [
        int(n) for n in request.config.getoption('--resolution').split('x')
    ]
    msaa = request.config.getoption('--msaa')
    glyphs = request.config.getoption('--glyphs')
    speed = float(request.config.getoption('--speed'))
    keep_render_window = request.config.getoption('--keep-render-window')
    render_method = request.config.getoption('--render-method')
    yield

    import numpy as np
    import OpenGL
    OpenGL.ERROR_CHECKING = False
    OpenGL.ERROR_LOGGING = False
    OpenGL.ERROR_ON_COPY = True
    import cyglfw3 as glfw
    from poolvr.glfw_app import setup_glfw, capture_window
    from poolvr.app import KB_MOVE_SPEED, KB_TURN_SPEED
    from poolvr.keyboard_controls import (init_keyboard, key_state, KEY_LEFT,
                                          KEY_RIGHT, KEY_W, KEY_S, KEY_A,
                                          KEY_D, KEY_Q, KEY_Z)
    from poolvr.game import PoolGame
    from poolvr.gl_rendering import set_matrix_from_quaternion
    logging.getLogger('poolvr.gl_rendering').setLevel(logging.WARNING)
    if render_method == 'ega':
        from poolvr.gl_techniques import EGA_TECHNIQUE as technique
    elif render_method == 'lambert':
        from poolvr.gl_techniques import LAMBERT_TECHNIQUE as technique
    physics = pool_physics
    table = pool_table
    game = PoolGame(physics=pool_physics, table=table)
    title = '_'.join(
        [request.function.__name__, pool_physics.ball_collision_model])
    window, renderer = setup_glfw(window_size=[xres, yres],
                                  double_buffered=True,
                                  multisample=int(msaa),
                                  title=title)
    camera_world_matrix = renderer.camera_matrix
    camera_position = camera_world_matrix[3, :3]
    camera_position[1] = table.H + 0.6
    camera_position[2] = table.L - 0.1
    table_mesh = table.export_mesh(surface_technique=technique,
                                   cushion_technique=technique,
                                   rail_technique=technique)
    ball_meshes = table.export_ball_meshes(technique=technique)
    ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes]
    for ball_mesh, shadow_mesh, on_table in zip(ball_meshes,
                                                ball_shadow_meshes,
                                                physics._on_table):
        if not on_table:
            ball_mesh.visible = False
            shadow_mesh.visible = False
    if not meshes:
        meshes = [table_mesh] + ball_meshes + ball_shadow_meshes
    else:
        glyphs = False
    for mesh in meshes:
        mesh.init_gl(force=True)
    ball_mesh_positions = [mesh.world_matrix[3, :3] for mesh in ball_meshes]
    ball_mesh_rotations = [mesh.world_matrix[:3, :3].T for mesh in ball_meshes]
    ball_shadow_mesh_positions = [
        mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes
    ]
    init_keyboard(window)
    theta = 0.0

    def process_keyboard_input(dt, camera_world_matrix):
        nonlocal theta
        theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] -
                                       key_state[KEY_RIGHT])
        sin, cos = np.sin(theta), np.cos(theta)
        camera_world_matrix[0, 0] = cos
        camera_world_matrix[0, 2] = -sin
        camera_world_matrix[2, 0] = sin
        camera_world_matrix[2, 2] = cos
        dist = dt * KB_MOVE_SPEED
        camera_world_matrix[3,:3] += \
            dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \
          + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \
          + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3]

    def process_input(dt):
        glfw.PollEvents()
        process_keyboard_input(dt, camera_world_matrix)

    _logger.info('entering render loop...')
    stdout.flush()
    nframes = 0
    max_frame_time = 0.0
    lt = glfw.GetTime()
    if should_render:
        t_end = physics.events[-1].t if physics.events else 5.0
    else:
        t_end = game.t
    while not glfw.WindowShouldClose(window) and (keep_render_window
                                                  or game.t < t_end):
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        process_input(dt)
        if glyphs:
            glyph_meshes = physics.glyph_meshes(game.t)
        else:
            glyph_meshes = []
        game.step(speed * dt)
        with renderer.render(meshes=meshes + glyph_meshes, dt=dt):
            for i, pos in enumerate(game.ball_positions):
                ball_mesh_positions[i][:] = pos
                set_matrix_from_quaternion(game.ball_quaternions[i],
                                           out=ball_mesh_rotations[i])
                ball_shadow_mesh_positions[i][0::2] = pos[0::2]
        max_frame_time = max(max_frame_time, dt)
        if nframes == 0:
            st = glfw.GetTime()
        nframes += 1
        glfw.SwapBuffers(window)
    if nframes > 1:
        _logger.info(
            '''...exited render loop:
        average FPS: %f
        minimum FPS: %f
        average frame time: %f
        maximum frame time: %f
        ''', (nframes - 1) / (t - st), 1 / max_frame_time,
            (t - st) / (nframes - 1), max_frame_time)
    if should_screenshot:
        if physics.events:
            t_end = physics.events[-1].t
        with renderer.render(meshes=meshes):
            physics.eval_positions(t_end, out=game.ball_positions)
            for i, pos in enumerate(game.ball_positions):
                ball_mesh_positions[i][:] = pos
                set_matrix_from_quaternion(game.ball_quaternions[i],
                                           out=ball_mesh_rotations[i])
                ball_shadow_mesh_positions[i][0::2] = pos[0::2]
        glfw.SwapBuffers(window)
        capture_window(window,
                       filename=os.path.join(os.path.dirname(__file__),
                                             'screenshots',
                                             title.replace(' ', '_') + '.png'))
    renderer.shutdown()
    glfw.DestroyWindow(window)
    glfw.Terminate()
Beispiel #28
0
def render_meshes(request):
    should_render = request.config.getoption('--render')
    should_screenshot = request.config.getoption('--screenshot')
    if not (should_render or should_screenshot):
        yield None
        return
    xres, yres = [
        int(n) for n in request.config.getoption('--resolution').split('x')
    ]
    msaa = int(request.config.getoption('--msaa'))
    vr = request.config.getoption('--vr')
    import numpy as np
    import OpenGL
    OpenGL.ERROR_CHECKING = False
    OpenGL.ERROR_LOGGING = False
    OpenGL.ERROR_ON_COPY = True
    import cyglfw3 as glfw
    from poolvr.glfw_app import setup_glfw, capture_window
    from poolvr.app import KB_MOVE_SPEED, KB_TURN_SPEED
    from poolvr.keyboard_controls import (init_keyboard, key_state, KEY_LEFT,
                                          KEY_RIGHT, KEY_W, KEY_S, KEY_A,
                                          KEY_D, KEY_Q, KEY_Z)
    window_size = [xres, yres]
    title = request.function.__name__
    window, renderer = setup_glfw(window_size=window_size,
                                  double_buffered=not vr,
                                  multisample=msaa,
                                  title=title)
    camera_world_matrix = renderer.camera_matrix
    if vr:
        from poolvr.pyopenvr_renderer import OpenVRRenderer
        renderer = OpenVRRenderer(multisample=msaa, window_size=window_size)

    class Yielded(list):
        def __init__(self, renderer, window):
            self.renderer = renderer
            self.window = window

    meshes = Yielded(renderer, window)
    yield meshes

    camera_position = camera_world_matrix[3, :3]
    camera_position[1] = 0.5
    camera_position[2] = 0.75
    for mesh in meshes:
        mesh.init_gl(force=True)
    init_keyboard(window)
    theta = 0.0

    def process_keyboard_input(dt, camera_world_matrix):
        nonlocal theta
        theta += KB_TURN_SPEED * dt * (key_state[KEY_LEFT] -
                                       key_state[KEY_RIGHT])
        sin, cos = np.sin(theta), np.cos(theta)
        camera_world_matrix[0, 0] = cos
        camera_world_matrix[0, 2] = -sin
        camera_world_matrix[2, 0] = sin
        camera_world_matrix[2, 2] = cos
        dist = dt * KB_MOVE_SPEED
        camera_world_matrix[3,:3] += \
            dist*(key_state[KEY_S]-key_state[KEY_W]) * camera_world_matrix[2,:3] \
          + dist*(key_state[KEY_D]-key_state[KEY_A]) * camera_world_matrix[0,:3] \
          + dist*(key_state[KEY_Q]-key_state[KEY_Z]) * camera_world_matrix[1,:3]

    def process_input(dt):
        glfw.PollEvents()
        process_keyboard_input(dt, camera_world_matrix)

    _logger.info('entering render loop...')
    stdout.flush()
    nframes = 0
    max_frame_time = 0.0
    lt = glfw.GetTime()
    while not glfw.WindowShouldClose(window):
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        process_input(dt)
        with renderer.render(meshes=meshes, dt=dt):
            pass
        max_frame_time = max(max_frame_time, dt)
        if nframes == 0:
            st = glfw.GetTime()
        nframes += 1
        glfw.SwapBuffers(window)
    if nframes > 1:
        _logger.info(
            '''...exited render loop:
        average FPS: %f
        minimum FPS: %f
        average frame time: %f
        maximum frame time: %f
        ''', (nframes - 1) / (t - st), 1 / max_frame_time,
            (t - st) / (nframes - 1), max_frame_time)
    if should_screenshot:
        with renderer.render(meshes=meshes, dt=0.0):
            pass
        glfw.SwapBuffers(window)
        capture_window(window,
                       filename=os.path.join(os.path.dirname(__file__),
                                             'screenshots',
                                             title.replace(' ', '_') + '.png'))
    renderer.shutdown()
    glfw.DestroyWindow(window)
    glfw.Terminate()
Beispiel #29
0
def main(window_size=(800, 600),
         novr=False,
         use_simple_ball_collisions=False,
         use_ode=False,
         multisample=0,
         use_bb_particles=False):
    """
    The main routine.

    Performs initializations, setups, kicks off the render loop.
    """
    _logger.info('HELLO')
    game = PoolGame(use_simple_ball_collisions=use_simple_ball_collisions)
    cue = PoolCue()
    if use_ode and ODEPoolPhysics is not None:
        game.physics = ODEPoolPhysics(num_balls=game.num_balls,
                                      ball_radius=game.ball_radius,
                                      initial_positions=game.ball_positions,
                                      table=game.table)
    cue_body, cue_geom = game.physics.add_cue(cue)
    physics = game.physics
    cue.position[1] = game.table.height + 0.1
    cue_quaternion = np.zeros(4, dtype=np.float32)
    cue_quaternion[3] = 1
    game.reset()
    ball_meshes = game.table.setup_balls(game.ball_radius,
                                         game.ball_colors[:9],
                                         game.ball_positions,
                                         striped_balls=set(
                                             range(9, game.num_balls)),
                                         use_bb_particles=use_bb_particles)
    window, fallback_renderer = setup_glfw(width=window_size[0],
                                           height=window_size[1],
                                           double_buffered=novr,
                                           multisample=multisample)
    if not novr and OpenVRRenderer is not None:
        try:
            renderer = OpenVRRenderer(window_size=window_size,
                                      multisample=multisample)
            button_press_callbacks = {
                openvr.k_EButton_Grip: game.reset,
                openvr.k_EButton_ApplicationMenu: game.advance_time
            }
            if ODEPoolPhysics is not None:

                def on_cue_ball_collision(renderer=renderer,
                                          game=game,
                                          physics=physics,
                                          impact_speed=None):
                    if impact_speed > 0.0015:
                        renderer.vr_system.triggerHapticPulse(
                            renderer._controller_indices[0], 0,
                            int(
                                max(
                                    0.8, impact_speed**2 / 4.0 +
                                    impact_speed**3 / 16.0) * 2750))
                    game.ntt = physics.next_turn_time()

                physics.set_cue_ball_collision_callback(on_cue_ball_collision)

                def on_cue_surface_collision(renderer=renderer,
                                             game=game,
                                             physics=physics,
                                             impact_speed=None):
                    if impact_speed > 0.003:
                        renderer.vr_system.triggerHapticPulse(
                            renderer._controller_indices[0], 0,
                            int(
                                max(
                                    0.75, 0.2 * impact_speed**2 +
                                    0.07 * impact_speed**3) * 2500))
        except Exception as err:
            renderer = fallback_renderer
            _logger.error('could not initialize OpenVRRenderer: %s', err)
    else:
        renderer = fallback_renderer
    camera_world_matrix = fallback_renderer.camera_matrix
    camera_position = camera_world_matrix[3, :3]
    camera_position[1] = game.table.height + 0.6
    camera_position[2] = game.table.length - 0.1

    process_keyboard_input = init_keyboard(window)

    def on_keydown(window, key, scancode, action, mods):
        if key == glfw.KEY_R and action == glfw.PRESS:
            game.reset()

    set_on_keydown(window, on_keydown)

    process_mouse_input = init_mouse(window)

    def process_input(dt):
        glfw.PollEvents()
        process_keyboard_input(dt, camera_world_matrix, cue)
        process_mouse_input(dt, cue)

    # textured_text = TexturedText()
    if use_bb_particles:
        ball_shadow_meshes = []
    else:
        ball_shadow_meshes = [mesh.shadow_mesh for mesh in ball_meshes]

    meshes = [skybox_mesh, floor_mesh, game.table.mesh
              ] + ball_meshes + ball_shadow_meshes + [cue.shadow_mesh, cue]
    for mesh in meshes:
        mesh.init_gl()

    ball_positions = game.ball_positions.copy()
    ball_quaternions = game.ball_quaternions
    if use_bb_particles:
        billboard_particles = ball_meshes[0]
        ball_mesh_positions = billboard_particles.primitive.attributes[
            'translate']
        ball_mesh_rotations = np.array(game.num_balls * [np.eye(3)])
    else:
        ball_mesh_positions = [
            mesh.world_matrix[3, :3] for mesh in ball_meshes
        ]
        ball_mesh_rotations = [
            mesh.world_matrix[:3, :3].T for mesh in ball_meshes
        ]
        ball_shadow_mesh_positions = [
            mesh.world_matrix[3, :3] for mesh in ball_shadow_meshes
        ]
    gl.glViewport(0, 0, window_size[0], window_size[1])
    gl.glClearColor(*BG_COLOR)
    gl.glEnable(gl.GL_DEPTH_TEST)

    init_sound()

    _logger.info('entering render loop...')
    sys.stdout.flush()

    nframes = 0
    max_frame_time = 0.0
    lt = glfw.GetTime()
    while not glfw.WindowShouldClose(window):
        t = glfw.GetTime()
        dt = t - lt
        lt = t
        process_input(dt)

        with renderer.render(meshes=meshes) as frame_data:

            ##### VR mode: #####

            if isinstance(renderer, OpenVRRenderer) and frame_data:
                renderer.process_input(
                    button_press_callbacks=button_press_callbacks)
                hmd_pose = frame_data['hmd_pose']
                camera_position[:] = hmd_pose[:, 3]
                for i, pose in enumerate(frame_data['controller_poses'][:1]):
                    velocity = frame_data['controller_velocities'][i]
                    angular_velocity = frame_data[
                        'controller_angular_velocities'][i]
                    cue.world_matrix[:3, :3] = pose[:, :3].dot(cue.rotation).T
                    cue.world_matrix[3, :3] = pose[:, 3]
                    cue.velocity[:] = velocity
                    cue.angular_velocity = angular_velocity
                    set_quaternion_from_matrix(pose[:, :3], cue_quaternion)
                    # if game.t >= game.ntt:
                    #     for i, position in cue.aabb_check(ball_positions, ball_radius):
                    #         if game.t - last_contact_t[i] < 0.02:
                    #             continue
                    #         poc = cue.contact(position, ball_radius)
                    #         if poc is not None:
                    #             renderer.vr_system.triggerHapticPulse(renderer._controller_indices[-1],
                    #                                                   0, int(np.linalg.norm(cue.velocity + np.cross(position, cue.angular_velocity))**2 / 2.0 * 2700))
                    #             poc[:] = [0.0, 0.0, ball_radius]
                    #             # physics.strike_ball(game.t, i, poc, cue.velocity, cue.mass)
                    #             game.ntt = physics.next_turn_time()
                    #             break

            ##### desktop mode: #####

            elif isinstance(renderer, OpenGLRenderer):
                set_quaternion_from_matrix(
                    cue.rotation.dot(cue.world_matrix[:3, :3].T),
                    cue_quaternion)
                #frame_data['view_matrix'].T.dot(light_position, out=u_light_position)

                # if game.t >= game.ntt:
                #     for i, position in cue.aabb_check(ball_positions, ball_radius):
                #         poc = cue.contact(position, ball_radius)
                #         if poc is not None:
                #             poc[:] = [0.0, 0.0, ball_radius]
                #             physics.strike_ball(game.t, i, poc, cue.velocity, cue.mass)
                #             game.ntt = physics.next_turn_time()
                #             break

            cue_body.setPosition(cue.world_position)
            # x, y, z, w = cue_quaternion
            w = cue_quaternion[3]
            cue_quaternion[1:] = cue_quaternion[:3]
            cue_quaternion[0] = w
            # cue_body.setQuaternion((w, x, y, z))
            # cue_geom.setQuaternion((w, x, y, z))
            cue_body.setQuaternion(cue_quaternion)
            cue_geom.setQuaternion(cue_quaternion)
            cue_body.setLinearVel(cue.velocity)
            cue_body.setAngularVel(cue.angular_velocity)
            cue.shadow_mesh.update()

            physics.eval_positions(game.t, out=ball_positions)
            physics.eval_quaternions(game.t, out=ball_quaternions)
            ball_positions[
                ~physics.
                on_table] = camera_position  # hacky way to only show balls that are on table
            for i, quat in enumerate(ball_quaternions):
                set_matrix_from_quaternion(quat, ball_mesh_rotations[i])
            if use_bb_particles:
                billboard_particles.update_gl()
            else:
                for i, pos in enumerate(ball_positions):
                    ball_mesh_positions[i][:] = pos
                    ball_shadow_mesh_positions[i][0::2] = pos[0::2]

            # sdf_text.set_text("%9.3f" % dt)
            # sdf_text.update_gl()

        game.t += dt
        physics.step(dt)

        max_frame_time = max(max_frame_time, dt)
        if nframes == 0:
            st = glfw.GetTime()
        nframes += 1
        glfw.SwapBuffers(window)

    if nframes > 1:
        _logger.info(
            '...exited render loop: average FPS: %f, maximum frame time: %f, average frame time: %f',
            (nframes - 1) / (t - st), max_frame_time, (t - st) / (nframes - 1))

    renderer.shutdown()
    _logger.info('...shut down renderer')
    glfw.DestroyWindow(window)
    glfw.Terminate()
    _logger.info('GOODBYE')
Beispiel #30
0
    def _compute_matrices_from_input(self):
        old_focus = self._focus
        self._focus = glfw.GetWindowAttrib(self.window, glfw.FOCUSED)
        if old_focus != self._focus and self._focus:
            glfw.SetCursorPos(self.window, self._window_size[0] / 2,
                              self._window_size[1] / 2)

        FoV = 45
        mouse_speed = 0.001
        speed = 5.0
        # glfwGetTime is called only once, the first time this function is called
        if self._lastTime is None:
            self._lastTime = glfw.GetTime()

        currentTime = glfw.GetTime()
        if self._focus:
            if self._is_key_pressed(glfw.KEY_O):
                self._camera_position = self._org_camera_position.copy()
                self._horizontalAngle = self._org_angle[0]
                self._verticalAngle = self._org_angle[1]

            deltaTime = currentTime - self._lastTime
            #if deltaTime > 0.01:
            xpos, ypos = glfw.GetCursorPos(self.window)

            # Reset mouse position for next frame
            if xpos != self._window_size[0] / 2 or ypos != self._window_size[
                    1] / 2:
                glfw.SetCursorPos(self.window, self._window_size[0] / 2,
                                  self._window_size[1] / 2)

            # Compute new orientation
            self._horizontalAngle += mouse_speed * float(self._window_size[0] /
                                                         2.0 - xpos)
            self._verticalAngle += mouse_speed * float(self._window_size[1] /
                                                       2.0 - ypos)

        # Direction : Spherical coordinates to Cartesian coordinates conversion
        direction = vec3(
            mathf.cos(self._verticalAngle) * mathf.sin(self._horizontalAngle),
            mathf.sin(self._verticalAngle),
            mathf.cos(self._verticalAngle) * mathf.cos(self._horizontalAngle))

        # Right vector
        right = vec3(mathf.sin(self._horizontalAngle - 3.14 / 2.0), 0.0,
                     mathf.cos(self._horizontalAngle - 3.14 / 2.0))

        # Up vector
        up = vec3.cross(right, direction)

        if self._focus:
            # Move forward
            if self._is_key_pressed([glfw.KEY_W, glfw.KEY_UP]):
                self._camera_position += direction * deltaTime * speed

            # Move backward
            if self._is_key_pressed([glfw.KEY_S, glfw.KEY_DOWN]):
                self._camera_position -= direction * deltaTime * speed

            # Strafe right
            if self._is_key_pressed([glfw.KEY_D, glfw.KEY_RIGHT]):
                self._camera_position += right * deltaTime * speed

            # Strafe left
            if self._is_key_pressed([glfw.KEY_A, glfw.KEY_LEFT]):
                self._camera_position -= right * deltaTime * speed

            if self._is_key_pressed(glfw.KEY_C):
                new_press = glfw.GetTime()
                if new_press - self._last_key_pressed > 0.15:
                    for object in self._render_objects:
                        object.flip_collapse_mode()
                    self._last_key_pressed = new_press

            if self._is_key_pressed(glfw.KEY_T):
                new_press = glfw.GetTime()
                if new_press - self._last_key_pressed > 0.15:
                    for object in self._render_objects:
                        object.flip_color_mode()
                    self._last_key_pressed = new_press

            if self._is_key_pressed(glfw.KEY_U):
                new_press = glfw.GetTime()
                if new_press - self._last_key_pressed > 0.15:
                    for object in self._render_objects:
                        object.flip_unproject()
                    self._last_key_pressed = new_press

        ProjectionMatrix = mat4.perspective(
            FoV, self._window_size[0] / float(self._window_size[1]), 0.1,
            100.0)
        ViewMatrix = mat4.lookat(self._camera_position,
                                 self._camera_position + direction, up)

        vp = ProjectionMatrix * ViewMatrix

        glUniformMatrix4fv(self._mapping['V'], 1, GL_FALSE, ViewMatrix.data)
        self._lastTime = currentTime

        return vp