vg_console.input[0] = '\0';
console_update_suggestions( ctx );
}
+
+ vg_console.auto_focus = 1;
}
int vg_console_exec( int argc, const char *argv[] )
if( line[0] != 0x00 )
{
+ strcpy( vg_console.input, line );
vg_execute_console_input( line, silent );
}
}
vg_error( "Could not open '%s'\n", path );
}
+ vg_console.input[0] = '\0';
return 0;
}
.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
int history_last, history_pos, history_count;
i32 enabled, cheats;
+ bool auto_focus;
}
extern vg_console;
#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"
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
{
if( event.key.keysym.scancode == SDL_SCANCODE_GRAVE )
{
+ vg_console.auto_focus = 1;
vg_console.enabled = 1;
}
else
(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();
static void _vg_terminate(void)
{
/* Shutdown */
+ vg_magi_save();
vg_console_write_persistent();
SDL_AtomicLock( &vg.sl_status );
/* 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 );
#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"
--- /dev/null
+#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 );
+}
--- /dev/null
+#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);
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 )
{
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;
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 ];
.ui_ctx = ctx,
.alloc = alloc,
.indices = indices,
+ .result = result,
+ .root_colour = root_colour
};
if( alloc->allocation_count )
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;
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
}
}
+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 );
}
#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 );
{
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 )
{
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];
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;
k_ui_shader_colour,
k_ui_shader_image,
k_ui_shader_hsv,
+ k_ui_shader_grad
};
typedef u32 ui_scheme[8*4];
#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
.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 = {
}
};
+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 = {
"}"
}
};
-#endif
void vg_ui_set_screen( i32 width, i32 height )
{
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;
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,
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 );
}