@ -151,10 +151,10 @@ struct g_buffer {
@@ -151,10 +151,10 @@ struct g_buffer {
/*
* The output textures of the G fragment shader .
*/
GLuint attachments [ 3 ] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT 1 , GL_COLOR_ATTACHMENT2 } ;
GLuint attachments [ 3 ] = { GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 , GL_COLOR_ATTACHMENT3 } ;
g_buffer ( int width , int height ) : g_buffer ( width , height , 1 ) { }
g_buffer ( int width , int height , in t scaling ) : screen_width ( width ) , screen_height ( height ) , logical_width ( width ) , logical_height ( height ) { }
g_buffer ( int width , int height , floa t scaling ) : screen_width ( width ) , screen_height ( height ) , logical_width ( width * scaling ) , logical_height ( height * scaling ) { }
void create_buffers ( ) {
@ -193,7 +193,7 @@ struct g_buffer {
@@ -193,7 +193,7 @@ struct g_buffer {
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA16F , screen_x , screen_y , 0 , GL_RGBA , GL_FLOAT , NULL ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , g_position , 0 ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , attachments [ 0 ] , GL_TEXTURE_2D , g_position , 0 ) ;
// - normal color buffer
glGenTextures ( 1 , & g_normal ) ;
@ -201,7 +201,7 @@ struct g_buffer {
@@ -201,7 +201,7 @@ struct g_buffer {
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA16F , screen_x , screen_y , 0 , GL_RGBA , GL_FLOAT , NULL ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT1 , GL_TEXTURE_2D , g_normal , 0 ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , attachments [ 1 ] , GL_TEXTURE_2D , g_normal , 0 ) ;
// - color + specular color buffer
glGenTextures ( 1 , & g_albedo_specular ) ;
@ -209,10 +209,10 @@ struct g_buffer {
@@ -209,10 +209,10 @@ struct g_buffer {
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , screen_x , screen_y , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT2 , GL_TEXTURE_2D , g_albedo_specular , 0 ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , attachments [ 2 ] , GL_TEXTURE_2D , g_albedo_specular , 0 ) ;
// - tell OpenGL which color attachments we'll use (of this framebuffer) for rendering
unsigned int attachments [ 3 ] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 } ;
//unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
glDrawBuffers ( 3 , attachments ) ;
glCheckError ( ) ;
@ -224,20 +224,20 @@ struct g_buffer {
@@ -224,20 +224,20 @@ struct g_buffer {
}
void bind_textures ( ) {
glActiveTexture ( GL_TEXTURE0 ) ;
glBindTexture ( GL_TEXTURE_2D , g_position ) ;
glActiveTexture ( GL_TEXTURE1 ) ;
glBindTexture ( GL_TEXTURE_2D , g_normal ) ;
glBindTexture ( GL_TEXTURE_2D , g_position ) ;
glActiveTexture ( GL_TEXTURE2 ) ;
glBindTexture ( GL_TEXTURE_2D , g_normal ) ;
glActiveTexture ( GL_TEXTURE3 ) ;
glBindTexture ( GL_TEXTURE_2D , g_albedo_specular ) ;
}
void present ( std : : shared_ptr < shader_handle > deferred_lighting , GLuint quad_vao ) {
bind_textures ( ) ;
deferred_lighting - > set ( " gPosition " , 0 ) ;
deferred_lighting - > set ( " gNormal " , 1 ) ;
deferred_lighting - > set ( " gAlbedoSpec " , 2 ) ;
deferred_lighting - > set ( " gPosition " , 1 ) ;
deferred_lighting - > set ( " gNormal " , 2 ) ;
deferred_lighting - > set ( " gAlbedoSpec " , 3 ) ;
deferred_lighting - > use ( ) ;
glDisable ( GL_DEPTH_TEST ) ;
@ -245,6 +245,7 @@ struct g_buffer {
@@ -245,6 +245,7 @@ struct g_buffer {
//glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//glBlitFramebuffer(0, 0, logical_width, logical_height, 0, 0, screen_width, screen_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer ( GL_READ_FRAMEBUFFER , fbo ) ;
glBindVertexArray ( quad_vao ) ;
glDrawArrays ( GL_TRIANGLES , 0 , 6 ) ;
glCheckError ( ) ;
@ -253,116 +254,6 @@ struct g_buffer {
@@ -253,116 +254,6 @@ struct g_buffer {
} ;
struct g_buffer_multisampled {
GLuint fbo ;
int width , height ;
// texture ids
GLuint g_position , g_normal , g_albedo_specular ;
GLuint stencil_depth ;
g_buffer g_buffer_out ;
/*
* The output textures of the G fragment shader .
*/
GLuint attachments [ 3 ] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 } ;
g_buffer_multisampled ( int width , int height ) : width ( width ) , height ( height ) , g_buffer_out ( width , height ) { }
void create_out_buffers ( ) {
g_buffer_out . create_buffers ( ) ;
}
void create_buffers ( ) {
GLuint samples = 2 ;
glGenFramebuffers ( 1 , & fbo ) ;
glBindFramebuffer ( GL_FRAMEBUFFER , fbo ) ;
int screen_x = width ;
int screen_y = height ;
// bind to the existing framebuffer
glBindFramebuffer ( GL_FRAMEBUFFER , fbo ) ;
// depth test and stencil texture
glGenTextures ( 1 , & stencil_depth ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , stencil_depth ) ;
glTexImage2DMultisample ( GL_TEXTURE_2D_MULTISAMPLE ,
samples ,
GL_DEPTH24_STENCIL8 ,
width ,
height ,
0 ) ;
glCheckError ( ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER ,
GL_DEPTH_STENCIL_ATTACHMENT ,
GL_TEXTURE_2D_MULTISAMPLE ,
stencil_depth ,
0 ) ;
glCheckError ( ) ;
// - position color buffer
glGenTextures ( 1 , & g_position ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_position ) ;
glTexImage2DMultisample ( GL_TEXTURE_2D_MULTISAMPLE , samples , GL_RGBA16F , screen_x , screen_y , 0 ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D_MULTISAMPLE , g_position , 0 ) ;
glCheckError ( ) ;
// - normal color buffer
glGenTextures ( 1 , & g_normal ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_normal ) ;
glTexImage2DMultisample ( GL_TEXTURE_2D_MULTISAMPLE , samples , GL_RGBA16F , screen_x , screen_y , 0 ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT1 , GL_TEXTURE_2D_MULTISAMPLE , g_normal , 0 ) ;
glCheckError ( ) ;
// - color + specular color buffer
glGenTextures ( 1 , & g_albedo_specular ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_albedo_specular ) ;
glTexImage2DMultisample ( GL_TEXTURE_2D_MULTISAMPLE , samples , GL_RGBA , screen_x , screen_y , 0 ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT2 , GL_TEXTURE_2D_MULTISAMPLE , g_albedo_specular , 0 ) ;
glCheckError ( ) ;
// - tell OpenGL which color attachments we'll use (of this framebuffer) for rendering
unsigned int attachments [ 3 ] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT1 , GL_COLOR_ATTACHMENT2 } ;
glDrawBuffers ( 3 , attachments ) ;
glCheckError ( ) ;
create_out_buffers ( ) ;
if ( glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ! = GL_FRAMEBUFFER_COMPLETE ) {
throw std : : runtime_error ( " Error creating G buffer. " ) ;
}
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
}
void bind ( ) {
glActiveTexture ( GL_TEXTURE0 ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_position ) ;
glActiveTexture ( GL_TEXTURE1 ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_normal ) ;
glActiveTexture ( GL_TEXTURE2 ) ;
glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , g_albedo_specular ) ;
}
void present ( std : : shared_ptr < shader_handle > deferred_lighting , GLuint quad_vao ) {
glBindFramebuffer ( GL_READ_FRAMEBUFFER , fbo ) ;
glBindFramebuffer ( GL_DRAW_FRAMEBUFFER , g_buffer_out . fbo ) ;
glBlitFramebuffer ( 0 , 0 , width , height , 0 , 0 , width , height , GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT , GL_NEAREST ) ;
g_buffer_out . bind_textures ( ) ;
g_buffer_out . present ( deferred_lighting , quad_vao ) ;
}
} ;
void move_player ( game_state & g , glm : : vec3 walking_state , float time_delta ) {
@ -422,6 +313,12 @@ int main_loop(game_state& g)
@@ -422,6 +313,12 @@ int main_loop(game_state& g)
SDL_Event e ;
bool quit = false ;
struct {
float exposure = 1.0 ;
float gamma = 2.2 ;
bool use_hdr = false ;
} tone_mapping ;
glCheckError ( ) ;
glClearColor ( 0.0F , 0.0F , 0.0F , 1.0F ) ;
glDisable ( GL_CULL_FACE ) ;
@ -439,7 +336,8 @@ int main_loop(game_state& g)
@@ -439,7 +336,8 @@ int main_loop(game_state& g)
g . asset_dir / " shaders " / " g_frag.gl " ) ;
auto forward_pass_shader = g_shader ;
struct g_buffer G { g . render_target - > width , g . render_target - > height } ;
// set scaling
struct g_buffer G { g . render_target - > width , g . render_target - > height , 1.0f } ; // scaling 1x
glCheckError ( ) ;
G . create_buffers ( ) ;
glCheckError ( ) ;
@ -586,12 +484,13 @@ int main_loop(game_state& g)
@@ -586,12 +484,13 @@ int main_loop(game_state& g)
if ( deferred ) {
glBindFramebuffer ( GL_FRAMEBUFFER , G . fbo ) ;
glBindFramebuffer ( GL_DRAW_FRAMEBUFFER , G . fbo ) ;
glViewport ( 0 , 0 , G . logical_width , G . logical_height ) ;
G . bind_textures ( ) ;
forward_pass_shader = g_shader ;
} else {
forward_pass_shader = forward_lighting ;
glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
g . render_target - > bind ( ) ;
}
forward_pass_shader - > use ( ) ;
@ -658,7 +557,7 @@ int main_loop(game_state& g)
@@ -658,7 +557,7 @@ int main_loop(game_state& g)
xenia_transform = glm : : translate ( xenia_transform , parent_transform . position ) ;
xenia_transform = glm : : translate ( xenia_transform , glm : : vec3 ( 0 , - 8 , 0 ) ) ;
xenia_transform = glm : : rotate ( xenia_transform , ( float ) M_PI , glm : : vec3 ( 1 , 0 , 0 ) ) ;
xenia_transform = glm : : rotate ( xenia_transform , ( float ) M_PI / 2 - ( glm : : radians ( cam . euler_angles [ 0 ] * walking_state . z ) - glm : : radians ( 90 * walking_state . x ) ) , glm : : vec3 ( 0 , 1 , 0 ) ) ;
xenia_transform = glm : : rotate ( xenia_transform , ( float ) M_PI / 2 - ( glm : : radians ( cam . euler_angles [ 0 ] * walking_state . z ) - glm : : radians ( ( cam . euler_angles [ 0 ] + 90 ) * walking_state . x ) ) , glm : : vec3 ( 0 , 1 , 0 ) ) ;
xenia_transform = glm : : scale ( xenia_transform , glm : : vec3 ( 0.5 ) ) ;
xenia . draw ( mat_ubo , model_ubo , forward_pass_shader , xenia_transform ) ;
@ -696,10 +595,10 @@ int main_loop(game_state& g)
@@ -696,10 +595,10 @@ int main_loop(game_state& g)
glCheckError ( ) ;
if ( deferred ) {
g . render_target - > bind ( ) ;
// now draw the g buffer into the final buffer
//g.render_target->present(g.screen_shader);
glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
glDisable ( GL_DEPTH_TEST ) ;
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
//g.screen_shader->use();
// now execute deferred lighting shader
deferred_lighting - > use ( ) ;
@ -709,6 +608,7 @@ int main_loop(game_state& g)
@@ -709,6 +608,7 @@ int main_loop(game_state& g)
G . present ( deferred_lighting , g . platonic_shapes . quad_vao ) ;
}
g . render_target - > present ( g . screen_shader ) ;
// forward render imgui on top of the scene
ImGui : : Begin ( " Trees " ) ;
ImGui : : SliderInt ( " Num Lights " , & num_lights , 1 , max_lights ) ;
@ -718,6 +618,9 @@ int main_loop(game_state& g)
@@ -718,6 +618,9 @@ int main_loop(game_state& g)
ImGui : : Checkbox ( " Enable fog " , ( bool * ) & fog_enabled ) ;
ImGui : : Checkbox ( " Move lights " , ( bool * ) & move_lights ) ;
ImGui : : Checkbox ( " Deferred Shading " , ( bool * ) & deferred ) ;
ImGui : : Checkbox ( " HDR " , ( bool * ) & tone_mapping . use_hdr ) ;
ImGui : : SliderFloat ( " Exposure " , & tone_mapping . exposure , 0 , 3.0 ) ;
ImGui : : SliderFloat ( " Gamma " , & tone_mapping . gamma , 0 , 4.0 ) ;
ImGui : : Combo ( " Debug shader " , & debug_shader , debug_shaders , IM_ARRAYSIZE ( debug_shaders ) ) ;
ImGui : : End ( ) ;
ImGui : : Render ( ) ;
@ -725,6 +628,9 @@ int main_loop(game_state& g)
@@ -725,6 +628,9 @@ int main_loop(game_state& g)
SDL_GL_SwapWindow ( g . window ) ;
mat_ubo - > current_lights ( num_lights ) ;
mat_ubo - > enable_fog ( fog_enabled ) ;
g . screen_shader - > set ( " gamma " , tone_mapping . gamma ) ;
g . screen_shader - > set ( " exposure " , tone_mapping . exposure ) ;
g . screen_shader - > set ( " use_hdr " , tone_mapping . use_hdr ) ;
while ( SDL_PollEvent ( & e ) ! = 0 ) {
ImGui_ImplSDL2_ProcessEvent ( & e ) ;