From b4dce48fa7eae83e500980c586bbb1b200a0faa4 Mon Sep 17 00:00:00 2001 From: Quantum Date: Wed, 22 Aug 2018 04:18:29 -0400 Subject: [PATCH] Punyverse 0.3: adding Python 3 support. --- README.md | 2 +- punyverse/__main__.py | 4 +- punyverse/_model.pyx | 65 ++++++++++++++++----------------- punyverse/entity.py | 6 ++- punyverse/game.py | 27 ++++++++------ punyverse/glgeom.py | 28 ++++++++------ punyverse/model.py | 77 +++++++++++++++++++-------------------- punyverse/small_images.py | 14 ++++--- punyverse/texture.py | 62 +++++++++++++++---------------- punyverse/world.py | 26 +++++++------ setup.py | 4 +- 11 files changed, 164 insertions(+), 151 deletions(-) diff --git a/README.md b/README.md index 5517035..7fcea53 100644 --- a/README.md +++ b/README.md @@ -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`. diff --git a/punyverse/__main__.py b/punyverse/__main__.py index 7e1861c..393bf8f 100644 --- a/punyverse/__main__.py +++ b/punyverse/__main__.py @@ -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, diff --git a/punyverse/_model.pyx b/punyverse/_model.pyx index 163dcb7..7bf026e 100644 --- a/punyverse/_model.pyx +++ b/punyverse/_model.pyx @@ -29,7 +29,7 @@ cdef enum: cdef class Face(object): cdef public int type cdef public list verts, norms, texs, vertices, normals, textures - + def __init__(self, int type, list verts, list norms, list texs, list vertices, list normals, list textures): self.type = type @@ -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 = () @@ -101,35 +101,36 @@ cdef class WavefrontObject(object): self.materials = {} 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): self.current_material.Ka = (float(words[1]), float(words[2]), float(words[3])) - + cdef void Kd(self, list words): self.current_material.Kd = (float(words[1]), float(words[2]), float(words[3])) - + cdef void Ks(self, list words): self.current_material.Ks = (float(words[1]), float(words[2]), float(words[3])) - + cdef void material_shininess(self, list words): 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): self.vertices.append((float(words[1]), float(words[2]), float(words[3]))) - + @cython.nonecheck(False) cdef void normal(self, list words): self.normals.append((float(words[1]), float(words[2]), float(words[3]))) - + cdef void texture(self, list words): cdef int l = len(words) cdef object x = 0, y = 0, z = 0 @@ -141,7 +142,7 @@ cdef class WavefrontObject(object): if l >= 4: z = float(words[3]) self.textures.append((x, y, z)) - + cdef void face(self, list words): cdef int l = len(words) cdef int type = -1 @@ -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,11 +268,7 @@ 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') + model_base = os.path.join(os.path.dirname(__file__), 'assets', 'models') if not os.path.isabs(path): path = os.path.join(model_base, path) if not isinstance(path, unicode): @@ -305,7 +302,7 @@ cpdef int model_list(WavefrontObject model, float sx=1, float sy=1, float sz=1, cdef float pitch, yaw, roll cdef float kx, ky, kz - + pitch, yaw, roll = rotation glPushAttrib(GL_TRANSFORM_BIT) glRotatef(pitch, 1, 0, 0) diff --git a/punyverse/entity.py b/punyverse/entity.py index 4b4ea87..59da6cb 100644 --- a/punyverse/entity.py +++ b/punyverse/entity.py @@ -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() diff --git a/punyverse/game.py b/punyverse/game.py index 7ac6469..58febbc 100644 --- a/punyverse/game.py +++ b/punyverse/game.py @@ -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 @@ -234,14 +239,14 @@ class Applet(pyglet.window.Window): from PIL import Image 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) diff --git a/punyverse/glgeom.py b/punyverse/glgeom.py index a8b5dde..b028f74 100644 --- a/punyverse/glgeom.py +++ b/punyverse/glgeom.py @@ -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 diff --git a/punyverse/model.py b/punyverse/model.py index 7753bcb..010ec92 100644 --- a/punyverse/model.py +++ b/punyverse/model.py @@ -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) + glBegin(GL_TRIANGLES) for f in g.faces: - if type != f.type: - if type != -1: - glEnd() - glBegin(GL_TRIANGLES) - type = f.type - 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) @@ -325,4 +324,4 @@ def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)): glPopMatrix() glEndList() - return display \ No newline at end of file + return display diff --git a/punyverse/small_images.py b/punyverse/small_images.py index 1f839ca..0d0903d 100644 --- a/punyverse/small_images.py +++ b/punyverse/small_images.py @@ -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() diff --git a/punyverse/texture.py b/punyverse/texture.py index 9cf9857..1c3539c 100644 --- a/punyverse/texture.py +++ b/punyverse/texture.py @@ -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,18 +253,17 @@ 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), - itertools.repeat(white), - itertools.islice(texture, 0, None, depth))) + 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 - return id \ No newline at end of file + return id diff --git a/punyverse/world.py b/punyverse/world.py index 4b1a40f..6c55ee1 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -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) diff --git a/setup.py b/setup.py index 45dadf7..5bf7c0d 100644 --- a/setup.py +++ b/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',