diff --git a/punyverse/assets/textures.txt b/punyverse/assets/textures.txt index b9d7361..1e01337 100644 --- a/punyverse/assets/textures.txt +++ b/punyverse/assets/textures.txt @@ -11,7 +11,12 @@ moon.jpg mars.jpg jupiter.jpg saturn.jpg -sky.jpg +sky_px.jpg +sky_py.jpg +sky_pz.jpg +sky_nx.jpg +sky_ny.jpg +sky_nz.jpg moons/io.jpg moons/europa.jpg moons/ganymede.jpg diff --git a/punyverse/assets/textures/constellation_nx.png b/punyverse/assets/textures/constellation_nx.png new file mode 100644 index 0000000..1dabc48 Binary files /dev/null and b/punyverse/assets/textures/constellation_nx.png differ diff --git a/punyverse/assets/textures/constellation_ny.png b/punyverse/assets/textures/constellation_ny.png new file mode 100644 index 0000000..db24a25 Binary files /dev/null and b/punyverse/assets/textures/constellation_ny.png differ diff --git a/punyverse/assets/textures/constellation_nz.png b/punyverse/assets/textures/constellation_nz.png new file mode 100644 index 0000000..16f4570 Binary files /dev/null and b/punyverse/assets/textures/constellation_nz.png differ diff --git a/punyverse/assets/textures/constellation_px.png b/punyverse/assets/textures/constellation_px.png new file mode 100644 index 0000000..65b5ccf Binary files /dev/null and b/punyverse/assets/textures/constellation_px.png differ diff --git a/punyverse/assets/textures/constellation_py.png b/punyverse/assets/textures/constellation_py.png new file mode 100644 index 0000000..587f9d7 Binary files /dev/null and b/punyverse/assets/textures/constellation_py.png differ diff --git a/punyverse/assets/textures/constellation_pz.png b/punyverse/assets/textures/constellation_pz.png new file mode 100644 index 0000000..a52c2c0 Binary files /dev/null and b/punyverse/assets/textures/constellation_pz.png differ diff --git a/punyverse/assets/textures/sky.jpg b/punyverse/assets/textures/sky.jpg deleted file mode 100644 index 6f96f29..0000000 Binary files a/punyverse/assets/textures/sky.jpg and /dev/null differ diff --git a/punyverse/assets/textures/sky_nx.jpg b/punyverse/assets/textures/sky_nx.jpg new file mode 100644 index 0000000..d251612 Binary files /dev/null and b/punyverse/assets/textures/sky_nx.jpg differ diff --git a/punyverse/assets/textures/sky_ny.jpg b/punyverse/assets/textures/sky_ny.jpg new file mode 100644 index 0000000..507b8fd Binary files /dev/null and b/punyverse/assets/textures/sky_ny.jpg differ diff --git a/punyverse/assets/textures/sky_nz.jpg b/punyverse/assets/textures/sky_nz.jpg new file mode 100644 index 0000000..3c6e447 Binary files /dev/null and b/punyverse/assets/textures/sky_nz.jpg differ diff --git a/punyverse/assets/textures/sky_px.jpg b/punyverse/assets/textures/sky_px.jpg new file mode 100644 index 0000000..5a20011 Binary files /dev/null and b/punyverse/assets/textures/sky_px.jpg differ diff --git a/punyverse/assets/textures/sky_py.jpg b/punyverse/assets/textures/sky_py.jpg new file mode 100644 index 0000000..b52f823 Binary files /dev/null and b/punyverse/assets/textures/sky_py.jpg differ diff --git a/punyverse/assets/textures/sky_pz.jpg b/punyverse/assets/textures/sky_pz.jpg new file mode 100644 index 0000000..3463c28 Binary files /dev/null and b/punyverse/assets/textures/sky_pz.jpg differ diff --git a/punyverse/entity.py b/punyverse/entity.py index 02e566e..59abb27 100644 --- a/punyverse/entity.py +++ b/punyverse/entity.py @@ -5,10 +5,10 @@ from pyglet.gl import * # noinspection PyUnresolvedReferences from six.moves import range -from punyverse.glgeom import compile, glRestore, belt, Disk, OrbitVBO, Matrix4f, SimpleSphere, TangentSphere +from punyverse.glgeom import compile, glRestore, belt, Disk, OrbitVBO, Matrix4f, SimpleSphere, TangentSphere, Cube from punyverse.model import load_model, WavefrontVBO from punyverse.orbit import KeplerOrbit -from punyverse.texture import get_best_texture, load_clouds +from punyverse.texture import get_best_texture, load_clouds, get_cube_map from punyverse.utils import cached_property G = 6.67384e-11 # Gravitation Constant @@ -126,11 +126,11 @@ class Sky(Entity): yaw = world.evaluate(info.get('yaw', 0)) roll = world.evaluate(info.get('roll', 0)) - super(Sky, self).__init__(world, 'Sky', (0, 0, 0), (pitch, yaw, roll)) + super(Sky, self).__init__(world, 'Sky', (0, 0, 0), [pitch, yaw, roll]) - self.texture = get_best_texture(info['texture']) - division = info.get('division', 30) - self.sphere = SimpleSphere(division, division) + self.texture = get_best_texture(info['texture'], loader=get_cube_map) + self.constellation = get_cube_map(info['constellation']) + self.cube = Cube() def draw(self, options): cam = self.world.cam @@ -140,16 +140,20 @@ class Sky(Entity): Matrix4f.from_angles(rotation=self.rotation)) glActiveTexture(GL_TEXTURE0) - glBindTexture(GL_TEXTURE_2D, self.texture) + glBindTexture(GL_TEXTURE_CUBE_MAP, self.texture) shader.uniform_texture('u_skysphere', 0) - glBindBuffer(GL_ARRAY_BUFFER, self.sphere.vbo) - shader.vertex_attribute('a_direction', self.sphere.direction_size, self.sphere.type, GL_FALSE, - self.sphere.stride, self.sphere.direction_offset) - shader.vertex_attribute('a_uv', self.sphere.uv_size, self.sphere.type, GL_FALSE, - self.sphere.stride, self.sphere.uv_offset) + glActiveTexture(GL_TEXTURE1) + glBindTexture(GL_TEXTURE_CUBE_MAP, self.constellation) + shader.uniform_texture('u_constellation', 1) - glDrawArrays(GL_TRIANGLE_STRIP, 0, self.sphere.vertex_count) + shader.uniform_bool('u_lines', options.constellations) + + glBindBuffer(GL_ARRAY_BUFFER, self.cube.vbo) + shader.vertex_attribute('a_direction', self.cube.direction_size, self.cube.type, GL_FALSE, + self.cube.stride, self.cube.direction_offset) + + glDrawArrays(GL_TRIANGLES, 0, self.cube.vertex_count) shader.deactivate_attributes() glBindBuffer(GL_ARRAY_BUFFER, 0) diff --git a/punyverse/glgeom.py b/punyverse/glgeom.py index 952e10b..ab1003e 100644 --- a/punyverse/glgeom.py +++ b/punyverse/glgeom.py @@ -283,6 +283,22 @@ class TangentSphere(object): self.vbo = array_to_gl_buffer(buffer) +class Cube(object): + type = GL_SHORT + stride = 3 * 2 + direction_offset = 0 + direction_size = 3 + vertex_count = 36 + + def __init__(self): + self.vbo = array_to_gl_buffer([ + -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, + -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, + -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1 + ], 'h') + + class OrbitVBO(object): def __init__(self, orbit): buffer = 360 * 3 * [0] diff --git a/punyverse/shaders/sky.fragment.glsl b/punyverse/shaders/sky.fragment.glsl index 1821625..d65e402 100644 --- a/punyverse/shaders/sky.fragment.glsl +++ b/punyverse/shaders/sky.fragment.glsl @@ -1,9 +1,13 @@ #version 130 -in vec2 v_uv; +in vec3 v_direction; out vec4 o_fragColor; -uniform sampler2D u_skysphere; +uniform bool u_lines; +uniform samplerCube u_skysphere; +uniform samplerCube u_constellation; void main() { - o_fragColor = vec4(texture(u_skysphere, vec2(1 - v_uv.s, v_uv.t)).rgb, 1); + o_fragColor = texture(u_skysphere, v_direction); + if (u_lines) + o_fragColor += texture(u_constellation, v_direction); } diff --git a/punyverse/shaders/sky.vertex.glsl b/punyverse/shaders/sky.vertex.glsl index 075207e..890cc28 100644 --- a/punyverse/shaders/sky.vertex.glsl +++ b/punyverse/shaders/sky.vertex.glsl @@ -1,11 +1,10 @@ #version 130 in vec3 a_direction; -in vec2 a_uv; -out vec2 v_uv; +out vec3 v_direction; uniform mat4 u_mvpMatrix; void main() { gl_Position = (u_mvpMatrix * vec4(a_direction, 1)).xyww; - v_uv = a_uv; + v_direction = a_direction; } diff --git a/punyverse/texture.py b/punyverse/texture.py index b74512a..d4f8c4a 100644 --- a/punyverse/texture.py +++ b/punyverse/texture.py @@ -2,7 +2,7 @@ from __future__ import print_function import os.path import struct -from ctypes import c_int, byref, c_uint +from ctypes import c_int, byref from io import BytesIO import six @@ -42,7 +42,7 @@ except ImportError: result[y1 * row:y1 * row + row] = source[y2 * row:y2 * row + row] return six.binary_type(result) -__all__ = ['load_texture', 'load_clouds', 'load_image', 'get_best_texture', 'max_texture_size'] +__all__ = ['load_texture', 'load_clouds', 'load_image', 'get_best_texture', 'max_texture_size', 'get_cube_map'] id = 0 cache = {} @@ -177,31 +177,30 @@ def load_image(file, path): return path, width, height, len(raw.format), mode, flip_vertical(texture, width, height) -def load_texture(file, clamp=False): +def get_file_path(file): if os.path.isabs(file): path = file file = os.path.basename(path) else: path = os.path.join(os.path.dirname(__file__), 'assets', 'textures', file) + return path, file + +def load_texture(file, clamp=False): + path, file = get_file_path(file) if path in cache: return cache[path] path, width, height, depth, mode, texture = load_image(file, path) - buffer = c_uint() + buffer = GLuint() glGenTextures(1, byref(buffer)) id = buffer.value glBindTexture(GL_TEXTURE_2D, id) if gl_info.have_version(3) or gl_info.have_extension('GL_ARB_framebuffer_object'): - glTexImage2D(GL_TEXTURE_2D, 0, { - GL_RGB: GL_RGB8, - GL_BGR: GL_RGB8, - GL_RGBA: GL_RGBA8, - GL_BGRA: GL_RGBA8, - }[mode], width, height, 0, mode, GL_UNSIGNED_BYTE, texture) + glTexImage2D(GL_TEXTURE_2D, 0, get_internal_mode(mode), width, height, 0, mode, GL_UNSIGNED_BYTE, texture) glGenerateMipmap(GL_TEXTURE_2D) else: gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height, mode, GL_UNSIGNED_BYTE, texture) @@ -220,13 +219,17 @@ def load_texture(file, clamp=False): return id -def load_clouds(file): - if os.path.isabs(file): - path = file - file = os.path.basename(path) - else: - path = os.path.join(os.path.dirname(__file__), 'assets', 'textures', file) +def get_internal_mode(mode): + return { + GL_RGB: GL_RGB8, + GL_BGR: GL_RGB8, + GL_RGBA: GL_RGBA8, + GL_BGRA: GL_RGBA8, + }[mode] + +def load_clouds(file): + path, file = get_file_path(file) if path in cache: return cache[path] @@ -235,7 +238,7 @@ def load_clouds(file): if depth != 1: texture = texture[::depth] - buffer = c_uint() + buffer = GLuint() glGenTextures(1, byref(buffer)) id = buffer.value @@ -257,6 +260,35 @@ def load_clouds(file): return id +def get_cube_map(files): + assert len(files) == 6 + + buffer = GLuint() + glGenTextures(1, byref(buffer)) + id = buffer.value + + glBindTexture(GL_TEXTURE_CUBE_MAP, id) + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0) + glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0) + for file, part in zip(files, [ + GL_TEXTURE_CUBE_MAP_POSITIVE_X, + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, + ]): + try: + path, file = get_file_path(file) + path, width, height, depth, mode, texture = load_image(file, path) + except Exception: + glDeleteTextures(1, byref(buffer)) + raise + glTexImage2D(part, 0, get_internal_mode(mode), width, height, 0, mode, GL_UNSIGNED_BYTE, texture) + + return id + + def get_best_texture(info, loader=load_texture, optional=False, **kwargs): if isinstance(info, list): for item in info: diff --git a/punyverse/ui.py b/punyverse/ui.py index a78de86..4b35521 100644 --- a/punyverse/ui.py +++ b/punyverse/ui.py @@ -38,6 +38,7 @@ class Punyverse(pyglet.window.Window): self.info_precise = False self.atmosphere = True self.cloud = True + self.constellations = False self.ticks = [ 1, 2, 5, 10, 20, 40, 60, # Second range @@ -104,6 +105,7 @@ class Punyverse(pyglet.window.Window): key.P: attribute_toggler(self, 'info_precise'), key.C: attribute_toggler(self, 'cloud'), key.X: attribute_toggler(self, 'atmosphere'), + key.L: attribute_toggler(self, 'constellations'), key.ENTER: attribute_toggler(self, 'running'), key.INSERT: increment_tick, key.DELETE: decrement_tick, diff --git a/punyverse/world.json b/punyverse/world.json index db6b2a6..0fac145 100644 --- a/punyverse/world.json +++ b/punyverse/world.json @@ -299,12 +299,17 @@ } }, "sky": { - "texture": ["sky.jpg", "sky_large.jpg", "sky_medium.jpg", "sky_small.jpg"], + "texture": [ + ["sky_px.jpg", "sky_nx.jpg", "sky_py.jpg", "sky_ny.jpg", "sky_pz.jpg", "sky_nz.jpg"] + ], + "constellation": [ + "constellation_px.png", "constellation_nx.png", "constellation_py.png", + "constellation_ny.png", "constellation_pz.png", "constellation_nz.png" + ], "rotation": 0, "division": 30, - "pitch": -150.19, - "yaw": 0, - "roll": 0 + "pitch": -119.3, + "yaw": -97 }, "asteroids": ["asteroids/01.obj", "asteroids/02.obj", "asteroids/03.obj"], "start": {