X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=render.h;h=f17018bb2e767006dbd6701c355a7f5e9dd5b33b;hb=6e9b9e12e1f9da0419cd4d89707c7d599512d3b8;hp=0bb4c3330bd42a878940e26feae5f9fb5213422a;hpb=c88172d6968a02a4e643b74cc419c0ac8168d92a;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/render.h b/render.h index 0bb4c33..f17018b 100644 --- a/render.h +++ b/render.h @@ -5,17 +5,23 @@ #include "common.h" #include "model.h" #include "camera.h" +#include "world.h" #include "shaders/blit.h" #include "shaders/blitblur.h" +#include "shaders/blitcolour.h" + +#if 0 #include "shaders/standard.h" #include "shaders/vblend.h" +#endif -VG_STATIC void render_water_texture( camera *cam ); -VG_STATIC void render_water_surface( camera *cam ); -VG_STATIC void render_world( camera *cam ); -VG_STATIC void shader_link_standard_ub( GLuint shader, int texture_id ); -VG_STATIC void render_world_depth( camera *cam ); +VG_STATIC void render_water_texture( world_instance *world, camera *cam, + int layer_depth ); +VG_STATIC void render_water_surface( world_instance *world, camera *cam ); +VG_STATIC void render_world( world_instance *world, camera *cam, + int layer_depth ); +VG_STATIC void render_world_depth( world_instance *world, camera *cam ); #ifndef RENDER_H #define RENDER_H @@ -31,28 +37,9 @@ VG_STATIC struct pipeline glmesh fsquad; framebuffer *fb_main, - *fb_heightmap, *fb_water_reflection, *fb_water_beneath; - /* STD140 */ - struct ub_world_lighting - { - /* v3f (padded) */ - v4f g_light_colours[3], - g_light_directions[3], - g_ambient_colour; - - v4f g_water_plane, - g_depth_bounds; - - float g_water_fog; - int g_light_count; - int g_light_preview; - int g_shadow_samples; - } - ub_world_lighting; - struct light_widget { int enabled; @@ -62,8 +49,6 @@ VG_STATIC struct pipeline widgets[3]; float shadow_spread, shadow_length; - GLuint ubo_world_lighting, - ubo_world; int ready; } @@ -89,11 +74,6 @@ gpipeline = }, .shadow_spread = 0.65f, .shadow_length = 9.50f, - - .ub_world_lighting = - { - .g_ambient_colour = { 0.09f, 0.03f, 0.07f } - } }; struct framebuffer @@ -121,13 +101,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 +122,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 +136,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,54 +145,31 @@ 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 } } }, - { - /* - * A ortho projection of the world, used for shadows and ocean colouring. - * Note: it does not have a render buffer attachement because it's - * intended to be drawn to in a MAX blending mode - */ - "Heightmap", - .link = &gpipeline.fb_heightmap, - .fixed_w = 1024, - .fixed_h = 1024, - - .attachments = - { - { - "Depth", k_framebuffer_attachment_type_colour, - - .internalformat = GL_R32F, - .format = GL_RED, - .type = GL_FLOAT, - .attachment = GL_COLOR_ATTACHMENT0 - } - } - }, { /* * 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 +181,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, - .internalformat = GL_RGBA, - .format = GL_RGBA, + "colour", k_framebuffer_attachment_type_colour, + .internalformat = GL_RED, + .format = GL_RED, .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 @@ -294,51 +254,6 @@ VG_STATIC void render_fb_bind_texture( framebuffer *fb, /* * Shaders */ -VG_STATIC void shader_link_standard_ub( GLuint shader, int texture_id ) -{ - GLuint idx = glGetUniformBlockIndex( shader, "ub_world_lighting" ); - glUniformBlockBinding( shader, idx, 0 ); - - render_fb_bind_texture( gpipeline.fb_heightmap, 0, texture_id ); - glUniform1i( glGetUniformLocation( shader, "g_world_depth" ), texture_id ); -} - -VG_STATIC void render_update_lighting_ub(void) -{ - struct ub_world_lighting *winf = &gpipeline.ub_world_lighting; - int c = 0; - - for( int i=0; i<3; i++ ) - { - struct light_widget *lw = &gpipeline.widgets[i]; - - if( lw->enabled ) - { - float pitch = lw->dir[0], - yaw = lw->dir[1], - xz = cosf( pitch ); - - v3_copy( (v3f){ xz*cosf(yaw), sinf(pitch), xz*sinf(yaw) }, - winf->g_light_directions[c] ); - v3_copy( lw->colour, winf->g_light_colours[c] ); - - c ++; - } - } - - winf->g_light_count = c; - winf->g_light_directions[0][3] = gpipeline.shadow_length; - winf->g_light_colours[0][3] = gpipeline.shadow_spread; - - if( vg.quality_profile == k_quality_profile_low ) - winf->g_shadow_samples = 0; - else - winf->g_shadow_samples = 8; - - glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting ); - glBufferSubData( GL_UNIFORM_BUFFER, 0, sizeof(struct ub_world_lighting), - &gpipeline.ub_world_lighting ); -} #define FB_FORMAT_STR( E ) { E, #E }, @@ -588,15 +503,50 @@ VG_STATIC void render_fb_resize(void) } } +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 ); @@ -605,33 +555,17 @@ 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(); } -VG_STATIC void render_init_uniform_buffers(void) -{ - vg_info( "[render] Allocate uniform buffer\n" ); - - glGenBuffers( 1, &gpipeline.ubo_world_lighting ); - glBindBuffer( GL_UNIFORM_BUFFER, gpipeline.ubo_world_lighting ); - glBufferData( GL_UNIFORM_BUFFER, sizeof(struct ub_world_lighting), - NULL, GL_DYNAMIC_DRAW ); - - render_update_lighting_ub(); - glBindBufferBase( GL_UNIFORM_BUFFER, 0, gpipeline.ubo_world_lighting ); - - VG_CHECK_GL_ERR(); -} - VG_STATIC void render_init(void) { shader_blit_register(); shader_blitblur_register(); - shader_standard_register(); - shader_vblend_register(); + shader_blitcolour_register(); vg_acquire_thread_sync(); { @@ -645,7 +579,6 @@ VG_STATIC void render_init(void) } render_init_fs_quad(); - render_init_uniform_buffers(); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); gpipeline.ready = 1; @@ -669,4 +602,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 */