Skip to content

Instantly share code, notes, and snippets.

@DuaneNielsen
Created January 22, 2020 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DuaneNielsen/a5a5957e4d2a646d5a5c02d65f88ed3c to your computer and use it in GitHub Desktop.
Save DuaneNielsen/a5a5957e4d2a646d5a5c02d65f88ed3c to your computer and use it in GitHub Desktop.
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import numpy as np
import pyrr
def init_window(width, height, title="My OpenGL window"):
# initializing glfw library
if not glfw.init():
raise Exception("glfw can not be initialized!")
# creating the window
window = glfw.create_window(width, height, title, None, None)
# check if window was created
if not window:
glfw.terminate()
raise Exception("glfw window can not be created!")
# make the context current
glfw.make_context_current(window)
return window
def resize_window(window, height, width):
glViewport(0, 0, width, height)
def compile_shaders(vertex_src, fragment_src):
vshader = compileShader(vertex_src, GL_VERTEX_SHADER)
if not glGetShaderiv(vshader, GL_COMPILE_STATUS):
raise Exception('failed to compile shader "%s":\n%s' % ('shader', glGetShaderInfoLog(vshader).decode()))
fshader = compileShader(fragment_src, GL_FRAGMENT_SHADER)
if not glGetShaderiv(fshader, GL_COMPILE_STATUS):
raise Exception('failed to compile shader "%s":\n%s' % ('shader', glGetShaderInfoLog(fshader).decode()))
shader = compileProgram(vshader, fshader)
if not glGetProgramiv(shader, GL_LINK_STATUS):
raise Exception(f'linking failed : {glGetProgramInfoLog(shader)}')
return shader
class Poly:
def __init__(self, vertices, indices):
self.vertex_src = """
# version 330 core
layout(location = 0) in vec3 aPos;
uniform mat4 model;
void main() {
gl_Position = model * vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
"""
self.fragment_src = """
# version 330 core
out vec4 FragColor;
void main() {
FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
"""
self.shader = compile_shaders(self.vertex_src, self.fragment_src)
self.model_loc = glGetUniformLocation(self.shader, "model")
self.model = pyrr.matrix44.create_from_translation(pyrr.Vector3([0.0, 0.0, 0.0]))
self.vertices = np.array(vertices, dtype=np.float32)
self.indices = np.array(indices, dtype=np.uint32)
# initialize a vao
self.vao = glGenVertexArrays(1)
glBindVertexArray(self.vao)
# configure and bind the vertex buffer
self.vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
# specify location and layout for aPos
glEnableVertexAttribArray(0) # layout (location = 0) in the shader code
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride=self.vertices.itemsize * 3, pointer=None)
# configure the element buffer
self.ebo = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.ebo)
# load the data into buffer
glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, self.indices.nbytes, self.indices, GL_STATIC_DRAW)
def translate(self, vec3):
self.model = pyrr.matrix44.create_from_translation(vec3)
def draw(self):
# select the shader
glUseProgram(self.shader)
# bind the vertex array objects
glBindVertexArray(self.vao)
# load the model position
glUniformMatrix4fv(self.model_loc, 1, GL_FALSE, self.model)
# draw
glDrawElements(GL_TRIANGLES, len(self.indices), GL_UNSIGNED_INT, None)
if __name__ == '__main__':
window_width, window_height = 800, 600
# create the window
window = init_window(window_width, window_height)
# use the full window as viewport
glViewport(0, 0, window_width, window_height)
# set the window resize callback
glfw.set_window_size_callback(window, resize_window)
# set window's position
glfw.set_window_pos(window, 400, 200)
quad = Poly(
vertices=[
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, 0.5, 0.0,
],
indices=[0, 1, 2, 2, 3, 0]
)
triangle2 = Poly(
vertices=[
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
1.0, 0.5, 0.0
],
indices=[1, 2, 3]
)
# enable GL
glEnable(GL_DEPTH_TEST)
# set the background color
glClearColor(0.2, 0.3, 0.3, 1.0)
# the main application loop
while not glfw.window_should_close(window):
glfw.poll_events()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
quad.translate(pyrr.Vector3([-0.2, 0.4, -0.8]))
quad.draw()
triangle2.translate(pyrr.Vector3([0.1, -0.3, 0.8]))
triangle2.draw()
glfw.swap_buffers(window)
# terminate glfw, free up allocated resources
glfw.terminate()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment