dead
[carveJwlIkooP6JGAAIwe30JlM.git] / render.h
index 77bb56e1b570eeb7b4bddd0de12e6f82c5e21077..cd41ec33e836d65ef02d690fc824d4505efee3a1 100644 (file)
--- 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; i<vg_list_size(framebuffers); i++ )
+   {
+      struct framebuffer *fb = &framebuffers[i];
+
+      for( int j=0; j<vg_list_size(fb->attachments); 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 },
+                     "<hardware texture>", 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  <name>/"all"
+ * arg2: subname           <name>/none
+ */
+VG_STATIC int render_framebuffer_control( int argc, char const *argv[] )
+{
+   if( argc < 2 )
+   {
+      vg_error( "Usage: fb \"show/hide\" <name>/\"all\" <name>/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; i<vg_list_size(framebuffers); i++ )
+   {
+      struct framebuffer *fb = &framebuffers[i];
+      
+      for( int j=0; j<vg_list_size(fb->attachments); 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; i<vg_list_size(framebuffers); i++ )
+      {
+         struct framebuffer *fb = &framebuffers[i];
+         console_suggest_score_text( fb->display_name, term, 0 );
+      }
+   }
+   else if( argc == 3 )
+   {
+      int modify_all = 0;
+
+      if( !strcmp( argv[1], "all" ) )
+         modify_all = 1;
+
+      for( int i=0; i<vg_list_size(framebuffers); i++ )
+      {
+         struct framebuffer *fb = &framebuffers[i];
+         
+         for( int j=0; j<vg_list_size(fb->attachments); 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 */