Exemple #1
0
def setup_glfw(title="poolvr.py 0.0.1",
               window_size=(800,600),
               double_buffered=False,
               multisample=4,
               fullscreen=False):
    if not glfw.Init():
        raise Exception('failed to initialize glfw')
    if not double_buffered:
        glfw.WindowHint(glfw.DOUBLEBUFFER, False)
        glfw.SwapInterval(0)
    if multisample:
        glfw.WindowHint(glfw.SAMPLES, multisample)
    width, height = window_size
    if fullscreen:
        window = glfw.CreateWindow(width, height, title, glfw.GetPrimaryMonitor())
    else:
        window = glfw.CreateWindow(width, height, title)
    if not window:
        glfw.Terminate()
        raise Exception('failed to create glfw window')
    glfw.MakeContextCurrent(window)
    _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION))
    renderer = OpenGLRenderer(window_size=(width, height), znear=0.1, zfar=1000)
    def on_resize(renderer, window, width, height):
        gl.glViewport(0, 0, width, height)
        renderer.window_size[:] = (width, height)
        renderer.update_projection_matrix()
    from functools import partial
    on_resize = partial(on_resize, renderer)
    glfw.SetWindowSizeCallback(window, on_resize)
    renderer.init_gl()
    on_resize(window, window_size[0], window_size[1])
    return window, renderer
Exemple #2
0
    def run_loop(self):
        glfw.MakeContextCurrent(self._win)

        glfw.SetWindowShouldClose(self._win, False)
        while not glfw.WindowShouldClose(self._win):
            if self._next_renderer:
                if self._renderer:
                    self._renderer.dispose()

                self._renderer = self._next_renderer
                self._renderer.prepare()

                self._next_renderer = None

            glClearColor(0.5, 0.5, 0.5, 1.0)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            if self._renderer:
                self._renderer.render()

            glfw.SwapBuffers(self._win)

            # Poll for and process events
            glfw.PollEvents()

        if self._renderer:
            self._renderer.dispose()
        if self._next_renderer is None:
            self._next_renderer = self._renderer
Exemple #3
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
Exemple #4
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)
Exemple #5
0
def setup_glfw(width=800,
               height=600,
               double_buffered=False,
               title="poolvr.py 0.0.1",
               multisample=0):
    if not glfw.Init():
        raise Exception('failed to initialize glfw')
    if not double_buffered:
        glfw.WindowHint(glfw.DOUBLEBUFFER, False)
        glfw.SwapInterval(0)
    if multisample:
        glfw.WindowHint(glfw.SAMPLES, multisample)
    window = glfw.CreateWindow(width, height, title)
    if not window:
        glfw.Terminate()
        raise Exception('failed to create glfw window')
    glfw.MakeContextCurrent(window)
    _logger.info('GL_VERSION: %s', gl.glGetString(gl.GL_VERSION))
    renderer = OpenGLRenderer(window_size=(width, height),
                              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)
    return window, renderer
Exemple #6
0
 def render_scene(self):
     "render scene one time"
     self.init_gl()
     glfw.MakeContextCurrent(self.window)
     self.renderer.render_scene()
     glfw.SwapBuffers(self.window)
     glfw.PollEvents()
Exemple #7
0
 def dispose_gl(self):
     if self.window is not None:
         glfw.MakeContextCurrent(self.window)
         if self.renderer is not None:
             self.renderer.dispose_gl()
     glfw.Terminate()
     self._is_initialized = False
Exemple #8
0
def update_windows():
    for window in windows:
        if glfw.WindowShouldClose(window):
            return
        glfw.MakeContextCurrent(window)
        GL.glClearColor(0.2, 0.2, 0.2, 1.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        glfw.SwapBuffers(window)
    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 setup_glfw(width=800, height=600, double_buffered=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(width, height, "gltfview")
    if not window:
        glfw.Terminate()
        raise Exception('failed to create glfw window')
    glfw.MakeContextCurrent(window)
    _logger.info('GL_VERSION: %s' % gl.glGetString(gl.GL_VERSION))
    return window
Exemple #11
0
def test_vcgl(frame_block=None):
    # save current working directory
    cwd = os.getcwd()

    # initialize glfw - this changes cwd
    glfw.Init()

    # restore cwd
    os.chdir(cwd)

    # version hints
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2)
    glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True)
    glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    # make a window
    win = glfw.CreateWindow(WIDTH, HEIGHT, TITLE)

    # make context current
    glfw.MakeContextCurrent(win)

    glClearColor(0.5, 0.5, 0.5, 1.0)

    renderer = TextureRenderer()
    renderer.prepare()

    fps_checker = FPSChecker()

    webcam = Webcam()
    with webcam:
        while not glfw.WindowShouldClose(win):
            frame = webcam.frame
            if frame_block:
                frame = frame_block(frame)
            fps_checker.lab(frame)

            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame = frame[::-1, ...]
            renderer.image = frame

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            renderer.render()

            glfw.SwapBuffers(win)

            # Poll for and process events
            glfw.PollEvents()

    glfw.Terminate()
Exemple #12
0
    def snapshot(self, mode='RGB'):
        _modes = {
            'rgb': GL_RGB,
            'rgba': GL_RGBA,
        }

        if not self._win:
            return None

        glfw.MakeContextCurrent(self._win)
        _, _, w, h = glGetIntegerv(GL_VIEWPORT)
        data = glReadPixels(0, 0, w, h, _modes[mode.lower()], GL_UNSIGNED_BYTE)
        data = Image.frombytes(mode=mode, size=(w, h), data=data)

        return np.asarray(data, dtype='uint8')
Exemple #13
0
def main():
    cairoSavePath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                 'carpark.pdf')
    # cairoSavePath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'carpark.pdf')
    # cairoSavePath = os.path.join(os.path.basename(__file__), 'carpark.pdf')
    # cairoSavePath = os.path.join(os.getcwd(), 'carpark.pdf')

    if not glfw.Init():
        exit()

    window = CbWindow(640, 480, 'window')

    if not window.window:
        glfw.Terminate()
        print('GLFW: Failed to create window')
        exit()

    print glGetString(GL_VERSION)

    parkingLot = buildParkingLot()
    mainRender = ParkingLotRender(parkingLot)
    window.mainRender = mainRender
    window.cairoSavePath = cairoSavePath

    mainRender.renderCairo(window.playerCamera, cairoSavePath)

    # mainScene = Scene()

    glfw.MakeContextCurrent(window.window)
    while not glfw.WindowShouldClose(window.window):
        # Render here
        # mainScene.renderModels(window.playerCamera)
        # mainRender.renderOpenGL(window.playerCamera)
        mainRender.renderOpenGL(window.currentCamera, window.playerCamera)

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

        # Poll for and process events
        glfw.PollEvents()

        processCameraSelectInput(window, parkingLot)

        if not window.cameraLocked:
            window.currentCamera.processPlayerInput(window.window)

    glfw.DestroyWindow(window.window)
    glfw.Terminate()
Exemple #14
0
def main():
    appName = 'First App'

    glfw.Init()
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
    # glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
    # glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    window = glfw.CreateWindow(800, 800, appName)
    glfw.SetWindowSizeCallback(window, window_size_callback)
    glfw.SetKeyCallback(window, key_callback)
    glfw.MakeContextCurrent(window)
    glfw.SwapInterval(1)

    try:
        initOpenGL()
    except Exception as e:
        print(e)
        exit(1)

    prevTime = time()
    frameCount = 0
    frameTimeSum = 0
    lastUpdateTime = prevTime
    while not glfw.WindowShouldClose(window):
        glfw.PollEvents()
        display(window)
        glfw.SwapBuffers(window)
        curTime = time()
        frameTime = (curTime - prevTime)
        # if frameTime != 0: print(1 / frameTime)
        sleep(0.016)

        if curTime - lastUpdateTime > 1:
            glfw.SetWindowTitle(
                window, '%s, FPS: %s' %
                (appName, str(round(frameCount / frameTimeSum))))
            frameCount = 0
            frameTimeSum = 0
            lastUpdateTime = curTime

        frameTimeSum += frameTime
        frameCount += 1
        prevTime = curTime

    glfw.DestroyWindow(window)
    glfw.Terminate()
Exemple #15
0
def main():
    # save current working directory
    cwd = os.getcwd()

    # initialize glfw - this changes cwd
    glfw.Init()

    # restore cwd
    os.chdir(cwd)

    # version hints
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2)
    glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True)
    glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    # make a window
    win = glfw.CreateWindow(512, 512, b'simpleglfw')

    # make context current
    glfw.MakeContextCurrent(win)

    glClearColor(0.5, 0.5, 0.5, 1.0)

    # renderer = TriangleRenderer()
    # renderer = RectangleRenderer()
    with Image.open('./image/psh.jpg') as img:
        data = np.asarray(img, dtype='uint8')
        data = data[::-1, ...]
        renderer = TextureRenderer(image=data)

    renderer.prepare()
    while not glfw.WindowShouldClose(win):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        renderer.render()
        glfw.SwapBuffers(win)

        # Poll for and process events
        glfw.PollEvents()

    glfw.Terminate()
Exemple #16
0
    def __init__(self, width=1024, height=1024, title="vol_render"):
        curdir = os.getcwd()
        glfw.Init()
        # glfw sometimes changes the current working directory, see
        # https://github.com/adamlwgriffiths/cyglfw3/issues/21
        os.chdir(curdir)
        glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
        glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
        glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, True)
        glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        self.window = glfw.CreateWindow(width, height, title)
        if not self.window:
            glfw.Terminate()
            exit()

        glfw.MakeContextCurrent(self.window)
        GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        glfw.SwapBuffers(self.window)
        glfw.PollEvents()
Exemple #17
0
 def init_gl(self):
     if self._is_initialized:
         return
     if not glfw.Init():
         raise RuntimeError("GLFW Initialization failed")
     glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 4)
     glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 1)
     glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
     glfw.WindowHint(glfw.DOUBLEBUFFER, False)
     glfw.SwapInterval(0)
     self.window = glfw.CreateWindow(self.renderer.window_size[0],
                                     self.renderer.window_size[1],
                                     self.title)
     if self.window is None:
         glfw.Terminate()
         raise RuntimeError("GLFW Window creation failed")
     glfw.SetKeyCallback(self.window, self.key_callback)
     glfw.MakeContextCurrent(self.window)
     if self.renderer is not None:
         self.renderer.init_gl()
     self._is_initialized = True
Exemple #18
0
    def init(self):
        assert glfw.Init(), 'Glfw Init failed!'
        self.window = glfw.CreateWindow(self._window_size[0],
                                        self._window_size[1], self._title,
                                        None)
        glfw.WindowHint(glfw.SAMPLES, 4)
        glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
        glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
        glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
        glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

        glfw.MakeContextCurrent(self.window)
        glfw.SetInputMode(self.window, glfw.STICKY_KEYS, True)

        # Enable depth test
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_TEXTURE_3D)
        # Accept fragment if it closer to the camera than the former one
        glDepthFunc(GL_LESS)
        # disable vsync
        glfw.SwapInterval(0)
        self._init_shaders()
Unfortunately PyOpenGL doesn't always handle error cases well.
""")

version = 3,2

glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, version[0])
glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, version[1])
glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, 0)
glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

window = glfw.CreateWindow(640, 480, 'Hello World')
if not window:
    glfw.Terminate()
    print('Failed to create window')
    exit()

glfw.MakeContextCurrent(window)
print('GL:',GL.glGetString(GL.GL_VERSION))
print('GLFW3:',glfw.GetVersionString())
for iteration in range(100):
    if glfw.WindowShouldClose(window):
        break
    GL.glClearColor(0.2, 0.2, 0.2, 1.0)
    GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

    glfw.SwapBuffers(window)
    glfw.PollEvents()

glfw.DestroyWindow(window)
glfw.Terminate()
Exemple #20
0
    def __init__(self):
        glfw.Init()  #Init glfw
        glfw.WindowHint(
            glfw.CONTEXT_VERSION_MAJOR,
            3)  #set openGL context version to 3.3 (the latest we can support)
        glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
        glfw.WindowHint(
            glfw.OPENGL_FORWARD_COMPAT, GL_TRUE
        )  #tell OSX we don't give a shit about compatibility and want the newer GLSL versions
        glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

        self.width, self.height = 1440, 900
        self.aspect = self.width / float(self.height)
        self.win = glfw.CreateWindow(self.width, self.height, "test")
        #self.win = glfw.CreateWindow(self.width, self.height, "test", glfw.GetPrimaryMonitor(), None)
        self.exitNow = False
        glfw.MakeContextCurrent(self.win)

        glViewport(0, 0, self.width, self.height)
        glEnable(GL_DEPTH_TEST)
        glClearColor(0.5, 0.5, 0.5, 1.0)

        #glfw.SetMouseButtonCallback(self.win, self.onMouseButton)
        glfw.SetKeyCallback(self.win, self.keyPressed)
        #glfw.SetWindowSizeCallback(self.win, self.onSize)

        self.objs = []
        self.callbacks = {'keyPressed': [], 'keyReleased': [], 'logic': []}
        self.objs.append(Box(0, 0))
        player = Player()
        self.objs.append(player)
        self.callbacks['keyPressed'].append(player.getCallback('keyPressed'))
        self.callbacks['keyReleased'].append(player.getCallback('keyReleased'))
        self.callbacks['logic'].append(player.getCallback('logic'))
        #self.callbacks['keyReleased'].append(player.getCallbacks(['keyReleased']))
        for obj in self.objs:
            obj.geomArray = numpy.array(obj.geom, numpy.float32)
            obj.vao = vertex_array_object.glGenVertexArrays(1)
            glBindVertexArray(obj.vao)
            obj.vBuff = glGenBuffers(1)
            glBindBuffer(GL_ARRAY_BUFFER, obj.vBuff)
            glBufferData(GL_ARRAY_BUFFER, 4 * len(obj.geom), obj.geomArray,
                         GL_DYNAMIC_DRAW)
            glEnableVertexAttribArray(0)
            glVertexAttribPointer(
                0, 3, GL_FLOAT, GL_FALSE, 0,
                None)  #set the size & type of the argument to the shader

            #compile shaders
            obj.vertShader = shaders.compileShader(obj.vertShaderString,
                                                   GL_VERTEX_SHADER)
            obj.fragShader = shaders.compileShader(obj.fragShaderString,
                                                   GL_FRAGMENT_SHADER)
            try:
                obj.shader = shaders.compileProgram(obj.vertShader,
                                                    obj.fragShader)
            except (GLError, RuntimeError) as err:
                print err

            glBindVertexArray(0)  #unbind our VAO

        self.colorOffset = 255 * 3
        self.OnInit()
 def deactivate(self):
     glfw.MakeContextCurrent(_NULL_WINDOW)
 def activate(self):
     glfw.MakeContextCurrent(self._window)
Exemple #23
0
 def __del__(self):
     glfw.MakeContextCurrent(self._win)
     if self._renderer:
         self._renderer.dispose()
     glfw.Terminate()
     debug('GLView is being deleted: {}'.format(self))
def generate_binary_mask(faces, vertices_2d, width, height):
    if not glfw.Init():
        print('glfw not initialized')
        sys.exit()

    version = 3, 3
    glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, version[0])
    glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, version[1])
    glfw.WindowHint(glfw.OPENGL_FORWARD_COMPAT, 1)
    glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
    glfw.WindowHint(glfw.VISIBLE, 1)

    window = glfw.CreateWindow(width, height, 'Quad')
    if not window:
        print('glfw window not created')
        glfw.Terminate()
        sys.exit()

    glfw.MakeContextCurrent(window)

    strVS = """
        #version 330
        layout(location = 0) in vec2 aPosition;

        void main() {
            gl_Position = vec4(vec3(aPosition, 0), 1.0);
        }
        """
    strFS = """
        #version 330
        out vec3 fragColor;

        void main() {
            fragColor = vec3(0, 1, 0);
        }
        """

    program = glutils.loadShaders(strVS, strFS)
    glUseProgram(program)

    element_array = np.reshape(faces, -1)
    elementData = np.array(element_array, np.uint32)

    vertex_array = np.reshape(vertices_2d, -1)
    vertexData = np.array(vertex_array, np.float32)

    vao = glGenVertexArrays(1)
    glBindVertexArray(vao)

    ebo = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * len(elementData), elementData, GL_STATIC_DRAW)

    vbo = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, 4 * len(vertexData), vertexData, GL_STATIC_DRAW)

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

    glBindVertexArray(0)

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

    glUseProgram(program)
    glBindVertexArray(vao)
    glDrawElements(GL_TRIANGLES, len(element_array), GL_UNSIGNED_INT, None)
    glBindVertexArray(0)

    glPixelStorei(GL_PACK_ALIGNMENT, 1)
    pixel_data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, outputType=None)

    im = np.array(pixel_data)
    mask = Image.frombuffer('RGB', (width, height), im, 'raw', 'RGB')
    mask = np.array(mask)
    glfw.Terminate()
    return mask
Exemple #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()
    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,
            )