diff --git a/engine b/engine index eaff99a..84ea17f 160000 --- a/engine +++ b/engine @@ -1 +1 @@ -Subproject commit eaff99a5b61355f2c6fa138eb54feb654ba24e78 +Subproject commit 84ea17f1cca7d4d9c27be716c38e19f70335fa8a diff --git a/game/batch.py b/game/batch.py index de6b148..07cd6e7 100644 --- a/game/batch.py +++ b/game/batch.py @@ -13,40 +13,34 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +from ctypes import POINTER from array import array from engine import ( INSTANCE_FLAG_SPAWNED, BATCH_MAX_SIZE, create_batch, draw_batch, destroy_batch) class Batch: - __slots__ = '_batch', 'max_size', 'format', 'flags', 'meshes', 'params' + __slots__ = '_batch', '_paramsp', 'max_size', 'flags', 'meshes', 'params' - def __init__(self, vertices, max_size, params_format): + def __init__(self, vertices, max_size, params_format, params_type): assert max_size <= BATCH_MAX_SIZE self._batch = create_batch(vertices, max_size, params_format) + self._paramsp = POINTER(params_type) self.max_size = max_size - self.format = params_format self.flags = array('B') self.meshes = array('I') - self.params = array('f') + self.params = (params_type * max_size)() def __del__(self): destroy_batch(self._batch) def append(self, flags, mesh, params): - assert len(params) == len(self.format) index = len(self.flags) assert index < self.max_size self.flags.append(flags | INSTANCE_FLAG_SPAWNED) self.meshes.append(mesh) - def append_param(param): - start = len(self.params) - self.params.extend(param) - return slice(start, len(self.params)) - return tuple(map(append_param, params)) - - def set_param(self, param, id, value): - self.params[id[param]] = value + self.params[index] = params + return index def draw(self): - draw_batch(self._batch, self.flags, self.meshes, self.params) + draw_batch(self._batch, self.flags, self.meshes, self._paramsp(self.params)) diff --git a/game/environment.py b/game/environment.py index 35e6f7f..2c718b6 100644 --- a/game/environment.py +++ b/game/environment.py @@ -14,8 +14,8 @@ # along with this program. If not, see . from math import radians, cos -from engine import vec3, vec3_up, mat4_mul_vec3, resolve_input, set_input_vec3 -from game.math import vec3_add, vec3_sub, vec3_scale, vec3_mul, vec3_dot +from engine import vec3, mat4_mul_vec3, resolve_input, set_input_vec3 +from game.math import vec3_up, vec3_add, vec3_sub, vec3_scale, vec3_mul, vec3_dot def _angles(start, end): cmin = round(cos(radians(start)), 6) @@ -85,11 +85,11 @@ class Environment: def from_sun(self, view, sun_direction, sun_power): c = vec3_dot(sun_direction, vec3_up) light_power = _resolve_float(_light_power, c) * sun_power - mat4_mul_vec3(self.light_direction, view, sun_direction, 0.0) - self.light_color = vec3(vec3_scale(_resolve_color(_light_color, c), light_power)) - self.horizon_color = vec3(vec3_scale(_resolve_color(_horizon_color, c), light_power)) - self.sky_color = vec3(vec3_scale(_resolve_color(_sky_color, c), light_power)) - self.sun_color = vec3(_resolve_color(_sun_color, c)) + mat4_mul_vec3(self.light_direction, view, vec3(*sun_direction), 0.0) + self.light_color.set(*vec3_scale(_resolve_color(_light_color, c), light_power)) + self.horizon_color.set(*vec3_scale(_resolve_color(_horizon_color, c), light_power)) + self.sky_color.set(*vec3_scale(_resolve_color(_sky_color, c), light_power)) + self.sun_color.set(*_resolve_color(_sun_color, c)) def resolve_inputs(self, shader): return _Inputs(shader) diff --git a/game/game.py b/game/game.py index 16b9f88..ff4c63b 100644 --- a/game/game.py +++ b/game/game.py @@ -15,6 +15,7 @@ import time from math import pi, tau, dist +from ctypes import Structure from engine import * @@ -78,7 +79,7 @@ def main(): rock_model = archive.get_model('rock') mud_model = archive.get_model('mud') lava_model = archive.get_model('lava') - terrain_batch = batch.Batch(tiles_vertices, generated.size ** 2, params_format(PARAM_FORMAT_VEC3_SHORT)) + terrain_batch = batch.Batch(tiles_vertices, generated.size ** 2, params_format(PARAM_FORMAT_VEC3_SHORT), vec3) #TODO: generator & for real vc = generated.volcano_c @@ -109,7 +110,10 @@ def main(): model = mud_model else: model = rock_model - model.spawn(terrain_batch, (float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0)) + model.spawn(terrain_batch, vec3(float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0)) + + class testsparams(Structure): + _fields_ = ('translation', vec3), ('orientation', vec3) tests_texture = archive.get_texture('tests') tests_sampler = resolve_input(tests_shader, b'u_texture_sampler') @@ -118,12 +122,13 @@ def main(): cube_model = archive.get_model('cube') clouds_model = archive.get_model('clouds') tests_batch = batch.Batch(tests_vertices, 3, - params_format(PARAM_FORMAT_VEC3_FLOAT, PARAM_FORMAT_VEC3_INT10 | PARAM_FORMAT_NORMALIZE)) - blob_spawn_translation = vec3((-100.0, -500.0, 0.0)) - cube_spawn_translation = vec3((100.0, -500.0, 0.0)) - blob_id = blob_model.spawn(tests_batch, blob_spawn_translation, vec3_forward) - cube_id = cube_model.spawn(tests_batch, cube_spawn_translation, vec3_forward) - clouds_id = clouds_model.spawn(tests_batch, (0.0, 0.0, 32.0), vec3_forward) + params_format(PARAM_FORMAT_VEC3_FLOAT, PARAM_FORMAT_VEC3_INT10 | PARAM_FORMAT_NORMALIZE), testsparams) + blob_spawn_translation = vec3(-100.0, -500.0, 0.0) + cube_spawn_translation = vec3(100.0, -500.0, 0.0) + blob_id = blob_model.spawn(tests_batch, + testsparams(blob_spawn_translation, vec3(*math.vec3_normalize((sun_direction[0], sun_direction[1], 0.0))))) + cube_id = cube_model.spawn(tests_batch, testsparams(cube_spawn_translation, vec3_forward)) + clouds_id = clouds_model.spawn(tests_batch, testsparams(vec3(0.0, 0.0, 32.0), vec3_forward)) 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')) @@ -143,15 +148,9 @@ def main(): tests_environment_inputs = environment.resolve_inputs(tests_shader) sky_environment_inputs = environment.resolve_inputs(sky_shader) - _forward = vec3(vec3_forward) - _up = vec3(vec3_up) _rotation = mat3() _origin = vec3() _lookat = vec3() - _blob_translation = vec3() - _cube_translation = vec3() - _cube_orientation = vec3() - _clouds_orientation = vec3() print("Running...") start_time = time.monotonic() @@ -170,24 +169,19 @@ def main(): begin_frame() frame_begin = time.thread_time() - mat3_rotation(_rotation, _up, (current_time * 0.21) % tau) - mat3_mul_vec3(_blob_translation, _rotation, blob_spawn_translation) - tests_batch.set_param(0, blob_id, _blob_translation) - tests_batch.set_param(1, blob_id, vec3(math.vec3_normalize((sun_direction[0], sun_direction[1], 0.0)))) - mat3_mul_vec3(_cube_translation, _rotation, cube_spawn_translation) - tests_batch.set_param(0, cube_id, _cube_translation) - mat3_rotation(_rotation, _up, (current_time * 0.43) % tau) - mat3_mul_vec3(_cube_orientation, _rotation, _forward) - tests_batch.set_param(1, cube_id, _cube_orientation) - mat3_rotation(_rotation, _up, (current_time * -0.037) % tau) - mat3_mul_vec3(_clouds_orientation, _rotation, _forward) - tests_batch.set_param(1, clouds_id, _clouds_orientation) + mat3_rotation(_rotation, vec3_up, (current_time * 0.21) % tau) + mat3_mul_vec3(tests_batch.params[blob_id].translation, _rotation, blob_spawn_translation) + mat3_mul_vec3(tests_batch.params[cube_id].translation, _rotation, cube_spawn_translation) + mat3_rotation(_rotation, vec3_up, (current_time * 0.43) % tau) + mat3_mul_vec3(tests_batch.params[cube_id].orientation, _rotation, vec3_forward) + mat3_rotation(_rotation, vec3_up, (current_time * -0.037) % tau) + mat3_mul_vec3(tests_batch.params[clouds_id].orientation, _rotation, vec3_forward) - mat3_rotation(_rotation, _up, (current_time * 0.05) % tau) - mat3_mul_vec3(_origin, _rotation, vec3(camera_origin)) - mat3_mul_vec3(_lookat, _rotation, vec3(camera_lookat)) + mat3_rotation(_rotation, vec3_up, (current_time * 0.05) % tau) + mat3_mul_vec3(_origin, _rotation, vec3(*camera_origin)) + mat3_mul_vec3(_lookat, _rotation, vec3(*camera_lookat)) camera.set_view(_origin, _lookat) - environment.from_sun(camera.view, vec3(sun_direction), sun_power) + environment.from_sun(camera.view, sun_direction, sun_power) select_shader(terrain_shader) camera.update_inputs(terrain_camera_inputs) @@ -219,7 +213,9 @@ def main(): unselect_texture(2, normalmap) unselect_shader(tests_shader) - camera.set_view(vec3(math.vec3_scale(_origin, 0.001)), vec3(math.vec3_scale(_lookat, 0.001))) + camera.set_view( + vec3(_origin.x * 0.001, _origin.y * 0.001, _origin.z * 0.001), + vec3(_lookat.x * 0.001, _lookat.y * 0.001, _lookat.z * 0.001)) select_shader(sky_shader) camera.update_inputs(sky_camera_inputs) @@ -263,9 +259,14 @@ def main(): # camera_lookat = vec3((0.0, 500.0, -500.0)) # for x in range(10000) # current_time = 0 - # Draw * 9999 : min = 0.2 , max = 2.16 , avg = 0.26 ms - # Draw * 9999 : min = 0.2 , max = 2.77 , avg = 0.27 ms - # Draw * 9999 : min = 0.2 , max = 2.00 , avg = 0.27 ms + + # Draw * 9999 : min = 0.21 , max = 2.16 , avg = 0.27 ms + # Draw * 9999 : min = 0.20 , max = 1.96 , avg = 0.27 ms + # Draw * 9999 : min = 0.20 , max = 2.43 , avg = 0.27 ms + + # Frame * 9999 : min = 0.27 , max = 2.29 , avg = 0.38 ms + # Frame * 9999 : min = 0.26 , max = 2.08 , avg = 0.37 ms + # Frame * 9999 : min = 0.26 , max = 2.59 , avg = 0.38 ms print("Quitting...") del tests_batch diff --git a/game/math.py b/game/math.py index 7800fef..c427eaa 100644 --- a/game/math.py +++ b/game/math.py @@ -15,6 +15,10 @@ from math import hypot +vec3_right = (1.0, 0.0, 0.0) +vec3_forward = (0.0, 1.0, 0.0) +vec3_up = (0.0, 0.0, 1.0) + def vec3_add(a, b): return (a[0] + b[0], a[1] + b[1], a[2] + b[2]) diff --git a/game/resources.py b/game/resources.py index 2982503..7d7ed3d 100644 --- a/game/resources.py +++ b/game/resources.py @@ -191,7 +191,7 @@ class Model: self.flags = flags self.mesh = mesh - def spawn(self, batch, *params): + def spawn(self, batch, params): return batch.append(self.flags, self.mesh, params) def create_model(data):