Posts: 544
Threads: 15
Joined: Oct 2016
import numpy as np
class BoxProperty:
def __init__(self, pos, pos2=None, div=False):
self.pos = pos
self.pos2 = pos2
self.div = [1.0, 0.5][div]
def __get__(self, instance, owner):
if self.pos2 is None:
return instance[self.pos]
return instance[self.pos] + instance[self.pos2] * self.div
def __set__(self, instance, value):
if self.pos2 is None:
instance[self.pos] = value
else:
instance[self.pos] = value - instance[self.pos2] * self.div
class BoxCombineProperty:
def __init__(self, pos1, pos2, pos3):
if isinstance(pos1, (tuple, list)):
self.pos1 = BoxProperty(*pos1)
else:
self.pos1 = BoxProperty(pos1)
if isinstance(pos2, (tuple, list)):
self.pos2 = BoxProperty(*pos2)
else:
self.pos2 = BoxProperty(pos2)
if isinstance(pos3, (tuple, list)):
self.pos3 = BoxProperty(*pos3)
else:
self.pos3 = BoxProperty(pos3)
def __get__(self, instance, owner):
return (self.pos1.__get__(instance, owner),
self.pos2.__get__(instance, owner),
self.pos3.__get__(instance, owner))
def __set__(self, instance, value):
self.pos1.__set__(instance, value[0])
self.pos2.__set__(instance, value[1])
self.pos3.__set__(instance, value[2])
class ArrayProperty:
def __init__(self, position):
self.position = position
def __get__(self, instance, owner):
return instance[self.position]
def __set__(self, instance, value):
instance[self.position] = value
class BoundingBox(np.ndarray):
def __new__(cls, x, y, z, w, h, d):
return np.asarray((x, y, z, w, h, d)).view(cls)
def collidepoint(self, x, y=None, z=None):
if y is None:
x, y, z = x
if (self.left < x < self.right and
self.top < y < self.bottom and
self.front < z < self.back):
return True
return False
def collidebox(self, box):
return ( ((self[0] > box[0] and self[0] < box[3] + box[0]) or
(box[0] > self[0] and box[0] < self[3] + self[0])) and
((self[1] > box[1] and self[1] < box[4] + box[1]) or
(box[1] > self[1] and box[1] < self[4] + self[1])) and
((self[2] > box[2] and self[2] < box[5] + box[2]) or
(box[2] > self[2] and box[2] < self[5] + self[2])))
#return ( ((self.left > box.left and self.left < box.right) or
# (box.left > self.left and box.left < self.right)) and
# ((self.top > box.top and self.top < box.bottom) or
# (box.top > self.top and box.top < self.bottom)) and
# ((self.front > box.front and self.front < box.back) or
# (box.front > self.front and box.front < self.back)))
def _clamp(self, box):
x, y, z = self[:3]
clamp = 'xyz'
if self[3] >= box[3]:
x = box[0] + box[3] / 2 - self[3] / 2
elif self[0] < box[0]:
x = box[0]
elif self[0] + self[3] > box[0] + box[3]:
x = box[0] + box[3] - self[3]
else:
clamp = 'yz'
if self[4] >= box[4]:
y = box[1] + box[4] / 2 - self[4] / 2
elif self[1] < box[1]:
y = box[1]
elif self[1] + self[4] > box[1] + box[4]:
y = box[1] + box[4] - self[4]
else:
if clamp == 'yz':
clamp = 'z'
else:
clamp = 'xz'
if self[5] >= box[5]:
z = box[2] + box[5] / 2 - self[5] / 2
elif self[2] < box[2]:
z = box[2]
elif self[2] + self[5] > box[2] + box[5]:
z = box[2] + box[5] - self[5]
else:
if clamp == 'z':
clamp = None
elif clamp == 'yz':
clamp = 'y'
elif clamp == 'xz':
clamp = 'x'
else:
clamp = 'xy'
return x, y, z, clamp
def clamp(self, box):
c = self._clamp(box)
return BoundingBox(*c[:3], *self[3:]), c[3]
def clamp_ip(self, box):
c = self._clamp(box)
self[:3] = c[:3]
return c[3]
x = ArrayProperty(0)
y = ArrayProperty(1)
z = ArrayProperty(2)
w = ArrayProperty(3)
h = ArrayProperty(4)
d = ArrayProperty(5)
left = ArrayProperty(0)
top = ArrayProperty(1)
front = ArrayProperty(2)
right = BoxProperty(0, 3)
bottom = BoxProperty(1, 4)
back = BoxProperty(2, 5)
topleft_front = BoxCombineProperty(0, 1, 2)
topright_front = BoxCombineProperty((0, 3), 1, 2)
bottomleft_front = BoxCombineProperty(0, (1, 4), 2)
bottomright_front = BoxCombineProperty((0, 3), (1, 4), 2)
topleft_back = BoxCombineProperty(0, 1, (2, 5))
topright_back = BoxCombineProperty((0, 3), 1, (2, 5))
bottomleft_back = BoxCombineProperty(0, (1, 4), (2, 5))
bottomright_back = BoxCombineProperty((0, 3), (1, 4), (2, 5))
center = BoxCombineProperty((0, 3, 1), (1, 4, 1), (2, 5, 1))
boxsize = BoxCombineProperty(3, 4, 5)
centerx = BoxProperty(0, 3, 1)
centery = BoxProperty(1, 4, 1)
centerz = BoxProperty(2, 5, 1)
def main():
a = BoundingBox(10,10,10,50,50,50)
b = BoundingBox(40,40,40,30,30,30)
c = BoundingBox(10,60,10,50,50,50)
print(a)
print(a.collidebox(b))
print(a.collidebox(c))
print(b.collidebox(c))
print(a.collidepoint(45, 20, 45))
print(b.collidepoint(45, 20, 45))
print()
#a[:3] -= 20 # move in place
print(a)
screen = BoundingBox(0,0,50,800,600,250)
clamp = a.clamp_ip(screen)
print(a, clamp)
print(screen)
print(screen.center)
if __name__ == '__main__':
main() Example pyglet
import pyglet
from pyglet.gl import *
from pyglet.graphics.vertexbuffer import create_buffer
from boundingbox import BoundingBox
from random import randrange
import numpy as np
import ctypes
import math
import os
# base on gl3n row major
def perspective(width, height, fov, near, far):
array = np.array([0 for i in range(16)], dtype=GLfloat).reshape(4,4)
mat = np.matrix(array)
aspect = width/height
top = near * math.tan(fov * (math.pi/360.0))
bottom = -top
right = top * aspect
left = -right
mat[0,0] = (2 * near) / (right - left)
mat[0,2] = (right + left) / (right - left)
mat[1,1] = (2 * near) / (top - bottom)
mat[1,2] = (top + bottom) / (top - bottom)
mat[2,2] = -(far + near) / (far - near)
mat[2,3] = -(2 * far + near) / (far - near)
mat[3,2] = -1
return mat
def normalized(array):
if np.linalg.norm(array) != 0:
return array / np.linalg.norm(array)
return array
def matrix_idenity():
return np.matrix(np.identity(4, GLfloat))
def look_at(eye, target, up):
look_dir = normalized(target - eye)
up_dir = normalized(up)
right_dir = normalized(np.cross(look_dir, up_dir))
perp_up_dir = np.cross(right_dir, look_dir)
mat = matrix_idenity()
mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])
return mat
def unit_vector(data):
data = np.array(data, dtype=GLfloat, copy=True)
if data.ndim == 1:
data /= math.sqrt(np.dot(data, data))
return data
def rotation(alpha, axis):
cosa = math.cos(alpha)
sina = math.sin(alpha)
axis = unit_vector(axis)
R = np.diag([cosa, cosa, cosa])
R += np.outer(axis, axis) * (1.0 - cosa)
axis *= sina
R += np.array([[0.0, -axis[2], axis[1]],
[axis[2], 0.0, -axis[0]],
[-axis[1], axis[0], 0.0]], GLfloat)
M = np.identity(4)
M[:3, :3] = R
return M
class Face:
FRONT = 1 # counter clockwise
BACK = 2
LEFT = 4 # counter clockwise
RIGHT = 8
TOP = 16 # counter clockwise
BOTTOM = 32
ALL = 63
def create_cube(size, face=Face.ALL, element=True):
array = np.array([
size, size, size, #0 + + + right top front
-size, -size, -size, #1 - - - left bottom back
size, -size, -size, #2 + - - right bottom back
size, size, -size, #3 + + - right top back
-size, size, -size, #4 - + - left top back
-size, size, size, #5 - + + left top front
-size, -size, size, #6 - - + left bottom front
size, -size, size #7 + - + right bottom front
], GLfloat)
elements = np.array([], GLuint)
if face & Face.BACK:
elements = np.append(elements, [1,3,2,3,1,4])
if face & Face.FRONT:
elements = np.append(elements, [6,7,0,0,5,6])
if face & Face.LEFT:
elements = np.append(elements, [5,4,1,1,6,5])
if face & Face.RIGHT:
elements = np.append(elements, [0,2,3,2,0,7])
if face & Face.TOP:
elements = np.append(elements, [4,0,3,0,4,5])
if face & Face.BOTTOM:
elements = np.append(elements, [1,2,7,7,6,1])
if element:
return array, elements
pylist = []
for i in elements:
n = i * 3
pylist.extend(array[n:n + 3])
return np.array(pylist, GLfloat)
class Shader:
def __init__(self, vstring, fstring):
self.program = GLuint(glCreateProgram())
if not os.path.exists(vstring):
print(vstring, "doesn't exists")
return
if not os.path.exists(fstring):
print(fstring, "doesn't exists")
return
vbuffer = open(vstring, 'r')
vshader = glCreateShader(GL_VERTEX_SHADER)
vbuff = ctypes.create_string_buffer(vbuffer.read().encode())
vtext = ctypes.cast(ctypes.pointer(ctypes.pointer(vbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(vshader, 1, vtext, None)
glCompileShader(vshader)
success = GLint()
infoLog = ctypes.create_string_buffer(512)
glGetShaderiv(vshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(vshader, 512, None, infoLog)
print("Error: Vertex Shader ", infoLog.value)
fbuffer = open(fstring, 'r')
fshader = glCreateShader(GL_FRAGMENT_SHADER)
fbuff = ctypes.create_string_buffer(fbuffer.read().encode())
ftext = ctypes.cast(ctypes.pointer(ctypes.pointer(fbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(fshader, 1, ftext, None)
glCompileShader(fshader)
glGetShaderiv(fshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Fragment Shader ", infoLog.value)
glAttachShader(self.program, vshader)
glAttachShader(self.program, fshader)
glLinkProgram(self.program)
glGetProgramiv(self.program, GL_LINK_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Program ", infoLog.value)
# clean up
glDeleteShader(vshader)
glDeleteShader(fshader)
vbuffer.close()
fbuffer.close()
def uniformMatrix4fv(self, key, count, transpose, value):
buff = ctypes.create_string_buffer(key.encode())
location = glGetUniformLocation(self.program, buff)
nvalue = np.array(value, GLfloat) # .flatten()
nref = nvalue.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
glUniformMatrix4fv(location, count, transpose, nref)
def use(self):
glUseProgram(self.program)
def destroy(self):
glDeleteProgram(self.program)
class CubeRandom:
def __init__(self, w, h):
ar = np.arange(0, 1, 0.1)
self.box = BoundingBox(np.random.choice(ar), np.random.choice(ar),
np.random.choice(ar), 0.1, 0.1, 0.1).astype(float)
speed = np.arange(0, 0.05, 0.002)
self.dir = np.array([np.random.choice(speed) for i in range(3)])
def move(self, screenbox):
screenbox = BoundingBox(0.0, 0.0, 0.0, 2.0, 2.0, 2.0)
self.box[:3] += self.dir
clamp = self.box.clamp_ip(screenbox)
if clamp is None:
return
if 'x' in clamp:
self.dir[0] = -self.dir[0]
if 'y' in clamp:
self.dir[1] = -self.dir[1]
if 'z' in clamp:
self.dir[2] = -self.dir[2]
class Window(pyglet.window.Window):
def __init__(self):
pyglet.window.Window.__init__(self)
self.context.config.alpha_size = 8
self.context.config.buffer_size = 32
self.context.config.sample_buffers = 1
self.context.config.samples = 4
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glClearColor(0.1, 0.0, 0.0, 1.0)
glViewport(0, 0, self.width, self.height)
self.model = matrix_idenity()
self.view = look_at(
np.array([4,3,3], dtype=GLfloat),
np.array([0,0,0], dtype=GLfloat),
np.array([0,1,0], dtype=GLfloat))
self.projection = perspective(self.width, self.height, 45.0, 1.0, 100.0)
self.mvp = self.projection * self.view * self.model
self.vertices = create_cube(0.1, element=False)
print("How many vertices.", len(self.vertices) / 3)
color_choice = [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0],
[1.0,0.0,1.0], [1.0,1.0,0.0], [0.0,0.5,1.0]]
colors = []
for i in range(6):
color = color_choice[i]
colors.extend(color + color + color + color + color + color)
self.colors = np.array(colors, GLfloat)
print("How many colors.", len(self.colors) / 3)
self.vao = GLuint()
glGenVertexArrays(1, self.vao)
glBindVertexArray(self.vao)
self.vbo = create_buffer(self.vertices.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.vbo.set_data(self.vertices.ctypes.data)
self.vbo.bind()
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
self.color_vbo = create_buffer(self.colors.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.color_vbo.set_data(self.colors.ctypes.data)
self.color_vbo.bind()
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
self.tick = 0.0
self.shader = Shader('vshader.glsl', 'fshader.glsl')
pyglet.clock.schedule_interval(self.tick_update, 1.0 / 30.0)
self.screenbox = BoundingBox(0,0,10, self.width, self.height, 100)
self.cubes = [CubeRandom(self.width, self.height) for i in range(6)]
def tick_update(self, dt):
self.tick += dt
#self.model = rotation(self.tick, np.array([0.2, 0.4, 0.2], GLfloat))
for cube in self.cubes:
cube.move(self.screenbox)
#self.mvp = self.projection * self.view * self.model
def on_draw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.shader.use()
#self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, self.mvp)
glBindVertexArray(self.vao);
for cube in self.cubes:
model = np.identity(4)
model[0::1, 3][:3] = cube.box[:3]
mvp = self.projection * self.view * np.matrix(model)
self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, mvp)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
glBindVertexArray(0)
def clean_up(self):
self.shader.destroy()
self.vbo.delete()
self.color_vbo.delete()
glDeleteVertexArrays(1, self.vao)
if __name__ == '__main__':
window = Window()
pyglet.app.run()
window.clean_up()
99 percent of computer problems exists between chair and keyboard.
Posts: 544
Threads: 15
Joined: Oct 2016
Jan-06-2018, 12:41 AM
(This post was last modified: Jan-06-2018, 12:41 AM by Windspar.)
Made very small improvement
import numpy as np
class BoxProperty:
def __init__(self, pos, pos2=None, div=False):
self.pos = pos
self.pos2 = pos2
self.div = [1.0, 0.5][div]
def __get__(self, instance, owner):
if self.pos2 is None:
return instance[self.pos]
return instance[self.pos] + instance[self.pos2] * self.div
def __set__(self, instance, value):
if self.pos2 is None:
instance[self.pos] = value
else:
instance[self.pos] = value - instance[self.pos2] * self.div
class BoxCombineProperty:
def __init__(self, pos1, pos2, pos3):
if isinstance(pos1, (tuple, list)):
self.pos1 = BoxProperty(*pos1)
else:
self.pos1 = BoxProperty(pos1)
if isinstance(pos2, (tuple, list)):
self.pos2 = BoxProperty(*pos2)
else:
self.pos2 = BoxProperty(pos2)
if isinstance(pos3, (tuple, list)):
self.pos3 = BoxProperty(*pos3)
else:
self.pos3 = BoxProperty(pos3)
def __get__(self, instance, owner):
return (self.pos1.__get__(instance, owner),
self.pos2.__get__(instance, owner),
self.pos3.__get__(instance, owner))
def __set__(self, instance, value):
self.pos1.__set__(instance, value[0])
self.pos2.__set__(instance, value[1])
self.pos3.__set__(instance, value[2])
class ArrayProperty:
def __init__(self, position):
self.position = position
def __get__(self, instance, owner):
return instance[self.position]
def __set__(self, instance, value):
instance[self.position] = value
class BoundingBox(np.ndarray):
def __new__(cls, x, y, z, w, h, d):
return np.asarray((x, y, z, w, h, d)).view(cls)
def collidepoint(self, x, y=None, z=None):
if y is None:
x, y, z = x
if (self.left < x < self.right and
self.top < y < self.bottom and
self.front < z < self.back):
return True
return False
def collidebox(self, box):
return ( ((self[0] > box[0] and self[0] < box[3] + box[0]) or
(box[0] > self[0] and box[0] < self[3] + self[0])) and
((self[1] > box[1] and self[1] < box[4] + box[1]) or
(box[1] > self[1] and box[1] < self[4] + self[1])) and
((self[2] > box[2] and self[2] < box[5] + box[2]) or
(box[2] > self[2] and box[2] < self[5] + self[2])))
#return ( ((self.left > box.left and self.left < box.right) or
# (box.left > self.left and box.left < self.right)) and
# ((self.top > box.top and self.top < box.bottom) or
# (box.top > self.top and box.top < self.bottom)) and
# ((self.front > box.front and self.front < box.back) or
# (box.front > self.front and box.front < self.back)))
def _clamp(self, box):
x, y, z = self[:3]
clamp = 'xyz'
if self[3] >= box[3]:
x = box[0] + box[3] / 2 - self[3] / 2
elif self[0] < box[0]:
x = box[0]
elif self[0] + self[3] > box[0] + box[3]:
x = box[0] + box[3] - self[3]
else:
clamp = 'yz'
if self[4] >= box[4]:
y = box[1] + box[4] / 2 - self[4] / 2
elif self[1] < box[1]:
y = box[1]
elif self[1] + self[4] > box[1] + box[4]:
y = box[1] + box[4] - self[4]
else:
clamp = clamp.replace('y', '')
if self[5] >= box[5]:
z = box[2] + box[5] / 2 - self[5] / 2
elif self[2] < box[2]:
z = box[2]
elif self[2] + self[5] > box[2] + box[5]:
z = box[2] + box[5] - self[5]
else:
clamp = clamp.replace('z', '')
return x, y, z, clamp
def clamp(self, box):
c = self._clamp(box)
return BoundingBox(*c[:3], *self[3:]), c[3]
def clamp_ip(self, box):
c = self._clamp(box)
self[:3] = c[:3]
return c[3]
x = ArrayProperty(0)
y = ArrayProperty(1)
z = ArrayProperty(2)
w = ArrayProperty(3)
h = ArrayProperty(4)
d = ArrayProperty(5)
left = ArrayProperty(0)
top = ArrayProperty(1)
front = ArrayProperty(2)
right = BoxProperty(0, 3)
bottom = BoxProperty(1, 4)
back = BoxProperty(2, 5)
topleft_front = BoxCombineProperty(0, 1, 2)
topright_front = BoxCombineProperty((0, 3), 1, 2)
bottomleft_front = BoxCombineProperty(0, (1, 4), 2)
bottomright_front = BoxCombineProperty((0, 3), (1, 4), 2)
topleft_back = BoxCombineProperty(0, 1, (2, 5))
topright_back = BoxCombineProperty((0, 3), 1, (2, 5))
bottomleft_back = BoxCombineProperty(0, (1, 4), (2, 5))
bottomright_back = BoxCombineProperty((0, 3), (1, 4), (2, 5))
center = BoxCombineProperty((0, 3, 1), (1, 4, 1), (2, 5, 1))
boxsize = BoxCombineProperty(3, 4, 5)
centerx = BoxProperty(0, 3, 1)
centery = BoxProperty(1, 4, 1)
centerz = BoxProperty(2, 5, 1)
def main():
a = BoundingBox(10,10,10,50,50,50)
b = BoundingBox(40,40,40,30,30,30)
c = BoundingBox(10,60,10,50,50,50)
print(a)
print(a.collidebox(b))
print(a.collidebox(c))
print(b.collidebox(c))
print(a.collidepoint(45, 20, 45))
print(b.collidepoint(45, 20, 45))
print()
#a[:3] -= 20 # move in place
print(a)
screen = BoundingBox(0,0,50,800,600,250)
clamp = a.clamp_ip(screen)
print(a, clamp)
print(screen)
print(screen.center)
if __name__ == '__main__':
main() Example pyglet. Now with mouse and wasd, qe movement.
import pyglet
from pyglet.gl import *
from pyglet.graphics.vertexbuffer import create_buffer
from boundingbox import BoundingBox
from random import randrange
import numpy as np
import ctypes
import math
import os
# base on gl3n row major
def perspective(width, height, fov, near, far):
array = np.array([0 for i in range(16)], dtype=GLfloat).reshape(4,4)
mat = np.matrix(array)
aspect = width/height
top = near * math.tan(fov * (math.pi/360.0))
bottom = -top
right = top * aspect
left = -right
mat[0,0] = (2 * near) / (right - left)
mat[0,2] = (right + left) / (right - left)
mat[1,1] = (2 * near) / (top - bottom)
mat[1,2] = (top + bottom) / (top - bottom)
mat[2,2] = -(far + near) / (far - near)
mat[2,3] = -(2 * far + near) / (far - near)
mat[3,2] = -1
return mat
def normalized(array):
if np.linalg.norm(array) != 0:
return array / np.linalg.norm(array)
return array
def matrix_idenity():
return np.matrix(np.identity(4, GLfloat))
def look_at(eye, target, up):
look_dir = normalized(target - eye)
up_dir = normalized(up)
right_dir = normalized(np.cross(look_dir, up_dir))
perp_up_dir = np.cross(right_dir, look_dir)
mat = matrix_idenity()
mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])
return mat
def unit_vector(data):
data = np.array(data, dtype=GLfloat, copy=True)
if data.ndim == 1:
data /= math.sqrt(np.dot(data, data))
return data
def rotation(alpha, axis):
cosa = math.cos(alpha)
sina = math.sin(alpha)
axis = unit_vector(axis)
R = np.diag([cosa, cosa, cosa])
R += np.outer(axis, axis) * (1.0 - cosa)
axis *= sina
R += np.array([[0.0, -axis[2], axis[1]],
[axis[2], 0.0, -axis[0]],
[-axis[1], axis[0], 0.0]], GLfloat)
M = np.identity(4)
M[:3, :3] = R
return M
class Face:
FRONT = 1 # counter clockwise
BACK = 2
LEFT = 4 # counter clockwise
RIGHT = 8
TOP = 16 # counter clockwise
BOTTOM = 32
ALL = 63
def create_cube(size, face=Face.ALL, element=True):
array = np.array([
size, size, size, #0 + + + right top front
-size, -size, -size, #1 - - - left bottom back
size, -size, -size, #2 + - - right bottom back
size, size, -size, #3 + + - right top back
-size, size, -size, #4 - + - left top back
-size, size, size, #5 - + + left top front
-size, -size, size, #6 - - + left bottom front
size, -size, size #7 + - + right bottom front
], GLfloat)
elements = np.array([], GLuint)
if face & Face.BACK:
elements = np.append(elements, [1,3,2,3,1,4])
if face & Face.FRONT:
elements = np.append(elements, [6,7,0,0,5,6])
if face & Face.LEFT:
elements = np.append(elements, [5,4,1,1,6,5])
if face & Face.RIGHT:
elements = np.append(elements, [0,2,3,2,0,7])
if face & Face.TOP:
elements = np.append(elements, [4,0,3,0,4,5])
if face & Face.BOTTOM:
elements = np.append(elements, [1,2,7,7,6,1])
if element:
return array, elements
pylist = []
for i in elements:
n = i * 3
pylist.extend(array[n:n + 3])
return np.array(pylist, GLfloat)
class Shader:
def __init__(self, vstring, fstring):
self.program = GLuint(glCreateProgram())
if not os.path.exists(vstring):
print(vstring, "doesn't exists")
return
if not os.path.exists(fstring):
print(fstring, "doesn't exists")
return
vbuffer = open(vstring, 'r')
vshader = glCreateShader(GL_VERTEX_SHADER)
vbuff = ctypes.create_string_buffer(vbuffer.read().encode())
vtext = ctypes.cast(ctypes.pointer(ctypes.pointer(vbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(vshader, 1, vtext, None)
glCompileShader(vshader)
success = GLint()
infoLog = ctypes.create_string_buffer(512)
glGetShaderiv(vshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(vshader, 512, None, infoLog)
print("Error: Vertex Shader ", infoLog.value)
fbuffer = open(fstring, 'r')
fshader = glCreateShader(GL_FRAGMENT_SHADER)
fbuff = ctypes.create_string_buffer(fbuffer.read().encode())
ftext = ctypes.cast(ctypes.pointer(ctypes.pointer(fbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(fshader, 1, ftext, None)
glCompileShader(fshader)
glGetShaderiv(fshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Fragment Shader ", infoLog.value)
glAttachShader(self.program, vshader)
glAttachShader(self.program, fshader)
glLinkProgram(self.program)
glGetProgramiv(self.program, GL_LINK_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Program ", infoLog.value)
# clean up
glDeleteShader(vshader)
glDeleteShader(fshader)
vbuffer.close()
fbuffer.close()
def uniformMatrix4fv(self, key, count, transpose, value):
buff = ctypes.create_string_buffer(key.encode())
location = glGetUniformLocation(self.program, buff)
nvalue = np.array(value, GLfloat) # .flatten()
nref = nvalue.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
glUniformMatrix4fv(location, count, transpose, nref)
def use(self):
glUseProgram(self.program)
def destroy(self):
glDeleteProgram(self.program)
class Camera:
def __init__(self):
self.position = np.array((0.0, 1.0, 5.0))
self.front = np.array((0.0, 0.0, 0.0))
self.up = np.array((0.0, 1.0, 0.0))
self.yaw = -80.0
self.pitch = 0.0
self.sensitivity = 0.05
self.speed = 1.0
self.push_front()
def view(self):
return look_at(self.position, self.position + self.front, self.up)
def push_front(self):
self.front[0] = np.cos(np.radians(self.yaw)) * np.cos(np.radians(self.pitch))
self.front[1] = np.sin(np.radians(self.pitch))
self.front[2] = np.sin(np.radians(self.yaw)) * np.cos(np.radians(self.pitch))
def mouse_motion(self, dx, dy):
self.yaw += dx * self.sensitivity
self.yaw %= 360
self.pitch -= dy * self.sensitivity
if self.pitch > 89.0:
self.pitch = 89.0
if self.pitch < -89.0:
self.pitch = -89.0
self.push_front()
def movement(self, keys, dt):
if keys[pyglet.window.key.W]:
self.position += self.front * self.speed * dt
elif keys[pyglet.window.key.S]:
self.position -= self.front * self.speed * dt
if keys[pyglet.window.key.A]:
self.position -= normalized(np.cross(self.front, self.up)) * self.speed * dt
elif keys[pyglet.window.key.D]:
self.position += normalized(np.cross(self.front, self.up)) * self.speed * dt
if keys[pyglet.window.key.Q]:
self.yaw -= 20.0 * dt
self.push_front()
elif keys[pyglet.window.key.E]:
self.yaw += 20.0 * dt
self.push_front()
class CubeRandom:
def __init__(self, w, h):
ar = np.arange(0, 1, 0.1)
self.box = BoundingBox(np.random.choice(ar), np.random.choice(ar),
np.random.choice(ar), 0.1, 0.1, 0.1).astype(float)
speed = np.arange(0, 0.05, 0.002)
self.dir = np.array([np.random.choice(speed) for i in range(3)])
def move(self, screenbox):
screenbox = BoundingBox(0.0, 0.0, 0.0, 2.0, 2.0, 2.0)
self.box[:3] += self.dir
clamp = self.box.clamp_ip(screenbox)
if 'x' in clamp:
self.dir[0] = -self.dir[0]
if 'y' in clamp:
self.dir[1] = -self.dir[1]
if 'z' in clamp:
self.dir[2] = -self.dir[2]
class Window(pyglet.window.Window):
def __init__(self):
pyglet.window.Window.__init__(self)
self.context.config.alpha_size = 8
self.context.config.buffer_size = 32
self.context.config.sample_buffers = 1
self.context.config.samples = 4
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glClearColor(0.1, 0.0, 0.0, 1.0)
glViewport(0, 0, self.width, self.height)
self.set_exclusive_mouse(True)
self.camera = Camera()
self.model = matrix_idenity()
#self.view = camera.view()
self.projection = perspective(self.width, self.height, 45.0, 1.0, 100.0)
#self.mvp = self.projection * self.view * self.model
self.vertices = create_cube(0.1, element=False)
print("How many vertices.", len(self.vertices) / 3)
color_choice = [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0],
[1.0,0.0,1.0], [1.0,1.0,0.0], [0.0,0.5,1.0]]
colors = []
for i in range(6):
color = color_choice[i]
colors.extend(color + color + color + color + color + color)
self.colors = np.array(colors, GLfloat)
print("How many colors.", len(self.colors) / 3)
self.vao = GLuint()
glGenVertexArrays(1, self.vao)
glBindVertexArray(self.vao)
self.vbo = create_buffer(self.vertices.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.vbo.set_data(self.vertices.ctypes.data)
self.vbo.bind()
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
self.color_vbo = create_buffer(self.colors.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.color_vbo.set_data(self.colors.ctypes.data)
self.color_vbo.bind()
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys, self.on_mouse_motion)
self.tick = 0.0
self.shader = Shader('vshader.glsl', 'fshader.glsl')
pyglet.clock.schedule_interval(self.tick_update, 1.0 / 30.0)
self.screenbox = BoundingBox(0,0,10, self.width, self.height, 100)
self.cubes = [CubeRandom(self.width, self.height) for i in range(6)]
self.still_cubes = [(10,0,0), (0,10,0), (0,0,10), (-10,0,0), (0,-10,0), (0,0,-10),
(10,10,0), (10,0,10), (0,10,10), (-10,-10,0), (-10,0,-10), (0,-10,-10),]
def on_mouse_motion(self, x, y, dx, dy):
self.camera.mouse_motion(dx, dy)
def tick_update(self, dt):
self.tick += dt
self.camera.movement(self.keys, dt)
for cube in self.cubes:
cube.move(self.screenbox)
def on_draw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.shader.use()
#self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, self.mvp)
view = self.camera.view()
glBindVertexArray(self.vao);
for cube in self.cubes:
model = np.identity(4)
model[0::1, 3][:3] = cube.box[:3]
mvp = self.projection * view * np.matrix(model)
self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, mvp)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
for pos in self.still_cubes:
model = np.identity(4)
model[0::1, 3][:3] = pos
mvp = self.projection * view * np.matrix(model)
self.shader.uniformMatrix4fv('mvp', 1, GL_TRUE, mvp)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
glBindVertexArray(0)
def clean_up(self):
self.shader.destroy()
self.vbo.delete()
self.color_vbo.delete()
glDeleteVertexArrays(1, self.vao)
if __name__ == '__main__':
window = Window()
pyglet.app.run()
window.clean_up()
99 percent of computer problems exists between chair and keyboard.
Posts: 544
Threads: 15
Joined: Oct 2016
Improve pyglet example.
commonglet.py
import os
import ctypes
import pyglet
import numpy as np
from pyglet.gl import *
from glmath import normalize, GlMat
class VertexArray:
def __init__(self, size=1):
self.vao = GLuint(0)
self.size = size
glGenVertexArrays(size, self.vao)
def attribute(self, index, size, gl_type, gl_norm, stride, pointer):
glVertexAttribPointer(index, size, gl_type, gl_norm, stride, pointer)
glEnableVertexAttribArray(index)
def bind(self):
glBindVertexArray(self.vao)
def destroy(self):
glDeleteVertexArrays(self.size, self.vao)
def disable_attribute(self, n):
glDisableVertexAttribArray(n)
def enable_attribute(self, n):
glEnableVertexAttribArray(n)
def unbind(self):
glBindVertexArray(0)
class Shader:
def __init__(self, vstring, fstring):
self.program = GLuint(glCreateProgram())
if not os.path.exists(vstring):
print(vstring, "doesn't exists")
return
if not os.path.exists(fstring):
print(fstring, "doesn't exists")
return
vbuffer = open(vstring, 'r')
vshader = glCreateShader(GL_VERTEX_SHADER)
vbuff = ctypes.create_string_buffer(vbuffer.read().encode())
vtext = ctypes.cast(ctypes.pointer(ctypes.pointer(vbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(vshader, 1, vtext, None)
glCompileShader(vshader)
success = GLint()
infoLog = ctypes.create_string_buffer(512)
glGetShaderiv(vshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(vshader, 512, None, infoLog)
print("Error: Vertex Shader ", infoLog.value)
fbuffer = open(fstring, 'r')
fshader = glCreateShader(GL_FRAGMENT_SHADER)
fbuff = ctypes.create_string_buffer(fbuffer.read().encode())
ftext = ctypes.cast(ctypes.pointer(ctypes.pointer(fbuff)), ctypes.POINTER(ctypes.POINTER(GLchar)))
glShaderSource(fshader, 1, ftext, None)
glCompileShader(fshader)
glGetShaderiv(fshader, GL_COMPILE_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Fragment Shader ", infoLog.value)
glAttachShader(self.program, vshader)
glAttachShader(self.program, fshader)
glLinkProgram(self.program)
glGetProgramiv(self.program, GL_LINK_STATUS, ctypes.byref(success))
if not success:
glGetShaderInfoLog(fshader, 512, None, infoLog)
print("Error: Program ", infoLog.value)
# clean up
glDeleteShader(vshader)
glDeleteShader(fshader)
vbuffer.close()
fbuffer.close()
def uniformMatrix4fv(self, key, count, transpose, value):
buff = ctypes.create_string_buffer(key.encode())
location = glGetUniformLocation(self.program, buff)
nvalue = np.array(value, GLfloat) # .flatten()
nref = nvalue.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
glUniformMatrix4fv(location, count, transpose, nref)
def use(self):
glUseProgram(self.program)
def destroy(self):
glDeleteProgram(self.program)
class Camera:
def __init__(self,
position = np.array((0.0, 0.0, 5.0)),
yaw = -90,
pitch = 0,
roll = 0,
sensitivity = 0.05,
speed = 5.0,
turn = 70.0):
self.position = position
self.front = np.array((0,0,0), float)
self.top = np.array((0.0, 1.0, 0.0))
self.yaw = float(yaw)
self.pitch = float(pitch)
self.roll = float(roll)
self.sensitivity = sensitivity
self.speed = speed
self.turn = turn
self.update()
def view(self):
return GlMat.look_at(self.position, self.position + self.front, self.up)
def constrain_pitch(self):
if self.pitch > 89.0:
self.pitch = 89.0
if self.pitch < -89.0:
self.pitch = -89.0
def update(self):
self.front[0] = np.cos(np.radians(self.yaw)) * np.cos(np.radians(self.pitch))
self.front[1] = np.sin(np.radians(self.pitch))
self.front[2] = np.sin(np.radians(self.yaw)) * np.cos(np.radians(self.pitch))
self.front = normalize(self.front)
self.across = normalize(np.cross(self.front, self.top))
self.up = normalize(np.cross(self.across, self.front))
# roll
self.up[0] = np.sin(np.radians(self.roll)) * np.cos(np.radians(self.pitch))
self.up[1] = np.cos(np.radians(self.roll)) * np.cos(np.radians(self.pitch))
self.up[2] = np.sin(np.radians(self.pitch))
self.up = normalize(self.up)
def mouse_motion(self, dx, dy):
self.yaw += dx * self.sensitivity
self.yaw %= 360
self.pitch -= dy * self.sensitivity
self.constrain_pitch()
self.update()
def movement(self, keys, dt):
if keys[pyglet.window.key.SPACE]:
self.pitch = 0.0
self.roll = 0.0
self.update()
if keys[pyglet.window.key.W]:
self.position += self.front * self.speed * dt
elif keys[pyglet.window.key.S]:
self.position -= self.front * self.speed * dt
if keys[pyglet.window.key.A]:
self.position -= self.across * self.speed * dt
elif keys[pyglet.window.key.D]:
self.position += self.across * self.speed * dt
if keys[pyglet.window.key.Q]:
self.yaw -= self.turn * dt
self.update()
elif keys[pyglet.window.key.E]:
self.yaw += self.turn * dt
self.update()
def movement_plus(self, keys, dt):
self.movement(keys, dt)
# works but needs more testing
if keys[pyglet.window.key.Z]:
self.roll -= self.turn * dt
self.update()
elif keys[pyglet.window.key.X]:
self.roll += self.turn * dt
self.update()
if keys[pyglet.window.key.R]:
self.position += normalize(self.up) * self.speed * dt
elif keys[pyglet.window.key.F]:
self.position -= normalize(self.up) * self.speed * dt glmath.py
import numpy as np
import numpy.matlib as matlib
def normalize(array):
norm = np.linalg.norm(array)
if norm != 0:
return array / norm
return array
# row major, base on gl3n
class GlMat(np.matrix):
def __new__(cls, data=None, dtype=float):
if data is None:
data = matlib.identity(4, dtype)
return np.asmatrix(data, dtype).view(cls)
def identity(self):
self[:] = matlib.identity(4, self.dtype)
def translate(self, vec3):
for i in range(3):
self[i,3] += vec3[i]
def translation(self, vec3):
for i in range(3):
self[i,3] = vec3[i]
def rotate(self, alpha, x, y, z):
self[:] = GlMat.rotation(alpha, x, y, z) * self
def rotatex(self, alpha):
self[:] = GlMat.xrotation(alpha) * self
def rotatey(self, alpha):
self[:] = GlMat.yrotation(alpha) * self
def rotatez(self, alpha):
self[:] = GlMat.zrotation(alpha) * self
@staticmethod
def rotation(alpha, x, y, z):
mult = GlMat()
axis = normalize(np.array((x,y,z)))
cosa = np.cos(alpha)
sina = np.sin(alpha)
temp = np.array((1 - cosa) * axis)
mult[0,0] = temp[0] * axis[0] + cosa
mult[0,1] = temp[0] * axis[1] + sina * axis[2]
mult[0,2] = temp[0] * axis[2] - sina * axis[1]
mult[1,0] = temp[1] * axis[0] - sina * axis[2]
mult[1,1] = temp[1] * axis[1] + cosa
mult[1,2] = temp[1] * axis[2] + sina * axis[0]
mult[2,0] = temp[2] * axis[0] + sina * axis[1]
mult[2,1] = temp[2] * axis[1] - sina * axis[0]
mult[2,2] = temp[2] * axis[2] + cosa
return mult
@staticmethod
def xrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[1,1] = cosa
mult[1,2] = -sina
mult[2,1] = sina
mult[2,2] = cosa
return mult
@staticmethod
def yrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[0,0] = cosa
mult[0,2] = sina
mult[2,0] = -sina
mult[2,2] = cosa
return mult
@staticmethod
def zrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[0,0] = cosa
mult[0,1] = -sina
mult[1,0] = sina
mult[1,1] = cosa
return mult
@staticmethod
def perspective(width, height, fov, near, far):
mat = GlMat()
aspect = width/height
top = near * np.tan(fov * (np.pi/360.0))
bottom = -top
right = top * aspect
left = -right
mat[0,0] = (2 * near) / (right - left)
mat[0,2] = (right + left) / (right - left)
mat[1,1] = (2 * near) / (top - bottom)
mat[1,2] = (top + bottom) / (top - bottom)
mat[2,2] = -(far + near) / (far - near)
mat[2,3] = -(2 * far + near) / (far - near)
mat[3,2] = -1
return mat
@staticmethod
def look_at(eye, target, up):
look_dir = normalize(target - eye)
up_dir = normalize(up)
right_dir = normalize(np.cross(look_dir, up_dir))
perp_up_dir = np.cross(right_dir, look_dir)
mat = GlMat()
mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])
return mat
if __name__ == '__main__':
m = GlMat()
m.translate(np.array((1,2,3)))
m.rotatez(0.2)
print(m)
print(GlMat.rotation(0.5,0.1,0.2,0.3)) shapes.py
import numpy as np
import numpy.matlib as matlib
def normalize(array):
norm = np.linalg.norm(array)
if norm != 0:
return array / norm
return array
# row major, base on gl3n
class GlMat(np.matrix):
def __new__(cls, data=None, dtype=float):
if data is None:
data = matlib.identity(4, dtype)
return np.asmatrix(data, dtype).view(cls)
def identity(self):
self[:] = matlib.identity(4, self.dtype)
def translate(self, vec3):
for i in range(3):
self[i,3] += vec3[i]
def translation(self, vec3):
for i in range(3):
self[i,3] = vec3[i]
def rotate(self, alpha, x, y, z):
self[:] = GlMat.rotation(alpha, x, y, z) * self
def rotatex(self, alpha):
self[:] = GlMat.xrotation(alpha) * self
def rotatey(self, alpha):
self[:] = GlMat.yrotation(alpha) * self
def rotatez(self, alpha):
self[:] = GlMat.zrotation(alpha) * self
@staticmethod
def rotation(alpha, x, y, z):
mult = GlMat()
axis = normalize(np.array((x,y,z)))
cosa = np.cos(alpha)
sina = np.sin(alpha)
temp = np.array((1 - cosa) * axis)
mult[0,0] = temp[0] * axis[0] + cosa
mult[0,1] = temp[0] * axis[1] + sina * axis[2]
mult[0,2] = temp[0] * axis[2] - sina * axis[1]
mult[1,0] = temp[1] * axis[0] - sina * axis[2]
mult[1,1] = temp[1] * axis[1] + cosa
mult[1,2] = temp[1] * axis[2] + sina * axis[0]
mult[2,0] = temp[2] * axis[0] + sina * axis[1]
mult[2,1] = temp[2] * axis[1] - sina * axis[0]
mult[2,2] = temp[2] * axis[2] + cosa
return mult
@staticmethod
def xrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[1,1] = cosa
mult[1,2] = -sina
mult[2,1] = sina
mult[2,2] = cosa
return mult
@staticmethod
def yrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[0,0] = cosa
mult[0,2] = sina
mult[2,0] = -sina
mult[2,2] = cosa
return mult
@staticmethod
def zrotation(alpha):
mult = GlMat()
cosa = np.cos(alpha)
sina = np.sin(alpha)
mult[0,0] = cosa
mult[0,1] = -sina
mult[1,0] = sina
mult[1,1] = cosa
return mult
@staticmethod
def perspective(width, height, fov, near, far):
mat = GlMat()
aspect = width/height
top = near * np.tan(fov * (np.pi/360.0))
bottom = -top
right = top * aspect
left = -right
mat[0,0] = (2 * near) / (right - left)
mat[0,2] = (right + left) / (right - left)
mat[1,1] = (2 * near) / (top - bottom)
mat[1,2] = (top + bottom) / (top - bottom)
mat[2,2] = -(far + near) / (far - near)
mat[2,3] = -(2 * far + near) / (far - near)
mat[3,2] = -1
return mat
@staticmethod
def look_at(eye, target, up):
look_dir = normalize(target - eye)
up_dir = normalize(up)
right_dir = normalize(np.cross(look_dir, up_dir))
perp_up_dir = np.cross(right_dir, look_dir)
mat = GlMat()
mat[0] = np.append(right_dir, [-np.dot(eye, right_dir)])
mat[1] = np.append(perp_up_dir, [-np.dot(eye, perp_up_dir)])
mat[2] = np.append(-look_dir, [np.dot(eye, look_dir)])
return mat
if __name__ == '__main__':
m = GlMat()
m.translate(np.array((1,2,3)))
m.rotatez(0.2)
print(m)
print(GlMat.rotation(0.5,0.1,0.2,0.3)) cube.py main
import ctypes
import pyglet
import numpy as np
from pyglet.gl import *
from boundingbox import BoundingBox
from shapes import create_cube, Face
from glmath import GlMat, normalize
from commonglet import VertexArray, Shader, Camera
from pyglet.graphics.vertexbuffer import create_buffer
class CubeRandom:
def __init__(self):
ar = np.arange(-1, 1, 0.1)
self.box = BoundingBox(np.random.choice(ar), np.random.choice(ar),
np.random.choice(ar), 0.1, 0.1, 0.1).astype(float)
speed = np.arange(-0.05, 0.05, 0.002)
self.dir = np.array([np.random.choice(speed) for i in range(3)])
def move(self):
screenbox = BoundingBox(-5.0, -5.0, -5.0, 10.0, 10.0, 10.0)
self.box[:3] += self.dir
clamp = self.box.clamp_ip(screenbox)
if 'x' in clamp:
self.dir[0] = -self.dir[0]
if 'y' in clamp:
self.dir[1] = -self.dir[1]
if 'z' in clamp:
self.dir[2] = -self.dir[2]
class Window(pyglet.window.Window):
def __init__(self):
pyglet.window.Window.__init__(self)
self.set_location(100,100)
self._gl_setup()
self._cube_setup(0.2)
self.cube_shader = Shader('vshader.glsl', 'fshader.glsl')
pyglet.clock.schedule_interval(self.time_update, 1.0 / 30.0)
self.projection = GlMat.perspective(self.width, self.height, 45.0, 1.0, 100.0)
self.cubes = [CubeRandom() for i in range(10)]
self.set_exclusive_mouse(True)
self.camera = Camera(np.array((0, 0, 20), float))
self.keys = pyglet.window.key.KeyStateHandler()
self.push_handlers(self.keys, self.on_mouse_motion)
def on_mouse_motion(self, x, y, dx, dy):
self.camera.mouse_motion(dx, dy)
def time_update(self, dt):
self.camera.movement_plus(self.keys, dt)
for cube in self.cubes:
cube.move()
def _gl_setup(self):
self.context.config.alpha_size = 8
self.context.config.buffer_size = 32
self.context.config.sample_buffers = 1
self.context.config.samples = 4
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glClearColor(0.1, 0.0, 0.0, 1.0)
glViewport(0, 0, self.width, self.height)
def _cube_setup(self, size):
color_choice = [
[1.0,0.0,0.0],
[0.0,1.0,0.0],
[0.0,0.0,1.0],
[1.0,0.0,1.0],
[1.0,1.0,0.0],
[0.0,0.5,1.0]]
colors = []
for i in range(6):
color = color_choice[i]
colors.extend(color + color + color + color + color + color)
self.colors = np.array(colors, GLfloat)
self.vertices = create_cube(size, element=False)
self.cube_vao = VertexArray()
self.cube_vao.bind()
self.cube_vbo = create_buffer(self.vertices.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.cube_vbo.set_data(self.vertices.ctypes.data)
self.cube_vbo.bind()
self.cube_vao.attribute(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
self.cube_color_vbo = create_buffer(self.colors.nbytes, GL_ARRAY_BUFFER, GL_STATIC_DRAW)
self.cube_color_vbo.set_data(self.colors.ctypes.data)
self.cube_color_vbo.bind()
self.cube_vao.attribute(1, 3, GL_FLOAT, GL_FALSE, 0, 0)
self.cube_vao.unbind()
def on_draw(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.cube_shader.use()
self.cube_vao.bind()
for cube in self.cubes:
model = GlMat()
model.translate(cube.box[:3])
mvp = self.projection * self.camera.view() * model
self.cube_shader.uniformMatrix4fv('mvp', 1, GL_TRUE, mvp)
glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))
self.cube_vao.unbind()
def clean_up(self):
self.cube_vbo.delete()
self.cube_color_vbo.delete()
self.cube_shader.destroy()
self.cube_vao.destroy()
if __name__ == '__main__':
window = Window()
pyglet.app.run()
window.clean_up()
99 percent of computer problems exists between chair and keyboard.
|