Cube map sky and add constellation lines.

This commit is contained in:
Quantum 2018-08-28 03:32:25 -04:00
parent 168434ce37
commit f11e0b6fc7
21 changed files with 108 additions and 41 deletions

View file

@ -11,7 +11,12 @@ moon.jpg
mars.jpg mars.jpg
jupiter.jpg jupiter.jpg
saturn.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/io.jpg
moons/europa.jpg moons/europa.jpg
moons/ganymede.jpg moons/ganymede.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View file

@ -5,10 +5,10 @@ from pyglet.gl import *
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from six.moves import range 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.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, get_cube_map
from punyverse.utils import cached_property from punyverse.utils import cached_property
G = 6.67384e-11 # Gravitation Constant G = 6.67384e-11 # Gravitation Constant
@ -126,11 +126,11 @@ 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__(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']) self.texture = get_best_texture(info['texture'], loader=get_cube_map)
division = info.get('division', 30) self.constellation = get_cube_map(info['constellation'])
self.sphere = SimpleSphere(division, division) self.cube = Cube()
def draw(self, options): def draw(self, options):
cam = self.world.cam cam = self.world.cam
@ -140,16 +140,20 @@ class Sky(Entity):
Matrix4f.from_angles(rotation=self.rotation)) Matrix4f.from_angles(rotation=self.rotation))
glActiveTexture(GL_TEXTURE0) glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, self.texture) glBindTexture(GL_TEXTURE_CUBE_MAP, self.texture)
shader.uniform_texture('u_skysphere', 0) shader.uniform_texture('u_skysphere', 0)
glBindBuffer(GL_ARRAY_BUFFER, self.sphere.vbo) glActiveTexture(GL_TEXTURE1)
shader.vertex_attribute('a_direction', self.sphere.direction_size, self.sphere.type, GL_FALSE, glBindTexture(GL_TEXTURE_CUBE_MAP, self.constellation)
self.sphere.stride, self.sphere.direction_offset) shader.uniform_texture('u_constellation', 1)
shader.vertex_attribute('a_uv', self.sphere.uv_size, self.sphere.type, GL_FALSE,
self.sphere.stride, self.sphere.uv_offset)
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() shader.deactivate_attributes()
glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0)

View file

@ -283,6 +283,22 @@ class TangentSphere(object):
self.vbo = array_to_gl_buffer(buffer) 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): class OrbitVBO(object):
def __init__(self, orbit): def __init__(self, orbit):
buffer = 360 * 3 * [0] buffer = 360 * 3 * [0]

View file

@ -1,9 +1,13 @@
#version 130 #version 130
in vec2 v_uv; in vec3 v_direction;
out vec4 o_fragColor; out vec4 o_fragColor;
uniform sampler2D u_skysphere; uniform bool u_lines;
uniform samplerCube u_skysphere;
uniform samplerCube u_constellation;
void main() { 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);
} }

View file

@ -1,11 +1,10 @@
#version 130 #version 130
in vec3 a_direction; in vec3 a_direction;
in vec2 a_uv; out vec3 v_direction;
out vec2 v_uv;
uniform mat4 u_mvpMatrix; uniform mat4 u_mvpMatrix;
void main() { void main() {
gl_Position = (u_mvpMatrix * vec4(a_direction, 1)).xyww; gl_Position = (u_mvpMatrix * vec4(a_direction, 1)).xyww;
v_uv = a_uv; v_direction = a_direction;
} }

View file

@ -2,7 +2,7 @@ from __future__ import print_function
import os.path import os.path
import struct import struct
from ctypes import c_int, byref, c_uint from ctypes import c_int, byref
from io import BytesIO from io import BytesIO
import six import six
@ -42,7 +42,7 @@ except ImportError:
result[y1 * row:y1 * row + row] = source[y2 * row:y2 * row + row] result[y1 * row:y1 * row + row] = source[y2 * row:y2 * row + row]
return six.binary_type(result) 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 id = 0
cache = {} cache = {}
@ -177,31 +177,30 @@ def load_image(file, path):
return path, width, height, len(raw.format), mode, flip_vertical(texture, width, height) 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): if os.path.isabs(file):
path = file path = file
file = os.path.basename(path) file = os.path.basename(path)
else: else:
path = os.path.join(os.path.dirname(__file__), 'assets', 'textures', file) 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: if path in cache:
return cache[path] return cache[path]
path, width, height, depth, mode, texture = load_image(file, path) path, width, height, depth, mode, texture = load_image(file, path)
buffer = c_uint() buffer = GLuint()
glGenTextures(1, byref(buffer)) glGenTextures(1, byref(buffer))
id = buffer.value id = buffer.value
glBindTexture(GL_TEXTURE_2D, id) glBindTexture(GL_TEXTURE_2D, id)
if gl_info.have_version(3) or gl_info.have_extension('GL_ARB_framebuffer_object'): if gl_info.have_version(3) or gl_info.have_extension('GL_ARB_framebuffer_object'):
glTexImage2D(GL_TEXTURE_2D, 0, { glTexImage2D(GL_TEXTURE_2D, 0, get_internal_mode(mode), width, height, 0, mode, GL_UNSIGNED_BYTE, texture)
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)
glGenerateMipmap(GL_TEXTURE_2D) glGenerateMipmap(GL_TEXTURE_2D)
else: else:
gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height, mode, GL_UNSIGNED_BYTE, texture) gluBuild2DMipmaps(GL_TEXTURE_2D, depth, width, height, mode, GL_UNSIGNED_BYTE, texture)
@ -220,13 +219,17 @@ def load_texture(file, clamp=False):
return id return id
def load_clouds(file): def get_internal_mode(mode):
if os.path.isabs(file): return {
path = file GL_RGB: GL_RGB8,
file = os.path.basename(path) GL_BGR: GL_RGB8,
else: GL_RGBA: GL_RGBA8,
path = os.path.join(os.path.dirname(__file__), 'assets', 'textures', file) GL_BGRA: GL_RGBA8,
}[mode]
def load_clouds(file):
path, file = get_file_path(file)
if path in cache: if path in cache:
return cache[path] return cache[path]
@ -235,7 +238,7 @@ def load_clouds(file):
if depth != 1: if depth != 1:
texture = texture[::depth] texture = texture[::depth]
buffer = c_uint() buffer = GLuint()
glGenTextures(1, byref(buffer)) glGenTextures(1, byref(buffer))
id = buffer.value id = buffer.value
@ -257,6 +260,35 @@ def load_clouds(file):
return id 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): def get_best_texture(info, loader=load_texture, optional=False, **kwargs):
if isinstance(info, list): if isinstance(info, list):
for item in info: for item in info:

View file

@ -38,6 +38,7 @@ class Punyverse(pyglet.window.Window):
self.info_precise = False self.info_precise = False
self.atmosphere = True self.atmosphere = True
self.cloud = True self.cloud = True
self.constellations = False
self.ticks = [ self.ticks = [
1, 2, 5, 10, 20, 40, 60, # Second range 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.P: attribute_toggler(self, 'info_precise'),
key.C: attribute_toggler(self, 'cloud'), key.C: attribute_toggler(self, 'cloud'),
key.X: attribute_toggler(self, 'atmosphere'), key.X: attribute_toggler(self, 'atmosphere'),
key.L: attribute_toggler(self, 'constellations'),
key.ENTER: attribute_toggler(self, 'running'), key.ENTER: attribute_toggler(self, 'running'),
key.INSERT: increment_tick, key.INSERT: increment_tick,
key.DELETE: decrement_tick, key.DELETE: decrement_tick,

View file

@ -299,12 +299,17 @@
} }
}, },
"sky": { "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, "rotation": 0,
"division": 30, "division": 30,
"pitch": -150.19, "pitch": -119.3,
"yaw": 0, "yaw": -97
"roll": 0
}, },
"asteroids": ["asteroids/01.obj", "asteroids/02.obj", "asteroids/03.obj"], "asteroids": ["asteroids/01.obj", "asteroids/02.obj", "asteroids/03.obj"],
"start": { "start": {