Skip to content

Instantly share code, notes, and snippets.

@stuaxo
Last active August 29, 2015 17:31
Show Gist options
  • Save stuaxo/ed0b5bd691f766098faf to your computer and use it in GitHub Desktop.
Save stuaxo/ed0b5bd691f766098faf to your computer and use it in GitHub Desktop.
Port of mozilla sample5 to pyopengl.py
"""
Well ... this isn't the nicest port, I tried a second time with all the comments, but it didn't seem to work
- the 2nd version is here https://gist.github.com/stuaxo/5c641637f65a53cc8020
Instead of webgl uses pyopengl
Instead of glm uses pyrr
Install Dependencies
pip install numpy pyopengl pyrr
"""
# Also info from http://stackoverflow.com/questions/14365484/how-to-draw-with-vertex-array-objects-and-gldrawelements-in-pyopengl
from OpenGL.GL import shaders
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \
glBindVertexArray
from pyrr.matrix44 import *
from pyrr import Vector3
from ctypes import sizeof, c_float
import math
import time
import pygame
import numpy as np
from textwrap import dedent
FLOAT_SIZE = sizeof(c_float)
cube_rotation = 10.0
cubeXOffset = 0.0
cubeYOffset = 0.0
cubeZOffset = 0.0
lastCubeUpdateTime = 0
xIncValue = 0.2
yIncValue = 1.4
zIncValue = 0.3
mv_matrix_stack = []
mv_matrix = create_identity(dtype=np.float32)
perspective_matrix = create_perspective_projection_matrix(45, 640.0/480.0, 0.1, 100.0, dtype=np.float32)
def load_identity():
global mv_matrix
mv_matrix = create_identity(dtype=np.float32)
def mult_matrix(m):
global mv_matrix
mv_matrix = multiply(m, mv_matrix)
def mv_translate(*v):
global mv_matrix
m = create_from_translation(v, dtype=np.float32)
mult_matrix( m )
def set_matrix_uniforms():
global perspective_matrix, mv_matrix
p_uniform = glGetUniformLocation(program, "uPMatrix")
glUniformMatrix4fv(p_uniform, 1, GL_FALSE, perspective_matrix)
# set modelview matrix
mv_uniform = glGetUniformLocation(program, "uMVMatrix")
glUniformMatrix4fv(mv_uniform, 1, GL_FALSE, mv_matrix)
#uMVMatrixID = glGetUniformLocation(vertexShader, "uMVMatrix")
def mv_push_matrix(m=None):
global mv_matrix
if m:
mv_matrix_stack.append(m.copy())
mv_matrix = m.copy()
else:
mv_matrix_stack.append(mv_matrix.copy())
def mv_pop_matrix():
global mv_matrix
try:
mv_matrix = mv_matrix_stack.pop()
except IndexError:
raise IndexError("Can't pop from an empty matrix stack.")
return mv_matrix
def mv_rotate(angle, axis):
x, y, z = axis
theta = math.radians(angle)
m = create_from_eulers([theta * x, theta * y, theta * z], dtype=np.float32)
mult_matrix(m)
def start():
pass
def run():
global program
global cubeXOffset, cubeYOffset, cubeZOffset, cube_rotation
global xIncValue, yIncValue, zIncValue
global element_width
lastCubeUpdateTime = time.time()
pygame.init()
screen = pygame.display.set_mode((800,600), pygame.OPENGL|pygame.DOUBLEBUF)
vertices = np.array([
# Front face
[-1.0, -1.0, 1.0],
[1.0, -1.0, 1.0],
[1.0, 1.0, 1.0],
[-1.0, 1.0, 1.0],
# Back face
[-1.0, -1.0, -1.0],
[-1.0, 1.0, -1.0],
[1.0, 1.0, -1.0],
[1.0, -1.0, -1.0],
# Top face
[-1.0, 1.0, -1.0],
[-1.0, 1.0, 1.0],
[1.0, 1.0, 1.0],
[1.0, 1.0, -1.0],
# Bottom face
[-1.0, -1.0, -1.0],
[1.0, -1.0, -1.0],
[1.0, -1.0, 1.0],
[-1.0, -1.0, 1.0],
# Right face
[1.0, -1.0, -1.0],
[1.0, 1.0, -1.0],
[1.0, 1.0, 1.0],
[1.0, -1.0, 1.0],
# Left face
[-1.0, -1.0, -1.0],
[-1.0, -1.0, 1.0],
[-1.0, 1.0, 1.0],
[-1.0, 1.0, -1.0]
], dtype='f')
colors = np.array([
[1.0, 1.0, 1.0, 1.0], # Front face: white
[1.0, 0.0, 0.0, 1.0], # Back face: red
[0.0, 1.0, 0.0, 1.0], # Top face: green
[0.0, 0.0, 1.0, 1.0], # Bottom face: blue
[1.0, 1.0, 0.0, 1.0], # Right face: yellow
[1.0, 0.0, 1.0, 1.0] # Left face: purple
], dtype='f')
# expand colors out to 1 for each of the 4 vertices
generated_colors = []
for color in colors:
for i in range(0, 4):
generated_colors += [color]
colorVerts = np.column_stack([vertices, np.array(generated_colors, dtype=np.float32)])
element_width = colorVerts.shape[-1]
vertexPositions = vbo.VBO(colorVerts)
#Create the index buffer object
#indices = np.array([[0,1,2]], dtype=np.int32)
indices = np.array([
[0, 1, 2], [0, 2, 3], # front
[4, 5, 6], [4, 6, 7], # back
[8, 9, 10], [8, 10, 11], # top
[12, 13, 14], [12, 14, 15], # bottom
[16, 17, 18], [16, 18, 19], # right
[20, 21, 22], [20, 22, 23] # left
], dtype='uint16').flatten()
#indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
indexPositions = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
#Now create the shaders
vertexShader = shaders.compileShader("""
#version 130
in vec3 position; // TODO - rename to vertexPosition
in vec3 col; // TODO - rename to vertexColor
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
out vec4 frag_color;
void main()
{
//gl_Position = vec4(position, 1);
gl_Position = uPMatrix * uMVMatrix * vec4(position, 1.0);
frag_color = vec4(col, 1.0);
}
""", GL_VERTEX_SHADER)
fragmentShader = shaders.compileShader("""
#version 130
in vec4 frag_color;
out vec4 outputColor;
void main()
{
outputColor = frag_color;
}
""", GL_FRAGMENT_SHADER)
program = glCreateProgram()
glAttachShader(program, vertexShader)
glAttachShader(program, fragmentShader)
POSITION_IDX = 0
COLOR_IDX = 1
glBindAttribLocation(program, POSITION_IDX, "position")
glBindAttribLocation(program, COLOR_IDX, "col")
#uMVMatrixID = glGetUniformLocation(vertexShader, "uMVMatrix")
#uPMatrixID = glGetUniformLocation(vertexShader, "uPMatrix")
glLinkProgram(program)
#The draw loop
while True:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
##perspective_matrix = make_perspective(45, 640.0/480.0, 0.1, 100.0) # moved out
load_identity()
mv_translate(-0.0, 0.0, -6.0)
mv_push_matrix()
mv_rotate(cube_rotation, [1, 0, 1])
mv_translate(cubeXOffset, cubeYOffset, cubeZOffset)
glUseProgram(program)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)
vertexPositions.bind()
glEnableVertexAttribArray(POSITION_IDX)
glVertexAttribPointer(POSITION_IDX, 3, GL_FLOAT, False, element_width * FLOAT_SIZE, ctypes.c_void_p(0)) # position
glEnableVertexAttribArray(COLOR_IDX)
glVertexAttribPointer(COLOR_IDX, 3, GL_FLOAT, False, element_width * FLOAT_SIZE, ctypes.c_void_p(12)) # color color
set_matrix_uniforms()
glDrawElements(GL_TRIANGLES, indices.size, GL_UNSIGNED_SHORT, None) #This line does work too!
mv_pop_matrix()
# Update the rotation for the next draw, if it's time to do so.
currentTime = time.time()
if lastCubeUpdateTime:
delta = currentTime - lastCubeUpdateTime
cube_rotation += (30 * delta)
cubeXOffset += xIncValue * delta
cubeYOffset += yIncValue * delta
cubeZOffset += zIncValue * delta
if abs(cubeYOffset) > 2.5:
xIncValue = -xIncValue
yIncValue = -yIncValue
zIncValue = -zIncValue
lastCubeUpdateTime = currentTime
# Show the screen
pygame.display.flip()
time.sleep(1. / 60.)
run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment