small refactor ui api
authorhgn <hgodden00@gmail.com>
Thu, 14 Oct 2021 14:33:52 +0000 (15:33 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 14 Oct 2021 14:33:52 +0000 (15:33 +0100)
fishladder.c
vg/vg_ui.h

index 3bcd9af194be3d324c2dfa10b6c3af01ce5e1162..7c026532f66178d5496bc86ddf5830e14e110909 100644 (file)
@@ -415,8 +415,6 @@ void vg_start(void)
        }
        
        map_load( level_pack[ 0 ] );
-       
-       ui_test_init();
 }
 
 void vg_free(void)
@@ -427,7 +425,6 @@ void vg_free(void)
        free_mesh( &world.splitter_r );
 
        map_free();
-       ui_test_free();
 }
 
 static int cell_interactive( v2i co )
@@ -939,5 +936,5 @@ void vg_render(void)
 
 void vg_ui(void)
 {
-       ui_test();
+       //ui_test();
 }
index 4d54a6d7ccae0db31af5e8261553a0ac62897d9b..45120fd8b03b0740d234459f876e043da28e345a 100644 (file)
@@ -1,16 +1,4 @@
 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
-/*
-
-       Concurrent UI buffer system
-       Coordinate space:
-
-   0,0 --- +(res:x)
-        |
-        |
-        |
-+(res:y)
-       
-*/
 
 SHADER_DEFINE( shader_ui,
 
@@ -47,23 +35,16 @@ SHADER_DEFINE( shader_ui,
 )
 
 #define UI_AUTO_FILL 0
+#define UI_DEBUG
 
 // Types
-// ================================================================
+// ===========================================================================================================
+
 typedef i16                            ui_px;
 typedef u32                            ui_colour;
 typedef ui_px                          ui_rect[4];
 typedef struct ui_ctx  ui_ctx;
 
-#pragma pack(push,1)
-struct ui_vert
-{
-       ui_px co[2];
-       u8 uv[2];
-       u32 colour;
-};
-#pragma pack(pop)
-
 struct ui_ctx
 {
        ui_px padding;
@@ -77,7 +58,16 @@ struct ui_ctx
        }
        stack[ 32 ];
        
-       struct ui_vert *verts;
+       #pragma pack(push,1)
+       struct ui_vert
+       {
+               ui_px co[2];
+               u8 uv[2];
+               u32 colour;
+       }
+       *verts;
+       #pragma pack(pop)
+       
        u32 num_verts;
        u16 *indices;
        u32 num_indices;
@@ -93,88 +83,99 @@ struct ui_ctx
        int click_state;        // 0: released, 1: on down, 2: pressed, 3: on release
 };
 
+// Globals
+// ===========================================================================================================
+
 // Opengl
 GLuint ui_glyph_texture;
 GLuint ui_vao;
 GLuint ui_vbo;
 GLuint ui_ebo;
 
-
-
 #define UI_BUFFER_SIZE 30000
 #define UI_INDEX_SIZE 20000
 
-static void ui_glyphs_load( u32 *compressed )
+ui_ctx ui_global_ctx = { .padding = 8 };
+
+
+// Initialization
+// ===========================================================================================================
+
+static void ui_default_init(void)
 {
-       u32 pixels = 0, total = 72*72, data = 0;
-       u8 *image = malloc( total );
-       
-       while( pixels < total )
+       // Load font
        {
-               for( int b = 31; b >= 0; b-- )
+               u32 compressed[] = {
+                       #include "fonts/weiholmir.h"
+               };
+       
+               u32 pixels = 0, total = 72*72, data = 0;
+               u8 *image = malloc( total );
+               
+               while( pixels < total )
                {
-                       image[ pixels ++ ] = (compressed[data] & (0x1 << b))? 0xff: 0x00;
-                       
-                       if( pixels >= total )
+                       for( int b = 31; b >= 0; b-- )
                        {
-                               total = 0;
-                               break;
+                               image[ pixels ++ ] = (compressed[data] & (0x1 << b))? 0xff: 0x00;
+                               
+                               if( pixels >= total )
+                               {
+                                       total = 0;
+                                       break;
+                               }
                        }
+                       data++;
                }
-               data++;
+               
+               glGenTextures( 1, &ui_glyph_texture );
+               glBindTexture( GL_TEXTURE_2D, ui_glyph_texture );
+               
+               glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 72, 72, 0, GL_RED, GL_UNSIGNED_BYTE, image );
+               
+               vg_tex2d_clamp();
+               vg_tex2d_nearest();
+               
+               free( image );
        }
        
-       for( int j = 0; j < 70; j ++ )
+       // Setup OpenGL memory
        {
-               for( int i = 0; i < 70; i ++ )
-                       printf( "%s",image[j*72+i]?"#":" " );
-               printf( "\n" );
+               SHADER_INIT( shader_ui );
+               
+               // Generate the buffer we are gonna be drawing to
+               glGenVertexArrays(1, &ui_vao);
+               glGenBuffers( 1, &ui_vbo );
+               glGenBuffers( 1, &ui_ebo );
+               glBindVertexArray( ui_vao );
+               
+               glBindBuffer( GL_ARRAY_BUFFER, ui_vbo );
+               
+               glBufferData( GL_ARRAY_BUFFER, UI_BUFFER_SIZE * sizeof( struct ui_vert ), NULL, GL_DYNAMIC_DRAW );
+               glBindVertexArray( ui_vao );
+               
+               glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ui_ebo );
+               glBufferData( GL_ELEMENT_ARRAY_BUFFER, UI_INDEX_SIZE * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW );
+               
+               u32 const stride = sizeof( struct ui_vert );
+               
+               // XY
+               glVertexAttribPointer( 0, 2, GL_UNSIGNED_SHORT, GL_FALSE, stride, (void *)offsetof( struct ui_vert, co ) );
+               glEnableVertexAttribArray( 0 );
+               
+               // UV
+               glVertexAttribPointer( 1, 2, GL_UNSIGNED_BYTE, GL_FALSE, stride, (void *)offsetof( struct ui_vert, uv ) );
+               glEnableVertexAttribArray( 1 );
+               
+               // COLOUR
+               glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_TRUE, stride, (void *)offsetof( struct ui_vert, colour ) );
+               glEnableVertexAttribArray( 2 );
        }
        
-       glGenTextures( 1, &ui_glyph_texture );
-       glBindTexture( GL_TEXTURE_2D, ui_glyph_texture );
-       
-       glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 72, 72, 0, GL_RED, GL_UNSIGNED_BYTE, image );
-       
-       vg_tex2d_clamp();
-       vg_tex2d_nearest();
-       
-       free( image );
-}
-
-static void ui_default_init(void)
-{
-       ui_glyphs_load( (u32[]){
-               #include "fonts/weiholmir.h"
-       });
-       
-       SHADER_INIT( shader_ui );
-       
-       // Generate the buffer we are gonna be drawing to
-       glGenVertexArrays(1, &ui_vao);
-       glGenBuffers( 1, &ui_vbo );
-       glGenBuffers( 1, &ui_ebo );
-       glBindVertexArray( ui_vao );
-       
-       glBindBuffer( GL_ARRAY_BUFFER, ui_vbo );
-       
-       glBufferData( GL_ARRAY_BUFFER, UI_BUFFER_SIZE * sizeof( struct ui_vert ), NULL, GL_DYNAMIC_DRAW );
-       glBindVertexArray( ui_vao );
-       
-       glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ui_ebo );
-       glBufferData( GL_ELEMENT_ARRAY_BUFFER, UI_INDEX_SIZE * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW );
-       
-       // XY
-       glVertexAttribPointer( 0, 2, GL_UNSIGNED_SHORT, GL_FALSE, sizeof( struct ui_vert ), (void *)offsetof( struct ui_vert, co ) );
-       glEnableVertexAttribArray( 0 );
-       
-       // UV
-       glVertexAttribPointer( 1, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof( struct ui_vert ), (void *)offsetof( struct ui_vert, uv ) );
-       glEnableVertexAttribArray( 1 );
-       
-       // COLOUR
-       glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof( struct ui_vert ), (void *)offsetof( struct ui_vert, colour ) );
-       glEnableVertexAttribArray( 2 );
+       // Initialize default context
+       {
+               ui_global_ctx.verts = (struct ui_vert *)malloc( UI_BUFFER_SIZE * sizeof(struct ui_vert) );
+               ui_global_ctx.indices = (u16*)malloc( UI_INDEX_SIZE * sizeof(u16) );
+       }
 }
 
 static void ui_default_free(void)
@@ -184,6 +185,9 @@ static void ui_default_free(void)
        glDeleteVertexArrays( 1, &ui_vao );
        glDeleteBuffers( 1, &ui_vbo );
        glDeleteBuffers( 1, &ui_ebo );
+       
+       free( ui_global_ctx.verts );
+       free( ui_global_ctx.indices );
 }
 
 static void ui_draw( ui_ctx *ctx )
@@ -219,7 +223,7 @@ static void ui_draw( ui_ctx *ctx )
 }
 
 // Rect controls
-// ==========================================================
+// ===========================================================================================================
 
 static void ui_rect_copy( ui_rect src, ui_rect dst )
 {
@@ -239,6 +243,7 @@ static void ui_rect_pad( ui_rect rect, ui_px pad )
 
 static void ui_vis_rect( ui_rect rect, u32 colour )
 {
+       #ifdef UI_DEBUG
        v2f p0;
        v2f p1;
        
@@ -251,6 +256,15 @@ static void ui_vis_rect( ui_rect rect, u32 colour )
        vg_line( (v2f){p1[0],p0[1]}, p1, colour );
        vg_line( p1, (v2f){p0[0],p1[1]}, colour );
        vg_line( (v2f){p0[0],p1[1]}, p0, colour );
+       #endif
+}
+
+// Stack control
+// ===========================================================================================================
+
+static struct ui_qnode *ui_current( ui_ctx *ctx )
+{
+       return &ctx->stack[ ctx->stack_count-1 ];
 }
 
 static void ui_new_node( ui_ctx *ctx )
@@ -278,7 +292,7 @@ static void ui_new_node( ui_ctx *ctx )
 
 static int ui_hasmouse( ui_ctx *ctx )
 {
-       struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];
+       struct ui_qnode *node = ui_current( ctx );
        return (node->mouse_over && (node->capture_id == ctx->capture_mouse_id));
 }
 
@@ -287,39 +301,57 @@ static void ui_end( ui_ctx *ctx )
        struct ui_qnode *node = &ctx->stack[ --ctx->stack_count ];
 
        ui_rect_copy( node->rect, ctx->cursor );
-       ui_vis_rect( ctx->cursor, (node->mouse_over && (node->capture_id == ctx->capture_mouse_id))? 0xffff0000: 0xff0000ff );
+       ui_vis_rect( ctx->cursor, 
+               (node->mouse_over && (node->capture_id == ctx->capture_mouse_id))? 0xffff0000: 0xff0000ff );
 }
 
 static void ui_end_down( ui_ctx *ctx )
 {
-       ui_px height = ctx->stack[ ctx->stack_count-1 ].rect[3];
+       ui_px height = ui_current( ctx )->rect[3];
        ui_end( ctx );
        ctx->cursor[1] += height;
 }
 
 static void ui_end_right( ui_ctx *ctx )
 {
-       ui_px width = ctx->stack[ ctx->stack_count-1 ].rect[2];
+       ui_px width = ui_current( ctx )->rect[2];
        ui_end( ctx );
        ctx->cursor[0] += width;
 }
 
 static void ui_fill_y( ui_ctx *ctx )
 {
-       struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];      
+       struct ui_qnode *node = ui_current( ctx );
        ctx->cursor[3] = node->rect[3] - (ctx->cursor[1]-node->rect[1]);
 }
 
+static void ui_fill_x( ui_ctx *ctx )
+{
+       struct ui_qnode *node = ui_current( ctx );
+       ctx->cursor[2] = node->rect[2] - (ctx->cursor[0]-node->rect[0]);
+}
+
+// Alignment: | []   | -> |    []|
+static void ui_align_bottom( ui_ctx *ctx )
+{
+       struct ui_qnode *node = ui_current( ctx );
+       ctx->cursor[1] = node->rect[1] + node->rect[3] - ctx->cursor[3];
+}
+
 static void ui_align_right( ui_ctx *ctx )
 {
-       struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];
+       struct ui_qnode *node = ui_current( ctx );
        ctx->cursor[0] = node->rect[0] + node->rect[2] - ctx->cursor[2];
 }
 
 static void ui_align_top( ui_ctx *ctx )
 {
-       struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ];
-       ctx->cursor[1] = node->rect[1] + node->rect[3] - ctx->cursor[3];
+       ctx->cursor[1] = ui_current( ctx )->rect[1];
+}
+
+static void ui_align_left( ui_ctx *ctx )
+{
+       ctx->cursor[0] = ui_current( ctx )->rect[0];
 }
 
 static void ui_clamp_rect( ui_rect parent, ui_rect dest )
@@ -348,6 +380,9 @@ static void ui_capture_mouse( ui_ctx *ctx, u32 id )
        }
 }
 
+// Drawing
+// ===========================================================================================================
+
 static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, u32 colour, ui_px uv[4] )
 {
        struct ui_vert *vertices = &ctx->verts[ ctx->num_verts ];
@@ -581,20 +616,6 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group )
        return 1;
 }
 
-ui_ctx test_ctx = { .padding = 8 };
-
-static void ui_test_init(void)
-{
-       test_ctx.verts = (struct ui_vert *)malloc( UI_BUFFER_SIZE * sizeof(struct ui_vert) );
-       test_ctx.indices = (u16*)malloc( UI_INDEX_SIZE * sizeof(u16) );
-}
-
-static void ui_test_free(void)
-{
-       free( test_ctx.verts );
-       free( test_ctx.indices );
-}
-
 static void ui_test(void)
 {
        /*
@@ -615,7 +636,7 @@ static void ui_test(void)
                +------+--------------+-+----------------------------+-+
        */
 
-       ui_begin( &test_ctx, vg_window_x, vg_window_y );
+       ui_begin( &ui_global_ctx, vg_window_x, vg_window_y );
        
        // TODO: Find a more elegent form for this
        int mouse_state = 0;
@@ -623,7 +644,7 @@ static void ui_test(void)
        if( vg_get_button_down( "primary" ) ) mouse_state = 1;
        if( vg_get_button_up( "primary" ) ) mouse_state = 3;
                
-       ui_set_mouse( &test_ctx, vg_mouse[0], vg_mouse[1], mouse_state );
+       ui_set_mouse( &ui_global_ctx, vg_mouse[0], vg_mouse[1], mouse_state );
        
        static struct ui_window window =
        {
@@ -631,50 +652,50 @@ static void ui_test(void)
                .title = "Central Market"
        };
        
-       if( ui_window( &test_ctx, &window, __COUNTER__ ) )
+       if( ui_window( &ui_global_ctx, &window, __COUNTER__ ) )
        {
                // Contents
-               //ui_text( &test_ctx, "A slice of heaven. O for awesome, this chocka \nfull cuzzie is as rip-off as a cracker.\nMeanwhile, in behind the bicycle shed, Hercules Morse,\nas big as a horse and Mrs Falani were up to no \ngood with a bunch of crook pikelets. Meanwhile, \nat the black singlet woolshed party, not even au,\nsort your drinking out.", 1, 0 );
-               test_ctx.cursor[2] = 75;
-               ui_fill_y( &test_ctx );
+               //ui_text( &ui_global_ctx, "A slice of heaven. O for awesome, this chocka \nfull cuzzie is as rip-off as a cracker.\nMeanwhile, in behind the bicycle shed, Hercules Morse,\nas big as a horse and Mrs Falani were up to no \ngood with a bunch of crook pikelets. Meanwhile, \nat the black singlet woolshed party, not even au,\nsort your drinking out.", 1, 0 );
+               ui_global_ctx.cursor[2] = 75;
+               ui_fill_y( &ui_global_ctx );
                
-               ui_new_node( &test_ctx );
+               ui_new_node( &ui_global_ctx );
                {
-                       test_ctx.cursor[3] = 75;
+                       ui_global_ctx.cursor[3] = 75;
                        
-                       if( ui_button( &test_ctx, __COUNTER__ ) )
+                       if( ui_button( &ui_global_ctx, __COUNTER__ ) )
                                vg_info( "Buy\n" );
                        {
-                               ui_rect_pad( test_ctx.cursor, 4 );
-                               ui_text( &test_ctx, "Buy", 2, 0 );
+                               ui_rect_pad( ui_global_ctx.cursor, 4 );
+                               ui_text( &ui_global_ctx, "Buy", 2, 0 );
                        }
-                       ui_end_down( &test_ctx );
+                       ui_end_down( &ui_global_ctx );
                        
-                       if( ui_button( &test_ctx, __COUNTER__ ) )
+                       if( ui_button( &ui_global_ctx, __COUNTER__ ) )
                                vg_info( "Sell\n" );
                        {
-                               ui_rect_pad( test_ctx.cursor, 4 );
-                               ui_text( &test_ctx, "Sell", 2, 0 );
+                               ui_rect_pad( ui_global_ctx.cursor, 4 );
+                               ui_text( &ui_global_ctx, "Sell", 2, 0 );
                        }
-                       ui_end_down( &test_ctx );
+                       ui_end_down( &ui_global_ctx );
                }
-               ui_end_right( &test_ctx );
+               ui_end_right( &ui_global_ctx );
                
-               test_ctx.cursor[2] = 200;
-               ui_new_node( &test_ctx );
+               ui_global_ctx.cursor[2] = 200;
+               ui_new_node( &ui_global_ctx );
                {
                
                }
-               ui_end_right( &test_ctx );
+               ui_end_right( &ui_global_ctx );
        }
-       ui_end( &test_ctx );
+       ui_end( &ui_global_ctx );
 
-       ui_resolve( &test_ctx );
+       ui_resolve( &ui_global_ctx );
        
        m3x3f view = M3X3_IDENTITY;
        m3x3_translate( view, (v3f){ -1.0f, 1.0f, 0.0f } );
        m3x3_scale( view, (v3f){ 1.0f/((float)vg_window_x*0.5f), -1.0f/((float)vg_window_y*0.5f), 1.0f } );
        vg_lines_drawall( (float*)view );
        
-       ui_draw( &test_ctx );
+       ui_draw( &ui_global_ctx );
 }