commit 9c95acbb97d6a9c2cecdede4a713a4d5bbab4c7b parent 7d65200a86d59344554941d39370be8d8a887a44 Author: Michael Savage <mikejsavage@gmail.com> Date: Tue Sep 6 13:18:36 -0700 Use texture buffers to draw dynamic lights Diffstat:
terrain_manager.cc | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
terrain_manager.h | | | 14 | ++++++++++++++ |
diff --git a/terrain_manager.cc b/terrain_manager.cc @@ -4,6 +4,7 @@ #include "glsl.h" #include <glm/glm.hpp> #include <glm/gtc/type_ptr.hpp> +#include <GLFW/glfw3.h> #include "intrinsics.h" #include "log.h" @@ -43,6 +44,11 @@ static const GLchar * frag_src = GLSL( uniform sampler2D horizons; uniform vec2 dimensions; + // uniform usamplerBuffer point_light_counts_and_offsets; + // uniform usamplerBuffer point_light_indices; + uniform samplerBuffer point_light_origins; + uniform samplerBuffer point_light_colours; + void main() { vec3 normal = normalize( texture( normals, smooth_position.xy / dimensions ).xyz ); @@ -78,14 +84,16 @@ static const GLchar * frag_src = GLSL( // int a = int( smooth_position.x ) / 10; // if( a % 2 == 0 ) colour.g = 1; - // place a light - vec3 light_position = vec3( 500.0, 1500.0, 50.0 ); - vec3 light_colour = vec3( 15.0, 0.0, 15.0 ); - float light_sqdistance = dot( light_position - smooth_position, light_position - smooth_position ); - vec3 light_direction = normalize( light_position - smooth_position ); - float lambert_scale = dot( light_direction, normal ); - float distance_scale = 1.0 / sqrt( light_sqdistance ); - colour += vec4( light_colour * lambert_scale * distance_scale, 0.0 ); + // place some lights + for( int i = 0; i < 5; i++ ) { + vec3 light_position = texelFetch( point_light_origins, i ).xyz; + vec3 light_colour = texelFetch( point_light_colours, i ).rgb; + float light_sqdistance = dot( light_position - smooth_position, light_position - smooth_position ); + vec3 light_direction = normalize( light_position - smooth_position ); + float lambert_scale = dot( light_direction, normal ); + float distance_scale = 1.0 / sqrt( light_sqdistance ); + colour += vec4( light_colour * lambert_scale * distance_scale, 0.0 ); + } } ); @@ -158,6 +166,20 @@ void terrain_init( tm->un_normals = glGetUniformLocation( tm->shader, "normals" ); tm->un_dimensions = glGetUniformLocation( tm->shader, "dimensions" ); + // tm->un_point_light_counts_and_offsets = glGetUniformLocation( tm->shader, "point_light_counts_and_offsets" ); + // tm->un_point_light_indices = glGetUniformLocation( tm->shader, "point_light_indices" ); + tm->un_point_light_origins = glGetUniformLocation( tm->shader, "point_light_origins" ); + tm->un_point_light_colours = glGetUniformLocation( tm->shader, "point_light_colours" ); + + // glGenBuffers( 1, &tm->tbo_point_light_counts_and_offsets ); + // glGenBuffers( 1, &tm->tbo_point_light_indices ); + glGenBuffers( 1, &tm->tbo_point_light_origins ); + glGenBuffers( 1, &tm->tbo_point_light_colours ); + // glGenTextures( 1, &tm->tex_point_light_counts_and_offsets ); + // glGenTextures( 1, &tm->tex_point_light_indices ); + glGenTextures( 1, &tm->tex_point_light_origins ); + glGenTextures( 1, &tm->tex_point_light_colours ); + tm->first_teleport = true; tm->view_left = tm->view_top = 0; } @@ -300,6 +322,36 @@ void terrain_render( const TerrainManager * tm, glm::mat4 V, glm::mat4 VP, float glUniform1f( tm->un_sun, 0.3 ); glUniform2f( tm->un_dimensions, TILE_SIZE, TILE_SIZE ); + float tbo1[ 15 ] = { + 500, 1500 + 500 * sin( glfwGetTime() + 3.14 * 1 / 5 ), 50, + 600, 1500 + 500 * sin( glfwGetTime() + 3.14 * 2 / 5 ), 50, + 700, 1500 + 500 * sin( glfwGetTime() + 3.14 * 3 / 5 ), 50, + 800, 1500 + 500 * sin( glfwGetTime() + 3.14 * 4 / 5 ), 50, + 900, 1500 + 500 * sin( glfwGetTime() + 3.14 * 5 / 5 ), 50, + }; + glBindBuffer( GL_TEXTURE_BUFFER, tm->tbo_point_light_origins ); + glBufferData( GL_TEXTURE_BUFFER, sizeof( tbo1 ), tbo1, GL_DYNAMIC_DRAW ); + glBindBuffer( GL_TEXTURE_BUFFER, 0 ); + glActiveTexture( GL_TEXTURE0 + 1 ); + glBindTexture( GL_TEXTURE_BUFFER, tm->tex_point_light_origins ); + glTexBuffer( GL_TEXTURE_BUFFER, GL_RGB32UI, tm->tbo_point_light_origins ); + glUniform1i( tm->un_point_light_origins, 1 ); + + float tbo2[ 15 ] = { + 15, 0, 0, + 15, 15, 0, + 0, 15, 0, + 0, 15, 15, + 0, 0, 15, + }; + glBindBuffer( GL_TEXTURE_BUFFER, tm->tbo_point_light_colours ); + glBufferData( GL_TEXTURE_BUFFER, sizeof( tbo2 ), tbo2, GL_DYNAMIC_DRAW ); + glBindBuffer( GL_TEXTURE_BUFFER, 0 ); + glActiveTexture( GL_TEXTURE0 + 2 ); + glBindTexture( GL_TEXTURE_BUFFER, tm->tex_point_light_colours ); + glTexBuffer( GL_TEXTURE_BUFFER, GL_RGB32F, tm->tbo_point_light_colours ); + glUniform1i( tm->un_point_light_colours, 2 ); + for( u16 vy = 0; vy < VIEW_SIZE; vy++ ) { for( u16 vx = 0; vx < VIEW_SIZE; vx++ ) { gpubtt_render( &tm->btt_tiles[ vx ][ vy ], tm->un_normals ); diff --git a/terrain_manager.h b/terrain_manager.h @@ -38,6 +38,20 @@ struct TerrainManager { GLint un_normals; GLint un_dimensions; + // clustered shading stuff + // GLint un_point_light_counts_and_offsets; + // GLint un_point_light_indices; + GLint un_point_light_origins; + GLint un_point_light_colours; + // GLuint tbo_point_light_counts_and_offsets; + // GLuint tbo_point_light_indices; + GLuint tbo_point_light_origins; + GLuint tbo_point_light_colours; + // GLuint tex_point_light_counts_and_offsets; + // GLuint tex_point_light_indices; + GLuint tex_point_light_origins; + GLuint tex_point_light_colours; + bool first_teleport; // tile_x and tile_y are the coordinates of the tile we are centered on