From a2198937c3eaed3baa4aa17c74d328af2eb70023 Mon Sep 17 00:00:00 2001 From: Quantum Date: Thu, 21 Nov 2013 20:47:29 -0500 Subject: [PATCH] Added normal map for earth as proof of concept. --- punyverse/assets/textures/earth_normal.jpg | Bin 0 -> 26014 bytes punyverse/glgeom.py | 64 ++++++++++++++++++++- punyverse/texture.py | 7 ++- punyverse/world.json | 3 +- punyverse/world.py | 5 +- 5 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 punyverse/assets/textures/earth_normal.jpg diff --git a/punyverse/assets/textures/earth_normal.jpg b/punyverse/assets/textures/earth_normal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..aeae547f0b066e17ae711466354520d59b05f980 GIT binary patch literal 26014 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 literal 0 HcmV?d00001 diff --git a/punyverse/glgeom.py b/punyverse/glgeom.py index 921ee12..12c6f38 100644 --- a/punyverse/glgeom.py +++ b/punyverse/glgeom.py @@ -1,11 +1,11 @@ from math import * from pyglet.gl import * -from random import random, uniform, gauss, choice +from random import random, gauss, choice TWOPI = pi * 2 __all__ = ['compile', 'ortho', 'frustrum', 'crosshair', 'circle', 'disk', 'sphere', 'colourball', 'torus', 'belt', - 'flare'] + 'flare', 'normal_sphere'] def compile(pointer, *args, **kwargs): @@ -160,6 +160,66 @@ def colourball(r, lats, longs, colour, fv4=GLfloat * 4): gluDeleteQuadric(sphere) +def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4): + from texture import pil_load + print 'Loading normal map: %s...' % normal, + normal_map = pil_load(normal) + normal = normal_map.load() + print + width, height = normal_map.size + + glEnable(GL_TEXTURE_2D) + if lighting: + glDisable(GL_BLEND) + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, fv4(1, 1, 1, 0)) + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, fv4(1, 1, 1, 0)) + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 125) + else: + glDisable(GL_LIGHTING) + glBindTexture(GL_TEXTURE_2D, tex) + + twopi_divide = TWOPI / divide + pi_divide = pi / divide + glBegin(GL_QUAD_STRIP) + for j in xrange(divide + 1): + phi1 = j * twopi_divide + phi2 = (j + 1) * twopi_divide + + for i in xrange(divide + 1): + theta = i * pi_divide + + s = phi2 / TWOPI + u = min(int(s * width), width - 1) + t = theta / pi + v = min(int(t * height), height - 1) + x, y, z = normal[u, v] + nx, ny, nz = sin(theta) * cos(phi2), sin(theta) * sin(phi2), cos(theta) + #delta = normal[u, v] / 255. + #glNormal3f(nx + delta, ny + delta, nz + delta) + #glNormal3f(nx + x / 64., ny + y / 64., nz + z / 64.) + glNormal3f(nx + x / 128. - 1, ny + y / 128. - 1, nz + z / 128. - 1) + #glNormal3f(nx, ny, nz) + glTexCoord2f(s, 1 - t) + glVertex3f(r * nx, r * ny, r * nz) + + s = phi1 / TWOPI # x + u = min(int(s * width), width - 1) + x, y, z = normal[u, v] + nx, ny, nz = sin(theta) * cos(phi1), sin(theta) * sin(phi1), cos(theta) + #delta = normal[u, v] / 255. + #glNormal3f(nx + delta, ny + delta, nz + delta) + #glNormal3f(nx + x / 64., ny + y / 64., nz + z / 64.) + glNormal3f(nx + x / 128. - 1, ny + y / 128. - 1, nz + z / 128. - 1) + #glNormal3f(nx, ny, nz) + glTexCoord2f(s, 1 - t) + glVertex3f(r * nx, r * ny, r * nz) + glEnd() + + glDisable(GL_TEXTURE_2D) + glEnable(GL_LIGHTING) + glEnable(GL_BLEND) + + def belt(radius, cross, object, count): for i in xrange(count): theta = TWOPI * random() diff --git a/punyverse/texture.py b/punyverse/texture.py index 83145f8..894e29e 100644 --- a/punyverse/texture.py +++ b/punyverse/texture.py @@ -42,7 +42,7 @@ try: except ImportError: from StringIO import StringIO -__all__ = ['load_texture', 'load_clouds', 'load_image'] +__all__ = ['load_texture', 'load_clouds', 'load_image', 'pil_load'] id = 0 cache = {} @@ -227,6 +227,11 @@ def load_texture(file): return id +def pil_load(file): + import Image + return Image.open(os.path.join(os.path.dirname(__file__), 'assets', 'textures', file)) + + def load_clouds(file): if os.path.isabs(file): path = file diff --git a/punyverse/world.json b/punyverse/world.json index 02c9eb2..9da6d1f 100644 --- a/punyverse/world.json +++ b/punyverse/world.json @@ -57,7 +57,8 @@ "roll": -90, "mass": 5.97219e+24, "rotation": 86400, - "division": 70, + "division": 250, + "normal": "earth_normal.jpg", "atmosphere": { "cloud_texture": ["cloudmap.jpg", "cloudmap_small.jpg"], "diffuse_texture": "atmosphere_earth.png", diff --git a/punyverse/world.py b/punyverse/world.py index fa5def2..ed73e0e 100644 --- a/punyverse/world.py +++ b/punyverse/world.py @@ -97,7 +97,10 @@ def load_world(file): if cheap: object_id = compile(colourball, radius, division, division, texture) else: - object_id = compile(sphere, radius, division, division, texture, lighting=lighting) + if 'normal' in info: + object_id = compile(normal_sphere, radius, division, texture, info['normal'], lighting=lighting) + else: + object_id = compile(sphere, radius, division, division, texture, lighting=lighting) elif 'model' in info: scale = info.get('scale', 1) object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),