mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Punyverse 0.3: adding Python 3 support.
This commit is contained in:
parent
bb928b6c55
commit
b4dce48fa7
|
@ -8,7 +8,7 @@ Python simulator of a puny universe. (How many words can I stick into one?)
|
|||
Installation
|
||||
------------
|
||||
|
||||
Currently, only Python 2 on Windows is supported.
|
||||
Currently, only Windows is supported.
|
||||
|
||||
To install, run `pip install punyverse`.
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ def main():
|
|||
raise SystemExit('Graphics configuration not supported.')
|
||||
else:
|
||||
if hasattr(config, '_attribute_names'):
|
||||
print 'OpenGL configuration:'
|
||||
print('OpenGL configuration:')
|
||||
for key in config._attribute_names:
|
||||
print ' %-17s %s' % (key + ':', getattr(config, key))
|
||||
print(' %-17s %s' % (key + ':', getattr(config, key)))
|
||||
|
||||
world_options = {
|
||||
'normal': args.normal,
|
||||
|
|
|
@ -41,11 +41,11 @@ cdef class Face(object):
|
|||
self.textures = textures
|
||||
|
||||
cdef class Material(object):
|
||||
cdef public str name, texture
|
||||
cdef public unicode name, texture
|
||||
cdef public tuple Ka, Kd, Ks
|
||||
cdef public double shininess
|
||||
|
||||
def __init__(self, str name, str texture=None, tuple Ka=(0, 0, 0),
|
||||
def __init__(self, unicode name, unicode texture=None, tuple Ka=(0, 0, 0),
|
||||
tuple Kd=(0, 0, 0), tuple Ks=(0, 0, 0), double shininess=0.0):
|
||||
self.name = name
|
||||
self.texture = texture
|
||||
|
@ -55,15 +55,15 @@ cdef class Material(object):
|
|||
self.shininess = shininess
|
||||
|
||||
cdef class Group(object):
|
||||
cdef public str name
|
||||
cdef public unicode name
|
||||
cdef public tuple min
|
||||
cdef public Material material
|
||||
cdef public list faces, indices, vertices, normals, textures
|
||||
cdef public int idx_count
|
||||
|
||||
def __init__(self, str name=None):
|
||||
def __init__(self, unicode name=None):
|
||||
if name is None:
|
||||
self.name = str(uuid4())
|
||||
self.name = unicode(uuid4())
|
||||
else:
|
||||
self.name = name
|
||||
self.min = ()
|
||||
|
@ -103,8 +103,9 @@ cdef class WavefrontObject(object):
|
|||
self.perform_io(self.path)
|
||||
|
||||
cdef void new_material(self, list words):
|
||||
material = Material(words[1])
|
||||
self.materials[words[1]] = material
|
||||
name = words[1].decode('utf-8')
|
||||
material = Material(name)
|
||||
self.materials[name] = material
|
||||
self.current_material = material
|
||||
|
||||
cdef void Ka(self, list words):
|
||||
|
@ -120,7 +121,7 @@ cdef class WavefrontObject(object):
|
|||
self.current_material.shininess = min(float(words[1]), 125)
|
||||
|
||||
cdef void material_texture(self, list words):
|
||||
self.current_material.texture = words[-1]
|
||||
self.current_material.texture = words[-1].decode('utf-8')
|
||||
|
||||
@cython.nonecheck(False)
|
||||
cdef void vertex(self, list words):
|
||||
|
@ -157,7 +158,7 @@ cdef class WavefrontObject(object):
|
|||
cdef list raw_faces, vindices = [], nindices = [], tindices = []
|
||||
|
||||
for i in xrange(1, vertex_count + 1):
|
||||
raw_faces = words[i].split('/')
|
||||
raw_faces = words[i].split(b'/')
|
||||
l = len(raw_faces)
|
||||
|
||||
current_value = int(raw_faces[0])
|
||||
|
@ -193,10 +194,10 @@ cdef class WavefrontObject(object):
|
|||
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
||||
|
||||
cdef bint material(self, list words) except False:
|
||||
return self.perform_io(os.path.join(self.root, words[1]))
|
||||
return self.perform_io(os.path.join(self.root, words[1].decode('utf-8')))
|
||||
|
||||
cdef void use_material(self, list words):
|
||||
mat = words[1]
|
||||
mat = words[1].decode('utf-8')
|
||||
try:
|
||||
self.current_group.material = self.materials[mat]
|
||||
except KeyError:
|
||||
|
@ -205,7 +206,7 @@ cdef class WavefrontObject(object):
|
|||
print "Warning: no group"
|
||||
|
||||
cdef void group(self, list words):
|
||||
name = words[1]
|
||||
name = words[1].decode('utf-8')
|
||||
group = Group(name)
|
||||
|
||||
if self.groups:
|
||||
|
@ -219,10 +220,10 @@ cdef class WavefrontObject(object):
|
|||
cdef int hash, length
|
||||
|
||||
ext = os.path.splitext(file)[1].lstrip('.')
|
||||
reader = openers.get(ext, open)(file)
|
||||
reader = openers.get(ext, lambda x: open(x, 'rb'))(file)
|
||||
with reader:
|
||||
for buf in reader:
|
||||
if not buf or buf.startswith(('\r', '\n', '#')):
|
||||
if not buf or buf.startswith((b'\r', b'\n', b'#')):
|
||||
continue # Empty or comment
|
||||
words = buf.split()
|
||||
type = words[0]
|
||||
|
@ -267,10 +268,6 @@ model_base = None
|
|||
def load_model(path):
|
||||
global model_base
|
||||
if model_base is None:
|
||||
import sys
|
||||
if hasattr(sys, 'frozen'):
|
||||
model_base = os.path.dirname(sys.executable)
|
||||
else:
|
||||
model_base = os.path.join(os.path.dirname(__file__), 'assets', 'models')
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(model_base, path)
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
from math import sqrt
|
||||
|
||||
from punyverse.orbit import KeplerOrbit
|
||||
from six.moves import range
|
||||
from pyglet.gl import *
|
||||
|
||||
from punyverse.orbit import KeplerOrbit
|
||||
|
||||
|
||||
class Entity(object):
|
||||
def __init__(self, id, location, rotation=(0, 0, 0), direction=(0, 0, 0), background=False):
|
||||
|
@ -118,7 +120,7 @@ class Satellite(Body):
|
|||
id = glGenLists(1)
|
||||
glNewList(id, GL_COMPILE)
|
||||
glBegin(GL_LINE_LOOP)
|
||||
for theta in xrange(360):
|
||||
for theta in range(360):
|
||||
x, z, y = self.orbit.orbit(theta)
|
||||
glVertex3f(x, y, z)
|
||||
glEnd()
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
from operator import attrgetter
|
||||
from math import hypot, sqrt, atan2, degrees
|
||||
from time import clock
|
||||
from itertools import izip_longest
|
||||
import time
|
||||
import random
|
||||
import os
|
||||
|
||||
import six
|
||||
|
||||
from punyverse.camera import Camera
|
||||
from punyverse.world import World
|
||||
from punyverse.glgeom import *
|
||||
|
@ -18,6 +19,11 @@ try:
|
|||
except ImportError:
|
||||
from punyverse.model import model_list, load_model
|
||||
|
||||
try:
|
||||
from itertools import zip_longest
|
||||
except ImportError:
|
||||
from itertools import izip_longest as zip_longest
|
||||
|
||||
from pyglet.gl import *
|
||||
from pyglet.window import key, mouse
|
||||
|
||||
|
@ -50,7 +56,7 @@ class Applet(pyglet.window.Window):
|
|||
info = [' %-22s %s' % (key + ':', getattr(self.config, key))
|
||||
for key in self.config._attribute_names]
|
||||
info = ['%-30s %-30s' % group for group in
|
||||
izip_longest(info[::2], info[1::2], fillvalue='')]
|
||||
zip_longest(info[::2], info[1::2], fillvalue='')]
|
||||
info = 'OpenGL configuration:\n' + '\n'.join(info)
|
||||
else:
|
||||
info = 'Unknown OpenGL configuration'
|
||||
|
@ -89,7 +95,7 @@ class Applet(pyglet.window.Window):
|
|||
self.fps = 0
|
||||
self.world = World('world.json', callback, self.world_options)
|
||||
phase = 'Initializing game...'
|
||||
print phase
|
||||
print(phase)
|
||||
callback(phase, '', 0)
|
||||
self.speed = INITIAL_SPEED
|
||||
self.keys = set()
|
||||
|
@ -158,7 +164,6 @@ class Applet(pyglet.window.Window):
|
|||
key.C: attribute_toggler(self, 'cloud'),
|
||||
key.X: attribute_toggler(self, 'atmosphere'),
|
||||
key.ENTER: attribute_toggler(self, 'running'),
|
||||
#key.Q: self.screenshot,
|
||||
key.INSERT: increment_tick,
|
||||
key.DELETE: decrement_tick,
|
||||
key.SPACE: self.launch_meteor,
|
||||
|
@ -203,7 +208,7 @@ class Applet(pyglet.window.Window):
|
|||
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
||||
|
||||
phase = 'Loading asteroids...'
|
||||
print phase
|
||||
print(phase)
|
||||
|
||||
def load_asteroids(files):
|
||||
for id, file in enumerate(files):
|
||||
|
@ -217,12 +222,12 @@ class Applet(pyglet.window.Window):
|
|||
c.pitch, c.yaw, c.roll = self.world.direction
|
||||
|
||||
phase = 'Updating entities...'
|
||||
print phase
|
||||
print(phase)
|
||||
callback(phase, '', 0)
|
||||
for entity in self.world.tracker:
|
||||
entity.update()
|
||||
|
||||
print 'Loaded in %s seconds.' % (clock() - start)
|
||||
print('Loaded in %s seconds.' % (clock() - start))
|
||||
self.loaded = True
|
||||
pyglet.clock.schedule(self.update)
|
||||
self.on_resize(self.width, self.height) # On resize handler does nothing unless it's loaded
|
||||
|
@ -235,13 +240,13 @@ class Applet(pyglet.window.Window):
|
|||
import tempfile
|
||||
CF_BITMAP = 2
|
||||
|
||||
image = Image.fromstring(image.format, (image.width, image.height), image.get_image_data().data)
|
||||
image = Image.frombytes(image.format, (image.width, image.height), image.get_image_data().data)
|
||||
image = image.convert('RGB').transpose(Image.FLIP_TOP_BOTTOM)
|
||||
fd, filename = tempfile.mkstemp('.bmp')
|
||||
try:
|
||||
with os.fdopen(fd, 'w') as file:
|
||||
with os.fdopen(fd, 'wb') as file:
|
||||
image.save(file, 'BMP')
|
||||
if not isinstance(filename, unicode):
|
||||
if isinstance(filename, six.binary_type):
|
||||
filename = filename.decode('mbcs')
|
||||
image = windll.user32.LoadImageW(None, filename, 0, 0, 0, 0x10)
|
||||
windll.user32.OpenClipboard(self._hwnd)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
from math import *
|
||||
from pyglet.gl import *
|
||||
from random import random, gauss, choice
|
||||
|
||||
from six.moves import range
|
||||
from pyglet.gl import *
|
||||
from pyglet.gl.gl_info import have_extension
|
||||
|
||||
TWOPI = pi * 2
|
||||
|
@ -68,7 +70,8 @@ def frustrum():
|
|||
glEnable(GL_DEPTH_TEST)
|
||||
|
||||
|
||||
def crosshair(size, (cx, cy)):
|
||||
def crosshair(size, coords):
|
||||
cx, cy = coords
|
||||
with glSection(GL_LINES):
|
||||
glVertex2f(cx - size, cy)
|
||||
glVertex2f(cx + size, cy)
|
||||
|
@ -76,9 +79,10 @@ def crosshair(size, (cx, cy)):
|
|||
glVertex2f(cx, cy + size)
|
||||
|
||||
|
||||
def circle(r, seg, (cx, cy)):
|
||||
def circle(r, seg, coords):
|
||||
cx, cy = coords
|
||||
with glSection(GL_LINE_LOOP):
|
||||
for i in xrange(seg):
|
||||
for i in range(seg):
|
||||
theta = TWOPI * i / seg
|
||||
glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r)
|
||||
|
||||
|
@ -95,7 +99,7 @@ def disk(rinner, router, segs, tex):
|
|||
with glSection(GL_TRIANGLE_STRIP):
|
||||
factor = TWOPI / res
|
||||
theta = 0
|
||||
for n in xrange(res + 1):
|
||||
for n in range(res + 1):
|
||||
theta += factor
|
||||
x = cos(theta)
|
||||
y = sin(theta)
|
||||
|
@ -117,7 +121,7 @@ def flare(rinner, router, res, prob, tex):
|
|||
factor = TWOPI / res
|
||||
rdelta = (router - rinner)
|
||||
with glSection(GL_QUADS):
|
||||
for i in xrange(res + 1):
|
||||
for i in range(res + 1):
|
||||
theta = last_theta + factor
|
||||
x = cos(theta)
|
||||
y = sin(theta)
|
||||
|
@ -192,7 +196,7 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
|||
if (not have_extension('GL_ARB_multitexture') or not
|
||||
have_extension('GL_ARB_texture_env_combine') or not
|
||||
have_extension('GL_EXT_texture_env_dot3')):
|
||||
print 'No hardware normal mapping support. No bumping for you.'
|
||||
print('No hardware normal mapping support. No bumping for you.')
|
||||
return sphere(r, divide, divide, tex, lighting)
|
||||
|
||||
from texture import load_texture
|
||||
|
@ -228,11 +232,11 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
|||
twopi_divide = TWOPI / divide
|
||||
pi_divide = pi / divide
|
||||
with glSection(GL_TRIANGLE_STRIP):
|
||||
for j in xrange(divide + 1):
|
||||
for j in range(divide + 1):
|
||||
phi1 = j * twopi_divide
|
||||
phi2 = (j + 1) * twopi_divide
|
||||
|
||||
for i in xrange(divide + 1):
|
||||
for i in range(divide + 1):
|
||||
theta = i * pi_divide
|
||||
|
||||
s = phi2 / TWOPI
|
||||
|
@ -252,7 +256,7 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
|||
|
||||
|
||||
def belt(radius, cross, object, count):
|
||||
for i in xrange(count):
|
||||
for i in range(count):
|
||||
theta = TWOPI * random()
|
||||
r = gauss(radius, cross)
|
||||
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
|
||||
|
@ -285,7 +289,7 @@ except ImportError:
|
|||
m = 1.0 / sqrt(x * x + y * y + z * z)
|
||||
return x * m, y * m, z * m
|
||||
|
||||
for i in xrange(n_major):
|
||||
for i in range(n_major):
|
||||
a0 = i * major_s
|
||||
a1 = a0 + major_s
|
||||
x0 = cos(a0)
|
||||
|
@ -294,7 +298,7 @@ except ImportError:
|
|||
y1 = sin(a1)
|
||||
|
||||
with glSection(GL_TRIANGLE_STRIP):
|
||||
for j in xrange(n_minor + 1):
|
||||
for j in range(n_minor + 1):
|
||||
b = j * minor_s
|
||||
c = cos(b)
|
||||
r = minor_radius * c + major_radius
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
from punyverse.texture import load_texture
|
||||
|
||||
from pyglet.gl import *
|
||||
from uuid import uuid4
|
||||
import os
|
||||
import gzip
|
||||
import bz2
|
||||
import zipfile
|
||||
|
||||
import six
|
||||
from six.moves import range
|
||||
from pyglet.gl import *
|
||||
|
||||
from punyverse.texture import load_texture
|
||||
|
||||
|
||||
def zip_open(file):
|
||||
zip = zipfile.ZipFile(file)
|
||||
|
@ -82,8 +85,9 @@ class WavefrontObject(object):
|
|||
self.perform_io(self.path)
|
||||
|
||||
def new_material(self, words):
|
||||
material = Material(words[1])
|
||||
self.materials[words[1]] = material
|
||||
name = words[1].decode('utf-8')
|
||||
material = Material(name)
|
||||
self.materials[name] = material
|
||||
self.current_material = material
|
||||
|
||||
def Ka(self, words):
|
||||
|
@ -99,7 +103,7 @@ class WavefrontObject(object):
|
|||
self.current_material.shininess = min(float(words[1]), 125)
|
||||
|
||||
def material_texture(self, words):
|
||||
self.current_material.texture = words[-1]
|
||||
self.current_material.texture = words[-1].decode('utf-8')
|
||||
|
||||
def vertex(self, words):
|
||||
self.vertices.append((float(words[1]), float(words[2]), float(words[3])))
|
||||
|
@ -138,8 +142,8 @@ class WavefrontObject(object):
|
|||
nindices = []
|
||||
tindices = []
|
||||
|
||||
for i in xrange(1, vertex_count + 1):
|
||||
raw_faces = words[i].split('/')
|
||||
for i in range(1, vertex_count + 1):
|
||||
raw_faces = words[i].split(b'/')
|
||||
l = len(raw_faces)
|
||||
|
||||
current_value = int(raw_faces[0])
|
||||
|
@ -174,19 +178,19 @@ class WavefrontObject(object):
|
|||
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
||||
|
||||
def material(self, words):
|
||||
self.perform_io(os.path.join(self.root, words[1]))
|
||||
self.perform_io(os.path.join(self.root, words[1].decode('utf-8')))
|
||||
|
||||
def use_material(self, words):
|
||||
mat = words[1]
|
||||
mat = words[1].decode('utf-8')
|
||||
try:
|
||||
self.current_group.material = self.materials[mat]
|
||||
except KeyError:
|
||||
print "Warning: material %s undefined, only %s defined." % (mat, self.materials)
|
||||
print("Warning: material %s undefined, only %s defined." % (mat, self.materials))
|
||||
except AttributeError:
|
||||
print "Warning: no group"
|
||||
print("Warning: no group")
|
||||
|
||||
def group(self, words):
|
||||
name = words[1]
|
||||
name = words[1].decode('utf-8')
|
||||
group = Group(name)
|
||||
|
||||
if self.groups:
|
||||
|
@ -196,29 +200,29 @@ class WavefrontObject(object):
|
|||
|
||||
def perform_io(self, file):
|
||||
ext = os.path.splitext(file)[1].lstrip('.')
|
||||
reader = openers.get(ext, open)(file)
|
||||
reader = openers.get(ext, lambda x: open(x, 'rb'))(file)
|
||||
|
||||
dispatcher = {
|
||||
'v': self.vertex,
|
||||
'vn': self.normal,
|
||||
'vt': self.texture,
|
||||
'f': self.face,
|
||||
'mtllib': self.material,
|
||||
'usemtl': self.use_material,
|
||||
'g': self.group,
|
||||
'o': self.group,
|
||||
'newmtl': self.new_material,
|
||||
'Ka': self.Ka,
|
||||
'Kd': self.Kd,
|
||||
'Ks': self.Ks,
|
||||
'Ns': self.material_shininess,
|
||||
'map_Kd': self.material_texture,
|
||||
b'v': self.vertex,
|
||||
b'vn': self.normal,
|
||||
b'vt': self.texture,
|
||||
b'f': self.face,
|
||||
b'mtllib': self.material,
|
||||
b'usemtl': self.use_material,
|
||||
b'g': self.group,
|
||||
b'o': self.group,
|
||||
b'newmtl': self.new_material,
|
||||
b'Ka': self.Ka,
|
||||
b'Kd': self.Kd,
|
||||
b'Ks': self.Ks,
|
||||
b'Ns': self.material_shininess,
|
||||
b'map_Kd': self.material_texture,
|
||||
}
|
||||
default = lambda words: None
|
||||
|
||||
with reader:
|
||||
for buf in reader:
|
||||
if not buf or buf.startswith(('\r', '\n', '#')):
|
||||
if not buf or buf.startswith((b'\r', b'\n', b'#')):
|
||||
continue # Empty or comment
|
||||
words = buf.split()
|
||||
type = words[0]
|
||||
|
@ -236,13 +240,13 @@ else:
|
|||
def load_model(path):
|
||||
if not os.path.isabs(path):
|
||||
path = os.path.join(model_base, path)
|
||||
if not isinstance(path, unicode):
|
||||
if isinstance(path, six.binary_type):
|
||||
path = path.decode('mbcs')
|
||||
return WavefrontObject(path)
|
||||
|
||||
|
||||
def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
||||
for m, text in model.materials.iteritems():
|
||||
for m, text in six.iteritems(model.materials):
|
||||
if text.texture:
|
||||
load_texture(os.path.join(model.root, text.texture))
|
||||
|
||||
|
@ -300,18 +304,13 @@ def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
|||
x, y, z = vertices[f.verts[n]]
|
||||
glVertex3f(x * sx, y * sy, z * sz)
|
||||
|
||||
for f in g.faces:
|
||||
if type != f.type:
|
||||
if type != -1:
|
||||
glEnd()
|
||||
glBegin(GL_TRIANGLES)
|
||||
type = f.type
|
||||
|
||||
for f in g.faces:
|
||||
point(f, vertices, normals, textures, 0)
|
||||
point(f, vertices, normals, textures, 1)
|
||||
point(f, vertices, normals, textures, 2)
|
||||
|
||||
if type == FACE_QUADS:
|
||||
if f.type == FACE_QUADS:
|
||||
point(f, vertices, normals, textures, 2)
|
||||
point(f, vertices, normals, textures, 3)
|
||||
point(f, vertices, normals, textures, 0)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
@ -60,7 +62,7 @@ def shrink(file):
|
|||
image = get_image(file)
|
||||
width, height = get_size(image)
|
||||
if fits(width, height):
|
||||
print 'no need'
|
||||
print('no need')
|
||||
return
|
||||
width, height = resize(width, height, 2048)
|
||||
if fits(width, height):
|
||||
|
@ -68,14 +70,14 @@ def shrink(file):
|
|||
else:
|
||||
width, height = resize(width, height, 1024) # 1024 is minimum
|
||||
size = 'small'
|
||||
print 'size %s, %dx%d...' % (size, width, height),
|
||||
print('size %s, %dx%d...' % (size, width, height), end=' ')
|
||||
name = make_name(file, size)
|
||||
if not os.path.exists(name):
|
||||
image = scale(image, width, height)
|
||||
print 'saved to:', os.path.basename(name)
|
||||
print('saved to:', os.path.basename(name))
|
||||
save(image, name)
|
||||
else:
|
||||
print 'alrady there'
|
||||
print('alrady there')
|
||||
|
||||
textures = [
|
||||
'mercury.jpg',
|
||||
|
@ -106,12 +108,12 @@ def main():
|
|||
files = textures
|
||||
texture = os.path.join(punyverse, 'assets', 'textures')
|
||||
for file in files:
|
||||
print 'Resizing %s:' % file,
|
||||
print('Resizing %s:' % file, end=' ')
|
||||
file = os.path.join(texture, file.replace('/', os.sep))
|
||||
if os.path.exists(file):
|
||||
shrink(file)
|
||||
else:
|
||||
print 'exists not'
|
||||
print('exists not')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from pyglet import image
|
||||
from pyglet.gl import *
|
||||
from ctypes import c_int, byref, c_ulong
|
||||
import os.path
|
||||
import struct
|
||||
import itertools
|
||||
from io import BytesIO
|
||||
|
||||
import six
|
||||
from six.moves import zip
|
||||
|
||||
try:
|
||||
from _glgeom import bgr_to_rgb
|
||||
from punyverse._glgeom import bgr_to_rgb
|
||||
except ImportError:
|
||||
import warnings
|
||||
warnings.warn('Compile _glgeom.c, or double the start up time.')
|
||||
|
@ -19,17 +25,19 @@ except ImportError:
|
|||
else:
|
||||
magick = True
|
||||
|
||||
from six.moves import range
|
||||
|
||||
def bgr_to_rgb(source, width, height, alpha=False, bottom_up=True):
|
||||
length = len(source)
|
||||
depth = length / (width * height)
|
||||
depth = length // (width * height)
|
||||
depth2 = depth - alpha
|
||||
result = bytearray(length)
|
||||
row = width * depth
|
||||
for y in xrange(height):
|
||||
for x in xrange(width):
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
ioffset = y * width * depth + x * depth
|
||||
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
|
||||
for i in xrange(depth2):
|
||||
for i in range(depth2):
|
||||
result[ooffset+i] = source[ioffset+depth2-i-1]
|
||||
if alpha:
|
||||
result[ooffset+depth2] = source[ioffset+depth2]
|
||||
|
@ -37,11 +45,6 @@ except ImportError:
|
|||
else:
|
||||
magick = False
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except ImportError:
|
||||
from StringIO import StringIO
|
||||
|
||||
__all__ = ['load_texture', 'load_clouds', 'load_image', 'pil_load']
|
||||
|
||||
id = 0
|
||||
|
@ -64,10 +67,8 @@ def init():
|
|||
if badcard:
|
||||
import warnings
|
||||
warnings.warn('Please update your graphics drivers if possible')
|
||||
#extensions = gl_info.get_extensions()
|
||||
#bgra = 'GL_EXT_bgra' in extensions
|
||||
#if bgra and magick:
|
||||
# magick = False # Disable magick because BGRA needs it not
|
||||
# Currently, BGRA images are flipped.
|
||||
# bgra = gl_info.have_extension('GL_EXT_bgra')
|
||||
|
||||
if power_of_two is None:
|
||||
power_of_two = gl_info.have_version(2) or gl_info.have_extension('GL_ARB_texture_non_power_of_two')
|
||||
|
@ -111,7 +112,7 @@ def image_info(data):
|
|||
# handle JPEGs
|
||||
elif (size >= 2) and data.startswith('\377\330'):
|
||||
content_type = 'image/jpeg'
|
||||
jpeg = StringIO(data)
|
||||
jpeg = BytesIO(data)
|
||||
jpeg.read(2)
|
||||
b = jpeg.read(1)
|
||||
try:
|
||||
|
@ -140,21 +141,21 @@ def image_info(data):
|
|||
def check_size(width, height):
|
||||
init()
|
||||
if width > max_texture or height > max_texture:
|
||||
print 'too large'
|
||||
print('too large')
|
||||
raise ValueError('Texture too large')
|
||||
elif not power_of_two:
|
||||
if not is_power2(width) or not is_power2(height):
|
||||
print 'not power of two'
|
||||
print('not power of two')
|
||||
raise ValueError('Texture not power of two')
|
||||
|
||||
|
||||
def load_image(file, path):
|
||||
print "Loading image %s..." % file,
|
||||
print('Loading image %s...' % file, end=' ')
|
||||
|
||||
try:
|
||||
file = open(path, 'rb')
|
||||
except IOError:
|
||||
print 'exists not'
|
||||
print('exists not')
|
||||
raise ValueError('Texture exists not')
|
||||
type, width, height = image_info(file.read(65536))
|
||||
file.seek(0, 0)
|
||||
|
@ -166,7 +167,7 @@ def load_image(file, path):
|
|||
file = Image(path.encode('mbcs' if os.name == 'nt' else 'utf8'))
|
||||
geo = file.size()
|
||||
check_size(geo.width(), geo.height())
|
||||
print
|
||||
print()
|
||||
blob = Blob()
|
||||
file.flip()
|
||||
file.write(blob, 'RGBA')
|
||||
|
@ -176,12 +177,12 @@ def load_image(file, path):
|
|||
try:
|
||||
raw = image.load(path, file=file)
|
||||
except IOError:
|
||||
print 'exists not'
|
||||
print('exists not')
|
||||
raise ValueError('Texture exists not')
|
||||
|
||||
width, height = raw.width, raw.height
|
||||
check_size(width, height)
|
||||
print
|
||||
print()
|
||||
|
||||
mode = GL_RGBA if 'A' in raw.format else GL_RGB
|
||||
# Flip from BGR to RGB
|
||||
|
@ -252,17 +253,16 @@ def load_clouds(file):
|
|||
id = buffer.value
|
||||
|
||||
pixels = bytearray(len(texture) * 4)
|
||||
white = chr(255)
|
||||
pixels[:] = itertools.chain.from_iterable(itertools.izip(itertools.repeat(white), itertools.repeat(white),
|
||||
white = b'\xff'[0]
|
||||
pixels[:] = itertools.chain.from_iterable(zip(itertools.repeat(white), itertools.repeat(white),
|
||||
itertools.repeat(white),
|
||||
itertools.islice(texture, 0, None, depth)))
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, id)
|
||||
|
||||
filter = GL_LINEAR
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, str(pixels))
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, six.binary_type(pixels))
|
||||
|
||||
cache[path] = id
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
from __future__ import print_function
|
||||
|
||||
from collections import OrderedDict
|
||||
import os.path
|
||||
import os
|
||||
|
||||
try:
|
||||
import json
|
||||
|
@ -9,6 +11,8 @@ except ImportError:
|
|||
except ImportError:
|
||||
raise SystemExit('No JSON module found')
|
||||
|
||||
import six
|
||||
|
||||
try:
|
||||
from punyverse._model import model_list, load_model
|
||||
except ImportError:
|
||||
|
@ -97,11 +101,11 @@ class World(object):
|
|||
self._current_object = 0
|
||||
|
||||
def count_objects(bodies):
|
||||
for body in bodies.itervalues():
|
||||
for body in six.itervalues(bodies):
|
||||
self._objects += 1
|
||||
count_objects(body.get('satellites', {}))
|
||||
count_objects(root['bodies'])
|
||||
print self._objects, 'objects to be loaded...'
|
||||
print(self._objects, 'objects to be loaded...')
|
||||
|
||||
if 'start' in root:
|
||||
info = root['start']
|
||||
|
@ -114,9 +118,9 @@ class World(object):
|
|||
self.start = (x, y, z)
|
||||
self.direction = (pitch, yaw, roll)
|
||||
|
||||
for planet, info in root['bodies'].iteritems():
|
||||
for planet, info in six.iteritems(root['bodies']):
|
||||
message = 'Loading %s.' % planet
|
||||
print message
|
||||
print(message)
|
||||
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
||||
message, float(self._current_object) / self._objects)
|
||||
self._body(planet, info)
|
||||
|
@ -125,9 +129,9 @@ class World(object):
|
|||
if 'belts' in root:
|
||||
self._phase = 'Loading belts...'
|
||||
self._current_object = 0
|
||||
for name, info in root['belts'].iteritems():
|
||||
for name, info in six.iteritems(root['belts']):
|
||||
message = 'Loading %s.' % name
|
||||
print message
|
||||
print(message)
|
||||
self.callback(self._phase, message, float(self._current_object) / len(root['belts']))
|
||||
self._belt(name, info)
|
||||
|
||||
|
@ -189,7 +193,7 @@ class World(object):
|
|||
object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
||||
info.get('sz', scale), (0, 0, 0))
|
||||
else:
|
||||
print 'Nothing to load for %s.' % name
|
||||
print('Nothing to load for %s.' % name)
|
||||
return
|
||||
|
||||
params = {'world': self, 'orbit_distance': orbit_distance, 'radius': None if background else radius}
|
||||
|
@ -243,7 +247,7 @@ class World(object):
|
|||
if not cheap:
|
||||
atmosphere_id = compile(disk, radius, radius + atm_size, 30, atm_texture)
|
||||
|
||||
theta = 360 / (rotation + .0) if rotation else 0
|
||||
theta = 360.0 / rotation if rotation else 0
|
||||
object = type(object_id, (x, y, z), (pitch, yaw, roll), rotation_angle=theta,
|
||||
atmosphere=atmosphere_id, cloudmap=cloudmap_id, background=background,
|
||||
corona=corona_id, **params)
|
||||
|
@ -264,9 +268,9 @@ class World(object):
|
|||
type(compile(disk, distance, distance + size, 30, texture), (x, y, z),
|
||||
(pitch, yaw, roll), **params))
|
||||
|
||||
for satellite, info in info.get('satellites', {}).iteritems():
|
||||
for satellite, info in six.iteritems(info.get('satellites', {})):
|
||||
message = 'Loading %s, satellite of %s.' % (satellite, name)
|
||||
print message
|
||||
print(message)
|
||||
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
||||
message, float(self._current_object) / self._objects)
|
||||
self._body(satellite, info, object)
|
||||
|
|
4
setup.py
4
setup.py
|
@ -28,7 +28,7 @@ with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f:
|
|||
|
||||
setup(
|
||||
name='punyverse',
|
||||
version='0.2',
|
||||
version='0.3',
|
||||
packages=['punyverse'],
|
||||
package_data={
|
||||
'punyverse': [
|
||||
|
@ -60,7 +60,7 @@ setup(
|
|||
]
|
||||
|
||||
},
|
||||
install_requires=['pyglet', 'Pillow'],
|
||||
install_requires=['pyglet', 'Pillow', 'six'],
|
||||
|
||||
author='quantum',
|
||||
author_email='quantum2048@gmail.com',
|
||||
|
|
Loading…
Reference in a new issue