commit 94fd96d9b5d6c0164a3cb93e58c2a60a8addd6b0 parent 8cfe4f3afb92601b49cb74861c67c4d5e69772e9 Author: Michael Savage <mikejsavage@gmail.com> Date: Mon Oct 12 12:32:53 +0100 Add lighting (but not shadows) to the BTT renderer Diffstat:
btt.cc | | | 19 | ++++++++++++------- |
game.h | | | 2 | ++ |
gpubtt.cc | | | 24 | +++++++++++++++++++++++- |
gpubtt.h | | | 3 | ++- |
diff --git a/btt.cc b/btt.cc @@ -15,7 +15,6 @@ static ImmediateContext imm; static const GLchar * const vert_src = GLSL( in vec3 position; - in vec3 normal; in float lit; out vec3 n; @@ -23,10 +22,12 @@ static const GLchar * const vert_src = GLSL( out float l; uniform mat4 vp; + uniform sampler2D normals; + uniform vec2 dimensions; void main() { - n = normal; - l = lit; + n = texture( normals, position.xy / dimensions ).xyz; + l = lit + 1.0f; gl_Position = vp * vec4( position, 1.0 ); depth = gl_Position.z; } @@ -42,15 +43,17 @@ static const GLchar * frag_src = GLSL( uniform vec3 sun; void main() { + vec3 normal = normalize( n ); + vec3 ground; - if( n.z > 0.9 ) { + if( normal.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 d = max( 0, -dot( normal, sun ) ); float light = max( 0.2, l * d ); vec3 fog = vec3( 0.6, 0.6, 0.6 ); @@ -217,10 +220,11 @@ extern "C" GAME_INIT( game_init ) { state->test_shader = compile_shader( vert_src, frag_src, "screen_colour" ); state->test_at_position = glGetAttribLocation( state->test_shader, "position" ); - state->test_at_normal = glGetAttribLocation( state->test_shader, "normal" ); state->test_at_lit = glGetAttribLocation( state->test_shader, "lit" ); state->test_un_VP = glGetUniformLocation( state->test_shader, "vp" ); state->test_un_sun = glGetUniformLocation( state->test_shader, "sun" ); + state->test_un_normals = glGetUniformLocation( state->test_shader, "normals" ); + state->test_un_dimensions = glGetUniformLocation( state->test_shader, "dimensions" ); state->test_outline_shader = compile_shader( vert_outline_src, frag_outline_src, "screen_colour" ); state->test_outline_at_position = glGetAttribLocation( state->test_outline_shader, "position" ); @@ -307,7 +311,8 @@ extern "C" GAME_FRAME( game_frame ) { glUseProgram( state->test_shader ); glUniformMatrix4fv( state->test_un_VP, 1, GL_FALSE, glm::value_ptr( VP ) ); glUniform3fv( state->test_un_sun, 1, glm::value_ptr( sun ) ); - gpubtt_render( &state->gpubtt ); + glUniform2f( state->test_un_dimensions, state->hm.width, state->hm.height ); + gpubtt_render( &state->gpubtt, state->test_un_normals ); glUseProgram( 0 ); immediate_init( &imm, triangles, array_count( triangles ) ); diff --git a/game.h b/game.h @@ -111,6 +111,8 @@ struct GameState { GLint test_at_normal; GLint test_at_lit; GLint test_un_sun; + GLint test_un_normals; + GLint test_un_dimensions; GLuint test_outline_shader; GLint test_outline_at_position; diff --git a/gpubtt.cc b/gpubtt.cc @@ -67,18 +67,40 @@ void gpubtt_init( glEnableVertexAttribArray( at_position ); glVertexAttribPointer( at_position, 3, GL_FLOAT, GL_FALSE, 0, 0 ); + glm::vec3 * const normals = memarena_push_many( mem, glm::vec3, ohm->hm.width * ohm->hm.height ); + + for( u32 y = 0; y < ohm->hm.height; y++ ) { + for( u32 x = 0; x < ohm->hm.width; x++ ) { + const glm::vec3 normal = ohm->hm.point_normal( x, y ); + normals[ y * ohm->hm.width + x ] = normal; + } + } + + glGenTextures( 1, &gpubtt->tex_normals ); + glBindTexture( GL_TEXTURE_2D, gpubtt->tex_normals ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, ohm->hm.width, ohm->hm.height, 0, GL_RGB, GL_FLOAT, normals ); + glBindVertexArray( 0 ); gpubtt->num_verts = i; } void gpubtt_destroy( GPUBTT * const gpubtt ) { + glDeleteTextures( 1, &gpubtt->tex_normals ); glDeleteBuffers( 1, &gpubtt->vbo_verts ); glDeleteVertexArrays( 1, &gpubtt->vao ); } -void gpubtt_render( const GPUBTT * const gpubtt ) { +void gpubtt_render( const GPUBTT * const gpubtt, const GLuint un_normals ) { glBindVertexArray( gpubtt->vao ); + + glActiveTexture( GL_TEXTURE0 ); + glBindTexture( GL_TEXTURE_2D, gpubtt->tex_normals ); + glUniform1i( un_normals, 0 ); + glDrawArrays( GL_TRIANGLES, 0, gpubtt->num_verts * 3 ); + glBindVertexArray( 0 ); } diff --git a/gpubtt.h b/gpubtt.h @@ -9,6 +9,7 @@ struct GPUBTT { GLuint vao; GLuint vbo_verts; + GLuint tex_normals; u32 num_verts; }; @@ -18,6 +19,6 @@ void gpubtt_init( MemoryArena * const mem, GPUBTT * const gpubtt, void gpubtt_destroy( GPUBTT * const gpubtt ); -void gpubtt_render( const GPUBTT * const gpubtt ); +void gpubtt_render( const GPUBTT * const gpubtt, const GLuint un_normals ); #endif // _GPUBTT_H_