X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=render.h;h=cd41ec33e836d65ef02d690fc824d4505efee3a1;hb=23ef4d7f6bfe6a5a91c78822b081a9ea63cb74a6;hp=77bb56e1b570eeb7b4bddd0de12e6f82c5e21077;hpb=a1adba47558099cab82aa6d10abdc1dca11d3342;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/render.h b/render.h index 77bb56e..cd41ec3 100644 --- a/render.h +++ b/render.h @@ -121,13 +121,16 @@ struct framebuffer k_framebuffer_quality_high_only } quality; - + GLenum internalformat, format, type, attachment; GLuint id; + + /* Runtime */ + int debug_view; } attachments[5]; GLuint fb; @@ -139,13 +142,13 @@ framebuffers[] = /* * The primary draw target */ - "Main", + "main", .link = &gpipeline.fb_main, .resolution_div = 1, .attachments = { { - "Colour", k_framebuffer_attachment_type_colour, + "colour", k_framebuffer_attachment_type_colour, .internalformat = GL_RGB, .format = GL_RGB, @@ -153,7 +156,7 @@ framebuffers[] = .attachment = GL_COLOR_ATTACHMENT0 }, { - "Motion Vectors", k_framebuffer_attachment_type_colour, + "motion", k_framebuffer_attachment_type_colour, .quality = k_framebuffer_quality_high_only, .internalformat = GL_RG16F, @@ -162,7 +165,7 @@ framebuffers[] = .attachment = GL_COLOR_ATTACHMENT1 }, { - "Depth/Stencil", k_framebuffer_attachment_type_renderbuffer, + "depth_stencil", k_framebuffer_attachment_type_renderbuffer, .internalformat = GL_DEPTH24_STENCIL8, .attachment = GL_DEPTH_STENCIL_ATTACHMENT @@ -175,7 +178,7 @@ framebuffers[] = * Note: it does not have a render buffer attachement because it's * intended to be drawn to in a MAX blending mode */ - "Heightmap", + "heightmap", .link = &gpipeline.fb_heightmap, .fixed_w = 1024, .fixed_h = 1024, @@ -183,7 +186,7 @@ framebuffers[] = .attachments = { { - "Depth", k_framebuffer_attachment_type_colour, + "depth", k_framebuffer_attachment_type_colour, .internalformat = GL_R32F, .format = GL_RED, @@ -196,20 +199,20 @@ framebuffers[] = /* * Second rendered view from the perspective of the water reflection */ - "Water reflection", + "water_reflection", .link = &gpipeline.fb_water_reflection, .resolution_div = 3, .attachments = { { - "Colour", k_framebuffer_attachment_type_colour, + "colour", k_framebuffer_attachment_type_colour, .internalformat = GL_RGB, .format = GL_RGB, .type = GL_UNSIGNED_BYTE, .attachment = GL_COLOR_ATTACHMENT0 }, { - "Depth/Stencil", k_framebuffer_attachment_type_renderbuffer, + "depth_stencil", k_framebuffer_attachment_type_renderbuffer, .internalformat = GL_DEPTH24_STENCIL8, .attachment = GL_DEPTH_STENCIL_ATTACHMENT @@ -221,20 +224,20 @@ framebuffers[] = * Thid rendered view from the perspective of the camera, but just * captures stuff thats under the water */ - "Water Beneath", + "water_beneath", .link = &gpipeline.fb_water_beneath, .resolution_div = 4, .attachments = { { - "Colour", k_framebuffer_attachment_type_colour, + "colour", k_framebuffer_attachment_type_colour, .internalformat = GL_RGBA, .format = GL_RGBA, .type = GL_UNSIGNED_BYTE, .attachment = GL_COLOR_ATTACHMENT0 }, { - "Depth/Stencil", k_framebuffer_attachment_type_renderbuffer, + "depth_stencil", k_framebuffer_attachment_type_renderbuffer, .internalformat = GL_DEPTH24_STENCIL8, .attachment = GL_DEPTH_STENCIL_ATTACHMENT @@ -588,181 +591,50 @@ VG_STATIC void render_fb_resize(void) } } -#if 0 -VG_STATIC void fb_use( struct framebuffer *fb ) -{ - if( !fb ) - { - glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background ); - glViewport( 0, 0, vg.window_x, vg.window_y ); - } - else - { - glBindFramebuffer( GL_FRAMEBUFFER, fb->fb ); - glViewport( 0, 0, vg.window_x / fb->div, vg.window_y / fb->div ); - } -} - -VG_STATIC void fb_init( struct framebuffer *fb ) -{ - i32 ix = vg.window_x / fb->div, - iy = vg.window_y / fb->div; - - glGenFramebuffers( 1, &fb->fb ); - glBindFramebuffer( GL_FRAMEBUFFER, fb->fb ); - - glGenTextures( 1, &fb->colour ); - glBindTexture( GL_TEXTURE_2D, fb->colour ); - glTexImage2D( GL_TEXTURE_2D, 0, fb->format, ix, iy, - 0, fb->format, GL_UNSIGNED_BYTE, NULL); - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, fb->colour, 0); - - glGenRenderbuffers( 1, &fb->rb ); - glBindRenderbuffer( GL_RENDERBUFFER, fb->rb ); - glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, ix, iy ); - - glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, fb->rb ); - glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - - VG_CHECK_GL_ERR(); - fb->allocated = 1; -} - -VG_STATIC void _fb_glTexImage2D( GLsizei x, GLsizei y, GLint internalformat, - GLenum format, GLenum type, const void *data ) -{ - glTexImage2D( GL_TEXTURE_2D, 0, internalformat, x,y, 0, - format, type, data ); - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); -} - -#define fb_tex2d( X,Y, INTERNAL_FORMAT, FORMAT, TYPE, DATA ) \ - _fb_glTexImage2D( X,Y, INTERNAL_FORMAT, FORMAT, TYPE, DATA ); \ - vg_info( "texture( %dx%d, internal: %s, format: %s, type: %s )\n", \ - X,Y, #INTERNAL_FORMAT, #FORMAT, #TYPE ); - -VG_STATIC void fb_free( struct framebuffer *fb ) -{ - glDeleteTextures( 1, &fb->colour ); - glDeleteFramebuffers( 1, &fb->fb ); -} - -VG_STATIC void fb_bindtex( struct framebuffer *fb, int texture ) -{ - glActiveTexture( GL_TEXTURE0 + texture ); - glBindTexture( GL_TEXTURE_2D, fb->colour ); -} - -VG_STATIC void fb_resize( struct framebuffer *fb ) -{ - if( !fb->allocated ) - return; - - i32 ix = vg.window_x / fb->div, - iy = vg.window_y / fb->div; - - glBindTexture( GL_TEXTURE_2D, fb->colour ); - glTexImage2D( GL_TEXTURE_2D, 0, fb->format, ix, iy, 0, - fb->format, GL_UNSIGNED_BYTE, NULL ); - - glBindRenderbuffer( GL_RENDERBUFFER, fb->rb ); - glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, ix, iy ); -} -#endif - -#if 0 -VG_STATIC void render_init_temp_buffer(void) -{ - vg_info( "[render] Allocate framebuffer\n" ); - - glGenFramebuffers( 1, &gpipeline.fb_background ); - glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_background ); - - glGenTextures( 1, &gpipeline.rgb_background ); - glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_background ); - fb_tex2d( vg.window_x, vg.window_y, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, NULL ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - gpipeline.rgb_background, 0 ); - - glGenTextures( 1, &gpipeline.mv_background ); - glBindTexture( GL_TEXTURE_2D, gpipeline.mv_background ); -#if 0 - glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, vg.window_x, vg.window_y, - 0, GL_RG, GL_FLOAT, NULL); -#endif - glTexImage2D( GL_TEXTURE_2D, 0, GL_RG16F, vg.window_x, vg.window_y, - 0, GL_RG, GL_FLOAT, NULL); - - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, - GL_TEXTURE_2D, - gpipeline.mv_background, 0 ); - - /* render buffer */ - glGenRenderbuffers( 1, &gpipeline.rb_background ); - glBindRenderbuffer( GL_RENDERBUFFER, gpipeline.rb_background ); - glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, - vg.window_x, vg.window_y ); - glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - GL_RENDERBUFFER, gpipeline.rb_background ); - - GLuint attachments[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; - glDrawBuffers( 2, attachments ); - - render_check_framebuffer_complete(); - - glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - VG_CHECK_GL_ERR(); -} - -/* used for drawing world depth from the top view, used in our water and - * lighting calculations */ -VG_STATIC void render_init_depthmap_buffer(void) -{ - vg_info( "[render] Allocate depth map buffer\n" ); - - glGenFramebuffers( 1, &gpipeline.fb_depthmap ); - glBindFramebuffer( GL_FRAMEBUFFER, gpipeline.fb_depthmap ); - - glGenTextures( 1, &gpipeline.rgb_depthmap ); - glBindTexture( GL_TEXTURE_2D, gpipeline.rgb_depthmap ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 1024, 1024, 0, - GL_RED, GL_FLOAT, NULL ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - vg_tex2d_clamp(); - - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, - GL_TEXTURE_2D, - gpipeline.rgb_depthmap, 0); - - render_check_framebuffer_complete(); - VG_CHECK_GL_ERR(); -} -#endif - +VG_STATIC int render_framebuffer_control( int argc, char const *argv[] ); +VG_STATIC void render_framebuffer_poll( int argc, char const *argv[] ); VG_STATIC void render_init_fs_quad(void) { vg_info( "[render] Allocate quad\n" ); - float quad[] = { 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, - 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, + float quad[] = + { + 0.00f,0.00f, 1.00f,1.00f, 0.00f,1.00f, + 0.00f,0.00f, 1.00f,0.00f, 1.00f,1.00f, + + 0.20f,0.00f, 0.80f,1.00f, 0.20f,1.00f, + 0.20f,0.00f, 0.80f,0.00f, 0.80f,1.00f, + + /* 9x9 debug grid */ + /* row0 */ + 0.00f,0.00f, 0.30f,0.30f, 0.00f,0.30f, + 0.00f,0.00f, 0.30f,0.00f, 0.30f,0.30f, + 0.30f,0.00f, 0.60f,0.30f, 0.30f,0.30f, + 0.30f,0.00f, 0.60f,0.00f, 0.60f,0.30f, + 0.60f,0.00f, 0.90f,0.30f, 0.60f,0.30f, + 0.60f,0.00f, 0.90f,0.00f, 0.90f,0.30f, + /* row1 */ + 0.00f,0.30f, 0.30f,0.60f, 0.00f,0.60f, + 0.00f,0.30f, 0.30f,0.30f, 0.30f,0.60f, + 0.30f,0.30f, 0.60f,0.60f, 0.30f,0.60f, + 0.30f,0.30f, 0.60f,0.30f, 0.60f,0.60f, + 0.60f,0.30f, 0.90f,0.60f, 0.60f,0.60f, + 0.60f,0.30f, 0.90f,0.30f, 0.90f,0.60f, + /* row2 */ + 0.00f,0.60f, 0.30f,0.90f, 0.00f,0.90f, + 0.00f,0.60f, 0.30f,0.60f, 0.30f,0.90f, + 0.30f,0.60f, 0.60f,0.90f, 0.30f,0.90f, + 0.30f,0.60f, 0.60f,0.60f, 0.60f,0.90f, + 0.60f,0.60f, 0.90f,0.90f, 0.60f,0.90f, + 0.60f,0.60f, 0.90f,0.60f, 0.90f,0.90f, + }; - 0.2f, 0.0f, 0.8f, 1.0f, 0.2f, 1.0f, - 0.2f, 0.0f, 0.8f, 0.0f, 0.8f, 1.0f}; + vg_function_push( (struct vg_cmd) + { + .name = "fb", + .function = render_framebuffer_control, + .poll_suggest = render_framebuffer_poll + }); glGenVertexArrays( 1, &gpipeline.fsquad.vao ); glGenBuffers( 1, &gpipeline.fsquad.vbo ); @@ -771,7 +643,7 @@ VG_STATIC void render_init_fs_quad(void) glBufferData( GL_ARRAY_BUFFER, sizeof(quad), quad, GL_STATIC_DRAW ); glBindVertexArray( gpipeline.fsquad.vao ); glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, - sizeof(float)*2, (void*)0 ); + sizeof(float)*2, (void*)0 ); glEnableVertexAttribArray( 0 ); VG_CHECK_GL_ERR(); @@ -835,4 +707,181 @@ VG_STATIC void render_fsquad1(void) glDrawArrays( GL_TRIANGLES, 6, 6 ); } +/* + * Call this inside the UI function + */ +VG_STATIC void render_view_framebuffer_ui(void) +{ + int viewing_count = 0; + + glBindVertexArray( gpipeline.fsquad.vao ); + shader_blit_use(); + shader_blit_uTexMain( 0 ); + + for( int i=0; iattachments); j++ ) + { + struct framebuffer_attachment *at = &fb->attachments[j]; + + if( !at->debug_view ) + continue; + + v2f corner, + window = { vg.window_x, vg.window_y }; + + corner[0] = viewing_count % 3; + corner[1] = 1 + (viewing_count / 3); + v2_mul( corner, window, corner ); + v2_muls( corner, 0.3f, corner ); + corner[1] = vg.window_y - corner[1]; + + ui_text( (ui_rect){ corner[0], corner[1], 0.0f, 0.0f }, + fb->display_name, 2, k_text_align_left ); + ui_text( (ui_rect){ corner[0], corner[1] + 32, 0.0f, 0.0f, }, + at->display_name, 1, k_text_align_left ); + + if( at->purpose == k_framebuffer_attachment_type_renderbuffer ) + { + v2f center; + v2_muladds( corner, window, 0.15f, center ); + + ui_text( (ui_rect){ center[0], center[1], 0.0f, 0.0f }, + "", 1, k_text_align_center ); + } + else + { + render_fb_bind_texture( fb, j, 0 ); + + int start = (viewing_count+2) * 6, + count = 6; + glDrawArrays( GL_TRIANGLES, start, count ); + } + + viewing_count ++; + } + } +} + +VG_STATIC void render_framebuffer_show( struct framebuffer *fb, + struct framebuffer_attachment *at, + int operation ) +{ + at->debug_view = operation; + vg_info( "%s %s:%s\n", (operation?"shown": "hidden"), + fb->display_name, at->display_name ); +} + +/* + * arg0: command "show"/"hide" + * arg1: framebuffer name /"all" + * arg2: subname /none + */ +VG_STATIC int render_framebuffer_control( int argc, char const *argv[] ) +{ + if( argc < 2 ) + { + vg_error( "Usage: fb \"show/hide\" /\"all\" /none\n" ); + return 0; + } + + int modify_all = 0, + operation = 0; + + if( !strcmp( argv[0], "show" ) ) + operation = 1; + else if( !strcmp( argv[0], "hide" ) ) + operation = 0; + else + { + vg_error( "Unknown framebuffer operation: '%s'\n", argv[0] ); + return 0; + } + + if( !strcmp( argv[1], "all" ) ) + modify_all = 1; + + for( int i=0; iattachments); j++ ) + { + struct framebuffer_attachment *at = &fb->attachments[j]; + + if( at->purpose == k_framebuffer_attachment_type_none ) + continue; + + if( modify_all ) + { + render_framebuffer_show( fb, at, operation ); + } + else + { + if( !strcmp( fb->display_name, argv[1] ) ) + { + if( argc == 2 ) + render_framebuffer_show( fb, at, operation ); + else if( !strcmp( at->display_name, argv[2] ) ) + render_framebuffer_show( fb, at, operation ); + } + } + } + } + + return 0; +} + +VG_STATIC void render_framebuffer_poll( int argc, char const *argv[] ) +{ + const char *term = argv[argc-1]; + + if( argc == 1 ) + { + console_suggest_score_text( "show", term, 0 ); + console_suggest_score_text( "hide", term, 0 ); + } + else if( argc == 2 ) + { + console_suggest_score_text( "all", term, 0 ); + + for( int i=0; idisplay_name, term, 0 ); + } + } + else if( argc == 3 ) + { + int modify_all = 0; + + if( !strcmp( argv[1], "all" ) ) + modify_all = 1; + + for( int i=0; iattachments); j++ ) + { + struct framebuffer_attachment *at = &fb->attachments[j]; + + if( at->purpose == k_framebuffer_attachment_type_none ) + continue; + + if( modify_all ) + { + console_suggest_score_text( at->display_name, term, 0 ); + } + else if( !strcmp( fb->display_name, argv[1] ) ) + { + console_suggest_score_text( at->display_name, term, 0 ); + } + } + } + } +} + #endif /* RENDER_H */