Example #1
0
def main():
    time_start = time.time()

    if not init_opengl():
        return

    #key events
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glfw.set_cursor_pos(window, 1024 / 2, 768 / 2)
    glfw.set_key_callback(window, key_event)

    glClearColor(0, 0, 0.4, 0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)
    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    #Faces wont display if normal facing camera ie inside of mesh
    glEnable(GL_CULL_FACE)

    #Disable vsync
    glfw.swap_interval(0)

    shader_program = LoadShaders("VertexShader.vertexshader",
                                 "FragmentShader.fragmentshader")

    vao1 = glGenVertexArrays(1)
    glBindVertexArray(vao1)

    #Read obj
    vertices, faces, uvs, normals, colors = objloader.load("0000.obj")
    vertex_data, uv_data, normal_data = objloader.process_obj(
        vertices, faces, uvs, normals, colors)

    #convert to ctype
    #vertex_data = objloader.generate_2d_ctypes(vertex_data)
    #normal_data = objloader.generate_2d_ctypes(normal_data)
    #uv_data = objloader.generate_2d_ctypes(uv_data)

    vertex_data = np.array(vertex_data).astype(np.float32)
    normal_data = np.array(normal_data).astype(np.float32)
    uv_data = np.array(uv_data).astype(np.float32)

    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(vertex_data) * 4 * 3, vertex_data, GL_STATIC_DRAW)
    #glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4 * 3, vert_data, GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(normal_data) * 4 * 3, normal_data, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(uv_data) * 4 * 2, uv_data, GL_STATIC_DRAW)

    #Unbind
    glBindVertexArray(0)

    #Radial VAO
    vao2 = glGenVertexArrays(1)

    #Radial curves data
    #radialcurve.create_vertex_face_dict(vertices, faces)
    time_end = time.time()
    print("Time passed until radial functions: ", time_end - time_start,
          " seconds")
    time_start = time.time()
    radialcurve.vertex_face_sort(vertices, faces)
    time_end = time.time()
    print("Array Time: ", time_end - time_start)
    segment = 20
    time_start = time.time()
    radial_data_unfinished = radialcurve.get_radial_curves(
        segment, (5.163908, -21.303692), (0.601237, 58.022675), (-60, 0),
        (60, 0), (0, 60), (0, -60), (-40, -20), (20, -40))
    time_end = time.time()
    print("Radial Curve Time: ", time_end - time_start)

    radial_data = radial_data_unfinished[3]
    #Increase z by 1 so easier to see
    for point in radial_data:
        point[2] = point[2] + 1
        #point[2] = 25

    #matplot
    #`x = [0, 1/6, 2/6, 3/6, 4/6, 5/6, 1]
    x = [i / (segment + 1) for i in range(segment + 2)]
    y = []
    for lines in radial_data_unfinished:
        for data in lines:
            y.append(data[2])
        plt.plot(x, y)
        y = []
    #print(y)

    plt.xlabel("Distance")
    plt.ylabel("Depth")

    plt.show()

    #print(radial_data)
    #radial_data = [[5.163908, -21.303692, 25], [0.601237, 58.022675, 25]]
    radial_data = objloader.generate_2d_ctypes(radial_data)

    #Radial Curves
    radial_buffer = glGenBuffers(1)
    array_type = GLfloat * len(radial_data)
    glBindBuffer(GL_ARRAY_BUFFER, radial_buffer)
    #glBufferData(GL_ARRAY_BUFFER, len(radial_data) * 4, array_type(*radial_data), GL_STATIC_DRAW)
    rad_data = np.array(radial_data).astype(np.float32)
    glBufferData(GL_ARRAY_BUFFER,
                 len(radial_data) * 4 * 3, rad_data, GL_STATIC_DRAW)
    #Unbind
    glBindVertexArray(0)

    #####

    #Handles
    light_id = glGetUniformLocation(shader_program, "LightPosition_worldspace")
    matrix_id = glGetUniformLocation(shader_program, "MVP")
    view_matrix_id = glGetUniformLocation(shader_program, "V")
    model_matrix_id = glGetUniformLocation(shader_program, "M")

    # Enable key events
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)

    #Line Width
    glEnable(GL_LINE_SMOOTH)
    glLineWidth(3)

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

        glUseProgram(shader_program)

        controls.computeMatricesFromInputs(window)
        pm = controls.getProjectionMatrix()
        vm = controls.getViewMatrix()
        #at origin
        mm = mat4.identity()
        mvp = pm * vm * mm

        glUniformMatrix4fv(matrix_id, 1, GL_FALSE, mvp.data)
        glUniformMatrix4fv(model_matrix_id, 1, GL_FALSE, mm.data)
        glUniformMatrix4fv(view_matrix_id, 1, GL_FALSE, vm.data)

        lightPos = vec3(0, 0, 50)
        glUniform3f(light_id, lightPos.x, lightPos.y, lightPos.z)

        ##VAO1################
        glBindVertexArray(vao1)

        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(
            0,  # attribute
            3,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
        glVertexAttribPointer(
            1,  # attribute
            3,  # size
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        glEnableVertexAttribArray(2)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(
            2,  # attribute
            2,  # size
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # Draw
        glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))

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

        glBindVertexArray(0)

        ######################################

        #VAO2
        glBindVertexArray(vao2)

        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, radial_buffer)
        glVertexAttribPointer(
            0,  # attribute
            3,  # size
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        glDrawArrays(GL_LINE_STRIP, 0, len(radial_data))
        #glDrawArrays(GL_TRIANGLES, 0, len(radial_data))

        glBindVertexArray(0)

        glfw.swap_buffers(window)

        glfw.poll_events()

    glBindVertexArray(vao1)
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [normal_buffer])
    glBindVertexArray(0)
    glDeleteVertexArrays(1, [vao1])

    glBindVertexArray(vao2)
    glDeleteBuffers(1, [radial_buffer])
    glDeleteVertexArrays(1, [vao2])

    glDeleteProgram(shader_program)

    glfw.terminate()
Example #2
0
def main():
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glfw.set_cursor_pos(window, 1024 / 2, 768 / 2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0, 0.0, 0.4, 0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)
    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)

    program_id = common.LoadShaders(
        ".\\shaders\\Tutorial6\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial6\\TextureFragmentShader.fragmentshader")

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")

    texture = load_image(".\\content\\uvtemplate.bmp")
    texture_id = glGetUniformLocation(program_id, "myTextureSampler")

    # Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
    # A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
    vertex_data = [
        -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
        -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0,
        1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
        -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0,
        -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
        -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
        -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,
        1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0
    ]

    # Two UV coordinatesfor each vertex. They were created withe Blender.
    uv_data = [
        0.000059, 1.0 - 0.000004, 0.000103, 1.0 - 0.336048, 0.335973,
        1.0 - 0.335903, 1.000023, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851,
        0.999958, 1.0 - 0.336064, 0.667979, 1.0 - 0.335851, 0.336024,
        1.0 - 0.671877, 0.667969, 1.0 - 0.671889, 1.000023, 1.0 - 0.000013,
        0.668104, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851, 0.000059,
        1.0 - 0.000004, 0.335973, 1.0 - 0.335903, 0.336098, 1.0 - 0.000071,
        0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903, 0.336024,
        1.0 - 0.671877, 1.000004, 1.0 - 0.671847, 0.999958, 1.0 - 0.336064,
        0.667979, 1.0 - 0.335851, 0.668104, 1.0 - 0.000013, 0.335973,
        1.0 - 0.335903, 0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903,
        0.668104, 1.0 - 0.000013, 0.336098, 1.0 - 0.000071, 0.000103,
        1.0 - 0.336048, 0.000004, 1.0 - 0.671870, 0.336024, 1.0 - 0.671877,
        0.000103, 1.0 - 0.336048, 0.336024, 1.0 - 0.671877, 0.335973,
        1.0 - 0.335903, 0.667969, 1.0 - 0.671889, 1.000004, 1.0 - 0.671847,
        0.667979, 1.0 - 0.335851
    ]

    vertex_buffer = glGenBuffers(1)
    array_type = GLfloat * len(vertex_data)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(vertex_data) * 4, array_type(*vertex_data),
                 GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(uv_data) * 4, array_type(*uv_data), GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

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

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix()
        ViewMatrix = controls.getViewMatrix()
        ModelMatrix = mat4.identity()
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE, mvp.data)

        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture)
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0)

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(
            0,  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(
            1,  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0,
                     12 * 3)  #3 indices starting at 0 -> 1 triangle

        # Not strictly necessary because we only have
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)

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

        # Poll for and process events
        glfw.poll_events()

    # !Note braces around vertex_buffer and uv_buffer.
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
def main():
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE) 
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.4,0.0)
    
    # Enable depth test
    glEnable(GL_DEPTH_TEST)
    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    program_id = common.LoadShaders( ".\\shaders\\Tutorial6\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial6\\TextureFragmentShader.fragmentshader" )
    
    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP");

    texture = load_image(".\\content\\uvtemplate.bmp")
    texture_id  = glGetUniformLocation(program_id, "myTextureSampler")

    # Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
    # A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices
    vertex_data = [ 
        -1.0,-1.0,-1.0,
        -1.0,-1.0, 1.0,
        -1.0, 1.0, 1.0,
         1.0, 1.0,-1.0,
        -1.0,-1.0,-1.0,
        -1.0, 1.0,-1.0,
         1.0,-1.0, 1.0,
        -1.0,-1.0,-1.0,
         1.0,-1.0,-1.0,
         1.0, 1.0,-1.0,
         1.0,-1.0,-1.0,
        -1.0,-1.0,-1.0,
        -1.0,-1.0,-1.0,
        -1.0, 1.0, 1.0,
        -1.0, 1.0,-1.0,
         1.0,-1.0, 1.0,
        -1.0,-1.0, 1.0,
        -1.0,-1.0,-1.0,
        -1.0, 1.0, 1.0,
        -1.0,-1.0, 1.0,
         1.0,-1.0, 1.0,
         1.0, 1.0, 1.0,
         1.0,-1.0,-1.0,
         1.0, 1.0,-1.0,
         1.0,-1.0,-1.0,
         1.0, 1.0, 1.0,
         1.0,-1.0, 1.0,
         1.0, 1.0, 1.0,
         1.0, 1.0,-1.0,
        -1.0, 1.0,-1.0,
         1.0, 1.0, 1.0,
        -1.0, 1.0,-1.0,
        -1.0, 1.0, 1.0,
         1.0, 1.0, 1.0,
        -1.0, 1.0, 1.0,
         1.0,-1.0, 1.0]

    # Two UV coordinatesfor each vertex. They were created withe Blender.
    uv_data = [ 
        0.000059, 1.0-0.000004, 
        0.000103, 1.0-0.336048, 
        0.335973, 1.0-0.335903, 
        1.000023, 1.0-0.000013, 
        0.667979, 1.0-0.335851, 
        0.999958, 1.0-0.336064, 
        0.667979, 1.0-0.335851, 
        0.336024, 1.0-0.671877, 
        0.667969, 1.0-0.671889, 
        1.000023, 1.0-0.000013, 
        0.668104, 1.0-0.000013, 
        0.667979, 1.0-0.335851, 
        0.000059, 1.0-0.000004, 
        0.335973, 1.0-0.335903, 
        0.336098, 1.0-0.000071, 
        0.667979, 1.0-0.335851, 
        0.335973, 1.0-0.335903, 
        0.336024, 1.0-0.671877, 
        1.000004, 1.0-0.671847, 
        0.999958, 1.0-0.336064, 
        0.667979, 1.0-0.335851, 
        0.668104, 1.0-0.000013, 
        0.335973, 1.0-0.335903, 
        0.667979, 1.0-0.335851, 
        0.335973, 1.0-0.335903, 
        0.668104, 1.0-0.000013, 
        0.336098, 1.0-0.000071, 
        0.000103, 1.0-0.336048, 
        0.000004, 1.0-0.671870, 
        0.336024, 1.0-0.671877, 
        0.000103, 1.0-0.336048, 
        0.336024, 1.0-0.671877, 
        0.335973, 1.0-0.335903, 
        0.667969, 1.0-0.671889, 
        1.000004, 1.0-0.671847, 
        0.667979, 1.0-0.335851]

    vertex_buffer = glGenBuffers(1);
    array_type = GLfloat * len(vertex_data)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4, array_type(*vertex_data), GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1);
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(uv_data) * 4, array_type(*uv_data), GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()
    
    while glfw.get_key(window,glfw.KEY_ESCAPE) != glfw.PRESS and not glfw.window_should_close(window):
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        # Send our transformation to the currently bound shader, 
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
        
        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0);

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
        glVertexAttribPointer(
            0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
        glVertexAttribPointer(
            1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # Draw the triangle !
        glDrawArrays(GL_TRIANGLES, 0, 12*3) #3 indices starting at 0 -> 1 triangle

        # Not strictly necessary because we only have 
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
    
    
        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

    # !Note braces around vertex_buffer and uv_buffer.  
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
Example #4
0
def main():
    if not opengl_init():
        return

    OpenglInit()

    load_gedung("itb_coordinate.txt")

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE)
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.0,0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)
    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    program_id = common.LoadShaders( ".\\shaders\\Tutorial6\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial6\\TextureFragmentShader.fragmentshader" )

    vertex_data = createAllBuilding()

    # Two UV coordinatesfor each vertex. They were created withe Blender.
    uv_data = createUVData()

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP");

    texture = []
    texture_id = []

    texture_id.append(glGetUniformLocation(program_id, "myTextureSampler"))
    texture_id.append(glGetUniformLocation(program_id, "myTextureSampler2"))

    tex1 = TextureLoader.load_texture("res/crate.jpg")
    tex2 = TextureLoader.load_texture("res/metal.jpg")
    # Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
    # A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices



    vertex_buffer = glGenBuffers(1);
    array_type = GLfloat * len(vertex_data)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4, array_type(*vertex_data), GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1);
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(uv_data) * 4, array_type(*uv_data), GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

    glUseProgram(program_id)

    #1rst attribute buffer : vertices
    glEnableVertexAttribArray(0)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glVertexAttribPointer(
        0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  # len(vertex_data)
        GL_FLOAT,           # type
        GL_FALSE,           # ormalized?
        0,                  # stride
        null                # array buffer offset (c_type == void*)
        )

    # 2nd attribute buffer : colors
    glEnableVertexAttribArray(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
    glVertexAttribPointer(
        1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
        2,                  # len(vertex_data)
        GL_FLOAT,           # type
        GL_FALSE,           # ormalized?
        0,                  # stride
        null                # array buffer offset (c_type == void*)
        )

    glActiveTexture(GL_TEXTURE0);

    currentTexture = []
    for i in range(1, jumlah_tempat+1):
        currentTexture.append(TextureLoader.load_texture("img/building"+str(i)+".jpg"))

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

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        Display()

        ##################################################################### SET TEXTURE 1

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        # draws Aula barat, timur ; CC barat, timur

        # glBindTexture(GL_TEXTURE_2D, tex1);
        # glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)

        # # Draw the shapes
        # glDrawArrays(GL_TRIANGLES, 0, 12*3*4) #3 indices starting at 0 -> 1 triangle


        # ####################################################################### SET TEXTURE 2
        # #draws 4 labtek kembar + perpus, pau

        # glBindTexture(GL_TEXTURE_2D, tex2);
        # glUniformMatrix4fv(matrix_id, 1, GL_FALSE, mvp.data)

        # # Draw the shapes
        # glDrawArrays(GL_TRIANGLES, 12*3*4, 12*3*6) #3 indices starting at 0 -> 1 triangle
        # print (jumlah_tempat)

        for i in range(0, jumlah_tempat):
            # Send our transformation to the currently bound shader,
            # in the "MVP" uniform
            # draws Aula barat, timur ; CC barat, timur

            glBindTexture(GL_TEXTURE_2D, currentTexture[i]);
            glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)

            # # Draw the shapes
            glDrawArrays(GL_TRIANGLES, 12*3*i, 12*3) #3 indices starting at 0 -> 1 triangle

        ################################################### FINALIZE

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

        # Poll for and process events
        glfw.poll_events()

    # Not strictly necessary because we only have
    glDisableVertexAttribArray(0)
    glDisableVertexAttribArray(1)
    # !Note braces around vertex_buffer and uv_buffer.
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glfw.set_cursor_pos(window, 1024 / 2, 768 / 2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0, 0.0, 0.4, 0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders(
        ".\\shaders\\Tutorial8\\StandardShading.vertexshader",
        ".\\shaders\\Tutorial8\\StandardShading.fragmentshader")

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")
    view_matrix_id = glGetUniformLocation(program_id, "V")
    model_matrix_id = glGetUniformLocation(program_id, "M")

    # Load the texture
    texture = load_image(".\\content\\oppo.bmp")  #load image

    # Get a handle for our "myTextureSampler" uniform
    texture_id = glGetUniformLocation(program_id, "myTextureSampler")

    # Read our OBJ file
    # vertices,faces,uvs,normals,colors = objloader.load(".\\content\\suzanne.obj")
    # vertex_data,uv_data,normal_data = objloader.process_obj( vertices,faces,uvs,normals,colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    # vertex_data = objloader.generate_2d_ctypes(vertex_data)
    # uv_data = objloader.generate_2d_ctypes(uv_data)

    koordinat = 0.01
    koordinat2 = 0.5
    koordinat3 = 1.7
    koordinat4 = 1.0
    koordinat5 = 1.7
    koordinat6 = 0.1

    vertex_data = [
        -koordinat2, -koordinat3, -koordinat, -koordinat2, -koordinat3,
        koordinat6, -koordinat2, koordinat5, koordinat6, koordinat4,
        koordinat5, -koordinat, -koordinat2, -koordinat3, -koordinat,
        -koordinat2, koordinat5, -koordinat, koordinat4, -koordinat3,
        koordinat6, -koordinat2, -koordinat3, -koordinat, koordinat4,
        -koordinat3, -koordinat, koordinat4, koordinat5, -koordinat,
        koordinat4, -koordinat3, -koordinat, -koordinat2, -koordinat3,
        -koordinat, -koordinat2, -koordinat3, -koordinat, -koordinat2,
        koordinat5, koordinat6, -koordinat2, koordinat5, -koordinat,
        koordinat4, -koordinat3, koordinat6, -koordinat2, -koordinat3,
        koordinat6, -koordinat2, -koordinat3, -koordinat, -koordinat2,
        koordinat5, koordinat6, -koordinat2, -koordinat3, koordinat6,
        koordinat4, -koordinat3, koordinat6, koordinat4, koordinat5,
        koordinat6, koordinat4, -koordinat3, -koordinat, koordinat4,
        koordinat5, -koordinat, koordinat4, -koordinat3, -koordinat,
        koordinat4, koordinat5, koordinat6, koordinat4, -koordinat3,
        koordinat6, koordinat4, koordinat5, koordinat6, koordinat4, koordinat5,
        -koordinat, -koordinat2, koordinat5, -koordinat, koordinat4,
        koordinat5, koordinat6, -koordinat2, koordinat5, -koordinat,
        -koordinat2, koordinat5, koordinat6, koordinat4, koordinat5,
        koordinat6, -koordinat2, koordinat5, koordinat6, koordinat4,
        -koordinat3, koordinat6
    ]

    # Two UV coordinatesfor each vertex. They were created withe Blender.
    uv_data = [
        0.000059, 1.0 - 0.000004, 0.000103, 1.0 - 0.336048, 0.335973,
        1.0 - 0.335903, 1.000023, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851,
        0.999958, 1.0 - 0.336064, 0.667979, 1.0 - 0.335851, 0.336024,
        1.0 - 0.671877, 0.667969, 1.0 - 0.671889, 1.000023, 1.0 - 0.000013,
        0.668104, 1.0 - 0.000013, 0.667979, 1.0 - 0.335851, 0.000059,
        1.0 - 0.000004, 0.335973, 1.0 - 0.335903, 0.336098, 1.0 - 0.000071,
        0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903, 0.336024,
        1.0 - 0.671877, 1.000004, 1.0 - 0.671847, 0.999958, 1.0 - 0.336064,
        0.667979, 1.0 - 0.335851, 0.668104, 1.0 - 0.000013, 0.335973,
        1.0 - 0.335903, 0.667979, 1.0 - 0.335851, 0.335973, 1.0 - 0.335903,
        0.668104, 1.0 - 0.000013, 0.336098, 1.0 - 0.000071, 0.000103,
        1.0 - 0.336048, 0.000004, 1.0 - 0.671870, 0.336024, 1.0 - 0.671877,
        0.000103, 1.0 - 0.336048, 0.336024, 1.0 - 0.671877, 0.335973,
        1.0 - 0.335903, 0.667969, 1.0 - 0.671889, 1.000004, 1.0 - 0.671847,
        0.667979, 1.0 - 0.335851
    ]

    normal_data = [
        -0.5, 0, 0, -0.5, 0, 0, -0.5, 0, 0, 0, 0, -0.5, 0, 0, -0.5, 0, 0, -0.5,
        0, -0.5, 0, 0, -0.5, 0, 0, -0.5, 0, 0, 0, -0.5, 0, 0, -0.5, 0, 0, -0.5,
        -0.5, 0, 0, -0.5, 0, 0, -0.5, 0, 0, 0, -0.5, 0, 0, -0.5, 0, 0, -0.5, 0,
        0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
        1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1,
        0, 0, 1, 0, 0, 1
    ]

    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1)
    array_type = GLfloat * len(vertex_data)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(vertex_data) * 4, array_type(*vertex_data),
                 GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(uv_data) * 4, array_type(*uv_data), GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    array_type = GLfloat * len(normal_data)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(normal_data) * 4, array_type(*normal_data),
                 GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

    # Get a handle for our "LightPosition" uniform
    glUseProgram(program_id)
    light_id = glGetUniformLocation(program_id, "LightPosition_worldspace")

    last_time = glfw.get_time()
    frames = 0

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

        current_time = glfw.get_time()
        if current_time - last_time >= 1.0:
            glfw.set_window_title(window, "Tutorial 8.  FPS: %d" % (frames))
            frames = 0
            last_time = current_time

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix()
        ViewMatrix = controls.getViewMatrix()
        ModelMatrix = mat4.identity()
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE, mvp.data)
        glUniformMatrix4fv(model_matrix_id, 1, GL_FALSE, ModelMatrix.data)
        glUniformMatrix4fv(view_matrix_id, 1, GL_FALSE, ViewMatrix.data)

        lightPos = vec3(4, 4, 4)
        glUniform3f(light_id, lightPos.x, lightPos.y, lightPos.z)

        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture)
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0)

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(
            0,  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(
            1,  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # 3rd attribute buffer : normals
        glEnableVertexAttribArray(2)
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
        glVertexAttribPointer(
            2,  # attribute
            3,  # size
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
        glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))

        # Not strictly necessary because we only have
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
        glDisableVertexAttribArray(2)

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

        # Poll for and process events
        glfw.poll_events()

        frames += 1

    # !Note braces around vertex_buffer and uv_buffer.
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteBuffers(1, [normal_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE) 
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.4,0.0)
    
    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders( ".\\shaders\\Tutorial7\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial7\\TextureFragmentShader.fragmentshader" )
    
    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")

    # Load the texture
    texture = load_image(".\\content\\uvmap.bmp")

    # Get a handle for our "myTextureSampler" uniform
    texture_id  = glGetUniformLocation(program_id, "myTextureSampler")

    # Read our OBJ file
    vertices,faces,uvs,normals,colors = objloader.load(".\\content\\cube.obj")
    vertex_data,uv_data,normal_data = objloader.process_obj( vertices,faces,uvs,normals,colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    vertex_data = objloader.generate_2d_ctypes(vertex_data)
    uv_data = objloader.generate_2d_ctypes(uv_data)

    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4 * 3, vertex_data, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(uv_data) * 4 * 2, uv_data, GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()
    
    while glfw.get_key(window,glfw.KEY_ESCAPE) != glfw.PRESS and not glfw.window_should_close(window):
        glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT)

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix()
        ViewMatrix = controls.getViewMatrix()
        ModelMatrix = mat4.identity()
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix

        # Send our transformation to the currently bound shader, 
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
        
        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture)
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0)

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(
            0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(
            1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
        glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))

        # Not strictly necessary because we only have 
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
    
    
        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

    # !Note braces around vertex_buffer and uv_buffer.  
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE) 
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.4,0.0)
    
    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders( ".\\shaders\\Tutorial9\\StandardShading.vertexshader",
        ".\\shaders\\Tutorial9\\StandardShading.fragmentshader" )
    
    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")
    view_matrix_id = glGetUniformLocation(program_id, "V")
    model_matrix_id = glGetUniformLocation(program_id, "M")

    # Load the texture
    texture = textureutils.load_image(".\\content\\uvmap_suzanne.bmp")

    # Get a handle for our "myTextureSampler" uniform
    texture_id  = glGetUniformLocation(program_id, "myTextureSampler")

    # Read our OBJ file
    vertices,faces,uvs,normals,colors = objloader.load(".\\content\\suzanne.obj")
    vertex_data,uv_data,normal_data = objloader.process_obj( vertices,faces,uvs,normals,colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    vertex_data = objloader.generate_2d_ctypes(vertex_data)
    uv_data = objloader.generate_2d_ctypes(uv_data)
    normal_data = objloader.generate_2d_ctypes(normal_data)

    indexed_vertices, indexed_uvs, indexed_normals, indices = vboindexer.indexVBO(vertex_data,uv_data,normal_data)
    
    indexed_vertices = c_type_fill(indexed_vertices,GLfloat)
    indexed_uvs = c_type_fill(indexed_uvs,GLfloat)
    indexed_normals = c_type_fill(indexed_normals,GLfloat)
    indices = c_type_fill_1D(indices,GLushort)


    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_vertices) * 4 * 3, indexed_vertices, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_uvs) * 4 * 2, indexed_uvs, GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_normals) * 4 * 3, indexed_normals, GL_STATIC_DRAW)

    # Generate a buffer for the indices as well
    elementbuffer = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indices) * 2, indices , GL_STATIC_DRAW);

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()
    
    # Get a handle for our "LightPosition" uniform
    glUseProgram(program_id);
    light_id = glGetUniformLocation(program_id, "LightPosition_worldspace");

    last_time = glfw.get_time()
    frames = 0

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

        current_time = glfw.get_time()
        if current_time - last_time >= 1.0:
            glfw.set_window_title(window,"Tutorial 9.  FPS: %d"%(frames))
            frames = 0
            last_time = current_time

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        # Send our transformation to the currently bound shader, 
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
        glUniformMatrix4fv(model_matrix_id, 1, GL_FALSE, ModelMatrix.data);
        glUniformMatrix4fv(view_matrix_id, 1, GL_FALSE, ViewMatrix.data);

        lightPos = vec3(4,4,4)
        glUniform3f(light_id, lightPos.x, lightPos.y, lightPos.z)

        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0);

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
        glVertexAttribPointer(
            0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
        glVertexAttribPointer(
            1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 3rd attribute buffer : normals
        glEnableVertexAttribArray(2);
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
        glVertexAttribPointer(
            2,                                  # attribute
            3,                                  # size
            GL_FLOAT,                           # type
            GL_FALSE,                           # ormalized?
            0,                                  # stride
            null                                # array buffer offset (c_type == void*)
        )


        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
       # glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))
        # Index buffer
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer)

        # Draw the triangles !
        glDrawElements(
            GL_TRIANGLES,           # mode
            len(indices),           # count
            GL_UNSIGNED_SHORT,      # type
            null                    # element array buffer offset
        )
        # Not strictly necessary because we only have 
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
        glDisableVertexAttribArray(2)
    
    
        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

        frames += 1

    # !Note braces around vertex_buffer and uv_buffer.  
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteBuffers(1, [normal_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
Example #8
0
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE) 
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.4,0.0)
    
    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders( ".\\shaders\\Tutorial9\\StandardShading.vertexshader",
        ".\\shaders\\Tutorial9\\StandardShading.fragmentshader" )
    
    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")
    view_matrix_id = glGetUniformLocation(program_id, "V")
    model_matrix_id = glGetUniformLocation(program_id, "M")

    # Load the texture
    texture = textureutils.load_image(".\\content\\uvmap_suzanne.bmp")

    # Get a handle for our "myTextureSampler" uniform
    texture_id  = glGetUniformLocation(program_id, "myTextureSampler")

    # Read our OBJ file
    vertices,faces,uvs,normals,colors = objloader.load(".\\content\\suzanne.obj")
    vertex_data,uv_data,normal_data = objloader.process_obj( vertices,faces,uvs,normals,colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    vertex_data = objloader.generate_2d_ctypes(vertex_data)
    uv_data = objloader.generate_2d_ctypes(uv_data)
    normal_data = objloader.generate_2d_ctypes(normal_data)

    indexed_vertices, indexed_uvs, indexed_normals, indices = vboindexer.indexVBO(vertex_data,uv_data,normal_data)
    
    indexed_vertices = c_type_fill(indexed_vertices,GLfloat)
    indexed_uvs = c_type_fill(indexed_uvs,GLfloat)
    indexed_normals = c_type_fill(indexed_normals,GLfloat)
    indices = c_type_fill_1D(indices,GLushort)


    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_vertices) * 4 * 3, indexed_vertices, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_uvs) * 4 * 2, indexed_uvs, GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(indexed_normals) * 4 * 3, indexed_normals, GL_STATIC_DRAW)

    # Generate a buffer for the indices as well
    elementbuffer = glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indices) * 2, indices , GL_STATIC_DRAW);

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()
    
    # Get a handle for our "LightPosition" uniform
    glUseProgram(program_id);
    light_id = glGetUniformLocation(program_id, "LightPosition_worldspace");

    last_time = glfw.get_time()
    frames = 0

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

        current_time = glfw.get_time()
        if current_time - last_time >= 1.0:
            glfw.set_window_title(window,"Tutorial 9.  FPS: %d"%(frames))
            frames = 0
            last_time = current_time

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        # Send our transformation to the currently bound shader, 
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
        glUniformMatrix4fv(model_matrix_id, 1, GL_FALSE, ModelMatrix.data);
        glUniformMatrix4fv(view_matrix_id, 1, GL_FALSE, ViewMatrix.data);

        lightPos = vec3(4,4,4)
        glUniform3f(light_id, lightPos.x, lightPos.y, lightPos.z)

        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0);

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
        glVertexAttribPointer(
            0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
        glVertexAttribPointer(
            1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 3rd attribute buffer : normals
        glEnableVertexAttribArray(2);
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
        glVertexAttribPointer(
            2,                                  # attribute
            3,                                  # size
            GL_FLOAT,                           # type
            GL_FALSE,                           # ormalized?
            0,                                  # stride
            null                                # array buffer offset (c_type == void*)
        )


        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
       # glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))
        # Index buffer
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer)

        # Draw the triangles !
        glDrawElements(
            GL_TRIANGLES,           # mode
            len(indices),           # count
            GL_UNSIGNED_SHORT,      # type
            null                    # element array buffer offset
        )
        # Not strictly necessary because we only have 
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)
        glDisableVertexAttribArray(2)
    
    
        # Swap front and back buffers
        glfw.swap_buffers(window)

        # Poll for and process events
        glfw.poll_events()

        frames += 1

    # !Note braces around vertex_buffer and uv_buffer.  
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteBuffers(1, [normal_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE)
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.0,0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders( ".\\shaders\\common\\StandardShading.vertexshader",
        ".\\shaders\\common\\StandardShading.fragmentshader" )

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")
    view_matrix_id = glGetUniformLocation(program_id, "V")
    model_matrix_id = glGetUniformLocation(program_id, "M")

    # Read our OBJ file
    vertices,faces,uvs,normals,colors = objloader.load(".\\content\\male_apose_closed2.obj")
    vertex_data,uv_data,normal_data = objloader.process_obj( vertices,faces,uvs,normals,colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    vertex_data = objloader.generate_2d_ctypes(vertex_data)
    normal_data = objloader.generate_2d_ctypes(normal_data)

    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4 * 3, vertex_data, GL_STATIC_DRAW)

    normal_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, normal_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(normal_data) * 4 * 3, normal_data, GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

    # Get a handle for our "LightPosition" uniform
    glUseProgram(program_id);
    light_id = glGetUniformLocation(program_id, "LightPosition_worldspace");

    last_time = glfw.get_time()
    frames = 0

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

        current_time = glfw.get_time()
        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
        glUniformMatrix4fv(model_matrix_id, 1, GL_FALSE, ModelMatrix.data);
        glUniformMatrix4fv(view_matrix_id, 1, GL_FALSE, ViewMatrix.data);

        lightPos = vec3(0,4,4)
        glUniform3f(light_id, lightPos.x, lightPos.y, lightPos.z)

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
        glVertexAttribPointer(
            0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,                  # len(vertex_data)
            GL_FLOAT,           # type
            GL_FALSE,           # ormalized?
            0,                  # stride
            null                # array buffer offset (c_type == void*)
            )

        # 2nd attribute buffer : normals
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ARRAY_BUFFER, normal_buffer);
        glVertexAttribPointer(
            1,                                  # attribute
            3,                                  # size
            GL_FLOAT,                           # type
            GL_FALSE,                           # ormalized?
            0,                                  # stride
            null                                # array buffer offset (c_type == void*)
        )


        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
        glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))

        # Not strictly necessary because we only have
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)


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


        # Take screenshot of active buffer
        if glfw.get_key( window, glfw.KEY_P ) == glfw.PRESS:
            print("Saving screenshot as 'test.bmp'")
            screenshot('test.bmp',1024,768)

        # Dump MVP matrix to the command line
        if glfw.get_key( window, glfw.KEY_M ) == glfw.PRESS:
            print(mvp)
            
        # Poll for and process events
        glfw.poll_events()

        frames += 1

    # !Note braces around vertex_buffer and uv_buffer.
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [normal_buffer])
    glDeleteProgram(program_id)
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()
Example #10
0
def main():
    if not opengl_init():
        return

    load_gedung("itb_coordinate.txt")

    # Enable key events
    glfw.set_input_mode(window,glfw.STICKY_KEYS,GL_TRUE)
    glfw.set_cursor_pos(window, 1024/2, 768/2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0,0.0,0.0,0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)
    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS);
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray( vertex_array_id )

    program_id = common.LoadShaders( ".\\shaders\\Tutorial6\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial6\\TextureFragmentShader.fragmentshader" )

    vertex_data = createAllBuilding()

    # Two UV coordinatesfor each vertex. They were created withe Blender.
    uv_data = createUVData()

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP");

    texture = []
    texture_id = []

    texture_id.append(glGetUniformLocation(program_id, "myTextureSampler"))
    texture_id.append(glGetUniformLocation(program_id, "myTextureSampler2"))

    tex1 = TextureLoader.load_texture("res/crate.jpg")
    tex2 = TextureLoader.load_texture("res/metal.jpg")
    # Our vertices. Tree consecutive floats give a 3D vertex; Three consecutive vertices give a triangle.
    # A cube has 6 faces with 2 triangles each, so this makes 6*2=12 triangles, and 12*3 vertices



    vertex_buffer = glGenBuffers(1);
    array_type = GLfloat * len(vertex_data)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(vertex_data) * 4, array_type(*vertex_data), GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1);
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER, len(uv_data) * 4, array_type(*uv_data), GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

    glUseProgram(program_id)

    #1rst attribute buffer : vertices
    glEnableVertexAttribArray(0)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glVertexAttribPointer(
        0,                  # attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  # len(vertex_data)
        GL_FLOAT,           # type
        GL_FALSE,           # ormalized?
        0,                  # stride
        null                # array buffer offset (c_type == void*)
        )

    # 2nd attribute buffer : colors
    glEnableVertexAttribArray(1)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer);
    glVertexAttribPointer(
        1,                  # attribute 1. No particular reason for 1, but must match the layout in the shader.
        2,                  # len(vertex_data)
        GL_FLOAT,           # type
        GL_FALSE,           # ormalized?
        0,                  # stride
        null                # array buffer offset (c_type == void*)
        )

    glActiveTexture(GL_TEXTURE0);

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

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix();
        ViewMatrix = controls.getViewMatrix();
        ModelMatrix = mat4.identity();
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix;

        ##################################################################### SET TEXTURE 1

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        # draws Aula barat, timur ; CC barat, timur

        glBindTexture(GL_TEXTURE_2D, tex1);
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE,mvp.data)
Example #11
0
def main():

    # Initialize GLFW and open a window
    if not opengl_init():
        return

    # Enable key events
    glfw.set_input_mode(window, glfw.STICKY_KEYS, GL_TRUE)
    glfw.set_cursor_pos(window, 1024 / 2, 768 / 2)

    # Set opengl clear color to something other than red (color used by the fragment shader)
    glClearColor(0.0, 0.0, 0.4, 0.0)

    # Enable depth test
    glEnable(GL_DEPTH_TEST)

    # Accept fragment if it closer to the camera than the former one
    glDepthFunc(GL_LESS)

    # Cull triangles which normal is not towards the camera
    glEnable(GL_CULL_FACE)

    vertex_array_id = glGenVertexArrays(1)
    glBindVertexArray(vertex_array_id)

    # Create and compile our GLSL program from the shaders
    program_id = common.LoadShaders(
        ".\\shaders\\Tutorial7\\TransformVertexShader.vertexshader",
        ".\\shaders\\Tutorial7\\TextureFragmentShader.fragmentshader")

    # Get a handle for our "MVP" uniform
    matrix_id = glGetUniformLocation(program_id, "MVP")

    # Load the texture
    texture = load_image(".\\content\\uvmap.bmp")

    # Get a handle for our "myTextureSampler" uniform
    texture_id = glGetUniformLocation(program_id, "myTextureSampler")

    # Read our OBJ file
    vertices, faces, uvs, normals, colors = objloader.load(
        ".\\content\\cube.obj")
    vertex_data, uv_data, normal_data = objloader.process_obj(
        vertices, faces, uvs, normals, colors)

    # Our OBJ loader uses Python lists, convert to ctype arrays before sending to OpenGL
    vertex_data = objloader.generate_2d_ctypes(vertex_data)
    uv_data = objloader.generate_2d_ctypes(uv_data)

    # Load OBJ in to a VBO
    vertex_buffer = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(vertex_data) * 4 * 3, vertex_data, GL_STATIC_DRAW)

    uv_buffer = glGenBuffers(1)
    array_type = GLfloat * len(uv_data)
    glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
    glBufferData(GL_ARRAY_BUFFER,
                 len(uv_data) * 4 * 2, uv_data, GL_STATIC_DRAW)

    # vsync and glfw do not play nice.  when vsync is enabled mouse movement is jittery.
    common.disable_vsyc()

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

        glUseProgram(program_id)

        controls.computeMatricesFromInputs(window)
        ProjectionMatrix = controls.getProjectionMatrix()
        ViewMatrix = controls.getViewMatrix()
        ModelMatrix = mat4.identity()
        mvp = ProjectionMatrix * ViewMatrix * ModelMatrix

        # Send our transformation to the currently bound shader,
        # in the "MVP" uniform
        glUniformMatrix4fv(matrix_id, 1, GL_FALSE, mvp.data)

        # Bind our texture in Texture Unit 0
        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, texture)
        # Set our "myTextureSampler" sampler to user Texture Unit 0
        glUniform1i(texture_id, 0)

        #1rst attribute buffer : vertices
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer)
        glVertexAttribPointer(
            0,  # attribute 0. No particular reason for 0, but must match the layout in the shader.
            3,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # 2nd attribute buffer : colors
        glEnableVertexAttribArray(1)
        glBindBuffer(GL_ARRAY_BUFFER, uv_buffer)
        glVertexAttribPointer(
            1,  # attribute 1. No particular reason for 1, but must match the layout in the shader.
            2,  # len(vertex_data)
            GL_FLOAT,  # type
            GL_FALSE,  # ormalized?
            0,  # stride
            null  # array buffer offset (c_type == void*)
        )

        # Draw the triangles, vertex data now contains individual vertices
        # so use array length
        glDrawArrays(GL_TRIANGLES, 0, len(vertex_data))

        # Not strictly necessary because we only have
        glDisableVertexAttribArray(0)
        glDisableVertexAttribArray(1)

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

        # Poll for and process events
        glfw.poll_events()

    # !Note braces around vertex_buffer and uv_buffer.
    # glDeleteBuffers expects a list of buffers to delete
    glDeleteBuffers(1, [vertex_buffer])
    glDeleteBuffers(1, [uv_buffer])
    glDeleteProgram(program_id)
    glDeleteTextures([texture_id])
    glDeleteVertexArrays(1, [vertex_array_id])

    glfw.terminate()