mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Stop using OpenGL to do modelview matrices.
This commit is contained in:
parent
bfdefe43ef
commit
0607ab4d4c
|
@ -1,5 +1,8 @@
|
||||||
from math import sin, cos, radians, hypot
|
from math import sin, cos, radians, hypot
|
||||||
|
|
||||||
|
from punyverse.glgeom import Matrix4f
|
||||||
|
from punyverse.utils import cached_property
|
||||||
|
|
||||||
|
|
||||||
class Camera(object):
|
class Camera(object):
|
||||||
def __init__(self, x=0, y=0, z=0, pitch=0, yaw=0, roll=0):
|
def __init__(self, x=0, y=0, z=0, pitch=0, yaw=0, roll=0):
|
||||||
|
@ -20,6 +23,8 @@ class Camera(object):
|
||||||
self.y += dy * speed
|
self.y += dy * speed
|
||||||
self.z += dz * speed
|
self.z += dz * speed
|
||||||
|
|
||||||
|
self.view_matrix = None
|
||||||
|
|
||||||
def mouse_move(self, dx, dy):
|
def mouse_move(self, dx, dy):
|
||||||
if self.pitch > 90 or self.pitch < -90:
|
if self.pitch > 90 or self.pitch < -90:
|
||||||
dx = -dx
|
dx = -dx
|
||||||
|
@ -36,6 +41,8 @@ class Camera(object):
|
||||||
elif self.pitch > 180:
|
elif self.pitch > 180:
|
||||||
self.pitch -= 360
|
self.pitch -= 360
|
||||||
|
|
||||||
|
self.view_matrix = None
|
||||||
|
|
||||||
def direction(self):
|
def direction(self):
|
||||||
m = cos(radians(self.pitch))
|
m = cos(radians(self.pitch))
|
||||||
|
|
||||||
|
@ -46,14 +53,21 @@ class Camera(object):
|
||||||
|
|
||||||
def update(self, dt, move):
|
def update(self, dt, move):
|
||||||
if self.roll_left:
|
if self.roll_left:
|
||||||
self.roll += 4 * dt * 10
|
|
||||||
if self.roll:
|
|
||||||
self.roll -= 4 * dt * 10
|
self.roll -= 4 * dt * 10
|
||||||
|
self.view_matrix = None
|
||||||
|
if self.roll_right:
|
||||||
|
self.roll += 4 * dt * 10
|
||||||
|
self.view_matrix = None
|
||||||
if move:
|
if move:
|
||||||
self.move(self.speed * 10 * dt)
|
self.move(self.speed * 10 * dt)
|
||||||
|
|
||||||
def reset_roll(self):
|
def reset_roll(self):
|
||||||
self.roll = 0
|
self.roll = 0
|
||||||
|
self.view_matrix = None
|
||||||
|
|
||||||
def distance(self, x, y, z):
|
def distance(self, x, y, z):
|
||||||
return hypot(hypot(x - self.x, y - self.y), z - self.z)
|
return hypot(hypot(x - self.x, y - self.y), z - self.z)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def view_matrix(self):
|
||||||
|
return Matrix4f.from_angles((self.x, self.y, self.z), (self.pitch, self.yaw, self.roll), view=True)
|
||||||
|
|
|
@ -5,10 +5,11 @@ from pyglet.gl import *
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from six.moves import range
|
from six.moves import range
|
||||||
|
|
||||||
from punyverse.glgeom import compile, glMatrix, glRestore, belt, Sphere, Disk, OrbitVBO
|
from punyverse.glgeom import compile, glMatrix, glRestore, belt, Sphere, Disk, OrbitVBO, Matrix4f
|
||||||
from punyverse.model import load_model, WavefrontVBO
|
from punyverse.model import load_model, WavefrontVBO
|
||||||
from punyverse.orbit import KeplerOrbit
|
from punyverse.orbit import KeplerOrbit
|
||||||
from punyverse.texture import get_best_texture, load_clouds
|
from punyverse.texture import get_best_texture, load_clouds
|
||||||
|
from punyverse.utils import cached_property
|
||||||
|
|
||||||
G = 6.67384e-11 # Gravitation Constant
|
G = 6.67384e-11 # Gravitation Constant
|
||||||
|
|
||||||
|
@ -16,13 +17,19 @@ G = 6.67384e-11 # Gravitation Constant
|
||||||
class Entity(object):
|
class Entity(object):
|
||||||
background = False
|
background = False
|
||||||
|
|
||||||
def __init__(self, name, location, rotation=(0, 0, 0), direction=(0, 0, 0)):
|
def __init__(self, world, name, location, rotation=(0, 0, 0), direction=(0, 0, 0)):
|
||||||
|
self.world = world
|
||||||
self.name = name
|
self.name = name
|
||||||
self.location = location
|
self.location = location
|
||||||
self.rotation = rotation
|
self.rotation = rotation
|
||||||
self.direction = direction
|
self.direction = direction
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def mv_matrix(self):
|
||||||
|
return self.world.view_matrix() * Matrix4f.from_angles(self.location, self.rotation)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
self.mv_matrix = None
|
||||||
x, y, z = self.location
|
x, y, z = self.location
|
||||||
dx, dy, dz = self.direction
|
dx, dy, dz = self.direction
|
||||||
self.location = x + dx, y + dy, z + dz
|
self.location = x + dx, y + dy, z + dz
|
||||||
|
@ -35,24 +42,25 @@ class Entity(object):
|
||||||
|
|
||||||
|
|
||||||
class Asteroid(Entity):
|
class Asteroid(Entity):
|
||||||
def __init__(self, model, location, direction):
|
def __init__(self, world, model, location, direction):
|
||||||
super(Asteroid, self).__init__('Asteroid', location, direction=direction)
|
super(Asteroid, self).__init__(world, 'Asteroid', location, direction=direction)
|
||||||
self.model = model
|
self.model = model
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
super(Asteroid, self).update()
|
super(Asteroid, self).update()
|
||||||
|
|
||||||
rx, ry, rz = self.rotation
|
rx, ry, rz = self.rotation
|
||||||
# Increment all axis to 'spin'
|
# Increment all axis to 'spin'
|
||||||
self.rotation = rx + 1, ry + 1, rz + 1
|
self.rotation = rx + 1, ry + 1, rz + 1
|
||||||
|
|
||||||
def draw(self, options):
|
def draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation):
|
with glMatrix():
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
self.model.draw()
|
self.model.draw()
|
||||||
|
|
||||||
|
|
||||||
class AsteroidManager(object):
|
class AsteroidManager(object):
|
||||||
def __init__(self):
|
def __init__(self, world):
|
||||||
|
self.world = world
|
||||||
self.asteroids = []
|
self.asteroids = []
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
|
@ -60,16 +68,14 @@ class AsteroidManager(object):
|
||||||
__nonzero__ = __bool__
|
__nonzero__ = __bool__
|
||||||
|
|
||||||
def load(self, file):
|
def load(self, file):
|
||||||
self.asteroids.append(WavefrontVBO(load_model(file), 5, 5, 5, (0, 0, 0)))
|
self.asteroids.append(WavefrontVBO(load_model(file), 5, 5, 5))
|
||||||
|
|
||||||
def new(self, location, direction):
|
def new(self, location, direction):
|
||||||
return Asteroid(random.choice(self.asteroids), location, direction)
|
return Asteroid(self.world, random.choice(self.asteroids), location, direction)
|
||||||
|
|
||||||
|
|
||||||
class Belt(Entity):
|
class Belt(Entity):
|
||||||
def __init__(self, name, world, info):
|
def __init__(self, name, world, info):
|
||||||
self.world = world
|
|
||||||
|
|
||||||
x = world.evaluate(info.get('x', 0))
|
x = world.evaluate(info.get('x', 0))
|
||||||
y = world.evaluate(info.get('y', 0))
|
y = world.evaluate(info.get('y', 0))
|
||||||
z = world.evaluate(info.get('z', 0))
|
z = world.evaluate(info.get('z', 0))
|
||||||
|
@ -86,12 +92,12 @@ class Belt(Entity):
|
||||||
models = [models]
|
models = [models]
|
||||||
|
|
||||||
objects = [WavefrontVBO(load_model(model), info.get('sx', scale), info.get('sy', scale),
|
objects = [WavefrontVBO(load_model(model), info.get('sx', scale), info.get('sy', scale),
|
||||||
info.get('sz', scale), (0, 0, 0)) for model in models]
|
info.get('sz', scale)) for model in models]
|
||||||
|
|
||||||
self.belt_id = compile(belt, radius, cross, objects, count)
|
self.belt_id = compile(belt, radius, cross, objects, count)
|
||||||
self.rotation_angle = 360.0 / rotation if rotation else 0
|
self.rotation_angle = 360.0 / rotation if rotation else 0
|
||||||
|
|
||||||
super(Belt, self).__init__(name, (x, y, z), (inclination, longitude, argument))
|
super(Belt, self).__init__(world, name, (x, y, z), (inclination, longitude, argument))
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
super(Belt, self).update()
|
super(Belt, self).update()
|
||||||
|
@ -99,7 +105,8 @@ class Belt(Entity):
|
||||||
self.rotation = pitch, self.world.tick * self.rotation_angle % 360, roll
|
self.rotation = pitch, self.world.tick * self.rotation_angle % 360, roll
|
||||||
|
|
||||||
def draw(self, options):
|
def draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_CURRENT_BIT):
|
with glMatrix(), glRestore(GL_CURRENT_BIT):
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
glCallList(self.belt_id)
|
glCallList(self.belt_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,8 +118,7 @@ class Sky(Entity):
|
||||||
yaw = world.evaluate(info.get('yaw', 0))
|
yaw = world.evaluate(info.get('yaw', 0))
|
||||||
roll = world.evaluate(info.get('roll', 0))
|
roll = world.evaluate(info.get('roll', 0))
|
||||||
|
|
||||||
super(Sky, self).__init__('Sky', (0, 0, 0), (pitch, yaw, roll))
|
super(Sky, self).__init__(world, 'Sky', (0, 0, 0), (pitch, yaw, roll))
|
||||||
self.world = world
|
|
||||||
|
|
||||||
self.texture = get_best_texture(info['texture'])
|
self.texture = get_best_texture(info['texture'])
|
||||||
division = info.get('division', 30)
|
division = info.get('division', 30)
|
||||||
|
@ -120,7 +126,9 @@ class Sky(Entity):
|
||||||
|
|
||||||
def draw(self, options):
|
def draw(self, options):
|
||||||
cam = self.world.cam
|
cam = self.world.cam
|
||||||
with glMatrix((-cam.x, -cam.y, -cam.z), self.rotation), glRestore(GL_TEXTURE_BIT | GL_ENABLE_BIT):
|
with glMatrix(), glRestore(GL_TEXTURE_BIT | GL_ENABLE_BIT):
|
||||||
|
matrix = self.world.view_matrix() * Matrix4f.from_angles((-cam.x, -cam.y, -cam.z), self.rotation)
|
||||||
|
glLoadMatrixf(matrix.as_gl())
|
||||||
glEnable(GL_CULL_FACE)
|
glEnable(GL_CULL_FACE)
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
|
@ -132,7 +140,6 @@ class Sky(Entity):
|
||||||
|
|
||||||
class Body(Entity):
|
class Body(Entity):
|
||||||
def __init__(self, name, world, info, parent=None):
|
def __init__(self, name, world, info, parent=None):
|
||||||
self.world = world
|
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.satellites = []
|
self.satellites = []
|
||||||
|
|
||||||
|
@ -151,7 +158,7 @@ class Body(Entity):
|
||||||
self.orbit_blend = orbit_distance / 4
|
self.orbit_blend = orbit_distance / 4
|
||||||
self.orbit_opaque = orbit_distance
|
self.orbit_opaque = orbit_distance
|
||||||
|
|
||||||
super(Body, self).__init__(name, (x, y, z), (pitch, yaw, roll))
|
super(Body, self).__init__(world, name, (x, y, z), (pitch, yaw, roll))
|
||||||
self.initial_roll = roll
|
self.initial_roll = roll
|
||||||
|
|
||||||
self.orbit = None
|
self.orbit = None
|
||||||
|
@ -180,17 +187,23 @@ class Body(Entity):
|
||||||
self.orbit_vbo = None
|
self.orbit_vbo = None
|
||||||
self.orbit_cache = None
|
self.orbit_cache = None
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def orbit_matrix(self):
|
||||||
|
return self.world.view_matrix() * Matrix4f.from_angles(self.location)
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
super(Body, self).update()
|
super(Body, self).update()
|
||||||
|
|
||||||
pitch, yaw, roll = self.rotation
|
if self.rotation_angle:
|
||||||
roll = (self.initial_roll + self.world.tick * self.rotation_angle) % 360
|
pitch, yaw, roll = self.rotation
|
||||||
self.rotation = pitch, yaw, roll
|
roll = (self.initial_roll + self.world.tick * self.rotation_angle) % 360
|
||||||
|
self.rotation = pitch, yaw, roll
|
||||||
|
|
||||||
if self.orbit:
|
if self.orbit:
|
||||||
px, py, pz = self.parent.location
|
px, py, pz = self.parent.location
|
||||||
x, z, y = self.orbit.orbit(self.world.tick * self.orbit_speed % 360)
|
x, z, y = self.orbit.orbit(self.world.tick * self.orbit_speed % 360)
|
||||||
self.location = (x + px, y + py, z + pz)
|
self.location = (x + px, y + py, z + pz)
|
||||||
|
self.orbit_matrix = None
|
||||||
|
|
||||||
for satellite in self.satellites:
|
for satellite in self.satellites:
|
||||||
satellite.update()
|
satellite.update()
|
||||||
|
@ -212,7 +225,9 @@ class Body(Entity):
|
||||||
return self.orbit_vbo
|
return self.orbit_vbo
|
||||||
|
|
||||||
def _draw_orbits(self, distance):
|
def _draw_orbits(self, distance):
|
||||||
with glMatrix(self.parent.location), glRestore(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT):
|
with glMatrix(), glRestore(GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT):
|
||||||
|
glLoadMatrixf(self.parent.orbit_matrix.as_gl())
|
||||||
|
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
solid = distance < self.parent.orbit_opaque
|
solid = distance < self.parent.orbit_opaque
|
||||||
glColor4f(1, 1, 1, 1 if solid else (1 - (distance - self.parent.orbit_opaque) / self.parent.orbit_blend))
|
glColor4f(1, 1, 1, 1 if solid else (1 - (distance - self.parent.orbit_opaque) / self.parent.orbit_blend))
|
||||||
|
@ -284,7 +299,8 @@ class SphericalBody(Body):
|
||||||
self.ring = Disk(distance, distance + size, 30)
|
self.ring = Disk(distance, distance + size, 30)
|
||||||
|
|
||||||
def _draw_sphere(self, fv4=GLfloat * 4):
|
def _draw_sphere(self, fv4=GLfloat * 4):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
with glMatrix(), glRestore(GL_LIGHTING_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
glEnable(GL_CULL_FACE)
|
glEnable(GL_CULL_FACE)
|
||||||
glCullFace(GL_BACK)
|
glCullFace(GL_BACK)
|
||||||
|
|
||||||
|
@ -301,14 +317,11 @@ class SphericalBody(Body):
|
||||||
|
|
||||||
self.sphere.draw()
|
self.sphere.draw()
|
||||||
|
|
||||||
def _draw_atmosphere(self, glMatrixBuffer=GLfloat * 16):
|
def _draw_atmosphere(self):
|
||||||
with glMatrix(self.location), glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT):
|
with glMatrix(), glRestore(GL_ENABLE_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT):
|
||||||
matrix = glMatrixBuffer()
|
mv = self.mv_matrix.matrix
|
||||||
glGetFloatv(GL_MODELVIEW_MATRIX, matrix)
|
matrix = Matrix4f([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, mv[12], mv[13], mv[14], 1])
|
||||||
matrix[0: 3] = [1, 0, 0]
|
glLoadMatrixf(matrix.as_gl())
|
||||||
matrix[4: 7] = [0, 1, 0]
|
|
||||||
matrix[8:11] = [0, 0, 1]
|
|
||||||
glLoadMatrixf(matrix)
|
|
||||||
|
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
|
@ -319,7 +332,8 @@ class SphericalBody(Body):
|
||||||
self.atmosphere.draw()
|
self.atmosphere.draw()
|
||||||
|
|
||||||
def _draw_clouds(self):
|
def _draw_clouds(self):
|
||||||
with glMatrix(self.location, self.rotation), glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
with glMatrix(), glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
glEnable(GL_BLEND)
|
glEnable(GL_BLEND)
|
||||||
glEnable(GL_ALPHA_TEST)
|
glEnable(GL_ALPHA_TEST)
|
||||||
glEnable(GL_CULL_FACE)
|
glEnable(GL_CULL_FACE)
|
||||||
|
@ -331,7 +345,8 @@ class SphericalBody(Body):
|
||||||
self.clouds.draw()
|
self.clouds.draw()
|
||||||
|
|
||||||
def _draw_rings(self):
|
def _draw_rings(self):
|
||||||
with glMatrix(self.location, self.ring_rotation), glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
with glMatrix(), glRestore(GL_ENABLE_BIT | GL_TEXTURE_BIT):
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
glDisable(GL_LIGHTING)
|
glDisable(GL_LIGHTING)
|
||||||
glEnable(GL_TEXTURE_2D)
|
glEnable(GL_TEXTURE_2D)
|
||||||
glEnable(GL_BLEND)
|
glEnable(GL_BLEND)
|
||||||
|
@ -365,8 +380,9 @@ class ModelBody(Body):
|
||||||
|
|
||||||
scale = info.get('scale', 1)
|
scale = info.get('scale', 1)
|
||||||
self.vbo = WavefrontVBO(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
self.vbo = WavefrontVBO(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
||||||
info.get('sz', scale), (0, 0, 0))
|
info.get('sz', scale))
|
||||||
|
|
||||||
def _draw(self, options):
|
def _draw(self, options):
|
||||||
with glMatrix(self.location, self.rotation):
|
with glMatrix():
|
||||||
|
glLoadMatrixf(self.mv_matrix.as_gl())
|
||||||
self.vbo.draw()
|
self.vbo.draw()
|
||||||
|
|
|
@ -99,6 +99,59 @@ def array_to_gl_buffer(buffer, array_type='f'):
|
||||||
return vbo.value
|
return vbo.value
|
||||||
|
|
||||||
|
|
||||||
|
class Matrix4f(object):
|
||||||
|
def __init__(self, matrix):
|
||||||
|
self.matrix = array('f', matrix)
|
||||||
|
assert len(self.matrix) == 16
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_angles(cls, location=(0, 0, 0), rotation=(0, 0, 0), view=False):
|
||||||
|
m = [0] * 16
|
||||||
|
x, y, z = location
|
||||||
|
pitch, yaw, roll = rotation
|
||||||
|
sp, sy, sr = sin(radians(pitch)), sin(radians(yaw)), sin(radians(roll))
|
||||||
|
cp, cy, cr = cos(radians(pitch)), cos(radians(yaw)), cos(radians(roll))
|
||||||
|
|
||||||
|
m[0x0] = cy * cr
|
||||||
|
m[0x1] = sp * sy * cr + cp * sr
|
||||||
|
m[0x2] = sp * sr - cp * sy * cr
|
||||||
|
m[0x3] = 0
|
||||||
|
m[0x4] = -cy * sr
|
||||||
|
m[0x5] = cp * cr - sp * sy * sr
|
||||||
|
m[0x6] = cp * sy * sr + sp * cr
|
||||||
|
m[0x7] = 0
|
||||||
|
m[0x8] = sy
|
||||||
|
m[0x9] = -sp * cy
|
||||||
|
m[0xA] = cp * cy
|
||||||
|
m[0xB] = 0
|
||||||
|
if view:
|
||||||
|
m[0xC] = m[0x0] * -x + m[0x4] * -y + m[0x8] * -z
|
||||||
|
m[0xD] = m[0x1] * -x + m[0x5] * -y + m[0x9] * -z
|
||||||
|
m[0xE] = m[0x2] * -x + m[0x6] * -y + m[0xA] * -z
|
||||||
|
else:
|
||||||
|
m[0xC] = x
|
||||||
|
m[0xD] = y
|
||||||
|
m[0xE] = z
|
||||||
|
m[0xF] = 1
|
||||||
|
return cls(m)
|
||||||
|
|
||||||
|
def as_gl(self):
|
||||||
|
return array_to_ctypes(self.matrix)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bytes(self):
|
||||||
|
return self.matrix.itemsize * 16
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
if not isinstance(other, Matrix4f):
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
rows = ((0, 4, 8, 12), (1, 5, 9, 13), (2, 6, 10, 14), (3, 7, 11, 15))
|
||||||
|
cols = ((0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15))
|
||||||
|
a, b = self.matrix, other.matrix
|
||||||
|
return type(self)(sum(a[i] * b[j] for i, j in zip(r, c)) for c in cols for r in rows)
|
||||||
|
|
||||||
|
|
||||||
def compile(pointer, *args, **kwargs):
|
def compile(pointer, *args, **kwargs):
|
||||||
display = glGenLists(1)
|
display = glGenLists(1)
|
||||||
glNewList(display, GL_COMPILE)
|
glNewList(display, GL_COMPILE)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from pyglet.gl import *
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
from six.moves import range, zip
|
from six.moves import range, zip
|
||||||
|
|
||||||
from punyverse.glgeom import array_to_gl_buffer, glRestoreClient, glMatrix, glRestore
|
from punyverse.glgeom import array_to_gl_buffer, glRestoreClient, glRestore
|
||||||
from punyverse.texture import load_texture
|
from punyverse.texture import load_texture
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,10 +221,9 @@ class ModelVBO(object):
|
||||||
|
|
||||||
|
|
||||||
class WavefrontVBO(object):
|
class WavefrontVBO(object):
|
||||||
def __init__(self, model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
def __init__(self, model, sx=1, sy=1, sz=1):
|
||||||
self._tex_cache = {}
|
self._tex_cache = {}
|
||||||
self.vbos = []
|
self.vbos = []
|
||||||
self.rotation = rotation
|
|
||||||
self.scale = (sx, sy, sz)
|
self.scale = (sx, sy, sz)
|
||||||
|
|
||||||
for m, material in six.iteritems(model.materials):
|
for m, material in six.iteritems(model.materials):
|
||||||
|
@ -239,7 +238,7 @@ class WavefrontVBO(object):
|
||||||
self.vbos.append((group.material, self.process_group(group, vertices, normals, textures)))
|
self.vbos.append((group.material, self.process_group(group, vertices, normals, textures)))
|
||||||
|
|
||||||
def draw(self, fv4=GLfloat * 4):
|
def draw(self, fv4=GLfloat * 4):
|
||||||
with glMatrix(rotation=self.rotation), glRestore(GL_TEXTURE_BIT | GL_ENABLE_BIT):
|
with glRestore(GL_TEXTURE_BIT | GL_ENABLE_BIT):
|
||||||
for mat, vbo in self.vbos:
|
for mat, vbo in self.vbos:
|
||||||
tex_id = self._tex_cache[mat.texture] if mat and mat.texture else 0
|
tex_id = self._tex_cache[mat.texture] if mat and mat.texture else 0
|
||||||
|
|
||||||
|
|
|
@ -236,14 +236,10 @@ class Punyverse(pyglet.window.Window):
|
||||||
|
|
||||||
def on_draw(self):
|
def on_draw(self):
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
|
||||||
glLoadIdentity()
|
glLoadMatrixf(self.world.view_matrix().as_gl())
|
||||||
|
|
||||||
c = self.world.cam
|
c = self.world.cam
|
||||||
x, y, z = c.x, c.y, c.z
|
x, y, z = c.x, c.y, c.z
|
||||||
glRotatef(c.pitch, 1, 0, 0)
|
|
||||||
glRotatef(c.yaw, 0, 1, 0)
|
|
||||||
glRotatef(c.roll, 0, 0, 1)
|
|
||||||
glTranslatef(-x, -y, -z)
|
|
||||||
|
|
||||||
glEnable(GL_LIGHTING)
|
glEnable(GL_LIGHTING)
|
||||||
world = self.world
|
world = self.world
|
||||||
|
|
18
punyverse/utils.py
Normal file
18
punyverse/utils.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
class cached_property(object):
|
||||||
|
def __init__(self, func, name=None):
|
||||||
|
self.func = func
|
||||||
|
self.name = name or func.__name__
|
||||||
|
self.__doc__ = getattr(func, '__doc__')
|
||||||
|
|
||||||
|
def __get__(self, instance, owner=None):
|
||||||
|
if instance is None:
|
||||||
|
return self
|
||||||
|
result = instance.__dict__[self.name] = self.func(instance)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def __set__(self, instance, value):
|
||||||
|
if value is None:
|
||||||
|
if self.name in instance.__dict__:
|
||||||
|
del instance.__dict__[self.name]
|
||||||
|
else:
|
||||||
|
instance.__dict__[self.name] = value
|
|
@ -23,7 +23,7 @@ class World(object):
|
||||||
self.z = None
|
self.z = None
|
||||||
self.tick_length = 0
|
self.tick_length = 0
|
||||||
self.tick = 0
|
self.tick = 0
|
||||||
self.asteroids = AsteroidManager()
|
self.asteroids = AsteroidManager(self)
|
||||||
self.cam = Camera()
|
self.cam = Camera()
|
||||||
|
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
@ -143,3 +143,6 @@ class World(object):
|
||||||
c.move(c.speed * 12 * dt)
|
c.move(c.speed * 12 * dt)
|
||||||
else:
|
else:
|
||||||
self._time_accumulate += delta
|
self._time_accumulate += delta
|
||||||
|
|
||||||
|
def view_matrix(self):
|
||||||
|
return self.cam.view_matrix
|
||||||
|
|
Loading…
Reference in a new issue