Commits

Sean McKiernan committed 1b372ed

Chapters 1-6 (first commit)

  • Participants

Comments (0)

Files changed (50)

File 01_hello_triangle/01_hello_triangle.py

+"""This version of "01_hello_triangle" makes use of compileProgram and
+compileShader from OpenGL.GL.shaders. This takes care of shader compilation,
+attachment and linking for us and is quite convenient. For a greater
+understanding of what is going on behind the scenes, see
+"01_hello_triangle_manually"."""
+from OpenGL import GL
+from OpenGL.GL.shaders import compileProgram,compileShader
+import pygame as pg,sys,os
+
+VERTICES = [ 0.75,  0.75,  0.0,  1.0,
+             0.75, -0.75,  0.0,  1.0,
+            -0.75, -0.75,  0.0,  1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+#Shaders:
+VERT = """
+       #version 330
+       layout(location = 0) in vec4 position;
+       void main()
+       {
+          gl_Position = position;
+       }"""
+
+FRAG = """
+       #version 330
+       out vec4 outputColor;
+       void main()
+       {
+          outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
+       }"""
+
+class GLtests:
+    def __init__(self):
+        self.shader = compileProgram(compileShader(VERT,GL.GL_VERTEX_SHADER),
+                                     compileShader(FRAG,GL.GL_FRAGMENT_SHADER))
+        self.vbo = None
+        self.init_all()
+        self.reshape(500,500)
+    def init_all(self):
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        array_type = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        array_type(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def display(self):
+        GL.glClearColor(1, 1, 1, 1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES, 0, len(VERTICES)//VERT_COMPONENTS)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0, 0, width, height)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF)
+    MyClock = pg.time.Clock()
+    MyGL = GLtests()
+    while 1:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                pg.quit();sys.exit()
+            elif event.type == pg.KEYDOWN:
+                pass
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()

File 01_hello_triangle/01_hello_triangle_manually.py

+import sys,os
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.75,  0.75,  0.0,  1.0,
+             0.75, -0.75,  0.0,  1.0,
+            -0.75, -0.75,  0.0,  1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+#Shaders:
+VERT = """
+       #version 330
+       layout(location = 0) in vec4 position;
+       void main()
+       {
+          gl_Position = position;
+       }"""
+
+FRAG = """
+       #version 330
+       out vec4 outputColor;
+       void main()
+       {
+          outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
+       }"""
+
+class GLtests:
+    def __init__(self):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all()
+        self.reshape(500,500)
+    def init_all(self):
+        self.attach_shaders()
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        array_type = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        array_type(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self):
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,VERT))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,FRAG))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def display(self):
+        GL.glClearColor(1,1,1,1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES, 0, len(VERTICES)//VERT_COMPONENTS)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF)
+    MyClock = pg.time.Clock()
+    MyGL = GLtests()
+    while 1:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                pg.quit();sys.exit()
+            elif event.type == pg.KEYDOWN:
+                pass
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()

File 02_playing_with_colors/02_FragPosition.py

+import sys,os
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.75, 0.75, 0.0, 1.0,
+             0.75,-0.75, 0.0, 1.0,
+            -0.75,-0.75, 0.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+#Load shaders from files.
+with open(os.path.join("data","FragPosition.vert"),'r') as myfile:
+    VERT = myfile.read()
+with open(os.path.join("data","FragPosition.frag"),'r') as myfile:
+    FRAG = myfile.read()
+
+class GLtests:
+    def __init__(self):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all()
+        self.reshape(500,500)
+    def init_all(self):
+        self.attach_shaders()
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        array_type = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        array_type(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self):
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,VERT))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,FRAG))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def display(self):
+        GL.glClearColor(1,1,1,1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES, 0, len(VERTICES)//VERT_COMPONENTS)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF)
+    MyClock = pg.time.Clock()
+    MyGL = GLtests()
+    while 1:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                pg.quit();sys.exit()
+            elif event.type == pg.KEYDOWN:
+                pass
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()

File 02_playing_with_colors/02_VertexColors.py

+import sys,os
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.0, 0.5, 0.0, 1.0,
+             0.5,-0.366, 0.0, 1.0,
+            -0.5,-0.366, 0.0, 1.0,
+             1.0, 0.0, 0.0, 1.0,
+             0.0, 1.0, 0.0, 1.0,
+             0.0, 0.0, 1.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+#Load shaders from files.
+with open(os.path.join("data","VertexColors.vert"),'r') as myfile:
+    VERT = myfile.read()
+with open(os.path.join("data","VertexColors.frag"),'r') as myfile:
+    FRAG = myfile.read()
+
+class GLtests:
+    def __init__(self):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all()
+        self.reshape(500,500)
+    def init_all(self):
+        self.attach_shaders()
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        array_type = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        array_type(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self):
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,VERT))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,FRAG))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glVertexAttribPointer(1,VERT_COMPONENTS,GL.GL_FLOAT,False,0,GL.GLvoidp(48))
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,3)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF)
+    MyClock = pg.time.Clock()
+    MyGL = GLtests()
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 02_playing_with_colors/data/FragPosition.frag

+#version 330
+
+out vec4 outputColor;
+
+void main()
+{
+	float lerpValue = gl_FragCoord.y / 500.0f;
+
+	outputColor = mix(vec4(1.0f, 0.0f, 0.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), lerpValue);
+}

File 02_playing_with_colors/data/FragPosition.vert

+#version 330
+
+layout (location = 0) in vec4 position;
+
+void main()
+{
+	gl_Position = position;
+}

File 02_playing_with_colors/data/VertexColors.frag

+#version 330
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

File 02_playing_with_colors/data/VertexColors.vert

+#version 330
+
+layout (location = 0) in vec4 position;
+layout (location = 1) in vec4 color;
+
+smooth out vec4 theColor;
+
+void main()
+{
+	gl_Position = position;
+	theColor = color;
+}

File 03_OpenGLs_moving_triangle/03_cpuPositionOffset.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.25, 0.25, 0.0, 1.0,
+             0.25,-0.25, 0.0, 1.0,
+            -0.25,-0.25, 0.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+class Shader:
+    def __init__(self,vert_file,frag_file):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.offset = [0,0]
+        self.init_all(vert_file,frag_file)
+        self.reshape(500,500)
+    def init_all(self,vert_file,frag_file):
+        self.attach_shaders(vert_file,frag_file)
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        ArrayType(*VERTICES),GL.GL_STREAM_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self,vert_file,frag_file):
+        vert,frag = self.load_shader_files(vert_file,frag_file)
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,vert))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,frag))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def load_shader_files(self,vert_file,frag_file):
+        with open(vert_file,'r') as myfile:
+            vert = myfile.read()
+        with open(frag_file,'r') as myfile:
+            frag = myfile.read()
+        return vert,frag
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def display(self):
+        self.calc_position()
+        self.adjust_vert_data()
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,3)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+    def calc_position(self):
+        period = 5.0
+        angular_s = (2*math.pi)/period
+        magnitude = 0.5
+        elapsed_time = pg.time.get_ticks()/1000.0
+        times_through_loop = elapsed_time%period
+        x_offset = math.cos(times_through_loop*angular_s)*magnitude
+        y_offset = math.sin(times_through_loop*angular_s)*magnitude
+        self.offset = [x_offset,y_offset]
+    def adjust_vert_data(self):
+        moveit = VERTICES[:]
+        for i in range(0,len(VERTICES),4):
+            moveit[i] += self.offset[0]
+            moveit[i+1] += self.offset[1]
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        ArrayType = (GL.GLfloat*len(VERTICES))
+        Array = ArrayType(*moveit)
+        GL.glBufferSubData(GL.GL_ARRAY_BUFFER,0,len(VERTICES)*SIZE_FLOAT,Array)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(os.path.join("data","standard.vert"),os.path.join("data","standard.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 03_OpenGLs_moving_triangle/03_fragChangeColor.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.25, 0.25, 0.0, 1.0,
+             0.25,-0.25, 0.0, 1.0,
+            -0.25,-0.25, 0.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+class Shader:
+    def __init__(self,vert_file,frag_file):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all(vert_file,frag_file)
+        self.reshape(500,500)
+        self.setup_uniforms()
+    def init_all(self,vert_file,frag_file):
+        self.attach_shaders(vert_file,frag_file)
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        ArrayType(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self,vert_file,frag_file):
+        vert,frag = self.load_shader_files(vert_file,frag_file)
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,vert))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,frag))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def load_shader_files(self,vert_file,frag_file):
+        with open(vert_file,'r') as myfile:
+            vert = myfile.read()
+        with open(frag_file,'r') as myfile:
+            frag = myfile.read()
+        return vert,frag
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderError,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderError,"Linking failue:\n{}\n".format(log)
+
+    def setup_uniforms(self):
+        self.elapsed_time_uniform = GL.glGetUniformLocation(self.shader,"time")
+        self.period = GL.glGetUniformLocation(self.shader,"period")
+        self.frag_period = GL.glGetUniformLocation(self.shader,"frag_period");
+        GL.glUseProgram(self.shader)
+        GL.glUniform1f(self.period,5.0)
+        GL.glUniform1f(self.frag_period,10.0)
+        GL.glUseProgram(0)
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+        GL.glUseProgram(self.shader)
+
+        GL.glUniform1f(self.elapsed_time_uniform,pg.time.get_ticks()/1000.0)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,3)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+class ShaderError(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(os.path.join("data","calcOffset.vert"),os.path.join("data","calcColor.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 03_OpenGLs_moving_triangle/03_vertCalcOffset.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.25, 0.25, 0.0, 1.0,
+             0.25,-0.25, 0.0, 1.0,
+            -0.25,-0.25, 0.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+class Shader:
+    def __init__(self,vert_file,frag_file):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all(vert_file,frag_file)
+        self.reshape(500,500)
+        self.setup_uniforms()
+    def init_all(self,vert_file,frag_file):
+        self.attach_shaders(vert_file,frag_file)
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        ArrayType(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self,vert_file,frag_file):
+        vert,frag = self.load_shader_files(vert_file,frag_file)
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,vert))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,frag))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def load_shader_files(self,vert_file,frag_file):
+        with open(vert_file,'r') as myfile:
+            vert = myfile.read()
+        with open(frag_file,'r') as myfile:
+            frag = myfile.read()
+        return vert,frag
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def setup_uniforms(self):
+        self.elapsed_time_uniform = GL.glGetUniformLocation(self.shader,"time")
+        self.period = GL.glGetUniformLocation(self.shader,"period")
+        GL.glUseProgram(self.shader)
+        GL.glUniform1f(self.period,5.0)
+        GL.glUseProgram(0)
+
+    def display(self):
+        GL.glClearColor(1,1,1,1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+        GL.glUseProgram(self.shader)
+
+        GL.glUniform1f(self.elapsed_time_uniform,pg.time.get_ticks()/1000.0)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,3)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(os.path.join("data","calcOffset.vert"),os.path.join("data","standard.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 03_OpenGLs_moving_triangle/03_vertPositionOffset.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+VERTICES = [ 0.25, 0.25, 0.0, 1.0,
+             0.25,-0.25, 0.0, 1.0,
+            -0.25,-0.25, 0.0, 1.0]
+
+SIZE_FLOAT = VERT_COMPONENTS = 4
+
+SHADER2STRING = {GL.GL_VERTEX_SHADER   : "vertex",
+                 GL.GL_GEOMETRY_SHADER : "geometry",
+                 GL.GL_FRAGMENT_SHADER : "fragment"}
+
+class Shader:
+    def __init__(self,vert_file,frag_file):
+        self.shader = GL.glCreateProgram()
+        self.vbo = None
+        self.init_all(vert_file,frag_file)
+        self.reshape(500,500)
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+    def init_all(self,vert_file,frag_file):
+        self.attach_shaders(vert_file,frag_file)
+        self.init_vertex_buf()
+        vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(vao)
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = (GL.GLfloat*len(VERTICES))
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(VERTICES)*SIZE_FLOAT,
+                        ArrayType(*VERTICES),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+    def attach_shaders(self,vert_file,frag_file):
+        vert,frag = self.load_shader_files(vert_file,frag_file)
+        shade_list = []
+        shade_list.append(self.compile(GL.GL_VERTEX_SHADER,vert))
+        shade_list.append(self.compile(GL.GL_FRAGMENT_SHADER,frag))
+        for shade in shade_list:
+            GL.glAttachShader(self.shader,shade)
+        self.link()
+        for shade in shade_list:
+            GL.glDetachShader(self.shader,shade)
+            GL.glDeleteShader(shade)
+    def load_shader_files(self,vert_file,frag_file):
+        with open(vert_file,'r') as myfile:
+            vert = myfile.read()
+        with open(frag_file,'r') as myfile:
+            frag = myfile.read()
+        return vert,frag
+    def compile(self,shader_type,shader_str):
+        shader = GL.glCreateShader(shader_type)
+        GL.glShaderSource(shader,shader_str)
+        GL.glCompileShader(shader)
+        status = GL.glGetShaderiv(shader,GL.GL_COMPILE_STATUS)
+        if not status:
+            log = GL.glGetShaderInfoLog(shader)
+            shader_name = SHADER2STRING[shader_type]
+            raise ShaderException,"Compile failure in {} shader:\n{}\n".format(shader_name,log)
+        return shader
+
+    def link(self):
+        GL.glLinkProgram(self.shader)
+        status = GL.glGetProgramiv(self.shader,GL.GL_LINK_STATUS)
+        if not status:
+            log = GL.glGetProgramInfoLog(self.shader)
+            raise ShaderException,"Linking failue:\n{}\n".format(log)
+
+    def display(self):
+        offset = self.calc_position()
+        GL.glClearColor(0,1,1,1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+        GL.glUseProgram(self.shader)
+
+        GL.glUniform2f(self.offset_location,*offset)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glVertexAttribPointer(0,VERT_COMPONENTS,GL.GL_FLOAT,False,0,None)
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,3)
+        GL.glDisableVertexAttribArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        GL.glViewport(0,0,width,height)
+
+    def calc_position(self):
+        period = 5.0
+        angular_s = (2*math.pi)/period
+        magnitude = 0.5
+        elapsed_time = pg.time.get_ticks()/1000.0
+        times_through_loop = elapsed_time%period
+        x_offset = math.cos(times_through_loop*angular_s)*magnitude
+        y_offset = math.sin(times_through_loop*angular_s)*magnitude
+        return x_offset,y_offset
+
+class ShaderException(Exception):
+    pass
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(os.path.join("data","positionOffset.vert"),os.path.join("data","standard.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(65)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 03_OpenGLs_moving_triangle/data/calcColor.frag

+#version 330
+
+out vec4 outputColor;
+
+uniform float frag_period;
+uniform float time;
+
+const vec4 firstColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
+const vec4 secondColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
+
+void main()
+{
+	float currTime = mod(time, frag_period);
+	float currLerp = currTime / frag_period;
+
+	outputColor = mix(firstColor, secondColor, currLerp);
+}

File 03_OpenGLs_moving_triangle/data/calcOffset.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+uniform float period;
+uniform float time;
+
+void main()
+{
+	float timeScale = 3.14159f * 2.0f / period;
+
+	float currTime = mod(time, period);
+	vec4 totalOffset = vec4(
+		cos(currTime * timeScale) * 0.5f,
+		sin(currTime * timeScale) * 0.5f,
+		0.0f,
+		0.0f);
+
+	gl_Position = position + totalOffset;
+}

File 03_OpenGLs_moving_triangle/data/positionOffset.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+uniform vec2 offset;
+
+void main()
+{
+	vec4 total_offset = vec4(offset.x, offset.y, 0.0, 0.0);
+	gl_Position = position + total_offset;
+}

File 03_OpenGLs_moving_triangle/data/standard.frag

+#version 330
+
+out vec4 outputColor;
+
+void main()
+{
+    float lerp_value = gl_FragCoord.y / 500.0f;
+	outputColor = mix(vec4(1.0f, 0.0f, 1.0f, 1.0f), vec4(0.0f, 1.0f, 0.0f, 1.0f), lerp_value);
+}

File 03_OpenGLs_moving_triangle/data/standard.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+
+void main()
+{
+	gl_Position = position;
+}

File 04_objects_at_rest/04_AspectRatio.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertices_perspective import VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+        self.perspective_matrix_unif = GL.glGetUniformLocation(self.shader,"perspectiveMatrix")
+        self.frustum_scale = 1.0
+        self.z_near,self.z_far = 0.5,3.0
+        self.create_matrix()
+
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+
+    def create_matrix(self):
+        self.the_matrix = [0.0 for i in range(16)]
+        self.the_matrix[0] = self.frustum_scale
+        self.the_matrix[5] = self.frustum_scale
+        self.the_matrix[10] = (self.z_far+self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[14] = (2*self.z_far*self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[11] = -1.0
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform2f(self.offset_location,1.5,0.5)
+        color_data = GL.GLvoidp((len(self.vertices)*self.size_float)/2)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,color_data)
+
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,36)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        self.the_matrix[0] = self.frustum_scale/(width/float(height))
+        self.the_matrix[5] = self.frustum_scale
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+        GL.glViewport(0,0,width,height)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","MatrixPerspective.vert"),os.path.join("data","StandardColors.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 04_objects_at_rest/04_AspectRatio_interactive.py

+"""Added simple movement in the x-y plane with arrow keys.
+This is just independent experimentation and not part of the original tutorial."""
+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertices_perspective import VERTICES
+
+KEYDICT = {pg.K_UP    : ( 0,-1),
+           pg.K_DOWN  : ( 0, 1),
+           pg.K_RIGHT : (-1, 0),
+           pg.K_LEFT  : ( 1, 0)}
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+        self.offset = [-0.5,-0.5]
+        self.speed = 0.03
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+        self.perspective_matrix_unif = GL.glGetUniformLocation(self.shader,"perspectiveMatrix")
+        self.frustum_scale = 1.0
+        self.z_near,self.z_far = 0.5,3.0
+        self.create_matrix()
+
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+
+    def create_matrix(self):
+        self.the_matrix = [0.0 for i in range(16)]
+        self.the_matrix[0] = self.frustum_scale
+        self.the_matrix[5] = self.frustum_scale
+        self.the_matrix[10] = (self.z_far+self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[14] = (2*self.z_far*self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[11] = -1.0
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform2f(self.offset_location,*self.offset)
+        color_data = GL.GLvoidp((len(self.vertices)*self.size_float)/2)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,color_data)
+
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,36)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        self.the_matrix[0] = self.frustum_scale/(width/float(height))
+        self.the_matrix[5] = self.frustum_scale
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+        GL.glViewport(0,0,width,height)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","MatrixPerspective.vert"),os.path.join("data","StandardColors.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            keys = pg.key.get_pressed()
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+
+        for key in KEYDICT:
+            if keys[key]:
+                for i in (0,1):
+                    MyGL.offset[i] = MyGL.offset[i]+KEYDICT[key][i]*MyGL.speed
+
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 04_objects_at_rest/04_MatrixPerspective.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertices_perspective import VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+        self.perspective_matrix_unif = GL.glGetUniformLocation(self.shader,"perspectiveMatrix")
+        self.frustum_scale = 1.0
+        self.z_near,self.z_far = 0.5,3.0
+        self.create_matrix()
+
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+
+    def create_matrix(self):
+        self.the_matrix = [0.0 for i in range(16)]
+        self.the_matrix[0] = self.frustum_scale
+        self.the_matrix[5] = self.frustum_scale
+        self.the_matrix[10] = (self.z_far+self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[14] = (2*self.z_far*self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[11] = -1.0
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform2f(self.offset_location,0.5,0.5)
+        color_data = GL.GLvoidp((len(self.vertices)*self.size_float)/2)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,color_data)
+
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,36)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","MatrixPerspective.vert"),os.path.join("data","StandardColors.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 04_objects_at_rest/04_OrthoCube.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertices_ortho import VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+
+    def display(self):
+        GL.glClearColor(1,1,1,1)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform2f(self.offset_location,0.5,0.25)
+        color_data = GL.GLvoidp((len(self.vertices)*self.size_float)/2)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,color_data)
+
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,36)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","OrthoWithOffset.vert"),os.path.join("data","StandardColors.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 04_objects_at_rest/04_ShaderPerspective.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertices_perspective import VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+        self.frustum_scale_unif = GL.glGetUniformLocation(self.shader,"frustumScale")
+        self.z_near_unif = GL.glGetUniformLocation(self.shader,"zNear")
+        self.z_far_unif = GL.glGetUniformLocation(self.shader,"zFar")
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform1f(self.frustum_scale_unif,1.0)
+        GL.glUniform1f(self.z_near_unif,1.0)
+        GL.glUniform1f(self.z_far_unif,3.0)
+        GL.glUseProgram(0)
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glUniform2f(self.offset_location,0.5,0.5)
+        color_data = GL.GLvoidp((len(self.vertices)*self.size_float)/2)
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,self.vert_comp,GL.GL_FLOAT,GL.GL_FALSE,0,color_data)
+
+        GL.glDrawArrays(GL.GL_TRIANGLES,0,36)
+
+        GL.glDisableVertexAttribArray(0)
+        GL.glDisableVertexAttribArray(1)
+        GL.glUseProgram(0)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","ManualPerspective.vert"),os.path.join("data","StandardColors.frag"))
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 04_objects_at_rest/data/ManualPerspective.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+uniform float zNear;
+uniform float zFar;
+uniform float frustumScale;
+
+
+void main()
+{
+	vec4 cameraPos = position + vec4(offset.x, offset.y, 0.0, 0.0);
+	vec4 clipPos;
+	
+	clipPos.xy = cameraPos.xy * frustumScale;
+	
+	clipPos.z = cameraPos.z * (zNear + zFar) / (zNear - zFar);
+	clipPos.z += 2 * zNear * zFar / (zNear - zFar);
+	
+	clipPos.w = -cameraPos.z;
+	
+	gl_Position = clipPos;
+	theColor = color;
+}

File 04_objects_at_rest/data/MatrixPerspective.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+uniform mat4 perspectiveMatrix;
+
+void main()
+{
+	vec4 cameraPos = position + vec4(offset.x, offset.y, 0.0, 0.0);
+
+	gl_Position = perspectiveMatrix * cameraPos;
+	theColor = color;
+}

File 04_objects_at_rest/data/OrthoWithOffset.vert

+#version 330
+
+layout(location = 0) in vec4 position;
+layout(location = 1) in vec4 color;
+
+smooth out vec4 theColor;
+
+uniform vec2 offset;
+
+void main()
+{
+	gl_Position = position + vec4(offset.x, offset.y, 0.0, 0.0);
+	theColor = color;
+}

File 04_objects_at_rest/data/StandardColors.frag

+#version 330
+
+smooth in vec4 theColor;
+
+out vec4 outputColor;
+
+void main()
+{
+	outputColor = theColor;
+}

File 04_objects_at_rest/data/vertices_ortho.py

+VERTICES = [0.25, 0.25, 0.75, 1.0,
+            0.25, -0.25, 0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            0.25, -0.25, 0.75, 1.0,
+            -0.25, -0.25, 0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            0.25, 0.25, -0.75, 1.0,
+            -0.25, 0.25, -0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            -0.25, 0.25, -0.75, 1.0,
+            -0.25, -0.25, -0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            -0.25, -0.25, 0.75, 1.0,
+            -0.25, -0.25, -0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            -0.25, -0.25, -0.75, 1.0,
+            -0.25, 0.25, -0.75, 1.0,
+            0.25, 0.25, 0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            0.25, -0.25, 0.75, 1.0,
+            0.25, 0.25, 0.75, 1.0,
+            0.25, 0.25, -0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            0.25, 0.25, -0.75, 1.0,
+            0.25, 0.25, 0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            0.25, 0.25, -0.75, 1.0,
+            -0.25, 0.25, 0.75, 1.0,
+            -0.25, 0.25, -0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            -0.25, -0.25, 0.75, 1.0,
+            0.25, -0.25, 0.75, 1.0,
+            0.25, -0.25, -0.75, 1.0,
+            -0.25, -0.25, -0.75, 1.0,
+            -0.25, -0.25, 0.75, 1.0,
+
+            0.0, 0.0, 1.0, 1.0,
+            0.0,0.0, 1.0, 1.0,
+            0.0, 0.0,1.0, 1.0,
+            0.0, 0.0, 1.0,1.0,
+            0.0, 0.0, 1.0, 1.0,
+            0.0, 0.0, 1.0, 1.0,
+            0.8,0.8, 0.8, 1.0,
+            0.8, 0.8,0.8, 1.0,
+            0.8, 0.8, 0.8,1.0,
+            0.8, 0.8, 0.8, 1.0,
+            0.8, 0.8, 0.8, 1.0,
+            0.8,0.8, 0.8, 1.0,
+            0.0, 1.0,0.0, 1.0,
+            0.0, 1.0, 0.0,1.0,
+            0.0, 1.0, 0.0, 1.0,
+            0.0, 1.0, 0.0, 1.0,
+            0.0,1.0, 0.0, 1.0,
+            0.0, 1.0,0.0, 1.0,
+            0.5, 0.5, 0.0,1.0,
+            0.5, 0.5, 0.0, 1.0,
+            0.5, 0.5, 0.0, 1.0,
+            0.5,0.5, 0.0, 1.0,
+            0.5, 0.5,0.0, 1.0,
+            0.5, 0.5, 0.0,1.0,
+            1.0, 0.0, 0.0, 1.0,
+            1.0, 0.0, 0.0, 1.0,
+            1.0,0.0, 0.0, 1.0,
+            1.0, 0.0,0.0, 1.0,
+            1.0, 0.0, 0.0,1.0,
+            1.0, 0.0, 0.0, 1.0,
+            0.0, 1.0, 1.0, 1.0,
+            0.0,1.0, 1.0, 1.0,
+            0.0, 1.0,1.0, 1.0,
+            0.0, 1.0, 1.0,1.0,
+            0.0, 1.0, 1.0, 1.0,
+            0.0, 1.0, 1.0, 1.0]

File 04_objects_at_rest/data/vertices_perspective.py

+VERTICES = [0.25,0.25,-1.25,1.0,
+            0.25,-0.25,-1.25,1.0,
+            -0.25,0.25,-1.25,1.0,
+            0.25,-0.25,-1.25,1.0,
+            -0.25,-0.25,-1.25,1.0,
+            -0.25,0.25,-1.25,1.0,
+            0.25,0.25,-2.75,1.0,
+            -0.25,0.25,-2.75,1.0,
+            0.25,-0.25,-2.75,1.0,
+            0.25,-0.25,-2.75,1.0,
+            -0.25,0.25,-2.75,1.0,
+            -0.25,-0.25,-2.75,1.0,
+            -0.25,0.25,-1.25,1.0,
+            -0.25,-0.25,-1.25,1.0,
+            -0.25,-0.25,-2.75,1.0,
+            -0.25,0.25,-1.25,1.0,
+            -0.25,-0.25,-2.75,1.0,
+            -0.25,0.25,-2.75,1.0,
+            0.25,0.25,-1.25,1.0,
+            0.25,-0.25,-2.75,1.0,
+            0.25,-0.25,-1.25,1.0,
+            0.25,0.25,-1.25,1.0,
+            0.25,0.25,-2.75,1.0,
+            0.25,-0.25,-2.75,1.0,
+            0.25,0.25,-2.75,1.0,
+            0.25,0.25,-1.25,1.0,
+            -0.25,0.25,-1.25,1.0,
+            0.25,0.25,-2.75,1.0,
+            -0.25,0.25,-1.25,1.0,
+            -0.25,0.25,-2.75,1.0,
+            0.25,-0.25,-2.75,1.0,
+            -0.25,-0.25,-1.25,1.0,
+            0.25,-0.25,-1.25,1.0,
+            0.25,-0.25,-2.75,1.0,
+            -0.25,-0.25,-2.75,1.0,
+            -0.25,-0.25,-1.25,1.0,
+            0.0,0.0,1.0,1.0,
+            0.0,0.0,1.0,1.0,
+            0.0,0.0,1.0,1.0,
+            0.0,0.0,1.0,1.0,
+            0.0,0.0,1.0,1.0,
+            0.0,0.0,1.0,1.0,
+            0.8,0.8,0.8,1.0,
+            0.8,0.8,0.8,1.0,
+            0.8,0.8,0.8,1.0,
+            0.8,0.8,0.8,1.0,
+            0.8,0.8,0.8,1.0,
+            0.8,0.8,0.8,1.0,
+            0.0,1.0,0.0,1.0,
+            0.0,1.0,0.0,1.0,
+            0.0,1.0,0.0,1.0,
+            0.0,1.0,0.0,1.0,
+            0.0,1.0,0.0,1.0,
+            0.0,1.0,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            0.5,0.5,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            1.0,0.0,0.0,1.0,
+            0.0,1.0,1.0,1.0,
+            0.0,1.0,1.0,1.0,
+            0.0,1.0,1.0,1.0,
+            0.0,1.0,1.0,1.0,
+            0.0,1.0,1.0,1.0,
+            0.0,1.0,1.0,1.0]

File 05_objects_in_depth/05_BaseVertexOverlap.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertex_data import VERTICES,INDICES,NUMBER_OF_VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file,indices=None):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file,indices)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = GL.GLfloat*len(self.vertices)
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(self.vertices)*self.size_float,
+                        ArrayType(*self.vertices),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+        self.ibo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,self.ibo)
+        ArrayType = (GL.GLushort*len(self.indices))
+        GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER,len(self.indices)*self.size_short,
+                        ArrayType(*self.indices),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,0)
+
+    def init_vao(self):
+        self.vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(self.vao)
+        color_data_offset = 3*self.size_float*NUMBER_OF_VERTICES
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,3,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,4,GL.GL_FLOAT,GL.GL_FALSE,0,GL.GLvoidp(color_data_offset))
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,self.ibo)
+        GL.glBindVertexArray(0)
+
+    def setup_uniforms(self):
+        self.offset_location = GL.glGetUniformLocation(self.shader,"offset")
+        self.perspective_matrix_unif = GL.glGetUniformLocation(self.shader,"perspectiveMatrix")
+        self.frustum_scale = 1.0
+        self.z_near,self.z_far = 1.0,3.0
+        self.create_matrix()
+
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+
+    def create_matrix(self):
+        self.the_matrix = [0.0 for i in range(16)]
+        self.the_matrix[0] = self.frustum_scale
+        self.the_matrix[5] = self.frustum_scale
+        self.the_matrix[10] = (self.z_far+self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[14] = (2*self.z_far*self.z_near)/(self.z_near-self.z_far)
+        self.the_matrix[11] = -1.0
+
+    def display(self):
+        GL.glClearColor(0,0,0,0)
+        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
+
+        GL.glUseProgram(self.shader)
+        GL.glBindVertexArray(self.vao)
+        GL.glUniform3f(self.offset_location,0.0,0.0,0.0)
+        GL.glDrawElements(GL.GL_TRIANGLES,len(self.indices),GL.GL_UNSIGNED_SHORT,None)
+
+        GL.glUniform3f(self.offset_location,0.0,0.0,-1.0)
+        GL.glDrawElementsBaseVertex(GL.GL_TRIANGLES,len(self.indices),
+                                    GL.GL_UNSIGNED_SHORT,None,NUMBER_OF_VERTICES/2)
+        GL.glBindVertexArray(0)
+        GL.glUseProgram(0)
+
+    def reshape(self,width,height):
+        self.the_matrix[0] = self.frustum_scale/(width/float(height))
+        self.the_matrix[5] = self.frustum_scale
+        GL.glUseProgram(self.shader)
+        GL.glUniformMatrix4fv(self.perspective_matrix_unif,1,GL.GL_FALSE,self.the_matrix)
+        GL.glUseProgram(0)
+        GL.glViewport(0,0,width,height)
+
+def main():
+    pg.init()
+    os.environ['SDL_VIDEO_CENTERED'] = '1'
+    SCREEN = pg.display.set_mode((500,500),pg.HWSURFACE|pg.OPENGL|pg.DOUBLEBUF|pg.RESIZABLE)
+    MyClock = pg.time.Clock()
+    MyGL = Shader(VERTICES[:],os.path.join("data","Standard.vert"),
+                  os.path.join("data","Standard.frag"),INDICES[:])
+    done = False
+    while not done:
+        for event in pg.event.get():
+            if event.type==pg.QUIT or (event.type==pg.KEYDOWN and event.key==pg.K_ESCAPE):
+                done = True
+            elif event.type == pg.KEYDOWN:
+                pass
+            elif event.type == pg.VIDEORESIZE:
+                MyGL.reshape(*event.size)
+        MyGL.display()
+        pg.display.flip()
+        MyClock.tick(60)
+
+if __name__ == '__main__':
+    main()
+    pg.quit()
+    sys.exit()

File 05_objects_in_depth/05_DepthBuffer.py

+import sys,os,math
+import pygame as pg
+from OpenGL import GL
+
+sys.path.append("..")
+sys.path.append("data")
+import myframework
+from vertex_data import VERTICES,INDICES,NUMBER_OF_VERTICES
+
+class Shader(myframework.BaseShader):
+    def __init__(self,vertices,vert_file,frag_file,indices=None):
+        myframework.BaseShader.__init__(self,vertices,vert_file,frag_file,indices)
+        GL.glEnable(GL.GL_CULL_FACE)
+        GL.glCullFace(GL.GL_BACK)
+        GL.glFrontFace(GL.GL_CW)
+
+        GL.glEnable(GL.GL_DEPTH_TEST)
+        GL.glDepthMask(GL.GL_TRUE)
+        GL.glDepthFunc(GL.GL_LEQUAL)
+        GL.glDepthRange(0.0,1.0)
+
+    def init_vertex_buf(self):
+        self.vbo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        ArrayType = GL.GLfloat*len(self.vertices)
+        GL.glBufferData(GL.GL_ARRAY_BUFFER,len(self.vertices)*self.size_float,
+                        ArrayType(*self.vertices),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,0)
+
+        self.ibo = GL.glGenBuffers(1)
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,self.ibo)
+        ArrayType = (GL.GLushort*len(self.indices))
+        GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER,len(self.indices)*self.size_short,
+                        ArrayType(*self.indices),GL.GL_STATIC_DRAW)
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,0)
+
+    def init_vao(self):
+        self.vao = GL.glGenVertexArrays(1)
+        GL.glBindVertexArray(self.vao)
+        color_data_offset = 3*self.size_float*NUMBER_OF_VERTICES
+
+        GL.glBindBuffer(GL.GL_ARRAY_BUFFER,self.vbo)
+        GL.glEnableVertexAttribArray(0)
+        GL.glEnableVertexAttribArray(1)
+        GL.glVertexAttribPointer(0,3,GL.GL_FLOAT,GL.GL_FALSE,0,None)
+        GL.glVertexAttribPointer(1,4,GL.GL_FLOAT,GL.GL_FALSE,0,GL.GLvoidp(color_data_offset))
+        GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER,self.ibo)
+        GL.glBindVertexArray(0)
+
+    def setup_uniforms(self):