Last active
August 29, 2015 17:31
-
-
Save stuaxo/ed0b5bd691f766098faf to your computer and use it in GitHub Desktop.
Port of mozilla sample5 to pyopengl.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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