magi&memory view
authorhgn <hgodden00@gmail.com>
Wed, 25 Sep 2024 23:28:52 +0000 (00:28 +0100)
committerhgn <hgodden00@gmail.com>
Wed, 25 Sep 2024 23:28:52 +0000 (00:28 +0100)
vg_console.c
vg_console.h
vg_engine.c
vg_magi.c [new file with mode: 0644]
vg_magi.h [new file with mode: 0644]
vg_mem_view.c
vg_mem_view.h
vg_ui/imgui.c
vg_ui/imgui.h
vg_ui/imgui_impl_opengl.c

index b1f320a6deafed034ea12dfb03593d10d8080338..a57c1a26744c89206a5477129966ab20d78b595a 100644 (file)
@@ -584,6 +584,8 @@ static void _vg_console_on_enter( ui_context *ctx, char *buf, u32 len )
       vg_console.input[0] = '\0';
       console_update_suggestions( ctx );
    }
+
+   vg_console.auto_focus = 1;
 }
 
 int vg_console_exec( int argc, const char *argv[] )
@@ -608,6 +610,7 @@ int vg_console_exec( int argc, const char *argv[] )
 
                        if( line[0] != 0x00 )
          {
+            strcpy( vg_console.input, line );
                                vg_execute_console_input( line, silent );
                        }
                }
@@ -619,6 +622,7 @@ int vg_console_exec( int argc, const char *argv[] )
       vg_error( "Could not open '%s'\n", path );
    }
 
+   vg_console.input[0] = '\0';
    return 0;
 }
 
@@ -683,9 +687,13 @@ void vg_console_draw( ui_context *ctx )
       .change = _vg_console_on_update,
       .enter = _vg_console_on_enter,
    };
+
+   u32 flags = 0;
+   if( vg_console.auto_focus ) flags |= UI_TEXTBOX_AUTOFOCUS;
    ui_textbox( ctx, rect_input, NULL, 
                vg_console.input, VG_ARRAY_LEN(vg_console.input), 1,
-               UI_TEXTBOX_AUTOFOCUS, &callbacks );
+               flags, &callbacks );
+   vg_console.auto_focus = 0;
 
    /* 
     * suggestions 
index 27c11b8c59097ff78b4f06c903c726936db86a94..046b8118ef98f99a105b983f74ca4f249be1c663 100644 (file)
@@ -62,6 +62,7 @@ struct vg_console
        int history_last, history_pos, history_count;
        
        i32 enabled, cheats;
+   bool auto_focus;
 }
 extern vg_console;
 
index db025c8d8849eda12b6d717e0af8f445300268ed..9b0c1bf3611cd42d9c13b32447fb99b8f014a595 100644 (file)
@@ -50,6 +50,7 @@ static void _vg_opengl_sync_init(void)
 
 #include "vg_console.h"
 #include "vg_profiler.h"
+#include "vg_magi.h"
 #include "vg_mem_view.h"
 #ifndef VG_NO_AUDIO
   #include "vg_audio.h"
@@ -86,18 +87,16 @@ void async_internal_complete( void *payload, u32 size )
    vg_success( "Internal async setup complete\n" );
 
    SDL_AtomicLock( &vg.sl_status );
-
    if( vg.engine_status == k_engine_status_crashed )
    {
       SDL_AtomicUnlock( &vg.sl_status );
       return;
    }
    else
-   {
       vg.engine_status = k_engine_status_running;
-   }
-
    SDL_AtomicUnlock( &vg.sl_status );
+
+   vg_magi_restore();
 }
 
 #ifdef VG_CUSTOM_SHADERS
@@ -181,6 +180,7 @@ static void _vg_process_events(void)
          {
             if( event.key.keysym.scancode == SDL_SCANCODE_GRAVE )
             {
+               vg_console.auto_focus = 1;
                vg_console.enabled = 1;
             }
             else 
@@ -349,12 +349,15 @@ static void _vg_gameloop_render(void)
                   (ui_rect){258,4,900,900},perf,1,0,k_ui_align_left);
       }
 
+#if 0
       if( vg_mem_view && vg_loader_availible() )
       {
          vg_mem_view_ui( &vg_ui.ctx, (ui_rect){400,32,
                                                vg.window_x-400,vg.window_y-64},
                        vg_mem.rtmemory, 0, "rtmemory" );
       }
+#endif
+      _vg_magi_render( &vg_ui.ctx );
 
       ui_postrender( &vg_ui.ctx, vg.time_frame_delta );
       vg_ui_post_update();
@@ -715,6 +718,7 @@ static void _vg_init_window( const char *window_name )
 static void _vg_terminate(void)
 {
    /* Shutdown */
+   vg_magi_save();
    vg_console_write_persistent();
 
    SDL_AtomicLock( &vg.sl_status );
@@ -745,6 +749,7 @@ void vg_enter( int argc, char *argv[], const char *window_name )
    /* Systems init */
    vg_alloc_quota();
    vg_console_init();
+   vg_magi_init();
    
    vg_console_reg_var( "vg_fps_limit", &vg.fps_limit, 
                         k_var_dtype_i32, VG_VAR_PERSISTENT );
@@ -1338,6 +1343,7 @@ __attribute__((used)) int AmdPowerXpressRequestHighPerformance = 1;
 #include "vg_perlin.c"
 #include "vg_string.c"
 #include "vg_profiler.c"
+#include "vg_magi.c"
 #include "vg_rigidbody_collision.c"
 #include "vg_rigidbody_constraints.c"
 #include "vg_rigidbody.c"
diff --git a/vg_magi.c b/vg_magi.c
new file mode 100644 (file)
index 0000000..b068ee5
--- /dev/null
+++ b/vg_magi.c
@@ -0,0 +1,190 @@
+#include "vg_magi.h"
+#include "vg_console.h"
+
+struct vg_magi _vg_magi;
+
+struct vg_magi_panel *_vg_magi_open( ui_px w, ui_px h, u32 flags )
+{
+   VG_ASSERT( _vg_magi.panel_count < VG_MAGI_MAX_PANELS );
+   struct vg_magi_panel *panel = &_vg_magi.panels[ _vg_magi.panel_count ++ ];
+   panel->rect[0] = 32;
+   panel->rect[1] = 32;
+   panel->rect[2] = w;
+   panel->rect[3] = h;
+   panel->title = "";
+   panel->data = NULL;
+   panel->minimized = 0;
+   panel->flags = flags;
+   panel->ui_cb = NULL;
+   panel->close_cb = NULL;
+
+   if( flags & VG_MAGI_PERSISTENT )
+      strcpy( panel->cmd, vg_console.input );
+
+   return panel;
+}
+
+void _vg_magi_render( ui_context *ctx )
+{
+   if( _vg_magi.panel_count == 0 ) return;
+
+   u32 highlight = 0xffffffff,
+       top = _vg_magi.panel_count-1;
+
+   if( _vg_magi.mode == k_magi_mode_none )
+   {
+      for( u32 i=0; i<_vg_magi.panel_count; i ++ )
+      {
+         struct vg_magi_panel *panel = &_vg_magi.panels[ i ];
+         if( ui_inside_rect( panel->rect, ctx->mouse ) )
+            highlight = i;
+      }
+
+      /* bring to top */
+      if( (highlight < top) && ui_click_down( ctx, UI_MOUSE_ANY ) )
+      {
+         struct vg_magi_panel temp = _vg_magi.panels[ highlight ];
+
+         for( i32 i=0, j=0; i<_vg_magi.panel_count; i ++ )
+            if( i != highlight )
+               _vg_magi.panels[ j ++ ] = _vg_magi.panels[ i ];
+
+         _vg_magi.panels[ top ] = temp;
+         highlight = top;
+      }
+   }
+   else
+   {
+      highlight = top;
+      struct vg_magi_panel *ptop = &_vg_magi.panels[ top ];
+
+      if( _vg_magi.mode == k_magi_mode_drag )
+      {
+         ptop->rect[0] = _vg_magi.drag_original[0] + ctx->mouse_delta[0];
+         ptop->rect[1] = _vg_magi.drag_original[1] + ctx->mouse_delta[1];
+      }
+      else if( _vg_magi.mode == k_magi_mode_resize )
+      {
+         ptop->rect[2] = _vg_magi.drag_original[2] + ctx->mouse_delta[0];
+         ptop->rect[3] = _vg_magi.drag_original[3] + ctx->mouse_delta[1];
+
+         if( ptop->rect[2] < ptop->min_w ) ptop->rect[2] = ptop->min_w;
+         if( ptop->rect[3] < ptop->min_h ) ptop->rect[3] = ptop->min_h;
+      }
+
+      if( ui_click_up( ctx, UI_MOUSE_ANY ) ) 
+         _vg_magi.mode = k_magi_mode_none;
+   }
+
+   for( i32 i=0; i<_vg_magi.panel_count; i ++ )
+   {
+      struct vg_magi_panel *panel = &_vg_magi.panels[ i ];
+
+      ui_rect title, rect;
+      ui_split( panel->rect, k_ui_axis_h, 28, 0, title, rect );
+      ui_fill( ctx, title, ui_opacity( ui_colour( ctx, k_ui_bg+7 ), 0.9f ) );
+
+      if( panel->flags & VG_MAGI_PERSISTENT )
+      {
+         ui_text( ctx, title, panel->cmd, 1, k_ui_align_middle_center, 
+                  ui_colourcont( ctx, k_ui_bg+7 ) );
+      }
+      else
+      {
+         ui_text( ctx, title, panel->title, 1, k_ui_align_middle_center, 
+                  ui_colourcont( ctx, k_ui_bg+7 ) );
+      }
+
+      ui_fill( ctx, rect, ui_opacity( ui_colour( ctx, k_ui_bg+1 ), 0.7f ) );
+
+      if( i == highlight ) 
+      {
+         /* TODO: enable interaction */
+
+         if( ui_click_down( ctx, UI_MOUSE_MIDDLE ) )
+         {
+            if( panel->flags & VG_MAGI_MOVEABLE )
+            {
+               _vg_magi.mode = k_magi_mode_drag;
+               rect_copy( panel->rect, _vg_magi.drag_original );
+            }
+         }
+         else if( ui_click_down( ctx, UI_MOUSE_RIGHT ) )
+         {
+            if( panel->flags & VG_MAGI_RESIZEABLE )
+            {
+               _vg_magi.mode = k_magi_mode_resize;
+               rect_copy( panel->rect, _vg_magi.drag_original );
+            }
+         }
+
+         ui_outline( ctx, panel->rect, 1, ui_colour( ctx, k_ui_bg+7 ), 0 );
+      }
+      else
+      {
+         /* TODO: disable interaction */
+      }
+
+      panel->ui_cb( ctx, rect, panel );
+   }
+}
+
+void vg_magi_restore(void)
+{
+   vg_console_exec( 2, (const char *[]){ "magi.conf", "silent" } );
+}
+
+void vg_magi_save(void)
+{
+       FILE *fp = fopen( "cfg/magi.conf", "w" );
+
+   if( !fp )
+   {
+      vg_error( "Cannot open cfg/magi.conf\n" );
+      return;
+   }
+       
+   for( u32 i=0; i<_vg_magi.panel_count; i ++ )
+   {
+      struct vg_magi_panel *magi = &_vg_magi.panels[i];
+
+      if( magi->flags & VG_MAGI_PERSISTENT )
+      {
+         fprintf( fp, "%s\n", magi->cmd );
+         fprintf( fp, "magi_pos %d %d %d %d\n", 
+               magi->rect[0], magi->rect[1], magi->rect[2], magi->rect[3] );
+      }
+   }
+
+       fclose( fp );
+}
+
+static int cmd_vg_magi_dim( int argc, const char *argv[] )
+{
+   if( !_vg_magi.panel_count )
+   {
+      vg_error( "No active panels to apply that to.\n" );
+      return 0;
+   }
+
+   if( argc == 0 )
+   {
+      vg_error( "Usage: magi_pos x y w h\n" );
+      return 0;
+   }
+
+   struct vg_magi_panel *magi = &_vg_magi.panels[ _vg_magi.panel_count-1 ];
+   for( int i=0; i<4; i ++ )
+   {
+      if( argc >= i+1 ) 
+         magi->rect[i] = atoi( argv[i] );
+      else break;
+   }
+
+   return 1;
+}
+
+void vg_magi_init(void)
+{
+   vg_console_reg_cmd( "magi_pos", cmd_vg_magi_dim, NULL );
+}
diff --git a/vg_magi.h b/vg_magi.h
new file mode 100644 (file)
index 0000000..34c5f4a
--- /dev/null
+++ b/vg_magi.h
@@ -0,0 +1,44 @@
+#pragma once
+#define VG_MAGI_MAX_PANELS 8
+
+#define VG_MAGI_RESIZEABLE 0x1
+#define VG_MAGI_MOVEABLE 0x2
+#define VG_MAGI_PERSISTENT 0x4
+#define VG_MAGI_ALL (VG_MAGI_RESIZEABLE|VG_MAGI_MOVEABLE|VG_MAGI_PERSISTENT)
+
+struct vg_magi
+{
+   struct vg_magi_panel
+   {
+      bool minimized;
+      const char *title;
+      ui_rect rect;
+      u32 flags;
+      void *data;
+
+      char cmd[96]; /* used for persistence */
+      ui_px min_w, min_h;
+
+      void(*ui_cb)( ui_context *ctx, ui_rect rect, struct vg_magi_panel *magi );
+      void(*close_cb)( struct vg_magi_panel *me );
+   }
+   panels[ VG_MAGI_MAX_PANELS ];
+   u32 panel_count;
+
+   enum magi_mode
+   {
+      k_magi_mode_none,
+      k_magi_mode_drag,
+      k_magi_mode_resize
+   }
+   mode;
+   ui_rect drag_original;
+   ui_px drag_start[2];
+}
+extern _vg_magi;
+
+struct vg_magi_panel *_vg_magi_open( ui_px w, ui_px h, u32 flags );
+void _vg_magi_render( ui_context *ctx );
+void vg_magi_init(void);
+void vg_magi_save(void);
+void vg_magi_restore(void);
index 92af16d422d4aa838f1f68bd7d00edfaaf20b27f..d326b5dc67f1f8653f4595f20dadd57a49a5d4f5 100644 (file)
@@ -71,15 +71,26 @@ L_LOOP:
    goto L_LOOP_ADJUST;
 }
 
+struct vg_mem_view_result
+{
+   vg_allocation_meta *target;
+   ui_rect target_rect;
+   u32 colour;
+};
+
 struct vg_mem_draw_inf
 {
    ui_context *ui_ctx;
    vg_linear_allocator *alloc;
    i32 *indices;
+   u32 root_colour;
+
+   struct vg_mem_view_result *result;
 };
 
-void vg_mem_view_ui( ui_context *ctx, ui_rect rect, 
-                     void *lin_alloc, int depth, const char *name );
+static void vg_mem_view_ui( ui_context *ctx, ui_rect rect, 
+                            void *lin_alloc, const char *name, u32 root_colour,
+                            struct vg_mem_view_result *result );
 
 static void vg_mem_draw_cb( u32 idx, ui_rect rect, void *user )
 {
@@ -92,24 +103,27 @@ static void vg_mem_draw_cb( u32 idx, ui_rect rect, void *user )
    idx = inf->indices[idx];
    vg_allocation_meta *meta = &inf->alloc->alloc_table[idx];
 
+   u32 colour;
+   if( inf->root_colour ) colour = inf->root_colour;
+   else                   colour = ~0xff000000&((idx+5)*0x45d9f3b);
+
    if( meta->type == k_allocation_type_block )
    {
-      ui_fill( inf->ui_ctx, tmp, 0x80000000 | (~0xff000000&(idx*0x45d9f3b)) );
-
-      if( tmp[2] > 20 && tmp[3] > 16 )
-         ui_text( inf->ui_ctx, tmp, meta->name, 1, k_ui_align_left, 0 );
+      ui_fill( inf->ui_ctx, tmp, 0x80000000 | colour );
+      ui_outline( inf->ui_ctx, tmp, -1, 0xff000000 | colour, 0 );
    }
    else
+      vg_mem_view_ui( inf->ui_ctx, tmp, meta->data, meta->name, colour, NULL );
+
+   if( inf->result )
    {
-      vg_mem_view_ui( inf->ui_ctx, tmp, meta->data, 0, meta->name );
+      if( ui_inside_rect( rect, inf->ui_ctx->mouse ) )
+      {
+         inf->result->target = meta;
+         inf->result->colour = colour;
+         rect_copy( rect, inf->result->target_rect );
+      }
    }
-
-   return;
-
-
-   char buf[32];
-   vg_mem_print_size( meta->size, buf );
-   ui_text( inf->ui_ctx, tmp, buf, 1, k_ui_align_middle_center, 0 );
 }
 
 vg_linear_allocator *_CB_values;
@@ -121,8 +135,9 @@ int _CB_vg_mem_sort( const void *a, const void *b )
    return (fa < fb) - (fa > fb);
 }
 
-void vg_mem_view_ui( ui_context *ctx, ui_rect rect, 
-                     void *lin_alloc, int depth, const char *name )
+static void vg_mem_view_ui( ui_context *ctx, ui_rect rect, 
+                            void *lin_alloc, const char *name, u32 root_colour,
+                            struct vg_mem_view_result *result )
 {
    f32 sizes[ VG_MAX_ALLOCATIONS ];
    i32 indices[ VG_MAX_ALLOCATIONS ];
@@ -135,6 +150,8 @@ void vg_mem_view_ui( ui_context *ctx, ui_rect rect,
          .ui_ctx = ctx,
          .alloc = alloc,
          .indices = indices,
+         .result = result,
+         .root_colour = root_colour
       };
 
       if( alloc->allocation_count )
@@ -148,7 +165,11 @@ void vg_mem_view_ui( ui_context *ctx, ui_rect rect,
             out_box[ 2+short_side^0x1 ] = h;
             out_box[ 2+short_side ] = rect[ 2+short_side ];
 
-            ui_fill( ctx, out_box, 0x80303030 );
+            ui_fill( ctx, out_box, 0x80000000 );
+
+            char asize[32];
+            vg_mem_print_size( alloc->size-alloc->cur, asize );
+            ui_text( ctx, out_box, asize, 1, k_ui_align_middle_center, 0 );
 
             rect[ short_side^0x1 ] += h;
             rect[ 2+short_side^0x1 ] -= h;
@@ -181,7 +202,7 @@ void vg_mem_view_ui( ui_context *ctx, ui_rect rect,
       else
       {
          ui_fill( ctx, rect, 0x80101010 );
-         ui_text( ctx, rect, name, 1, k_ui_align_left, 0 );
+         //ui_text( ctx, rect, name, 1, k_ui_align_left, 0 );
       }
    }
    else
@@ -190,7 +211,191 @@ void vg_mem_view_ui( ui_context *ctx, ui_rect rect,
    }
 }
 
+static struct
+{
+   const char *name;
+   void **buffer;
+}
+_vg_mem_named_buffers[] = 
+{
+   { "rtmemory", &vg_mem.rtmemory },
+   { "scratch", &vg_mem.scratch }
+};
+
+struct mem_view_data
+{
+   void *main_buffer[8],
+        *inspecting;
+   v4f inspect_colour;
+
+   const char *walk[8];
+
+   u32 depth;
+
+   f32 vis_data[256*256];
+   GLuint tex;
+};
+
+static void cb_vg_mem_view( ui_context *ctx, ui_rect rect, 
+                            struct vg_magi_panel *magi )
+{
+   struct mem_view_data *mv = magi->data;
+   struct vg_mem_view_result result = { .target=NULL };
+
+   ui_rect left;
+   ui_split( rect, k_ui_axis_v, 256+16, 2, left, rect );
+   ui_fill( ctx, left, ui_opacity( ui_colour( ctx,k_ui_bg+1 ), 0.8f ) );
+
+   for( u32 i=0; i<mv->depth+1; i ++ )
+      ui_info( ctx, left, mv->walk[ i ] );
+
+   if( mv->depth )
+      if( ui_button( ctx, left, "up" ) == 1 )
+         mv->depth --;
+
+   vg_mem_view_ui( ctx, rect, mv->main_buffer[ mv->depth ], "", 0, &result );
+
+   if( result.target )
+   {
+      ui_outline( ctx, result.target_rect, 1, ui_colour( ctx,k_ui_bg+7 ), 0 );
+      ui_info( ctx, left, result.target->name );
+
+      char buf[32];
+      vg_mem_print_size( result.target->size, buf );
+      ui_info( ctx, left, buf );
+
+      if( mv->inspecting != result.target->data )
+      {
+         if( result.target->type == k_allocation_type_block )
+         {
+            for( u32 i=0; i<256*256; i++ ) mv->vis_data[i] = 0.0f;
+            f32 max_freq = 0.0f;
+            
+            const u8 *src = result.target->data;
+            for( u32 i=0; i<result.target->size-1; i ++ )
+            {
+               u8 x = src[i], y = src[i+1];
+               u32 offset = y*256 + x;
+
+               mv->vis_data[ offset ] += 1.0f;
+               max_freq = vg_maxf( mv->vis_data[ offset ], max_freq );
+            }
+
+            f32 median = 0.0f;
+            for( u32 i=0; i<256*256; i++ ) median += mv->vis_data[i];
+            median /= 256.0f*256.0f;
+
+            f32 inv_max = 1.0f/logf(1.0f+median*2.0f);
+            for( u32 i=0; i<256*256; i++ ) 
+            {
+               f32 v = logf(mv->vis_data[i]) * inv_max;
+               mv->vis_data[i] = v;
+            }
+
+            glBindTexture( GL_TEXTURE_2D, mv->tex );
+            glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 256, 256, 
+                              GL_RED, GL_FLOAT, mv->vis_data );
+         }
+
+         mv->inspecting = result.target->data;
+
+         f32 nrm = 1.6f / 255.0f;
+         mv->inspect_colour[0] = (f32)((result.colour    ) & 0xff) * nrm;
+         mv->inspect_colour[1] = (f32)((result.colour>>8 ) & 0xff) * nrm;
+         mv->inspect_colour[2] = (f32)((result.colour>>16) & 0xff) * nrm;
+         mv->inspect_colour[3] = 1.0f;
+      }
+
+      if( result.target->type == k_allocation_type_block )
+         ui_info( ctx, left, "Leaf" );
+      else
+         ui_info( ctx, left, "Linear Allocator (expand)" );
+
+      if( result.target->type == k_allocation_type_block )
+      {
+         ui_rect freq_box = { left[0]+8, left[1], 256,256 };
+
+         ui_flush( ctx, k_ui_shader_colour, NULL );
+         ui_fill_rect( ctx, freq_box, 0xffffffff, (ui_px[4]){ 0,256,256,0 } );
+         struct ui_batch_shader_data_image inf = { .resource = &mv->tex };
+         v4_copy( mv->inspect_colour, vg_ui.colour );
+         ui_flush( ctx, k_ui_shader_grad, &inf );
+         v4_copy( (v4f){1,1,1,1}, vg_ui.colour );
+      }
+
+      if( result.target->type == k_allocation_type_linear )
+      {
+         if( ui_click_down( ctx, UI_MOUSE_LEFT ) )
+         {
+            mv->main_buffer[ mv->depth+1 ] = result.target->data;
+            mv->walk[ mv->depth+1 ] = result.target->name;
+            mv->inspecting = NULL;
+            mv->depth ++;
+         }
+      }
+   }
+}
+
+static void cb_mem_view_close( struct vg_magi_panel *me )
+{
+   struct mem_view_data *mv = me->data;
+   glDeleteTextures( 1, &mv->tex );
+   free( me->data );
+}
+
+static int cmd_vg_mem_view( int argc, const char *argv[] )
+{
+   if( argc == 1 )
+   {
+      for( u32 i=0; i<VG_ARRAY_LEN( _vg_mem_named_buffers ); i ++ )
+      {
+         if( !strcmp( _vg_mem_named_buffers[i].name, argv[0] ) )
+         {
+            ui_px w = 512+16,
+                  h = 512;
+            struct vg_magi_panel *magi = _vg_magi_open( w,h, VG_MAGI_ALL );
+            magi->title = "Memory outliner";
+
+            struct mem_view_data *mv = malloc(sizeof(struct mem_view_data));
+            mv->main_buffer[0] = *_vg_mem_named_buffers[i].buffer;
+            mv->walk[0] = _vg_mem_named_buffers[i].name;
+            mv->depth = 0;
+            mv->inspecting = NULL;
+
+            glGenTextures( 1, &mv->tex );
+            glBindTexture( GL_TEXTURE_2D, mv->tex );
+            glTexImage2D( GL_TEXTURE_2D, 0, GL_R32F, 256,256, 0, 
+                          GL_RED, GL_FLOAT, NULL );
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
+
+            magi->data = mv;
+            magi->ui_cb = cb_vg_mem_view;
+            magi->close_cb = cb_mem_view_close;
+            magi->min_w = w;
+            magi->min_h = h;
+            return 1;
+         }
+      }
+
+      vg_error( "No named buffer '%s'\n", argv[0] );
+   }
+   else
+      vg_error( "Usage: vg_mem_view <named_buffer>\n" );
+
+   return 0;
+}
+
+static void cmd_vg_mem_view_poll( int argc, const char *argv[] )
+{
+   const char *term = argv[ argc-1 ];
+
+   if( argc == 1 )
+      for( u32 i=0; i<VG_ARRAY_LEN( _vg_mem_named_buffers ); i ++ )
+         console_suggest_score_text( _vg_mem_named_buffers[i].name, term, 0 );
+}
+
 void vg_mem_view_init(void)
 {
-   VG_VAR_I32( vg_mem_view, flags=VG_VAR_PERSISTENT );
+   vg_console_reg_cmd( "vg_mem_view", cmd_vg_mem_view, cmd_vg_mem_view_poll );
 }
index 87922571a77b83b5febc47e6f808a5f0a952e3c2..96421e6ef0a70710ea9ec30a3d761a664ea16502 100644 (file)
@@ -2,4 +2,3 @@
 #include "vg_ui/imgui.h"
 extern int vg_mem_view;
 void vg_mem_view_init(void);
-void vg_mem_view_ui( ui_context *ctx, ui_rect rect, void *lin_alloc, int depth, const char *name );
index 0b63730312aba77122b04076c249ec8294308f67..1a4ea5bd15f1692a410e8e82812a4059d20340f8 100644 (file)
@@ -241,8 +241,8 @@ void ui_update_mouse( ui_context *ctx, ui_px mouse[2], i32 mouse_state )
 {
    ctx->mouse_state[1] = ctx->mouse_state[0];
    ctx->mouse_state[0] = mouse_state;
-   ctx->mouse_delta[0] = mouse[0]-ctx->mouse[0];
-   ctx->mouse_delta[1] = mouse[1]-ctx->mouse[1];
+   ctx->mouse_delta[0] = mouse[0]-ctx->mouse_click[0];
+   ctx->mouse_delta[1] = mouse[1]-ctx->mouse_click[1];
 
    if( !ctx->mouse_pos_overriden )
    {
@@ -256,9 +256,7 @@ void ui_update_mouse( ui_context *ctx, ui_px mouse[2], i32 mouse_state )
       return;
    }
 
-   if( ui_click_down(ctx, UI_MOUSE_LEFT)||
-       ui_click_down(ctx, UI_MOUSE_MIDDLE)||
-       ui_click_down(ctx, UI_MOUSE_RIGHT) )
+   if( ui_click_down(ctx, UI_MOUSE_ANY) )
    {
       ctx->mouse_click[0] = ctx->mouse[0];
       ctx->mouse_click[1] = ctx->mouse[1];
@@ -926,12 +924,11 @@ static void ui_enum_post( ui_context *ctx )
    drawer[3] *= ctx->_enum.option_count;
 
    int close = 0;
-   int clickany= ui_click_up(ctx, UI_MOUSE_LEFT|UI_MOUSE_RIGHT|UI_MOUSE_MIDDLE),
+   int clickany= ui_click_up( ctx, UI_MOUSE_ANY ),
        hover   = ui_inside_rect( drawer, ctx->mouse );
 
-   if( clickany && !hover ){
+   if( clickany && !hover )
       return;
-   }
 
    /* HACK */
    ctx->focused_control_type = k_ui_control_none;
index 32e636a89621377b15f543e71940fc83e639e409..8672cf4369d2640fc55e23c25e51c2d220dca720 100644 (file)
@@ -42,6 +42,7 @@ enum ui_shader
    k_ui_shader_colour,
    k_ui_shader_image,
    k_ui_shader_hsv,
+   k_ui_shader_grad
 };
 
 typedef u32 ui_scheme[8*4];
@@ -76,15 +77,10 @@ enum ui_scheme_colour
 #define UI_MODAL_WARN      0x3
 #define UI_MODAL_TYPE_BITS 0x3
 
-#if 0
-#define UI_MOUSE_LEFT   (SDL_BUTTON(SDL_BUTTON_LEFT))
-#define UI_MOUSE_RIGHT  (SDL_BUTTON(SDL_BUTTON_RIGHT))
-#define UI_MOUSE_MIDDLE (SDL_BUTTON(SDL_BUTTON_MIDDLE))
-#else
 #define UI_MOUSE_LEFT 1
-#define UI_MOUSE_RIGHT 2
-#define UI_MOUSE_MIDDLE 4
-#endif
+#define UI_MOUSE_MIDDLE 2
+#define UI_MOUSE_RIGHT 4
+#define UI_MOUSE_ANY (UI_MOUSE_LEFT|UI_MOUSE_RIGHT|UI_MOUSE_MIDDLE)
 
 #define UI_TOP 0x1
 #define UI_LEFT 0x2
index 9c4dc32d14cfa429c64ceb99c9d9e68b9c984d42..18edb3e6f74b1b5ff875ae76c755495ee824477a 100644 (file)
@@ -53,48 +53,6 @@ struct vg_ui vg_ui =
    .bg_inverse_ratio = {1,1},
 };
 
-#if 0
-static vg_shader _shader_ui =
-{
-   .vs.static_src = 
-       "layout (location=0) in vec2 a_co;"
-       "layout (location=1) in vec2 a_uv;"
-       "layout (location=2) in vec4 a_colour;"
-       "uniform mat3 uPv;"
-   "uniform vec2 uInverseFontSheet;"
-       ""
-       "out vec2 aTexCoords;"
-       "out vec4 aColour;"
-       ""
-       "void main(){"
-               "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
-               "aTexCoords = a_uv * uInverseFontSheet;"
-               "aColour = a_colour;"
-       "}",
-   .fs.static_src =
-   "uniform sampler2D uTexGlyphs;"
-   "uniform lowp vec4 uColour;"
-       "out lowp vec4 FragColor;"
-       ""
-       "in highp vec2 aTexCoords;"
-       "in lowp vec4 aColour;"
-       ""
-       "void main(){"
-      "lowp vec4 avg = vec4(0.0);"
-
-               "if( aColour.a == 0.0 ){"
-         "avg = aColour;"
-                       "avg.a = texture( uTexGlyphs, aTexCoords ).r;"
-               "}"
-      "else{"
-         "avg = aColour;"
-      "}"
-
-               "FragColor = avg * uColour;"
-       "}"
-};
-#else
-
 static struct vg_shader _shader_ui ={
    .name = "[vg] ui - transparent",
    .vs = {
@@ -209,6 +167,50 @@ static struct vg_shader _shader_ui_image = {
    }
 };
 
+static struct vg_shader _shader_ui_image_grad = {
+   .name = "[vg] ui_image (gradient)",
+   .vs = 
+   {
+      .orig_file = NULL,
+      .static_src = 
+       "layout (location=0) in vec2 a_co;"
+       "layout (location=1) in vec2 a_uv;"
+       "layout (location=2) in vec4 a_colour;"
+       "uniform mat3 uPv;"
+
+       "out vec2 aTexCoords;"
+       "out vec4 aColour;"
+       "out vec2 aWsp;"
+
+       "void main()"
+       "{"
+               "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
+               "aTexCoords = a_uv * 0.00390625;"
+               "aColour = a_colour;"
+               
+               "aWsp = a_co;"
+       "}",
+   },
+   .fs = 
+   {
+      .orig_file = NULL,
+      .static_src = 
+       "uniform sampler2D uTexImage;"
+   "uniform vec4 uColour;"
+       "out vec4 FragColor;"
+
+       "in vec2 aTexCoords;"
+       "in vec4 aColour;"
+       "in vec2 aWsp;"
+
+       "void main()"
+       "{"
+               "vec4 colour = texture( uTexImage, aTexCoords );"
+               "FragColor = vec4(vec3(colour.r)*uColour.rgb,1.0);"
+       "}"
+   }
+};
+
 static struct vg_shader _shader_ui_hsv = {
    .name = "[vg] ui_hsv",
    .vs = {
@@ -253,7 +255,6 @@ static struct vg_shader _shader_ui_hsv = {
        "}"
    }
 };
-#endif
 
 void vg_ui_set_screen( i32 width, i32 height )
 {
@@ -322,6 +323,23 @@ void ui_impl_render_batch( ui_context *ctx, ui_batch *batch,
       glActiveTexture( GL_TEXTURE0 );
       glBindTexture( GL_TEXTURE_2D, *image );
    }
+   else if( shader == k_ui_shader_grad )
+   {
+      glUseProgram( _shader_ui_image_grad.id );
+      glUniformMatrix3fv( 
+            glGetUniformLocation( _shader_ui_image_grad.id, "uPv" ), 1, 
+                                  GL_FALSE, (float *)vg_ui.pv );
+      glUniform1i( 
+            glGetUniformLocation(_shader_ui_image_grad.id,"uTexImage"), 0 );
+      glUniform4fv( glGetUniformLocation( _shader_ui_image.id, "uColour" ), 1,
+                    vg_ui.colour );
+
+      struct ui_batch_shader_data_image *inf = shader_data;
+      GLuint *image = inf->resource;
+
+      glActiveTexture( GL_TEXTURE0 );
+      glBindTexture( GL_TEXTURE_2D, *image );
+   }
    else if( shader == k_ui_shader_hsv )
    {
       struct ui_batch_shader_data_hsv *inf = shader_data;
@@ -448,6 +466,7 @@ void vg_ui_init(void)
    vg_compile_shader( &_shader_ui );
    vg_compile_shader( &_shader_ui_hsv );
    vg_compile_shader( &_shader_ui_image );
+   vg_compile_shader( &_shader_ui_image_grad );
 
    u32 verts = 30000, indices = 20000;
    ui_init( &vg_ui.ctx, 
@@ -550,6 +569,7 @@ void ui_free(void)
    vg_free_shader( &_shader_ui );
    vg_free_shader( &_shader_ui_hsv );
    vg_free_shader( &_shader_ui_image );
+   vg_free_shader( &_shader_ui_image_grad );
    free( vg_ui.ctx.indice_buffer );
    free( vg_ui.ctx.vertex_buffer );
 }