Exemplo n.º 1
0
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

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

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

        monitor = None
        if self.fullscreen:
            self._set_fullscreen(True)

        self._window = glfw.create_window(self.width, self.height, self.title,
                                          monitor, None)
        self._has_focus = True

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

        self.cursor = self._cursor

        self._buffer_width, self._buffer_height = glfw.get_framebuffer_size(
            self._window)
        glfw.make_context_current(self._window)

        if self.vsync:
            glfw.swap_interval(1)
        else:
            glfw.swap_interval(0)

        glfw.set_key_callback(self._window, self.glfw_key_event_callback)
        glfw.set_cursor_pos_callback(self._window,
                                     self.glfw_mouse_event_callback)
        glfw.set_mouse_button_callback(self._window,
                                       self.glfw_mouse_button_callback)
        glfw.set_scroll_callback(self._window, self.glfw_mouse_scroll_callback)
        glfw.set_window_size_callback(self._window,
                                      self.glfw_window_resize_callback)
        glfw.set_char_callback(self._window, self.glfw_char_callback)
        glfw.set_window_focus_callback(self._window, self.glfw_window_focus)
        glfw.set_cursor_enter_callback(self._window, self.glfw_cursor_enter)
        glfw.set_window_iconify_callback(self._window,
                                         self.glfw_window_iconify)
        glfw.set_window_close_callback(self._window, self.glfw_window_close)

        self.init_mgl_context()
        self.set_default_viewport()
Exemplo n.º 2
0
 def movement(self):
     self.currentFrame = glfwGetTime()
     self.deltaTime = self.currentFrame - self.lastFrame
     self.keyhandler(self.deltaTime)
     self.lastFrame = self.currentFrame
     glfwSetScrollCallback(self.window, self.scroll_handler)
     glfwSetWindowSizeCallback(self.window, self.setwindowsize)
     g.set_cursor_enter_callback(self.window, self.mouse_entered)
     glfwSetCursorPosCallback(self.window, self.mousehandler)
Exemplo n.º 3
0
    def __init__(self, window):
        super().__init__(window)
        with window.context.glfw as window:
            glfw.set_cursor_pos_callback(window, self.__master_cursor_pos_callback)
            glfw.set_cursor_enter_callback(window, self.__master_cursor_enter_callback)
            glfw.set_mouse_button_callback(window, self.__master_mouse_button_callback)
            glfw.set_scroll_callback(window, self.__master_mouse_scroll_callback)
        self.window.append_predraw_callback(self.__set_cursor_pos_perframe)

        self.__pos_perframe = Vec(0, 0, 0)
        self.__pos_prev = Vec(0, 0, 0)
        self.__pos_instant = Vec(0, 0, 0)
        self.__accel = Vec(0, 0, 0)
Exemplo n.º 4
0
    def __init__(self, window_title, window_size, window_position, func_Ldown,
                 func_Lup, func_Rdown, func_Rup, func_Mdown, func_Mup,
                 func_mouse_move, func_mouse_wheel, func_draw_scene,
                 func_on_keydown, func_on_keyup, func_on_keykeep):

        self.window = glfw.create_window(window_size[0], window_size[1],
                                         window_title, None, None)
        self.cam_pos = np.array([0.0, 0.0, 1000.0], dtype=np.float32)
        self.cam_up = np.array([0.0, 1.0, 0.0], dtype=np.float32)
        self.cam_cnt = np.array([0.0, 0.0, 0.0], dtype=np.float32)
        self.b_rendering = False
        self.viewscale = 1000
        self.clearcolor = np.array([0.2, 0.2, 0.2, 1.0])

        if not self.window:
            glfw.terminate()
            raise RuntimeError('Could not create an window')

        self.func_Ldown, self.func_Lup = func_Ldown, func_Lup
        self.func_Rdown, self.func_Rup = func_Rdown, func_Rup
        self.func_Mdown, self.func_Mup = func_Mdown, func_Mup
        self.func_mouse_move = func_mouse_move
        self.func_draw_scene = func_draw_scene
        self.func_on_keydown = func_on_keydown
        self.func_on_keyup = func_on_keyup
        self.func_on_keykeep = func_on_keykeep
        self.func_mouse_wheel = func_mouse_wheel

        #set callback functions
        glfw.set_cursor_pos_callback(self.window, self.cursor_pos)
        glfw.set_cursor_enter_callback(self.window, self.cursor_enter)
        glfw.set_mouse_button_callback(self.window, self.mouse_button)
        glfw.set_scroll_callback(self.window, self.mouse_wheel)
        glfw.set_window_refresh_callback(self.window, self.window_refresh)
        glfw.set_key_callback(self.window, self.func_keyboard)
        glfw.set_window_pos(self.window, window_position[0],
                            window_position[1])

        #call display from here (TODO check! is this necessary?)
        glfw.make_context_current(self.window)
        self.display()  # necessary only on Windows
Exemplo n.º 5
0
    def __init__(self, window):
        super(Client, self).__init__()
        self.window = window

        self.gl = mg.create_context()
        if not self.gl:
            print("can't create gl context")
            return

        self._compile()

        def on_mod(e):
            self._dirty = True

        handler = FileSystemEventHandler()
        handler.on_modified = on_mod
        observer = Observer()
        observer.schedule(handler, "./gl", True)
        observer.start()

        self._isresizing = False
        self._isdrag_camera = False
        self._isdrag_light = False
        self._isdrag_right = False
        self._isdrag_mid = False
        self._campos = vec3(-2.0, 3.0, -5.0)
        self._lightpos = vec3(-10.0, 20.0, -50.0)
        self._prevpos = (0, 0)

        _, _, w0, h0 = glfw.get_monitor_workarea(glfw.get_primary_monitor())
        w1, h1 = glfw.get_window_size(window)
        glfw.set_window_pos(window, w0 // 2 - w1 // 2, h0 // 2 - h1 // 2)
        glfw.set_framebuffer_size_callback(window, self.on_framebuffer_size)
        glfw.set_mouse_button_callback(window, self.on_mouse_button)
        glfw.set_cursor_pos_callback(window, self.on_cursor_pos)
        glfw.set_scroll_callback(window, self.on_scroll)
        glfw.set_cursor_enter_callback(window, self.on_cursor_enter)
Exemplo n.º 6
0
window = glfw.create_window(WIDTH, HEIGHT, "My OpenGL window", None, None)

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

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

# set the callback function for window resize
glfw.set_window_size_callback(window, window_resize)
# set the mouse position callback
glfw.set_cursor_pos_callback(window, mouse_look_clb)
# set the mouse enter callback
glfw.set_cursor_enter_callback(window, mouse_enter_clb)

# make the context current
glfw.make_context_current(window)

# load here the 3d meshes
cube_indices, cube_buffer = ObjLoader.load_model("meshes/cube.obj")
monkey_indices, monkey_buffer = ObjLoader.load_model("meshes/monkey.obj")
floor_indices, floor_buffer = ObjLoader.load_model("meshes/floor.obj")

shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER),
                        compileShader(fragment_src, GL_FRAGMENT_SHADER))

# VAO and VBO
VAO = glGenVertexArrays(3)
VBO = glGenBuffers(3)
Exemplo n.º 7
0
    def __init__(self, win, backendConf=None):
        """Set up the backend window according the params of the PsychoPy win

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

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

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

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

            import psychopy.visual as visual

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

        """
        BaseBackend.__init__(self, win)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        # give the window class GLFW specific methods
        win.setMouseType = self.setMouseType
        if not win.allowGUI:
            self.setMouseVisibility(False)
Exemplo n.º 8
0
def main():
    qz_display_init()

    width = 1200
    height = 675

    # Initialize the library
    if not glfw.init():
        return
    # Create a windowed mode window and its OpenGL context
    window = glfw.create_window(width, height, 'SPEED QUIZ', None, None)
    if not window:
        glfw.terminate()
        return

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

    # register callback functions
    glfw.set_window_size_callback(window, on_reshape)
    glfw.set_key_callback(window, on_key)
    glfw.set_mouse_button_callback(window, on_mouse)
    #glfw.set_cursor_pos_callback(window, on_cursor_pos)
    glfw.set_cursor_enter_callback(window, on_cursor_enter)

    # init gl environment
    '''
	glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )
	glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE )
	glEnable( GL_DEPTH_TEST )
	glEnable( GL_COLOR_MATERIAL )
	'''
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    glEnable(GL_BLEND)

    on_reshape(window, width, height)
    #on_reshape(window, 1200, 675)

    # make freetype font
    loadfont()

    #gluPerspective(30, (640./480.), 0.5, 10.0)
    #glTranslate(0.0, 0.0, -7)

    timer_sec = 5.0
    countdown = timer_sec
    prev_time = glfw.get_time()

    # Loop until the user closes the window
    while not glfw.window_should_close(window):
        # Render here, e.g. using pyOpenGL
        #glRotatef(0.5,3,1,1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        on_display()

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

        # Poll for and process events
        glfw.poll_events()

        # check timer
        '''
		curr_time = glfw.get_time()
		dt = curr_time - prev_time
		if (dt.totalcountdown <= 0.):
			print 'timer called : ', countdown
			countdown += timer_sec
		'''

    glfw.ternimate()
Exemplo n.º 9
0
def processInput(window):
    glfw.set_cursor_pos_callback(window, cursorPositionCallback)
    glfw.set_input_mode(window, glfw.CURSOR, glfw.CURSOR_NORMAL)
    glfw.set_cursor_enter_callback(window, cursorEnterCallback)
    glfw.set_mouse_button_callback(window, mouseButtonCallback)
Exemplo n.º 10
0
def main():
    global shader

    vertex_src = """
    # version 330

    layout(location = 0) in vec3 a_position;
    layout(location = 1) in vec2 a_texture;
    layout(location = 2) in vec3 a_normal;

    uniform mat4 model;
    uniform mat4 projection;
    uniform mat4 view;

    out vec2 v_texture;

    void main()
    {
        gl_Position = projection * view * model * vec4(a_position, 1.0);
        v_texture = a_texture;
    }
    """

    fragment_src = """
    # version 330

    in vec2 v_texture;

    out vec4 out_color;

    uniform sampler2D s_texture;

    void main()
    {
        out_color = texture(s_texture, v_texture);
    }
    """

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

    if "Windows" in pltf.platform():
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 6)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)
    else:
        glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
        glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 1)
        glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
        glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, True)

    # creating the window
    window = glfw.create_window(WIDTH, HEIGHT, "My OpenGL window", None, None)

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

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

    # set the callback function for window resize
    glfw.set_window_size_callback(window, window_resize)
    # set the mouse position callback
    glfw.set_cursor_pos_callback(window, mouse_look_clb)
    # set the mouse enter callback
    glfw.set_cursor_enter_callback(window, mouse_enter_clb)

    # make the context current
    glfw.make_context_current(window)

    # load here the 3d meshes
    cube_indices, cube_buffer = ObjLoader.load_model("meshes/cube.obj")
    monkey_indices, monkey_buffer = ObjLoader.load_model("meshes/monkey.obj")
    floor_indices, floor_buffer = ObjLoader.load_model("meshes/floor.obj")

    # VAO and VBO
    VAO = glGenVertexArrays(3)
    VBO = glGenBuffers(3)

    # cube VAO
    glBindVertexArray(VAO[0])

    shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER),
                            compileShader(fragment_src, GL_FRAGMENT_SHADER))

    # cube Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, VBO[0])
    glBufferData(GL_ARRAY_BUFFER, cube_buffer.nbytes, cube_buffer,
                 GL_STATIC_DRAW)

    # cube vertices
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, cube_buffer.itemsize * 8,
                          ctypes.c_void_p(0))
    # cube textures
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, cube_buffer.itemsize * 8,
                          ctypes.c_void_p(12))
    # cube normals
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, cube_buffer.itemsize * 8,
                          ctypes.c_void_p(20))
    glEnableVertexAttribArray(2)

    # monkey VAO
    glBindVertexArray(VAO[1])
    # monkey Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, VBO[1])
    glBufferData(GL_ARRAY_BUFFER, monkey_buffer.nbytes, monkey_buffer,
                 GL_STATIC_DRAW)

    # monkey vertices
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8,
                          ctypes.c_void_p(0))
    # monkey textures
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8,
                          ctypes.c_void_p(12))
    # monkey normals
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, monkey_buffer.itemsize * 8,
                          ctypes.c_void_p(20))
    glEnableVertexAttribArray(2)

    # floor VAO
    glBindVertexArray(VAO[2])
    # floor Vertex Buffer Object
    glBindBuffer(GL_ARRAY_BUFFER, VBO[2])
    glBufferData(GL_ARRAY_BUFFER, floor_buffer.nbytes, floor_buffer,
                 GL_STATIC_DRAW)

    # floor vertices
    glEnableVertexAttribArray(0)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, floor_buffer.itemsize * 8,
                          ctypes.c_void_p(0))
    # floor textures
    glEnableVertexAttribArray(1)
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, floor_buffer.itemsize * 8,
                          ctypes.c_void_p(12))
    # floor normals
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, floor_buffer.itemsize * 8,
                          ctypes.c_void_p(20))
    glEnableVertexAttribArray(2)

    textures = glGenTextures(3)
    load_texture("meshes/cube.jpg", textures[0])
    load_texture("meshes/monkey.jpg", textures[1])
    load_texture("meshes/floor.jpg", textures[2])

    glUseProgram(shader)
    glClearColor(0, 0.1, 0.1, 1)
    glEnable(GL_DEPTH_TEST)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    projection = pyrr.matrix44.create_perspective_projection_matrix(
        45, WIDTH / HEIGHT, 0.1, 100)
    cube_pos = pyrr.matrix44.create_from_translation(pyrr.Vector3([6, 4, 0]))
    monkey_pos = pyrr.matrix44.create_from_translation(
        pyrr.Vector3([-4, 4, -4]))
    floor_pos = pyrr.matrix44.create_from_translation(pyrr.Vector3([0, 0, 0]))

    # eye, target, up
    # view = pyrr.matrix44.create_look_at(pyrr.Vector3([0, 2, 16]), pyrr.Vector3([0, 0, 0]), pyrr.Vector3([0, 1, 0]))

    model_loc = glGetUniformLocation(shader, "model")
    proj_loc = glGetUniformLocation(shader, "projection")
    view_loc = glGetUniformLocation(shader, "view")

    glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
    # glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)

    glUseProgram(0)

    # the main application loop
    while not glfw.window_should_close(window):
        glfw.poll_events()

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        view = cam.get_view_matrix()

        glUseProgram(shader)

        glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)

        rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time())
        model = pyrr.matrix44.multiply(rot_y, cube_pos)

        # draw the cube
        glBindVertexArray(VAO[0])
        glBindTexture(GL_TEXTURE_2D, textures[0])
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)
        glDrawArrays(GL_TRIANGLES, 0, len(monkey_indices))

        # draw the monkey
        glBindVertexArray(VAO[1])
        glBindTexture(GL_TEXTURE_2D, textures[1])
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, monkey_pos)
        glDrawArrays(GL_TRIANGLES, 0, len(monkey_indices))

        # draw the floor
        glBindVertexArray(VAO[2])
        glBindTexture(GL_TEXTURE_2D, textures[2])
        glUniformMatrix4fv(model_loc, 1, GL_FALSE, floor_pos)
        glDrawArrays(GL_TRIANGLES, 0, len(floor_indices))

        glUseProgram(0)

        glfw.swap_buffers(window)

    # terminate glfw, free up allocated resources
    glfw.terminate()