medfall

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit c868687d45f7d847e76fe2f3b3dfa6428e83bb1f
parent 6660d383385d8476c8d60f200ae5841098479d01
Author: Michael Savage <mikejsavage@gmail.com>
Date:   Fri Aug 28 22:31:36 +0200

Terrain manager and heightmap rendering simplifications

Diffstat:
heightmap.cc | 108+++++++++++++------------------------------------------------------------------
heightmap.h | 16+++-------------
hm.cc | 2+-
terrain_manager.cc | 92+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
terrain_manager.h | 14+++++++++++++-
5 files changed, 113 insertions(+), 119 deletions(-)
diff --git a/heightmap.cc b/heightmap.cc @@ -5,69 +5,19 @@ #include "platform_opengl.h" #include <glm/glm.hpp> -#include <glm/gtc/type_ptr.hpp> #include "intrinsics.h" #include "heightmap.h" #include "stb_image.h" #include "stb_perlin.h" -#include "shitty_glsl.h" const float SLOPE = 0.3; -static const GLchar * const vert_src = GLSL( - in vec3 position; - in vec3 normal; - in float lit; - - out vec3 n; - out float depth; - out float l; - - uniform mat4 vp; - - void main() { - n = normal; - l = lit; - gl_Position = vp * vec4( position, 1.0 ); - depth = gl_Position.z; - } -); - -static const GLchar * frag_src = GLSL( - in vec3 n; - in float depth; - in float l; - - out vec4 colour; - - uniform vec3 sun; - - void main() { - vec3 ground; - if( n.z > 0.9 ) { - ground = vec3( 0.4, 1.0, 0.4 ); - } - else { - ground = vec3( 0.7, 0.7, 0.5 ); - } - - float d = max( 0, -dot( n, sun ) ); - float light = max( 0.2, l * d ); - - vec3 fog = vec3( 0.6, 0.6, 0.6 ); - - float t = smoothstep( 400, 600, depth ); - - colour = vec4( ( 1.0 - t ) * ground * light + t * fog, 1.0 ); - } -); - -float lerp( const float a, const float b, const float t ) { +static float lerp( const float a, const float b, const float t ) { return a * ( 1 - t ) + b * t; } -float bilinear_interpolation( +static float bilinear_interpolation( const glm::vec3 & v1, const glm::vec3 & v2, const glm::vec3 & v3, @@ -85,31 +35,20 @@ float bilinear_interpolation( } // CCW winding points towards the camera -glm::vec3 triangle_normal_ccw( const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c ) { +static glm::vec3 triangle_normal_ccw( const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c ) { return glm::normalize( glm::cross( b - a, c - a ) ); } -glm::vec3 triangle_perp_ccw( const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c ) { +static glm::vec3 triangle_perp_ccw( const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c ) { return glm::cross( b - a, c - a ); } Heightmap::~Heightmap() { unload(); - glDeleteProgram( shader ); } -void Heightmap::init() { - shader = compile_shader( vert_src, frag_src, "colour" ); - - at_pos = glGetAttribLocation( shader, "position" ); - at_normal = glGetAttribLocation( shader, "normal" ); - at_lit = glGetAttribLocation( shader, "lit" ); - - un_vp = glGetUniformLocation( shader, "vp" ); - un_sun = glGetUniformLocation( shader, "sun" ); -} - -void Heightmap::load( const std::string & image, const int ox, const int oy ) { +void Heightmap::load( const std::string & image, const int ox, const int oy, + const GLint at_pos, const GLint at_normal, const GLint at_lit ) { pixels = stbi_load( image.c_str(), &w, &h, nullptr, 1 ); if( !pixels ) { @@ -199,19 +138,27 @@ void Heightmap::load( const std::string & image, const int ox, const int oy ) { glGenBuffers( 1, &vbo_verts ); glBindBuffer( GL_ARRAY_BUFFER, vbo_verts ); glBufferData( GL_ARRAY_BUFFER, w * h * sizeof( GLfloat ) * 3, vertices, GL_STATIC_DRAW ); + glEnableVertexAttribArray( at_pos ); + glVertexAttribPointer( at_pos, 3, GL_FLOAT, GL_FALSE, 0, 0 ); glGenBuffers( 1, &vbo_normals ); glBindBuffer( GL_ARRAY_BUFFER, vbo_normals ); glBufferData( GL_ARRAY_BUFFER, w * h * sizeof( GLfloat ) * 3, normals, GL_STATIC_DRAW ); + glEnableVertexAttribArray( at_normal ); + glVertexAttribPointer( at_normal, 3, GL_FLOAT, GL_FALSE, 0, 0 ); glGenBuffers( 1, &vbo_lit ); glBindBuffer( GL_ARRAY_BUFFER, vbo_lit ); glBufferData( GL_ARRAY_BUFFER, w * h * sizeof( GLfloat ), lit, GL_STATIC_DRAW ); + glEnableVertexAttribArray( at_lit ); + glVertexAttribPointer( at_lit, 1, GL_FLOAT, GL_FALSE, 0, 0 ); glGenBuffers( 1, &ebo ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ebo ); glBufferData( GL_ELEMENT_ARRAY_BUFFER, w * h * sizeof( GLuint ) * 6, indices, GL_STATIC_DRAW ); + glBindVertexArray( 0 ); + delete vertices; delete normals; delete indices; @@ -317,31 +264,10 @@ float Heightmap::height( const float x, const float y ) const { ); } -void Heightmap::render( const glm::mat4 & VP ) const { - if( vbo_verts == 0 ) { - return; - } +void Heightmap::render() const { + assert( vbo_verts != 0 ); - const glm::vec3 sun = glm::normalize( glm::vec3( 1, 0, -SLOPE ) ); - - glUseProgram( shader ); glBindVertexArray( vao ); - - glUniformMatrix4fv( un_vp, 1, GL_FALSE, glm::value_ptr( VP ) ); - glUniform3fv( un_sun, 1, glm::value_ptr( sun ) ); - - glBindBuffer( GL_ARRAY_BUFFER, vbo_verts ); - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ebo ); - glEnableVertexAttribArray( at_pos ); - glVertexAttribPointer( at_pos, 3, GL_FLOAT, GL_FALSE, 0, 0 ); - - glBindBuffer( GL_ARRAY_BUFFER, vbo_normals ); - glEnableVertexAttribArray( at_normal ); - glVertexAttribPointer( at_normal, 3, GL_FLOAT, GL_FALSE, 0, 0 ); - - glBindBuffer( GL_ARRAY_BUFFER, vbo_lit ); - glEnableVertexAttribArray( at_lit ); - glVertexAttribPointer( at_lit, 1, GL_FLOAT, GL_FALSE, 0, 0 ); - glDrawElements( GL_TRIANGLES, w * h * 6, GL_UNSIGNED_INT, 0 ); + glBindVertexArray( 0 ); } diff --git a/heightmap.h b/heightmap.h @@ -19,21 +19,11 @@ private: GLuint ebo; GLuint vao; - GLuint shader; - - GLint at_pos; - GLint at_normal; - GLint at_lit; - - GLint un_vp; - GLint un_sun; - public: ~Heightmap(); - void init(); - - void load( const std::string & image, const int ox, const int oy ); + void load( const std::string & image, const int ox, const int oy, + const GLint at_pos, const GLint at_normal, const GLint at_lit ); void unload(); glm::vec3 point( int x, int y ) const; @@ -41,7 +31,7 @@ public: float height( const float x, const float y ) const; - void render( const glm::mat4 & VP ) const; + void render() const; }; #endif // _HEIGHTMAP_H_ diff --git a/hm.cc b/hm.cc @@ -254,7 +254,7 @@ extern "C" GAME_FRAME( game_frame ) { -state->pos ); - terrain_render( &state->tm, VP ); + terrain_render( &state->tm, VP, 0.3f ); glDisable( GL_DEPTH_TEST ); glUseProgram( state->test_shader ); diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -11,10 +11,60 @@ #include <string.h> #include <glm/glm.hpp> +#include <glm/gtc/type_ptr.hpp> #include "intrinsics.h" #include "heightmap.h" #include "terrain_manager.h" +#include "shitty_glsl.h" + +static const GLchar * const vert_src = GLSL( + in vec3 position; + in vec3 normal; + in float lit; + + out vec3 n; + out float depth; + out float l; + + uniform mat4 vp; + + void main() { + n = normal; + l = lit; + gl_Position = vp * vec4( position, 1.0 ); + depth = gl_Position.z; + } +); + +static const GLchar * frag_src = GLSL( + in vec3 n; + in float depth; + in float l; + + out vec4 colour; + + uniform vec3 sun; + + void main() { + vec3 ground; + if( n.z > 0.9 ) { + ground = vec3( 0.4, 1.0, 0.4 ); + } + else { + ground = vec3( 0.7, 0.7, 0.5 ); + } + + float d = max( 0, -dot( n, sun ) ); + float light = max( 0.2, l * d ); + + vec3 fog = vec3( 0.6, 0.6, 0.6 ); + + float t = smoothstep( 400, 600, depth ); + + colour = vec4( ( 1.0 - t ) * ground * light + t * fog, 1.0 ); + } +); // TODO: lol static char tp_path[ 256 ]; @@ -35,12 +85,14 @@ void terrain_init( TerrainManager * const tm, const char * const tiles_dir ) { fclose( dims ); printf( "%d %d\n", tm->width, tm->height ); - for( u32 ty = 0; ty < tm->height / TILE_SIZE; ty++ ) { - printf( "init %u\n", ty ); - for( u32 tx = 0; tx < tm->width / TILE_SIZE; tx++ ) { - tm->tiles[ tx ][ ty ].init(); - } - } + tm->shader = compile_shader( vert_src, frag_src, "colour" ); + + tm->at_pos = glGetAttribLocation( tm->shader, "position" ); + tm->at_normal = glGetAttribLocation( tm->shader, "normal" ); + tm->at_lit = glGetAttribLocation( tm->shader, "lit" ); + + tm->un_vp = glGetUniformLocation( tm->shader, "vp" ); + tm->un_sun = glGetUniformLocation( tm->shader, "sun" ); tm->first_teleport = true; } @@ -68,7 +120,8 @@ void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ) { tm->tiles[ new_tx + tx - VIEW_HALF ][ new_ty + ty - VIEW_HALF ].load( tp( tm, new_tx + tx - VIEW_HALF, new_ty + ty - VIEW_HALF ), ( new_tx + tx - VIEW_HALF ) * TILE_SIZE, - ( new_ty + ty - VIEW_HALF ) * TILE_SIZE + ( new_ty + ty - VIEW_HALF ) * TILE_SIZE, + tm->at_pos, tm->at_normal, tm->at_lit ); } } @@ -87,7 +140,8 @@ void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { tm->tiles[ tm->last_tx + VIEW_HALF + 1 ][ ty ].load( tp( tm, tm->last_tx + VIEW_HALF + 1, tm->last_ty + ty - VIEW_HALF ), ( tm->last_tx + VIEW_HALF + 1 ) * TILE_SIZE, - ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE ); + ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE, + tm->at_pos, tm->at_normal, tm->at_lit ); } tm->last_tx++; @@ -100,7 +154,8 @@ void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { tm->tiles[ tm->last_tx - VIEW_HALF - 1 ][ ty ].load( tp( tm, tm->last_tx - VIEW_HALF - 1, tm->last_ty + ty - VIEW_HALF ), ( tm->last_tx - VIEW_HALF - 1 ) * TILE_SIZE, - ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE ); + ( tm->last_ty + ty - VIEW_HALF ) * TILE_SIZE, + tm->at_pos, tm->at_normal, tm->at_lit ); } tm->last_tx--; @@ -116,7 +171,8 @@ void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { tm->tiles[ tx ][ tm->last_ty + VIEW_HALF + 1 ].load( tp( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty + VIEW_HALF + 1 ), ( tm->last_tx + tx - VIEW_HALF ) * TILE_SIZE, - ( tm->last_ty + VIEW_HALF + 1 ) * TILE_SIZE ); + ( tm->last_ty + VIEW_HALF + 1 ) * TILE_SIZE, + tm->at_pos, tm->at_normal, tm->at_lit ); } tm->last_ty++; } @@ -128,17 +184,27 @@ void terrain_update( TerrainManager * const tm, const glm::vec3 position ) { tm->tiles[ tx ][ tm->last_ty - VIEW_HALF - 1 ].load( tp( tm, tm->last_tx + tx - VIEW_HALF, tm->last_ty - VIEW_HALF - 1 ), ( tm->last_tx + tx - VIEW_HALF ) * TILE_SIZE, - ( tm->last_ty - VIEW_HALF - 1 ) * TILE_SIZE ); + ( tm->last_ty - VIEW_HALF - 1 ) * TILE_SIZE, + tm->at_pos, tm->at_normal, tm->at_lit ); } tm->last_ty--; } } } -void terrain_render( const TerrainManager * const tm, const glm::mat4 VP ) { +void terrain_render( const TerrainManager * const tm, const glm::mat4 VP, const float sun_slope ) { + const glm::vec3 sun = glm::normalize( glm::vec3( 1, 0, -sun_slope ) ); + + glUseProgram( tm->shader ); + + glUniformMatrix4fv( tm->un_vp, 1, GL_FALSE, glm::value_ptr( VP ) ); + glUniform3fv( tm->un_sun, 1, glm::value_ptr( sun ) ); + for( u32 ty = 0; ty < VIEW_SIZE; ty++ ) { for( u32 tx = 0; tx < VIEW_SIZE; tx++ ) { - tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ].render( VP ); + tm->tiles[ tm->last_tx + tx - VIEW_HALF ][ tm->last_ty + ty - VIEW_HALF ].render(); } } + + glUseProgram( 0 ); } diff --git a/terrain_manager.h b/terrain_manager.h @@ -15,15 +15,27 @@ static const u32 VIEW_HALF = VIEW_SIZE / 2; struct TerrainManager { char dir[ 128 ]; + u32 width, height; u32 last_tx, last_ty; + + GLuint shader; + + GLint at_pos; + GLint at_normal; + GLint at_lit; + + GLint un_vp; + GLint un_sun; + bool first_teleport; + Heightmap tiles[ MAX_TILES_DIM ][ MAX_TILES_DIM ]; }; void terrain_init( TerrainManager * const tm, const char * const tiles_dir ); void terrain_teleport( TerrainManager * const tm, const glm::vec3 position ); void terrain_update( TerrainManager * const tm, const glm::vec3 position ); -void terrain_render( const TerrainManager * const tm, const glm::mat4 VP ); +void terrain_render( const TerrainManager * const tm, const glm::mat4 VP, const float sun_slope ); #endif // _TERRAIN_MANAGER_H_