commit a18fb1bcb20cda8154360738d8eb0392fbfde1a8
parent 15db347c7e71f657c8dc3f660193e5f2bc6bb4be
Author: Michael Savage <mikejsavage@gmail.com>
Date: Sun, 5 Nov 2017 09:49:07 +0200
Trees in the clipmap engine
Diffstat:
clipmap.cc | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 43 insertions(+), 0 deletions(-)
diff --git a/clipmap.cc b/clipmap.cc
@@ -7,6 +7,7 @@
#include "text_renderer.h"
#include "decompress_bc.h"
#include "gl.h"
+#include "obj.h"
#include "skybox.h"
#include "stream.h"
#include "hashtable.h"
@@ -56,9 +57,39 @@ static Pool< Explosion, 1024 > explosions;
static Pool< Player, 1024 > players;
static HashTable< Player *, 1024 * 2 > sid_to_player;
+static VB trees_instance_data;
+static u32 num_trees;
+static Mesh tree_mesh;
+
static constexpr u32 PATCH_RESOLUTION = 48;
static constexpr u32 NUM_LODS = 7;
+static void load_trees( MemoryArena * arena ) {
+ MEMARENA_SCOPED_CHECKPOINT( arena );
+
+ size_t compressed_len;
+ u8 * compressed_trees = file_get_contents( "terrains/gta16.png.parts/trees.lz4", &compressed_len );
+
+ // TODO: don't hardcode this!
+ array< v3 > trees = memarena_push_array( arena, v3, 300000 );
+ int decompressed_len = LZ4_decompress_safe( ( char * ) compressed_trees, ( char * ) trees.ptr(), compressed_len, trees.num_bytes() );
+ ASSERT( decompressed_len > 0 );
+
+ free( compressed_trees );
+
+ num_trees = decompressed_len / sizeof( v3 );
+ array< m4 > tree_matrices = memarena_push_array( arena, m4, num_trees );
+
+ m4 rot = m4_rotx( deg_to_rad( 90 ) );
+ for( size_t i = 0; i < num_trees; i++ ) {
+ tree_matrices[ i ] = m4_translation( trees[ i ] ) * rot;
+ }
+
+ trees_instance_data = renderer_new_vb( tree_matrices );
+
+ tree_mesh = load_obj( "models/trees/PineTree.obj", arena );
+}
+
static size_t patch2d( size_t x, size_t y ) {
return y * ( PATCH_RESOLUTION + 1 ) + x;
}
@@ -198,6 +229,8 @@ GAME_INIT( game_init ) {
skybox_init( &game->skybox );
+ load_trees( &mem->persistent_arena );
+
sock = net_new_udp( NET_NONBLOCKING );
if( !dns_first( "localhost", &server_addr ) ) {
@@ -472,6 +505,16 @@ GAME_FRAME( game_frame ) {
}
{
+ RenderState render_state;
+ render_state.shader = get_shader( SHADER_TREE );
+ render_state.uniforms[ UNIFORMS_VIEW ] = view_uniforms;
+ render_state.uniforms[ UNIFORMS_SUN ] = renderer_uniforms( sun_dir );
+ render_state.textures[ 0 ] = renderer_blue_noise();
+
+ renderer_draw_instances( tree_mesh, render_state, num_trees, trees_instance_data );
+ }
+
+ {
float t;
v3 normal;
if( ray_vs_quadtree( &clipmap.quadtree, Ray3( game->pos, forward ), &t, &normal ) ) {