X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=src%2Fvg%2Fvg_ui.h;h=4e09338dc2985149ea84f711e596433754ba37f4;hb=367883958336d1c04c8a304af6119b21f0f2f15a;hp=5b97133b3b1ceebe096300d0de8a9bdc0563a83d;hpb=deb49cc59884e298467c497d46518243ddb5a209;p=vg.git diff --git a/src/vg/vg_ui.h b/src/vg/vg_ui.h index 5b97133..4e09338 100644 --- a/src/vg/vg_ui.h +++ b/src/vg/vg_ui.h @@ -1,8 +1,16 @@ /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */ +/* + * TODO: Get rid of many context design + */ + #ifndef VG_UI_H #define VG_UI_H +#include "vg/vg.h" +#include "vg/vg_tex.h" +#include "vg/vg_shader.h" + static struct vg_shader _shader_ui = { .name = "[vg] ui", @@ -123,6 +131,8 @@ struct ui_ctx } *verts; #pragma pack(pop) + + u32 control_id; u32 num_verts; u16 *indices; @@ -133,8 +143,7 @@ struct ui_ctx u32 stack_count; u32 capture_mouse_id; int capture_lock; - u32 id_base; - int glyph_base; + /* User input */ ui_px mouse[2]; @@ -166,73 +175,93 @@ static ui_colourset ui_default_colours = { static ui_ctx ui_global_ctx; -static void ui_init_context( ui_ctx *ctx, int index_buffer_size ) +static void ui_context_vg_free( ui_ctx *ctx ) { - u32 vertex_buffer_size = (index_buffer_size+(index_buffer_size/2)); - - /* Generate the buffer we are gonna be drawing to */ - { - glGenVertexArrays(1, &ctx->vao); - glGenBuffers( 1, &ctx->vbo ); - glGenBuffers( 1, &ctx->ebo ); - glBindVertexArray( ctx->vao ); - - glBindBuffer( GL_ARRAY_BUFFER, ctx->vbo ); - - glBufferData( GL_ARRAY_BUFFER, - vertex_buffer_size * sizeof( struct ui_vert ), - NULL, GL_DYNAMIC_DRAW ); - glBindVertexArray( ctx->vao ); - - glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ctx->ebo ); - glBufferData( GL_ELEMENT_ARRAY_BUFFER, - index_buffer_size * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW ); - - u32 const stride = sizeof( struct ui_vert ); - - /* XY */ - glVertexAttribPointer( 0, 2, GL_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 ); - - /* CLIPPING */ - glVertexAttribPointer( 3, 4, GL_SHORT, GL_FALSE, stride, - (void *)offsetof( struct ui_vert, clip ) ); - glEnableVertexAttribArray( 3 ); - } + glDeleteVertexArrays( 1, &ctx->vao ); + glDeleteBuffers( 1, &ctx->vbo ); + glDeleteBuffers( 1, &ctx->ebo ); - /* Initialize default context */ - { - ctx->verts = (struct ui_vert *)malloc( - vertex_buffer_size * sizeof(struct ui_vert) ); - ctx->indices = (u16*)malloc( index_buffer_size * sizeof(u16) ); - - if( !ctx->colours ) - ctx->colours = &ui_default_colours; - } + vg_free( ctx->verts ); + vg_free( ctx->indices ); } -static void ui_context_free( ui_ctx *ctx ) +static int ui_init_context( ui_ctx *ctx, int index_buffer_size ) { - glDeleteVertexArrays( 1, &ctx->vao ); - glDeleteBuffers( 1, &ctx->vbo ); - glDeleteBuffers( 1, &ctx->ebo ); + u32 vertex_buffer_size = (index_buffer_size+(index_buffer_size/2)); - free( ctx->verts ); - free( ctx->indices ); + /* Generate the buffer we are gonna be drawing to */ + glGenVertexArrays( 1, &ctx->vao ); + glGenBuffers( 1, &ctx->vbo ); + glGenBuffers( 1, &ctx->ebo ); + + glBindVertexArray( ctx->vao ); + glBindBuffer( GL_ARRAY_BUFFER, ctx->vbo ); + + glBufferData( GL_ARRAY_BUFFER, + vertex_buffer_size * sizeof( struct ui_vert ), + NULL, GL_DYNAMIC_DRAW ); + glBindVertexArray( ctx->vao ); + + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ctx->ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, + index_buffer_size * sizeof( u16 ), NULL, GL_DYNAMIC_DRAW ); + + VG_CHECK_GL_ERR(); + + /* Set pointers */ + u32 const stride = sizeof( struct ui_vert ); + + /* XY */ + glVertexAttribPointer( 0, 2, GL_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 ); + + /* CLIPPING */ + glVertexAttribPointer( 3, 4, GL_SHORT, GL_FALSE, stride, + (void *)offsetof( struct ui_vert, clip ) ); + glEnableVertexAttribArray( 3 ); + + VG_CHECK_GL_ERR(); + + /* Alloc RAM default context */ + ctx->verts = (struct ui_vert *)vg_alloc( + vertex_buffer_size * sizeof(struct ui_vert) ); + if( !ctx->verts ) + goto il_fail_alloc_verts; + + ctx->indices = (u16*)vg_alloc( index_buffer_size * sizeof(u16) ); + if( !ctx->indices ) + goto il_fail_alloc_indices; + + if( !ctx->colours ) + ctx->colours = &ui_default_colours; + + return 1; + + vg_free( ctx->indices ); + ctx->indices = NULL; +il_fail_alloc_indices: + vg_free( ctx->verts ); + ctx->verts = NULL; +il_fail_alloc_verts: + glDeleteBuffers( 1, &ctx->ebo ); + glDeleteBuffers( 1, &ctx->vbo ); + glDeleteVertexArrays( 1, &ctx->vao ); + VG_CHECK_GL_ERR(); + return 0; } -static void ui_default_init(void) +static int ui_default_init(void) { /* Load default font */ u32 compressed[] = { @@ -240,7 +269,7 @@ static void ui_default_init(void) }; u32 pixels = 0, total = 256*256, data = 0; - u8 *image = malloc( total ); + u8 *image = vg_alloc( total ); while( pixels < total ) { @@ -259,23 +288,33 @@ static void ui_default_init(void) glGenTextures( 1, &ui_glyph_texture ); glBindTexture( GL_TEXTURE_2D, ui_glyph_texture ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, GL_RED, GL_UNSIGNED_BYTE, image ); + vg_free( image ); + + VG_CHECK_GL_ERR(); + vg_tex2d_clamp(); vg_tex2d_nearest(); - - free( image ); - vg_shader_register( &_shader_ui ); - ui_init_context( &ui_global_ctx, 20000 ); + if( !ui_init_context( &ui_global_ctx, 20000 ) ) goto il_generic_fail; + if( !vg_shader_compile( &_shader_ui ) ) goto il_shader_fail; + + return 1; + +il_shader_fail: +il_generic_fail: + glDeleteTextures( 1, &ui_glyph_texture ); + vg_free( image ); + return 0; } static void ui_default_free(void) { + vg_free_shader( &_shader_ui ); glDeleteTextures( 1, &ui_glyph_texture ); - ui_context_free( &ui_global_ctx ); + ui_context_vg_free( &ui_global_ctx ); } static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, @@ -373,7 +412,10 @@ static struct ui_qnode *ui_current( ui_ctx *ctx ) static void ui_new_node( ui_ctx *ctx ) { if( ctx->stack_count == vg_list_size( ctx->stack ) ) - vg_exiterr( "[UI] Stack overflow while creating box!" ); + { + vg_error( "[UI] Stack overflow while creating box!" ); + return; + } struct ui_qnode *parent = &ctx->stack[ ctx->stack_count-1 ]; struct ui_qnode *node = &ctx->stack[ ctx->stack_count++ ]; @@ -463,21 +505,14 @@ static void ui_clamp_rect( ui_rect parent, ui_rect dest ) dest[1] = vg_max( parent[1], dest[1] ); } -static u32 ui_group_id( ui_ctx *ctx, u32 lesser_unique ) -{ - return ctx->id_base | lesser_unique; -} - static void ui_capture_mouse( ui_ctx *ctx, u32 id ) { - u32 group_uid = ui_group_id(ctx,id); - struct ui_qnode *node = &ctx->stack[ ctx->stack_count-1 ]; - node->capture_id = group_uid; + node->capture_id = id; if( !ctx->capture_lock && node->mouse_over ) { - ctx->capture_mouse_id = group_uid; + ctx->capture_mouse_id = id; } } @@ -692,7 +727,10 @@ static void ui_begin( ui_ctx *ctx, ui_px res_x, ui_px res_y ) static void ui_resolve( ui_ctx *ctx ) { if( ctx->stack_count-1 ) - vg_exiterr( "[UI] Mismatched node create/drestroy!" ); + { + vg_error( "[UI] Mismatched node create/drestroy!" ); + return; + } if( ctx->click_state == 3 || ctx->click_state == 0 ) { @@ -728,11 +766,13 @@ enum button_state k_button_hold }; -static int ui_button( ui_ctx *ctx, u32 id ) +static int ui_button( ui_ctx *ctx ) { + u32 uid = ctx->control_id ++; + ui_new_node( ctx ); { - ui_capture_mouse( ctx, id ); + ui_capture_mouse( ctx, uid ); if( ui_hasmouse(ctx) ) { @@ -747,6 +787,8 @@ static int ui_button( ui_ctx *ctx, u32 id ) return k_button_click; else if( ctx->capture_lock && ctx->click_state == 2 ) return k_button_hold; + + return k_button_click; } else ui_fill_rect( ctx, ctx->cursor, ctx->colours->main ); @@ -757,8 +799,6 @@ static int ui_button( ui_ctx *ctx, u32 id ) static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) { - ctx->id_base = control_group << 16; - if( window->drag ) { window->transform[0] = ctx->mouse[0]+window->drag_offset[0]; @@ -776,13 +816,13 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) ui_new_node( ctx ); { - ui_capture_mouse( ctx, __COUNTER__ ); + ui_capture_mouse( ctx, ctx->control_id ++ ); /* Drag bar */ ctx->cursor[3] = 25; ui_new_node( ctx ); { - ui_capture_mouse( ctx, __COUNTER__ ); + ui_capture_mouse( ctx, ctx->control_id ++ ); struct ui_vert *drag_bar = ui_fill_rect( ctx, ctx->cursor, 0xff555555 ); @@ -798,7 +838,7 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) ui_align_top( ctx ); ui_rect_pad( ctx->cursor, 4 ); - if( ui_button( ctx, __COUNTER__ ) ) + if( ui_button( ctx ) ) { vg_info( "Click clacked\n" ); } @@ -870,12 +910,9 @@ static void ui_slider( ui_ctx *ctx, struct ui_slider *slider ) ctx->cursor[2] = fwidth; ctx->cursor[0] = slider_start + fpos * fmove; - /* TODO.. */ - u32 uid = (u32)(u64)slider->data; - int status = ui_button( ctx, uid ); - - if( ctx->capture_lock && - (ctx->capture_mouse_id == ui_group_id( ctx, uid ))) + u32 uid = ctx->control_id ++; + int status = ui_button( ctx ); + if( ctx->capture_lock && (ctx->capture_mouse_id == uid)) { float ui_new = ctx->mouse[0], local = ui_new - (slider_start + fstart), @@ -891,7 +928,6 @@ static void ui_slider( ui_ctx *ctx, struct ui_slider *slider ) snprintf( buf, 12, "%.2f", *slider->data ); ui_text( ctx, ctx->cursor, buf, 1, 0 ); ui_end_down( ctx ); - ui_end_down( ctx ); } @@ -908,8 +944,7 @@ static void ui_slider_vector( ui_ctx *ctx, struct ui_slider_vector *slider ) static void ui_checkbox( ui_ctx *ctx, struct ui_checkbox *cb ) { - u32 uid = (u32)(u64)cb->data; - if( ui_button(ctx,uid) == k_button_click ) + if( ui_button(ctx) == k_button_click ) *cb->data ^= 0x1; ui_new_node(ctx); @@ -938,7 +973,6 @@ static void ui_checkbox( ui_ctx *ctx, struct ui_checkbox *cb ) #define gui_align_top() ui_align_top( &ui_global_ctx ) #define gui_align_left() ui_align_left( &ui_global_ctx ) #define gui_clamp_rect(...) ui_clamp_rect( &ui_global_ctx, __VA_ARGS__) -#define gui_group_id(...) ui_group_id( &ui_global_ctx, __VA_ARGS__) #define gui_capture_mouse(...) ui_capture_mouse( &ui_global_ctx, __VA_ARGS__) #define gui_set_clip(...) ui_set_clip( &ui_global_ctx, __VA_ARGS__) #define gui_release_clip() ui_release_clip( &ui_global_ctx ) @@ -954,4 +988,4 @@ static void ui_checkbox( ui_ctx *ctx, struct ui_checkbox *cb ) #define gui_push_image(...) ui_push_image( &ui_global_ctx, __VA_ARGS__ ) #define gui_reset_colours(...) ui_reset_colours( &ui_global_ctx ) -#endif +#endif /* VG_UI_H */