diff --git a/engine b/engine index 5c9e10e..028ba40 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit 5c9e10eea8059353c7bd8d48e669a9009b60c218 +Subproject commit 028ba40148ec570f9f979c70d36fe268cfad1a2e diff --git a/game/batch.py b/game/batch.py index 036f5cb..de6b148 100644 --- a/game/batch.py +++ b/game/batch.py @@ -21,9 +21,9 @@ from engine import ( class Batch: __slots__ = '_batch', 'max_size', 'format', 'flags', 'meshes', 'params' - def __init__(self, max_size, params_format): + def __init__(self, vertices, max_size, params_format): assert max_size <= BATCH_MAX_SIZE - self._batch = create_batch(max_size, params_format) + self._batch = create_batch(vertices, max_size, params_format) self.max_size = max_size self.format = params_format self.flags = array('B') diff --git a/game/camera.py b/game/camera.py index 5e3d61d..030148f 100644 --- a/game/camera.py +++ b/game/camera.py @@ -18,10 +18,10 @@ from engine import mat4, mat4_projection, mat4_lookat, resolve_input, set_input_ class Camera: __slots__ = '_projection_input', '_projection', '_view_input', '_view' - def __init__(self, projection_input = b'u_projection', view_input = b'u_view'): - self._projection_input = resolve_input(projection_input) + def __init__(self): + self._projection_input = None self._projection = mat4() - self._view_input = resolve_input(view_input) + self._view_input = None self._view = mat4() @property @@ -38,6 +38,10 @@ class Camera: def set_view(self, origin, lookat): mat4_lookat(self._view, origin, lookat) + def resolve_inputs(self, shader, projection_input = b'u_projection', view_input = b'u_view'): + self._projection_input = resolve_input(shader, projection_input) + self._view_input = resolve_input(shader, view_input) + def update_inputs(self): set_input_mat4(self._projection_input, self._projection) set_input_mat4(self._view_input, self._view) diff --git a/game/environment.py b/game/environment.py index 348fd48..0c83b4a 100644 --- a/game/environment.py +++ b/game/environment.py @@ -65,12 +65,12 @@ def _resolve_color(ranges, c): w, (a, b) = _resolve(ranges, c) return vec3_add(a, vec3_scale(b, w)) -def resolve_inputs(): - light_direction = resolve_input(b'u_light_direction') - light_color = resolve_input(b'u_light_color') - horizon_color = resolve_input(b'u_horizon_color') - sky_color = resolve_input(b'u_sky_color') - sun_color = resolve_input(b'u_sun_color') +def resolve_inputs(shader): + light_direction = resolve_input(shader, b'u_light_direction') + light_color = resolve_input(shader, b'u_light_color') + horizon_color = resolve_input(shader, b'u_horizon_color') + sky_color = resolve_input(shader, b'u_sky_color') + sun_color = resolve_input(shader, b'u_sun_color') return (light_direction, light_color, horizon_color, sky_color, sun_color) def from_sun(view, sun_direction, sun_power): diff --git a/game/game.py b/game/game.py index cb3228f..9c38ea7 100644 --- a/game/game.py +++ b/game/game.py @@ -33,12 +33,20 @@ def main(): terrain_shader = shader.load('terrain') sky_shader = shader.load('sky') - select_shader(terrain_shader) - terrain_environment_inputs = environment.resolve_inputs() + heightmap = create_texture( + 1, TEXTURE_FORMAT_32F, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR, + generated.packed_heights) + heightmap_sampler = resolve_input(terrain_shader, b'u_height_sampler') + + normalmap = create_texture( + 2, TEXTURE_FORMAT_RGB10_A2, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR, + generated.packed_normals) + normalmap_sampler = resolve_input(terrain_shader, b'u_normal_sampler') print("Loading resources...") archive = resources.RuntimeArchive.load('data/rk_island.rkar') tiles_texture = archive.get_texture('tiles') + tiles_sampler = resolve_input(terrain_shader, b'u_texture_sampler') tiles_vertices = archive.get_vertices('tiles') water = archive.get_model('water') sand = archive.get_model('sand') @@ -48,18 +56,9 @@ def main(): mud = archive.get_model('mud') lava = archive.get_model('lava') - heightmap = create_texture(1, b'u_height_sampler', - TEXTURE_FORMAT_32F, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR, - generated.packed_heights) - normalmap = create_texture(2, b'u_normal_sampler', - TEXTURE_FORMAT_RGB10_A2, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR, - generated.packed_normals) - #TODO: generator & for real print("Building tiles...") - select_vertices(tiles_vertices) - terrain_orientation = resolve_param(b'i_orientation') - terrain_batch = batch.Batch(generated.size ** 2, params_format(PARAM_FORMAT_VEC3_SHORT)) + terrain_batch = batch.Batch(tiles_vertices, generated.size ** 2, params_format(PARAM_FORMAT_VEC3_SHORT)) vc = generated.volcano_c vr = generated.volcano_r for my, mx in generated.map_coords: @@ -89,15 +88,14 @@ def main(): else: model = rock model.spawn(terrain_batch, (float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0)) - unselect_vertices(tiles_vertices) tests_texture = archive.get_texture('tests') + tests_sampler = resolve_input(terrain_shader, b'u_texture_sampler') tests_vertices = archive.get_vertices('tests') blob = archive.get_model('blob') cube = archive.get_model('cube') clouds = archive.get_model('clouds') - select_vertices(tests_vertices) - tests_batch = batch.Batch(3, + tests_batch = batch.Batch(tests_vertices, 3, params_format(PARAM_FORMAT_VEC3_FLOAT, PARAM_FORMAT_VEC3_INT10 | PARAM_FORMAT_NORMALIZE)) blob_translation = vec3((-100.0, -500.0, 0.0)) cube_translation = vec3((100.0, -500.0, 0.0)) @@ -106,27 +104,30 @@ def main(): blob_id = blob.spawn(tests_batch, blob_translation, vec3_forward) cube_id = cube.spawn(tests_batch, cube_translation, cube_orientation) clouds_id = clouds.spawn(tests_batch, (0.0, 0.0, 32.0), clouds_orientation) - unselect_vertices(tests_vertices) proj_hfov = pi * 0.25 proj_ratio = 16.0 / 9.0 proj_near_z = 8.0 proj_far_z = 3000.0 + + terrain_environment_inputs = environment.resolve_inputs(terrain_shader) + terrain_orientation = resolve_param(terrain_shader, b'i_orientation') terrain_camera = camera.Camera() terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) - unselect_shader(terrain_shader) + terrain_camera.resolve_inputs(terrain_shader) - select_shader(sky_shader) - sky_environment_inputs = environment.resolve_inputs() - sea_phase = resolve_input(b'u_sea_phase') + sky_environment_inputs = environment.resolve_inputs(sky_shader) + sea_phase = resolve_input(sky_shader, b'u_sea_phase') sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png')) + sea_polar_sampler = resolve_input(sky_shader, b'u_sea_polar_sampler') sea_detail_texture = sea.load_detail_texture('data/sea_bump.png') + sea_detail_sampler = resolve_input(sky_shader, b'u_sea_detail_sampler') sky_triangles = create_triangles(triangles.sky_triangles(64, proj_far_z - 0.1, proj_ratio)) sky_camera = camera.Camera() sky_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) - unselect_shader(sky_shader) + sky_camera.resolve_inputs(sky_shader) - sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 0.25))) + sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 1.0))) sun_power = 1.0 origin = vec3((0.0, -1200.0, 500.0)) lookat = vec3((0.0, 500.0, -500.0)) @@ -175,15 +176,15 @@ def main(): tests_batch.set_param(1, clouds_id, _clouds_orientation) select_shader(terrain_shader) - select_texture(heightmap) - select_texture(normalmap) + select_texture(heightmap, heightmap_sampler) + select_texture(normalmap, normalmap_sampler) terrain_camera.set_view(_origin, _lookat) terrain_camera.update_inputs() environment_values = environment.from_sun(terrain_camera.view, sun_direction, sun_power) environment.update_inputs(terrain_environment_inputs, environment_values) - select_texture(tiles_texture) + select_texture(tiles_texture, tiles_sampler) select_vertices(tiles_vertices) set_param_vec3(terrain_orientation, vec3(vec3_forward)) draw_begin = time.thread_time() @@ -192,7 +193,7 @@ def main(): unselect_vertices(tiles_vertices) unselect_texture(tiles_texture) - select_texture(tests_texture) + select_texture(tests_texture, tests_sampler) select_vertices(tests_vertices) tests_batch.draw() unselect_vertices(tests_vertices) @@ -210,8 +211,8 @@ def main(): environment_values = environment.from_sun(sky_camera.view, sun_direction, sun_power) environment.update_inputs(sky_environment_inputs, environment_values) set_input_float(sea_phase, (current_time * 0.023) % 1.0) - select_texture(sea_polar_textures) - select_texture(sea_detail_texture) + select_texture(sea_polar_textures, sea_polar_sampler) + select_texture(sea_detail_texture, sea_detail_sampler) draw_triangles(sky_triangles) unselect_texture(sea_detail_texture) unselect_texture(sea_polar_textures) diff --git a/game/resources.py b/game/resources.py index 197a8d2..ef649d5 100644 --- a/game/resources.py +++ b/game/resources.py @@ -132,9 +132,9 @@ class TextureData: _write_struct(file, 'IIIII', (self.format, self.width, self.height, self.nlevels, self.flags)) _write_blob(file, self.pixels) -def create_texture(slot, input, data): +def create_texture(slot, data): return engine.create_texture( - slot, input, data.format, data.width, data.height, data.nlevels, data.flags, data.pixels) + slot, data.format, data.width, data.height, data.nlevels, data.flags, data.pixels) class VerticesData: __slots__ = 'name', 'vertices', 'indices' @@ -279,7 +279,7 @@ class Archive: class RuntimeArchive(Archive): @classmethod def _new_texture(cls, data): - return create_texture(0, b'u_texture_sampler', data) + return create_texture(0, data) @classmethod def _new_vertices(cls, data): diff --git a/game/sea.py b/game/sea.py index 7a31520..6e3b9d1 100644 --- a/game/sea.py +++ b/game/sea.py @@ -51,7 +51,7 @@ def load_polar_textures(paths, waves_height = 0.008): _width, _height, normals = load_texture(path) assert _width == width and _height == height data.extend(list(map(_conv, normals))) - return create_texture(0, b'u_sea_polar_sampler', _format, width, height, len(paths), _flags, data) + return create_texture(0, _format, width, height, len(paths), _flags, data) def load_detail_texture(path, scale = 0.5, waves_height = 0.002): width, height, data = load_png(path) @@ -68,4 +68,4 @@ def load_detail_texture(path, scale = 0.5, waves_height = 0.002): return vec3_scale(n, copysign(1.0, n[2])) normals = list(map(normal, product(range(height), range(width)), data)) data = array(_typecode, list(map(_conv, normals))) - return create_texture(1, b'u_sea_detail_sampler', _format, width, height, 0, _flags, data) + return create_texture(1, _format, width, height, 0, _flags, data)