mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Mostly working Intel integrated graphics compatibility.
This commit is contained in:
parent
96c8bbff11
commit
5e8db3ffb1
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -41,10 +41,12 @@ punyverse/*.c
|
|||
*.html
|
||||
*.exp
|
||||
*.lib
|
||||
punyverse/assets/textures/*_medium.*
|
||||
punyverse/assets/textures/*_small.*
|
||||
punyverse/assets/textures/*/*_medium.*
|
||||
punyverse/assets/textures/*/*_small.*
|
||||
/punyverse/assets/textures/*_large.*
|
||||
/punyverse/assets/textures/*_medium.*
|
||||
/punyverse/assets/textures/*_small.*
|
||||
/punyverse/assets/textures/*/*_large.*
|
||||
/punyverse/assets/textures/*/*_medium.*
|
||||
/punyverse/assets/textures/*/*_small.*
|
||||
temp
|
||||
|
||||
# There is a py2exe package that can execute punyverse directly
|
||||
|
|
|
@ -11,6 +11,7 @@ moon.jpg
|
|||
mars.jpg
|
||||
jupiter.jpg
|
||||
saturn.jpg
|
||||
sky.jpg
|
||||
moons/io.jpg
|
||||
moons/europa.jpg
|
||||
moons/ganymede.jpg
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import division
|
||||
|
||||
from math import sin, cos, radians, hypot, tan
|
||||
|
||||
from punyverse.glgeom import Matrix4f
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import time
|
||||
|
||||
import pyglet
|
||||
|
@ -8,6 +11,20 @@ from punyverse.glgeom import glContext, progress_bar
|
|||
from punyverse.world import World
|
||||
|
||||
|
||||
def get_context_info(context):
|
||||
info = [' %-22s %s' % (key + ':', value)
|
||||
for key, value in context.config.get_gl_attributes()]
|
||||
info = ['%-30s %-30s' % group for group in
|
||||
zip_longest(info[::2], info[1::2], fillvalue='')]
|
||||
|
||||
with glContext(context):
|
||||
return '\n'.join([
|
||||
'Graphics Vendor: ' + gl_info.get_vendor(),
|
||||
'Graphics Version: ' + gl_info.get_version(),
|
||||
'Graphics Renderer: ' + gl_info.get_renderer(),
|
||||
]) + '\n\n' + 'OpenGL configuration:\n' + '\n'.join(info)
|
||||
|
||||
|
||||
class LoaderWindow(pyglet.window.Window):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(LoaderWindow, self).__init__(*args, **kwargs)
|
||||
|
@ -33,18 +50,8 @@ class LoaderWindow(pyglet.window.Window):
|
|||
|
||||
def set_main_context(self, context):
|
||||
self._main_context = context
|
||||
|
||||
info = [' %-22s %s' % (key + ':', value)
|
||||
for key, value in context.config.get_gl_attributes()]
|
||||
info = ['%-30s %-30s' % group for group in
|
||||
zip_longest(info[::2], info[1::2], fillvalue='')]
|
||||
|
||||
with glContext(context):
|
||||
self.info_label.text = '\n'.join([
|
||||
'Graphics Vendor: ' + gl_info.get_vendor(),
|
||||
'Graphics Version: ' + gl_info.get_version(),
|
||||
'Graphics Renderer: ' + gl_info.get_renderer(),
|
||||
]) + '\n\n' + 'OpenGL configuration:\n' + '\n'.join(info)
|
||||
self.info_label.text = get_context_info(context)
|
||||
print(self.info_label.text)
|
||||
|
||||
def _load_callback(self, phase, message, progress):
|
||||
print(message)
|
||||
|
@ -74,3 +81,40 @@ class LoaderWindow(pyglet.window.Window):
|
|||
|
||||
def main_is_initializing(self):
|
||||
self._load_callback('Loading main window...', '', 0)
|
||||
|
||||
|
||||
class LoaderConsole(object):
|
||||
def __init__(self):
|
||||
from ctypes import windll
|
||||
self._own_console = False
|
||||
if windll.kernel32.AllocConsole():
|
||||
self._own_console = True
|
||||
self._output = open('CONOUT$', 'w')
|
||||
else:
|
||||
self._output = sys.stdout
|
||||
self._main_context = None
|
||||
|
||||
def _load_callback(self, phase, message, progress):
|
||||
print(message, file=self._output)
|
||||
|
||||
def load(self):
|
||||
start = time.clock()
|
||||
with glContext(self._main_context):
|
||||
world = World('world.json', self._load_callback)
|
||||
print('Loaded in %s seconds.' % (time.clock() - start), file=self._output)
|
||||
return world
|
||||
|
||||
def set_main_context(self, context):
|
||||
self._main_context = context
|
||||
print(get_context_info(context), file=self._output)
|
||||
print('=' * 79, file=self._output)
|
||||
print("You cannot see the normal loading screen because you are using Intel integrated graphics.",
|
||||
file=self._output)
|
||||
print('Please attempt to set python to execute with your dedicated graphics, if available.', file=self._output)
|
||||
print('=' * 79, file=self._output)
|
||||
|
||||
def close(self):
|
||||
if self._own_console:
|
||||
self._output.close()
|
||||
from ctypes import windll
|
||||
windll.kernel32.FreeConsole()
|
||||
|
|
|
@ -2,9 +2,11 @@ import argparse
|
|||
|
||||
import pyglet
|
||||
|
||||
from punyverse.loader import LoaderConsole
|
||||
|
||||
INITIAL_WIN_HEIGHT = 540
|
||||
INITIAL_WIN_WIDTH = 700
|
||||
DEBUG = False
|
||||
DEBUG = True
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -27,12 +29,12 @@ def main():
|
|||
from punyverse.loader import LoaderWindow
|
||||
from punyverse.ui import Punyverse
|
||||
loader = LoaderWindow(width=INITIAL_WIN_WIDTH, height=INITIAL_WIN_HEIGHT,
|
||||
caption='Punyverse is loading...')
|
||||
caption='Punyverse is loading...', visible=False)
|
||||
|
||||
template = pyglet.gl.Config(depth_size=args.depth, double_buffer=True,
|
||||
sample_buffers=args.multisample > 1,
|
||||
samples=args.multisample,
|
||||
major_version=3)
|
||||
major_version=3, minor_version=0)
|
||||
|
||||
platform = pyglet.window.get_platform()
|
||||
display = platform.get_default_display()
|
||||
|
@ -41,15 +43,20 @@ def main():
|
|||
config = screen.get_best_config(template)
|
||||
except pyglet.window.NoSuchConfigException:
|
||||
raise SystemExit('Graphics configuration not supported.')
|
||||
else:
|
||||
if hasattr(config, '_attribute_names'):
|
||||
print('OpenGL configuration:')
|
||||
for key in config._attribute_names:
|
||||
print(' %-22s %s' % (key + ':', getattr(config, key)))
|
||||
|
||||
punyverse = Punyverse(width=INITIAL_WIN_WIDTH, height=INITIAL_WIN_HEIGHT,
|
||||
caption='Punyverse', resizable=True, vsync=args.vsync,
|
||||
config=config, visible=False)
|
||||
create_args = dict(width=INITIAL_WIN_WIDTH, height=INITIAL_WIN_HEIGHT,
|
||||
caption='Punyverse', resizable=True, vsync=args.vsync, visible=False)
|
||||
|
||||
from pyglet.gl import gl_info
|
||||
if pyglet.compat_platform in ('win32', 'cygwin') and gl_info.get_vendor() == 'Intel':
|
||||
from pyglet.gl.win32 import Win32ARBContext
|
||||
context = Win32ARBContext(config, None)
|
||||
loader.close()
|
||||
loader = LoaderConsole()
|
||||
punyverse = Punyverse(context=context, **create_args)
|
||||
else:
|
||||
loader.set_visible(True)
|
||||
punyverse = Punyverse(config=config, **create_args)
|
||||
|
||||
loader.set_main_context(punyverse.context)
|
||||
world = loader.load()
|
||||
|
@ -57,7 +64,6 @@ def main():
|
|||
punyverse.initialize(world)
|
||||
loader.close()
|
||||
punyverse.set_visible(True)
|
||||
|
||||
pyglet.app.run()
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
from ctypes import pointer, byref, create_string_buffer, POINTER, cast
|
||||
|
|
|
@ -1,83 +1,57 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import print_function, division
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
from pyglet.gl import GLint, glGetIntegerv, GL_MAX_TEXTURE_SIZE
|
||||
from ctypes import byref
|
||||
from PIL import Image
|
||||
|
||||
buf = GLint()
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, byref(buf))
|
||||
max_texture = buf.value
|
||||
from punyverse.texture import max_texture_size
|
||||
|
||||
max_texture = max_texture_size()
|
||||
|
||||
del byref, GLint, glGetIntegerv, GL_MAX_TEXTURE_SIZE, buf
|
||||
|
||||
def resize(width, height, target):
|
||||
factor = (target + .0) / max(width, height)
|
||||
factor = target / max(width, height)
|
||||
return int(width * factor), int(height * factor)
|
||||
|
||||
|
||||
def fits(width, height):
|
||||
return width < max_texture and height < max_texture
|
||||
return width <= max_texture and height <= max_texture
|
||||
|
||||
|
||||
def make_name(image, suffix):
|
||||
name, ext = os.path.splitext(image)
|
||||
return '%s_%s%s' % (name, suffix, ext)
|
||||
|
||||
try:
|
||||
import pgmagick
|
||||
|
||||
def get_image(image):
|
||||
return pgmagick.Image(image)
|
||||
|
||||
def get_size(image):
|
||||
size = image.size()
|
||||
return size.width(), size.height()
|
||||
|
||||
def scale(image, width, height):
|
||||
image.filterType(pgmagick.FilterTypes.LanczosFilter)
|
||||
image.scale(pgmagick.Geometry(width, height))
|
||||
return image
|
||||
|
||||
def save(image, file):
|
||||
image.write(file)
|
||||
except ImportError:
|
||||
from PIL import Image
|
||||
|
||||
def get_image(image):
|
||||
return Image.open(image)
|
||||
|
||||
def get_size(image):
|
||||
return image.size
|
||||
|
||||
def scale(image, width, height):
|
||||
original_width, original_height = image.size
|
||||
if width * 3 < original_width and height * 3 < original_height:
|
||||
image = image.resize((width * 2, height * 2))
|
||||
return image.resize((width, height), Image.ANTIALIAS)
|
||||
|
||||
def save(image, file):
|
||||
image.save(file)
|
||||
|
||||
def shrink(file):
|
||||
image = get_image(file)
|
||||
width, height = get_size(image)
|
||||
image = Image.open(file)
|
||||
width, height = image.size
|
||||
|
||||
if fits(width, height):
|
||||
print('no need')
|
||||
return
|
||||
width, height = resize(width, height, 2048)
|
||||
if fits(width, height):
|
||||
size = 'medium'
|
||||
|
||||
for attempt, new_size in [(4096, 'large'), (2048, 'medium')]:
|
||||
width, height = resize(width, height, attempt)
|
||||
if fits(width, height):
|
||||
size = new_size
|
||||
break
|
||||
else:
|
||||
width, height = resize(width, height, 1024) # 1024 is minimum
|
||||
width, height = resize(width, height, 1024) # 1024 is minimum
|
||||
size = 'small'
|
||||
|
||||
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)
|
||||
|
||||
original_width, original_height = image.size
|
||||
if width * 3 < original_width and height * 3 < original_height:
|
||||
image = image.resize((width * 2, height * 2))
|
||||
image.resize((width, height), Image.ANTIALIAS).save(name)
|
||||
print('saved to:', os.path.basename(name))
|
||||
save(image, name)
|
||||
else:
|
||||
print('alrady there')
|
||||
print('already there')
|
||||
|
||||
|
||||
textures = [
|
||||
'mercury.jpg',
|
||||
|
@ -99,6 +73,7 @@ textures = [
|
|||
'moons/mimas.jpg',
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
punyverse = os.path.dirname(__file__)
|
||||
try:
|
||||
|
@ -115,5 +90,6 @@ def main():
|
|||
else:
|
||||
print('exists not')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -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']
|
||||
__all__ = ['load_texture', 'load_clouds', 'load_image', 'get_best_texture', 'max_texture_size']
|
||||
|
||||
id = 0
|
||||
cache = {}
|
||||
|
@ -117,7 +117,11 @@ def glGetInteger(index):
|
|||
|
||||
|
||||
def max_texture_size():
|
||||
return glGetInteger(GL_MAX_TEXTURE_SIZE)
|
||||
size = glGetInteger(GL_MAX_TEXTURE_SIZE)
|
||||
if gl_info.get_vendor() == 'Intel':
|
||||
# Intel can't seem to handle more than 4096
|
||||
size = min(size, 4096)
|
||||
return size
|
||||
|
||||
|
||||
def check_size(width, height):
|
||||
|
|
|
@ -208,6 +208,9 @@ class Punyverse(pyglet.window.Window):
|
|||
self.world.cam.roll_right = False
|
||||
|
||||
def on_resize(self, width, height):
|
||||
if not width or not height:
|
||||
# Sometimes this happen for no reason?
|
||||
return
|
||||
self.label.y = height - 20
|
||||
glViewport(0, 0, width, height)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"length": 63.7,
|
||||
"bodies": {
|
||||
"sun": {
|
||||
"texture": ["sun.jpg", [0.99, 0.97, 0.66, 1]],
|
||||
"texture": ["sun.jpg"],
|
||||
"radius": 80000,
|
||||
"pitch": -90,
|
||||
"yaw": 7.25,
|
||||
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
},
|
||||
"mercury": {
|
||||
"texture": ["mercury.jpg", "mercury_small.jpg", [0.44, 0.43, 0.43, 1]],
|
||||
"texture": ["mercury.jpg", "mercury_small.jpg"],
|
||||
"radius": 2439.7,
|
||||
"z": "0.466697 * AU",
|
||||
"pitch": -90,
|
||||
|
@ -38,7 +38,7 @@
|
|||
"rotation": 5067014
|
||||
},
|
||||
"venus": {
|
||||
"texture": ["venus.jpg", [0.655, 0.38, 0.1, 1]],
|
||||
"texture": ["venus.jpg"],
|
||||
"radius": 6051.8,
|
||||
"z": "0.723327 * AU",
|
||||
"pitch": -90,
|
||||
|
@ -47,7 +47,7 @@
|
|||
"rotation": -20996798
|
||||
},
|
||||
"earth": {
|
||||
"texture": ["earth.jpg", "earth_medium.jpg", "earth_small.jpg", [0.11, 0.32, 0.43, 1]],
|
||||
"texture": ["earth.jpg", "earth_large.jpg", "earth_medium.jpg", "earth_small.jpg"],
|
||||
"radius": 6378.1,
|
||||
"z": "AU",
|
||||
"pitch": -90,
|
||||
|
@ -67,7 +67,7 @@
|
|||
"orbit_distance": "AU",
|
||||
"satellites": {
|
||||
"moon": {
|
||||
"texture": ["moon.jpg", "moon_medium.jpg", "moon_small.jpg", [0.53, 0.53, 0.53, 1]],
|
||||
"texture": ["moon.jpg", "moon_medium.jpg", "moon_small.jpg"],
|
||||
"radius": 1738.14,
|
||||
"distance": 38439,
|
||||
"sma": 384399,
|
||||
|
@ -94,7 +94,7 @@
|
|||
}
|
||||
},
|
||||
"mars": {
|
||||
"texture": ["mars.jpg", "mars_small.jpg", "mars_medium.jpg", [0.85, 0.47, 0.2, 1]],
|
||||
"texture": ["mars.jpg", "mars_large.jpg", "mars_medium.jpg", "mars_small.jpg"],
|
||||
"radius": 3396.2,
|
||||
"z": "1.524 * AU",
|
||||
"pitch": -90,
|
||||
|
@ -113,7 +113,7 @@
|
|||
}
|
||||
},
|
||||
"jupiter": {
|
||||
"texture": ["jupiter.jpg", "jupiter_medium.jpg", "jupiter_small.jpg", [0.65, 0.36, 0.19, 1]],
|
||||
"texture": ["jupiter.jpg", "jupiter_medium.jpg", "jupiter_small.jpg"],
|
||||
"radius": 71492,
|
||||
"mass": 1.8986e+27,
|
||||
"z": "5.2 * AU",
|
||||
|
@ -124,7 +124,7 @@
|
|||
"orbit_distance": "3 * AU",
|
||||
"satellites": {
|
||||
"io": {
|
||||
"texture": ["moons/io.jpg", "moons/io_small.jpg", [0.62, 0.56, 0.35, 1]],
|
||||
"texture": ["moons/io.jpg", "moons/io_small.jpg"],
|
||||
"radius": "1821.3 * 5",
|
||||
"distance": 126510,
|
||||
"sma": 421700,
|
||||
|
@ -134,7 +134,7 @@
|
|||
"eccentricity": 0.0041
|
||||
},
|
||||
"europa": {
|
||||
"texture": ["moons/europa.jpg", "moons/europa_small.jpg", [0.77, 0.74, 0.65, 1]],
|
||||
"texture": ["moons/europa.jpg", "moons/europa_small.jpg"],
|
||||
"radius": "1560.8 * 5",
|
||||
"distance": 201270,
|
||||
"sma": 670900,
|
||||
|
@ -144,7 +144,7 @@
|
|||
"eccentricity": 0.009
|
||||
},
|
||||
"ganymede": {
|
||||
"texture": ["moons/ganymede.jpg", "moons/ganymede_small.jpg", [0.52, 0.47, 0.46, 1]],
|
||||
"texture": ["moons/ganymede.jpg", "moons/ganymede_small.jpg"],
|
||||
"radius": "2634.1 * 5",
|
||||
"distance": 321120,
|
||||
"sma": 1070400,
|
||||
|
@ -154,7 +154,7 @@
|
|||
"eccentricity": 0.0013
|
||||
},
|
||||
"callisto": {
|
||||
"texture": ["moons/callisto.jpg", "moons/callisto_small.jpg", [0.49, 0.43, 0.34, 1]],
|
||||
"texture": ["moons/callisto.jpg", "moons/callisto_small.jpg"],
|
||||
"radius": "2410.3 * 5",
|
||||
"distance": 564810,
|
||||
"sma": 1882700,
|
||||
|
@ -166,7 +166,7 @@
|
|||
}
|
||||
},
|
||||
"saturn": {
|
||||
"texture": ["saturn.jpg", "saturn_medium.jpg", "saturn_small.jpg", [0.9, 0.8, 0.64, 1]],
|
||||
"texture": ["saturn.jpg", "saturn_medium.jpg", "saturn_small.jpg"],
|
||||
"radius": 60268,
|
||||
"mass": 5.6846e+26,
|
||||
"z": "9.58 * AU",
|
||||
|
@ -181,7 +181,7 @@
|
|||
"orbit_distance": "4 * AU",
|
||||
"satellites": {
|
||||
"titan": {
|
||||
"texture": ["moons/titan.jpg", "moons/titan_small.jpg", [0.52, 0.39, 0.23, 1]],
|
||||
"texture": ["moons/titan.jpg", "moons/titan_small.jpg"],
|
||||
"radius": "2576 * 10",
|
||||
"distance": "1221870 / 3 + 200000",
|
||||
"sma": 1221870,
|
||||
|
@ -191,7 +191,7 @@
|
|||
"eccentricity": 0.0288
|
||||
},
|
||||
"rhea": {
|
||||
"texture": ["moons/rhea.jpg", "moons/rhea_small.jpg", [0.62, 0.60, 0.59, 1]],
|
||||
"texture": ["moons/rhea.jpg", "moons/rhea_small.jpg"],
|
||||
"radius": "763.8 * 10",
|
||||
"distance": "527108 / 3 + 200000",
|
||||
"sma": 527108,
|
||||
|
@ -201,7 +201,7 @@
|
|||
"eccentricity": 0.0012583
|
||||
},
|
||||
"iapetus": {
|
||||
"texture": ["moons/iapetus.jpg", "moons/iapetus_small.jpg", [0.62, 0.60, 0.59, 1]],
|
||||
"texture": ["moons/iapetus.jpg", "moons/iapetus_small.jpg"],
|
||||
"radius": "734.5 * 10",
|
||||
"distance": "3560820 / 3 + 200000",
|
||||
"sma": 3560820,
|
||||
|
@ -211,7 +211,7 @@
|
|||
"eccentricity": 0.0286125
|
||||
},
|
||||
"dione": {
|
||||
"texture": ["moons/dione.jpg", "moons/dione_small.jpg", [0.46, 0.46, 0.46, 1]],
|
||||
"texture": ["moons/dione.jpg", "moons/dione_small.jpg"],
|
||||
"radius": "561.4 * 10",
|
||||
"distance": "377396 / 3 + 200000",
|
||||
"sma": 377396,
|
||||
|
@ -221,7 +221,7 @@
|
|||
"eccentricity": 0.0022
|
||||
},
|
||||
"tethys": {
|
||||
"texture": ["moons/tethys.jpg", "moons/tethys_small.jpg", [0.68, 0.68, 0.66, 1]],
|
||||
"texture": ["moons/tethys.jpg", "moons/tethys_small.jpg"],
|
||||
"radius": "531.1 * 10",
|
||||
"distance": "294619 / 3 + 200000",
|
||||
"sma": 294619,
|
||||
|
@ -231,7 +231,7 @@
|
|||
"eccentricity": 0.0001
|
||||
},
|
||||
"enceladus": {
|
||||
"texture": ["moons/enceladus.jpg", "moons/enceladus_small.jpg", [0.74, 0.74, 0.74, 1]],
|
||||
"texture": ["moons/enceladus.jpg", "moons/enceladus_small.jpg"],
|
||||
"radius": "252.1 * 10",
|
||||
"distance": "237948 / 3 + 200000",
|
||||
"sma": 237948,
|
||||
|
@ -241,7 +241,7 @@
|
|||
"eccentricity": 0.0047
|
||||
},
|
||||
"mimas": {
|
||||
"texture": ["moons/mimas.jpg", "moons/mimas_small.jpg", [0.47, 0.47, 0.47, 1]],
|
||||
"texture": ["moons/mimas.jpg", "moons/mimas_small.jpg"],
|
||||
"radius": "198.2 * 10",
|
||||
"distance": "181902 / 3 + 200000",
|
||||
"sma": 181902,
|
||||
|
@ -261,7 +261,7 @@
|
|||
}
|
||||
},
|
||||
"uranus": {
|
||||
"texture": ["uranus.jpg", [0, 0.53, 0.84, 1]],
|
||||
"texture": ["uranus.jpg"],
|
||||
"radius": 25559,
|
||||
"mass": 8.6810e+25,
|
||||
"z": "19.23 * AU",
|
||||
|
@ -278,7 +278,7 @@
|
|||
}
|
||||
},
|
||||
"neptune": {
|
||||
"texture": ["neptune.jpg", [0.31, 0.49, 0.59, 1]],
|
||||
"texture": ["neptune.jpg"],
|
||||
"radius": 24764,
|
||||
"mass": 1.0243e+26,
|
||||
"z": "30.5 * AU",
|
||||
|
@ -299,7 +299,7 @@
|
|||
}
|
||||
},
|
||||
"sky": {
|
||||
"texture": "sky.jpg",
|
||||
"texture": ["sky.jpg", "sky_large.jpg", "sky_medium.jpg", "sky_small.jpg"],
|
||||
"rotation": 0,
|
||||
"division": 30,
|
||||
"pitch": 90,
|
||||
|
|
Loading…
Reference in a new issue