2022-08-28 05:09:52 +02:00
|
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
import time
|
|
|
|
from math import pi, tau, dist
|
2022-12-20 13:48:19 +01:00
|
|
|
from ctypes import Structure
|
2022-08-28 05:09:52 +02:00
|
|
|
|
|
|
|
from engine import *
|
|
|
|
|
2022-12-18 05:40:52 +01:00
|
|
|
from game import math
|
|
|
|
from game import generator
|
|
|
|
from game import shader
|
|
|
|
from game import resources
|
|
|
|
from game import batch
|
|
|
|
from game import triangles
|
|
|
|
from game import sea
|
2022-12-18 06:35:20 +01:00
|
|
|
from game.camera import Camera
|
|
|
|
from game.environment import Environment
|
2022-12-18 05:40:52 +01:00
|
|
|
|
|
|
|
proj_hfov = pi * 0.25
|
|
|
|
proj_ratio = 16.0 / 9.0
|
|
|
|
proj_near_z = 8.0
|
|
|
|
proj_far_z = 3000.0
|
|
|
|
|
2022-12-18 06:35:20 +01:00
|
|
|
camera_origin = (0.0, -1200.0, 500.0)
|
|
|
|
camera_lookat = (0.0, 500.0, -500.0)
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-19 06:40:49 +01:00
|
|
|
sun_direction = math.vec3_normalize((1.0, 0.0, 1.0))
|
|
|
|
sun_power = 1.0
|
|
|
|
|
2022-08-28 05:09:52 +02:00
|
|
|
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...")
|
2022-09-19 02:37:31 +02:00
|
|
|
window = initialize(b'RK Island', 1600, 900)
|
2022-12-18 04:53:28 +01:00
|
|
|
terrain_shader = shader.load('terrain', 'common')
|
|
|
|
tests_shader = shader.load('tests', 'common')
|
2022-12-04 03:23:03 +01:00
|
|
|
sky_shader = shader.load('sky')
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-18 03:44:31 +01:00
|
|
|
heightmap = create_texture(
|
2022-12-19 06:40:49 +01:00
|
|
|
TEXTURE_FORMAT_32F, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
2022-12-18 03:44:31 +01:00
|
|
|
generated.packed_heights)
|
2022-12-18 04:53:28 +01:00
|
|
|
terrain_heightmap_sampler = resolve_input(terrain_shader, b'u_height_sampler')
|
|
|
|
tests_heightmap_sampler = resolve_input(tests_shader, b'u_height_sampler')
|
2022-12-18 03:44:31 +01:00
|
|
|
|
|
|
|
normalmap = create_texture(
|
2022-12-19 06:40:49 +01:00
|
|
|
TEXTURE_FORMAT_RGB10_A2, 256, 256, 0, TEXTURE_FLAG_MIN_LINEAR | TEXTURE_FLAG_MAG_LINEAR,
|
2022-12-18 03:44:31 +01:00
|
|
|
generated.packed_normals)
|
2022-12-18 04:53:28 +01:00
|
|
|
terrain_normalmap_sampler = resolve_input(terrain_shader, b'u_normal_sampler')
|
|
|
|
tests_normalmap_sampler = resolve_input(tests_shader, b'u_normal_sampler')
|
2022-12-17 05:03:08 +01:00
|
|
|
|
|
|
|
print("Loading resources...")
|
2022-08-28 05:09:52 +02:00
|
|
|
archive = resources.RuntimeArchive.load('data/rk_island.rkar')
|
2022-12-19 06:40:49 +01:00
|
|
|
|
|
|
|
print("Building tiles...")
|
2022-08-28 05:09:52 +02:00
|
|
|
tiles_texture = archive.get_texture('tiles')
|
2022-12-18 03:44:31 +01:00
|
|
|
tiles_sampler = resolve_input(terrain_shader, b'u_texture_sampler')
|
2022-08-28 05:09:52 +02:00
|
|
|
tiles_vertices = archive.get_vertices('tiles')
|
2022-12-20 09:00:45 +01:00
|
|
|
water_model = archive.get_model('water')
|
|
|
|
sand_model = archive.get_model('sand')
|
|
|
|
grass_model = archive.get_model('grass')
|
|
|
|
forest_model = archive.get_model('forest')
|
|
|
|
rock_model = archive.get_model('rock')
|
|
|
|
mud_model = archive.get_model('mud')
|
|
|
|
lava_model = archive.get_model('lava')
|
2022-12-20 13:48:19 +01:00
|
|
|
terrain_batch = batch.Batch(tiles_vertices, generated.size ** 2, params_format(PARAM_FORMAT_VEC3_SHORT), vec3)
|
2022-12-17 05:03:08 +01:00
|
|
|
|
2022-08-28 05:09:52 +02:00
|
|
|
#TODO: generator & for real
|
|
|
|
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:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = water_model
|
2022-08-28 05:09:52 +02:00
|
|
|
elif h < 2.0:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = sand_model
|
2022-08-28 05:09:52 +02:00
|
|
|
elif h < 180:
|
|
|
|
if nz > 0.9:
|
|
|
|
if ny < -0.01 and nz > 0.93:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = forest_model
|
2022-08-28 05:09:52 +02:00
|
|
|
else:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = grass_model
|
2022-08-28 05:09:52 +02:00
|
|
|
else:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = rock_model
|
2022-08-28 05:09:52 +02:00
|
|
|
elif vd < vr - 3.0 and nz > 0.999:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = lava_model
|
2022-08-28 05:09:52 +02:00
|
|
|
elif vd < vr + 2.0:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = mud_model
|
2022-08-28 05:09:52 +02:00
|
|
|
elif vd < vr + 6.0 and nz < 0.67:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = mud_model
|
2022-08-28 05:09:52 +02:00
|
|
|
else:
|
2022-12-20 09:00:45 +01:00
|
|
|
model = rock_model
|
2022-12-20 13:48:19 +01:00
|
|
|
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)
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-17 05:03:08 +01:00
|
|
|
tests_texture = archive.get_texture('tests')
|
2022-12-18 04:53:28 +01:00
|
|
|
tests_sampler = resolve_input(tests_shader, b'u_texture_sampler')
|
2022-12-17 05:03:08 +01:00
|
|
|
tests_vertices = archive.get_vertices('tests')
|
2022-12-20 09:00:45 +01:00
|
|
|
blob_model = archive.get_model('blob')
|
|
|
|
cube_model = archive.get_model('cube')
|
|
|
|
clouds_model = archive.get_model('clouds')
|
2022-12-18 03:44:31 +01:00
|
|
|
tests_batch = batch.Batch(tests_vertices, 3,
|
2022-12-20 13:48:19 +01:00
|
|
|
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))
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-18 03:44:31 +01:00
|
|
|
sea_phase = resolve_input(sky_shader, b'u_sea_phase')
|
2022-08-28 05:09:52 +02:00
|
|
|
sea_polar_textures = sea.load_polar_textures(('data/sea_bump1.png', 'data/sea_bump2.png'))
|
2022-12-18 03:44:31 +01:00
|
|
|
sea_polar_sampler = resolve_input(sky_shader, b'u_sea_polar_sampler')
|
2022-08-28 05:09:52 +02:00
|
|
|
sea_detail_texture = sea.load_detail_texture('data/sea_bump.png')
|
2022-12-18 03:44:31 +01:00
|
|
|
sea_detail_sampler = resolve_input(sky_shader, b'u_sea_detail_sampler')
|
2022-08-28 05:09:52 +02:00
|
|
|
sky_triangles = create_triangles(triangles.sky_triangles(64, proj_far_z - 0.1, proj_ratio))
|
|
|
|
|
2022-12-18 05:40:52 +01:00
|
|
|
camera = Camera()
|
|
|
|
camera.set_projection(proj_hfov, proj_ratio, proj_near_z, proj_far_z)
|
|
|
|
terrain_camera_inputs = camera.resolve_inputs(terrain_shader)
|
|
|
|
tests_camera_inputs = camera.resolve_inputs(tests_shader)
|
|
|
|
sky_camera_inputs = camera.resolve_inputs(sky_shader)
|
|
|
|
|
2022-12-18 06:35:20 +01:00
|
|
|
environment = Environment()
|
2022-12-18 05:40:52 +01:00
|
|
|
terrain_environment_inputs = environment.resolve_inputs(terrain_shader)
|
|
|
|
tests_environment_inputs = environment.resolve_inputs(tests_shader)
|
|
|
|
sky_environment_inputs = environment.resolve_inputs(sky_shader)
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-20 15:39:38 +01:00
|
|
|
blob_translation = tests_batch.params[blob_id].translation
|
|
|
|
cube_translation = tests_batch.params[cube_id].translation
|
|
|
|
cube_orientation = tests_batch.params[cube_id].orientation
|
|
|
|
clouds_orientation = tests_batch.params[clouds_id].orientation
|
2022-08-28 05:09:52 +02:00
|
|
|
|
|
|
|
print("Running...")
|
2022-11-29 03:19:57 +01:00
|
|
|
start_time = time.monotonic()
|
|
|
|
current_time = 0.0
|
2022-08-28 05:09:52 +02:00
|
|
|
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:
|
2022-12-17 14:14:11 +01:00
|
|
|
for frame in range(10000):
|
2022-12-17 16:56:52 +01:00
|
|
|
current_time = time.monotonic() - start_time
|
2022-08-28 05:09:52 +02:00
|
|
|
|
|
|
|
begin_frame()
|
|
|
|
frame_begin = time.thread_time()
|
|
|
|
|
2022-12-20 15:39:38 +01:00
|
|
|
rotation = mat3()
|
|
|
|
mat3_rotation(rotation, vec3_up, (current_time * 0.21) % tau)
|
|
|
|
mat3_mul_vec3(blob_translation, rotation, blob_spawn_translation)
|
|
|
|
mat3_mul_vec3(cube_translation, rotation, cube_spawn_translation)
|
|
|
|
vec3_rotate(cube_orientation, vec3_forward, vec3_up, (current_time * 0.43) % tau)
|
|
|
|
vec3_rotate(clouds_orientation, vec3_forward, vec3_up, (current_time * -0.037) % tau)
|
|
|
|
|
|
|
|
origin = vec3()
|
|
|
|
lookat = vec3()
|
|
|
|
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)
|
2022-12-20 13:48:19 +01:00
|
|
|
environment.from_sun(camera.view, sun_direction, sun_power)
|
2022-12-18 05:40:52 +01:00
|
|
|
|
2022-08-28 05:09:52 +02:00
|
|
|
select_shader(terrain_shader)
|
2022-12-18 05:40:52 +01:00
|
|
|
camera.update_inputs(terrain_camera_inputs)
|
2022-12-18 06:35:20 +01:00
|
|
|
environment.update_inputs(terrain_environment_inputs)
|
2022-12-19 06:40:49 +01:00
|
|
|
select_texture(0, tiles_texture, tiles_sampler)
|
|
|
|
select_texture(1, heightmap, terrain_heightmap_sampler)
|
|
|
|
select_texture(2, normalmap, terrain_normalmap_sampler)
|
2022-08-28 05:09:52 +02:00
|
|
|
select_vertices(tiles_vertices)
|
|
|
|
draw_begin = time.thread_time()
|
|
|
|
terrain_batch.draw()
|
|
|
|
draw_end = time.thread_time()
|
|
|
|
unselect_vertices(tiles_vertices)
|
2022-12-19 06:40:49 +01:00
|
|
|
unselect_texture(0, tiles_texture)
|
|
|
|
unselect_texture(1, heightmap)
|
|
|
|
unselect_texture(2, normalmap)
|
2022-12-18 04:53:28 +01:00
|
|
|
unselect_shader(terrain_shader)
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-18 04:53:28 +01:00
|
|
|
select_shader(tests_shader)
|
2022-12-18 05:40:52 +01:00
|
|
|
camera.update_inputs(tests_camera_inputs)
|
2022-12-18 06:35:20 +01:00
|
|
|
environment.update_inputs(tests_environment_inputs)
|
2022-12-19 06:40:49 +01:00
|
|
|
select_texture(0, tests_texture, tests_sampler)
|
|
|
|
select_texture(1, heightmap, tests_heightmap_sampler)
|
|
|
|
select_texture(2, normalmap, tests_normalmap_sampler)
|
2022-08-28 05:09:52 +02:00
|
|
|
select_vertices(tests_vertices)
|
|
|
|
tests_batch.draw()
|
|
|
|
unselect_vertices(tests_vertices)
|
2022-12-19 06:40:49 +01:00
|
|
|
unselect_texture(0, tests_texture)
|
|
|
|
unselect_texture(1, heightmap)
|
|
|
|
unselect_texture(2, normalmap)
|
2022-12-18 04:53:28 +01:00
|
|
|
unselect_shader(tests_shader)
|
2022-08-28 05:09:52 +02:00
|
|
|
|
2022-12-20 15:39:38 +01:00
|
|
|
m2km = vec3(0.001, 0.001, 0.001)
|
|
|
|
origin_km = vec3()
|
|
|
|
lookat_km = vec3()
|
|
|
|
vec3_mul_vec3(origin_km, origin, m2km)
|
|
|
|
vec3_mul_vec3(lookat_km, lookat, m2km)
|
|
|
|
camera.set_view(origin_km, lookat_km)
|
2022-12-18 05:40:52 +01:00
|
|
|
|
2022-08-28 05:09:52 +02:00
|
|
|
select_shader(sky_shader)
|
2022-12-18 05:40:52 +01:00
|
|
|
camera.update_inputs(sky_camera_inputs)
|
2022-12-18 06:35:20 +01:00
|
|
|
environment.update_inputs(sky_environment_inputs)
|
2022-08-28 05:09:52 +02:00
|
|
|
set_input_float(sea_phase, (current_time * 0.023) % 1.0)
|
2022-12-19 06:40:49 +01:00
|
|
|
select_texture(0, sea_polar_textures, sea_polar_sampler)
|
|
|
|
select_texture(1, sea_detail_texture, sea_detail_sampler)
|
2022-08-28 05:09:52 +02:00
|
|
|
draw_triangles(sky_triangles)
|
2022-12-19 06:40:49 +01:00
|
|
|
unselect_texture(0, sea_polar_textures)
|
|
|
|
unselect_texture(1, sea_detail_texture)
|
2022-08-28 05:09:52 +02:00
|
|
|
unselect_shader(sky_shader)
|
|
|
|
|
|
|
|
frame_end = time.thread_time()
|
|
|
|
end_frame()
|
|
|
|
|
2022-12-17 14:14:11 +01:00
|
|
|
if frame > 0:
|
|
|
|
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
|
2022-08-28 05:09:52 +02:00
|
|
|
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
|
2022-12-18 05:40:52 +01:00
|
|
|
# camera_origin = vec3((0.0, -1200.0, 500.0))
|
|
|
|
# camera_lookat = vec3((0.0, 500.0, -500.0))
|
2022-08-28 05:09:52 +02:00
|
|
|
# for x in range(10000)
|
|
|
|
# current_time = 0
|
2022-12-20 13:48:19 +01:00
|
|
|
|
2022-12-20 15:39:38 +01:00
|
|
|
# Draw * 9999 : min = 0.2 , max = 2.31 , avg = 0.27 ms
|
|
|
|
# Draw * 9999 : min = 0.2 , max = 2.41 , avg = 0.27 ms
|
|
|
|
# Draw * 9999 : min = 0.2 , max = 2.73 , avg = 0.27 ms
|
2022-12-20 13:48:19 +01:00
|
|
|
|
2022-12-20 15:39:38 +01:00
|
|
|
# Frame * 9999 : min = 0.26 , max = 2.44 , avg = 0.38 ms
|
|
|
|
# Frame * 9999 : min = 0.26 , max = 2.54 , avg = 0.37 ms
|
|
|
|
# Frame * 9999 : min = 0.26 , max = 2.90 , avg = 0.38 ms
|
2022-08-28 05:09:52 +02:00
|
|
|
|
|
|
|
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)
|
2022-12-18 04:53:28 +01:00
|
|
|
destroy_shader(tests_shader)
|
2022-08-28 05:09:52 +02:00
|
|
|
destroy_shader(sky_shader)
|
|
|
|
terminate()
|