# Copyright (C) 2022 RozK # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import time from math import pi, tau, dist from engine import * from game import math, resources, camera, batch, triangles, generator, environment, sea def main(): print("Generating terrain...") gen_begin = time.process_time() generated = generator.Generator(256) gen_end = time.process_time() print("Done: ", round(gen_end - gen_begin, 2), "seconds") print("Initializing...") window = initialize(b'RK Island', 1600, 900) terrain_shader = load_shader(b'game/shaders/terrain') sky_shader = load_shader(b'game/shaders/sky') print("Loading resources...") select_shader(terrain_shader) archive = resources.RuntimeArchive.load('data/rk_island.rkar') tiles_texture = archive.get_texture('tiles') tiles_vertices = archive.get_vertices('tiles') water = archive.get_model('water') sand = archive.get_model('sand') grass = archive.get_model('grass') forest = archive.get_model('forest') rock = archive.get_model('rock') 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) select_vertices(tiles_vertices) terrain_batch = batch.Batch( generated.size ** 2, BATCH_TRANSLATION_FORMAT_SHORT, BATCH_ORIENTATION_FORMAT_NONE) unselect_vertices(tiles_vertices) terrain_environment_inputs = environment.resolve_inputs() tests_texture = archive.get_texture('tests') 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, BATCH_TRANSLATION_FORMAT_FLOAT, BATCH_ORIENTATION_FORMAT_FLOAT) unselect_vertices(tests_vertices) #TODO: generator & for real print("Building tiles...") vc = generated.volcano_c vr = generated.volcano_r for my, mx in generated.map_coords: vd = dist((mx + 0.5, my + 0.5), vc) nx, ny, nz, h = generated.unpack(my, mx) r = generated.rivers[my * generated.size + mx] if h == 0.0: continue if r > 0.0: model = water elif h < 2.0: model = sand elif h < 180: if nz > 0.9: if ny < -0.01 and nz > 0.93: model = forest else: model = grass else: model = rock elif vd < vr - 3.0 and nz > 0.999: model = lava elif vd < vr + 2.0: model = mud elif vd < vr + 6.0 and nz < 0.67: model = mud else: model = rock model.spawn(terrain_batch, (float(((mx - 128) * 8) + 4), float(((127 - my) * 8) + 4), 0.0), None) blob_translation = vec3((-100.0, -500.0, 0.0)) cube_translation = vec3((100.0, -500.0, 0.0)) cube_orientation = vec3(vec3_forward) clouds_orientation = vec3(vec3_forward) blob_id = blob.spawn(tests_batch, blob_translation) cube_id = cube.spawn(tests_batch, cube_translation, cube_orientation) clouds_id = clouds.spawn(tests_batch, (0.0, 0.0, 32.0), clouds_orientation) proj_hfov = pi * 0.25 proj_ratio = 16.0 / 9.0 proj_near_z = 8.0 proj_far_z = 3000.0 terrain_camera = camera.Camera() terrain_camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z) unselect_shader(terrain_shader) select_shader(sky_shader) sky_environment_inputs = environment.resolve_inputs() sea_phase = resolve_input(b'u_sea_phase') sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png')) sea_detail_texture = sea.load_detail_texture('data/sea_bump.png') 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) sun_direction = vec3(math.vec3_normalize((1.0, 0.0, 0.0))) sun_power = 1.0 origin = vec3((0.0, -1200.0, 500.0)) lookat = vec3((0.0, 500.0, -500.0)) 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() current_time = 0.0 frame_min = 10000.0 frame_max = 0.0 frame_avg = 0.0 draw_min = 10000.0 draw_max = 0.0 draw_avg = 0.0 perf_count = 0 try: for x in range(10000): current_time = time.monotonic() - start_time begin_frame() frame_begin = time.thread_time() mat3_rotation(_rotation, up, (current_time * 0.05) % tau) mat3_mul_vec3(_origin, _rotation, origin) mat3_mul_vec3(_lookat, _rotation, lookat) mat3_rotation(_rotation, up, (current_time * 0.21) % tau) mat3_mul_vec3(_blob_translation, _rotation, blob_translation) tests_batch.set_translation(blob_id, _blob_translation) tests_batch.set_orientation(blob_id, vec3(math.vec3_normalize((sun_direction[0], sun_direction[1], 0.0)))) mat3_mul_vec3(_cube_translation, _rotation, cube_translation) tests_batch.set_translation(cube_id, _cube_translation) mat3_rotation(_rotation, up, (current_time * 0.43) % tau) mat3_mul_vec3(_cube_orientation, _rotation, cube_orientation) tests_batch.set_orientation(cube_id, _cube_orientation) mat3_rotation(_rotation, up, (current_time * -0.037) % tau) mat3_mul_vec3(_clouds_orientation, _rotation, clouds_orientation) tests_batch.set_orientation(clouds_id, _clouds_orientation) select_shader(terrain_shader) select_texture(heightmap) select_texture(normalmap) 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_vertices(tiles_vertices) draw_begin = time.thread_time() terrain_batch.draw() draw_end = time.thread_time() unselect_vertices(tiles_vertices) unselect_texture(tiles_texture) select_texture(tests_texture) select_vertices(tests_vertices) tests_batch.draw() unselect_vertices(tests_vertices) unselect_texture(tests_texture) unselect_texture(normalmap) unselect_texture(heightmap) unselect_shader(terrain_shader) select_shader(sky_shader) sky_camera.set_view( vec3(math.vec3_scale(_origin, 0.001)), vec3(math.vec3_scale(_lookat, 0.001))) sky_camera.update_inputs() 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) draw_triangles(sky_triangles) unselect_texture(sea_detail_texture) unselect_texture(sea_polar_textures) unselect_shader(sky_shader) frame_end = time.thread_time() end_frame() draw_ms = draw_end - draw_begin draw_min = min(draw_min, draw_ms) draw_max = max(draw_max, draw_ms) draw_avg += draw_ms frame_ms = frame_end - frame_begin frame_min = min(frame_min, frame_ms) frame_max = max(frame_max, frame_ms) frame_avg += frame_ms perf_count += 1 except KeyboardInterrupt: pass print("\rDraw *", perf_count, ": min =", round(draw_min * 1000.0, 2), ", max =", round(draw_max * 1000.0, 2), ", avg =", round((draw_avg / perf_count) * 1000.0, 2), "ms") print("\rFrame *", perf_count, ": min =", round(frame_min * 1000.0, 2), ", max =", round(frame_max * 1000.0, 2), ", avg =", round((frame_avg / perf_count) * 1000.0, 2), "ms") # seed 666 # origin = vec3((0.0, -1200.0, 500.0)) # lookat = vec3((0.0, 500.0, -500.0)) # for x in range(10000) # current_time = 0 # Draw * 10000 : min = 0.11 , max = 1.87 , avg = 0.16 ms # Draw * 10000 : min = 0.11 , max = 1.75 , avg = 0.17 ms # Draw * 10000 : min = 0.11 , max = 1.84 , avg = 0.17 ms print("Quitting...") del tests_batch del terrain_batch destroy_texture(sea_polar_textures) destroy_texture(sea_detail_texture) destroy_texture(heightmap) destroy_triangles(sky_triangles) archive.destroy() destroy_shader(terrain_shader) destroy_shader(sky_shader) terminate()