X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=src%2Fvg%2Fvg_ui.h;h=f7f8a1ca791b8253057714ef262ee789ad04ca1d;hb=95c9a820474d4974ee394f2fcfae82fbfa367dbd;hp=f6fa8955333ac76f19987b477038c3c2dac6d70b;hpb=3d16c8f7df7ea8650c1c18b5bffa1d9510acf310;p=vg.git diff --git a/src/vg/vg_ui.h b/src/vg/vg_ui.h index f6fa895..f7f8a1c 100644 --- a/src/vg/vg_ui.h +++ b/src/vg/vg_ui.h @@ -1,12 +1,11 @@ -// Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved +/* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */ SHADER_DEFINE( shader_ui, - // VERTEX - "layout (location=0) in vec2 a_co;" // i16, i16, .. ? - "layout (location=1) in vec2 a_uv;" // i16, i16 - "layout (location=2) in vec4 a_colour;" // u32 - "layout (location=3) in vec4 a_clip;" // i16, i16, i16, i16 + "layout (location=0) in vec2 a_co;" + "layout (location=1) in vec2 a_uv;" + "layout (location=2) in vec4 a_colour;" + "layout (location=3) in vec4 a_clip;" "uniform mat3 uPv;" "" "out vec2 aTexCoords;" @@ -24,7 +23,7 @@ SHADER_DEFINE( shader_ui, "aClip = a_clip;" "}", - // FRAGMENT + /* Fragment */ "uniform sampler2D uTexGlyphs;" "out vec4 FragColor;" "" @@ -36,7 +35,11 @@ SHADER_DEFINE( shader_ui, "" "void main()" "{" - "float clip_blend = step( aWsp.x, aClip.z ) * step( aWsp.y, aClip.w ) * step( aClip.x, aWsp.x ) * step( aClip.y, aWsp.y );" + "float clip_blend = step( aWsp.x, aClip.z ) *" + "step( aWsp.y, aClip.w ) *" + "step( aClip.x, aWsp.x ) *" + "step( aClip.y, aWsp.y ); " + "vec4 glyph = vec4(1.0,1.0,1.0,1.0);" "if( aColour.a == 0.0 )" @@ -55,16 +58,13 @@ SHADER_DEFINE( shader_ui, UNIFORMS({ "uPv", "uTexGlyphs" }) ) -// Types -// =========================================================================================================== - typedef i16 ui_px; typedef u32 ui_colour; typedef ui_px ui_rect[4]; typedef struct ui_ctx ui_ctx; typedef struct ui_colourset ui_colourset; -// Relative to cursor p0 +/* Relative to cursor p0 */ enum ui_text_align { k_text_align_left = 0, @@ -105,10 +105,10 @@ struct ui_ctx #pragma pack(push,1) struct ui_vert { - ui_px co[2]; //32 4 - u8 uv[2]; //16 2 - u32 colour; //32 4 - ui_rect clip; //64 8 + ui_px co[2]; + u8 uv[2]; + u32 colour; + ui_rect clip; } *verts; #pragma pack(pop) @@ -125,9 +125,9 @@ struct ui_ctx u32 id_base; int glyph_base; - // User input + /* User input */ ui_px mouse[2]; - int click_state; // 0: released, 1: on down, 2: pressed, 3: on release + int click_state; /* 0: released, 1: on down, 2: pressed, 3: on release */ ui_colourset *colours; @@ -144,9 +144,6 @@ struct ui_ctx int image_count; }; -// Globals -// =========================================================================================================== - #define UI_GLYPH_SPACING_X 9 static GLuint ui_glyph_texture = 0; @@ -158,14 +155,11 @@ static ui_colourset ui_default_colours = { static ui_ctx ui_global_ctx; -// Initialization -// =========================================================================================================== - static void ui_init_context( ui_ctx *ctx, int index_buffer_size ) { u32 vertex_buffer_size = (index_buffer_size+(index_buffer_size/2)); - // Generate the buffer we are gonna be drawing to + /* Generate the buffer we are gonna be drawing to */ { glGenVertexArrays(1, &ctx->vao); glGenBuffers( 1, &ctx->vbo ); @@ -174,34 +168,42 @@ static void ui_init_context( ui_ctx *ctx, int index_buffer_size ) glBindBuffer( GL_ARRAY_BUFFER, ctx->vbo ); - glBufferData( GL_ARRAY_BUFFER, vertex_buffer_size * sizeof( struct ui_vert ), NULL, GL_DYNAMIC_DRAW ); + 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 ); + 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 ) ); + /* 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 ) ); + /* 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 ) ); + /* 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 ) ); + /* CLIPPING */ + glVertexAttribPointer( 3, 4, GL_SHORT, GL_FALSE, stride, + (void *)offsetof( struct ui_vert, clip ) ); glEnableVertexAttribArray( 3 ); } - // Initialize default context + /* Initialize default context */ { - ctx->verts = (struct ui_vert *)malloc( vertex_buffer_size * sizeof(struct ui_vert) ); + 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 ) @@ -221,7 +223,7 @@ static void ui_context_free( ui_ctx *ctx ) static void ui_default_init(void) { - // Load default font + /* Load default font */ u32 compressed[] = { #include "vg/vg_pxfont.h" }; @@ -247,14 +249,14 @@ 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 ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_R8, 256, 256, 0, + GL_RED, GL_UNSIGNED_BYTE, image ); vg_tex2d_clamp(); vg_tex2d_nearest(); free( image ); - // Setup OpenGL memory SHADER_INIT( shader_ui ); ui_init_context( &ui_global_ctx, 20000 ); } @@ -265,22 +267,29 @@ static void ui_default_free(void) ui_context_free( &ui_global_ctx ); } -static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, u32 colour, ui_px uv[4] ); +static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, + u32 colour, ui_px uv[4] ); + static void ui_draw( ui_ctx *ctx, m3x3f view_override ) { u32 num_indices_normal = ctx->num_indices; - // Append images to back of buffer + /* Append images to back of buffer */ for( int i = 0; i < ctx->image_count; i ++ ) - ui_fill_rect_uv( ctx, ctx->images[i].rc, 0xffffffff, (ui_px[4]){0,0,128,128} ); + { + ui_fill_rect_uv( ctx, ctx->images[i].rc, + 0xffffffff, (ui_px[4]){0,0,128,128} ); + } glBindVertexArray( ctx->vao ); glBindBuffer( GL_ARRAY_BUFFER, ctx->vbo ); - glBufferSubData( GL_ARRAY_BUFFER, 0, ctx->num_verts * sizeof( struct ui_vert ), ctx->verts ); + glBufferSubData( GL_ARRAY_BUFFER, 0, + ctx->num_verts * sizeof( struct ui_vert ), ctx->verts ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ctx->ebo ); - glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, ctx->num_indices * sizeof( u16 ), ctx->indices ); + glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, + ctx->num_indices * sizeof( u16 ), ctx->indices ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -295,32 +304,36 @@ static void ui_draw( ui_ctx *ctx, m3x3f view_override ) view_override = view; 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 } ); + m3x3_scale( view, (v3f){ 1.0f/((float)vg_window_x*0.5f), + -1.0f/((float)vg_window_y*0.5f), 1.0f } ); } - glUniformMatrix3fv( SHADER_UNIFORM( shader_ui, "uPv" ), 1, GL_FALSE, (float *)view_override ); + glUniformMatrix3fv( SHADER_UNIFORM( shader_ui, "uPv" ), 1, + GL_FALSE, (float *)view_override ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, ui_glyph_texture ); glUniform1i( SHADER_UNIFORM( shader_ui, "uTexGlyphs" ), 0 ); - glDrawElements( GL_TRIANGLES, num_indices_normal, GL_UNSIGNED_SHORT, (void*)(0) ); + glDrawElements( GL_TRIANGLES, num_indices_normal, + GL_UNSIGNED_SHORT, (void*)(0) ); - // Draw image elements + /* Draw image elements */ for( int i = 0; i < ctx->image_count; i ++ ) { struct ui_image *img = &ctx->images[i]; glBindTexture( GL_TEXTURE_2D, img->image ); - glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)( (num_indices_normal + 6*i)*sizeof(u16) ) ); + glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, + (void*)( (num_indices_normal + 6*i)*sizeof(u16) ) ); } glDisable(GL_BLEND); } -// Rect controls -// =========================================================================================================== - +/* + * Rect controls + */ static void ui_rect_copy( ui_rect src, ui_rect dst ) { dst[0] = src[0]; @@ -337,9 +350,9 @@ static void ui_rect_pad( ui_rect rect, ui_px pad ) rect[3] -= pad*2; } -// Stack control -// =========================================================================================================== - +/* + * Stack control + */ static struct ui_qnode *ui_current( ui_ctx *ctx ) { return &ctx->stack[ ctx->stack_count-1 ]; @@ -356,8 +369,10 @@ static void ui_new_node( ui_ctx *ctx ) if( parent->mouse_over ) { - if( ctx->mouse[0] >= node->rect[0] && ctx->mouse[0] < node->rect[0]+node->rect[2] && - ctx->mouse[1] >= node->rect[1] && ctx->mouse[1] < node->rect[1]+node->rect[3] ) + if( ctx->mouse[0] >= node->rect[0] && + ctx->mouse[0] < node->rect[0]+node->rect[2] && + ctx->mouse[1] >= node->rect[1] && + ctx->mouse[1] < node->rect[1]+node->rect[3] ) node->mouse_over = 1; else node->mouse_over = 0; @@ -406,7 +421,6 @@ static void ui_fill_x( ui_ctx *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 ); @@ -476,10 +490,8 @@ static void ui_release_clip( ui_ctx *ctx ) ctx->clipping[3] = 32000; } -// Drawing -// =========================================================================================================== - -static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, u32 colour, ui_px uv[4] ) +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 ]; vertices[0].co[0] = rect[0]; @@ -529,7 +541,8 @@ static struct ui_vert *ui_fill_rect( ui_ctx *ctx, ui_rect rect, u32 colour ) return ui_fill_rect_uv( ctx, rect, colour, (ui_px[4]){ 4,4, 4,4 } ); } -static ui_px ui_text_line_offset( const char *str, ui_px scale, enum ui_text_align align ) +static ui_px ui_text_line_offset( const char *str, ui_px scale, + enum ui_text_align align ) { if( align == k_text_align_left ) return 0; @@ -550,7 +563,8 @@ static ui_px ui_text_line_offset( const char *str, ui_px scale, enum ui_text_ali return (-length * scale*8) / 2; } -static void ui_text( ui_ctx *ctx, ui_px pos[2], const char *str, ui_px scale, enum ui_text_align align ) +static void ui_text( ui_ctx *ctx, ui_px pos[2], + const char *str, ui_px scale, enum ui_text_align align ) { ui_rect text_cursor; u32 current_colour = 0x00ffffff; @@ -581,7 +595,13 @@ static void ui_text( ui_ctx *ctx, ui_px pos[2], const char *str, ui_px scale, en glyph_base[0] *= 8; glyph_base[1] *= 8; - ui_fill_rect_uv( ctx, text_cursor, current_colour, (ui_px[4]){glyph_base[0]+2,glyph_base[1]+1,glyph_base[0]+6,glyph_base[1]+8} ); + ui_fill_rect_uv( ctx, text_cursor, current_colour, (ui_px[4]) + { + glyph_base[0]+2, + glyph_base[1]+1, + glyph_base[0]+6, + glyph_base[1]+8 + }); } else if( c == '\x1B' ) { @@ -631,9 +651,9 @@ static void ui_text( ui_ctx *ctx, ui_px pos[2], const char *str, ui_px scale, en } } -// API control -// ==================================================================== - +/* + * API Control + */ static void ui_begin( ui_ctx *ctx, ui_px res_x, ui_px res_y ) { ctx->cursor[0] = 0; @@ -668,9 +688,6 @@ static void ui_resolve( ui_ctx *ctx ) } } -// User Input piping -// ==================================================================== - static void ui_set_mouse( ui_ctx *ctx, int x, int y, int click_state ) { ctx->mouse[0] = x; @@ -679,9 +696,9 @@ static void ui_set_mouse( ui_ctx *ctx, int x, int y, int click_state ) ctx->click_state = click_state; } -// High level controls -// ==================================================================== - +/* + * High level controls + */ struct ui_window { const char *title; @@ -749,7 +766,7 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) { ui_capture_mouse( ctx, __COUNTER__ ); - // Drag bar + /* Drag bar */ ctx->cursor[3] = 25; ui_new_node( ctx ); { @@ -757,12 +774,12 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) struct ui_vert *drag_bar = ui_fill_rect( ctx, ctx->cursor, 0xff555555 ); - // title.. + /* title.. */ ctx->cursor[0] += 2; ctx->cursor[1] += 2; ui_text( ctx, ctx->cursor, window->title, 2, 0 ); - // Close button + /* Close button */ ctx->cursor[3] = 25; ctx->cursor[2] = 25; ui_align_right( ctx ); @@ -784,7 +801,7 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) drag_bar[2].colour = 0xff777777; drag_bar[3].colour = 0xff777777; - // start drag + /* start drag */ if( ctx->click_state == 1 ) { window->drag = 1; @@ -799,71 +816,6 @@ static int ui_window( ui_ctx *ctx, struct ui_window *window, u32 control_group ) return 1; } -struct ui_scrollbar -{ - int drag; - ui_px drag_offset; - - ui_px py; - ui_px bar_height; - ui_px view_height; -}; - -static void ui_scrollbar( ui_ctx *ctx, struct ui_scrollbar *scrollbar, u32 id ) -{ - scrollbar->view_height = ctx->cursor[3]; - - if( scrollbar->drag ) - { - scrollbar->py = ctx->mouse[1]+scrollbar->drag_offset; - scrollbar->py = VG_MAX( scrollbar->py, 0 ); - scrollbar->py = VG_MIN( scrollbar->py, ctx->cursor[3] - scrollbar->bar_height ); - - if( ctx->click_state == 0 || ctx->click_state == 3 ) - scrollbar->drag = 0; - } - - ui_new_node( ctx ); - { - ui_fill_rect( ctx, ctx->cursor, ctx->colours->background ); - ui_capture_mouse( ctx, id ); - - ctx->cursor[1] += scrollbar->py; - ctx->cursor[3] = scrollbar->bar_height; - - ui_new_node( ctx ); - { - ui_capture_mouse( ctx, __COUNTER__ ); - struct ui_vert *drag_bar = ui_fill_rect( ctx, ctx->cursor, ctx->colours->bar ); - - if( ui_hasmouse( ctx ) || scrollbar->drag ) - { - drag_bar[0].colour = ctx->colours->bar_hover; - drag_bar[1].colour = ctx->colours->bar_hover; - drag_bar[2].colour = ctx->colours->bar_hover; - drag_bar[3].colour = ctx->colours->bar_hover; - - // start drag - if( ctx->click_state == 1 ) - { - scrollbar->drag = 1; - scrollbar->drag_offset = scrollbar->py - ctx->mouse[1]; - } - } - } - ui_end_down( ctx ); - } - ui_end( ctx ); -} - -static ui_px ui_calculate_content_scroll( struct ui_scrollbar *scrollbar, ui_px content ) -{ - float overlap = vg_maxf( 0.0f, (float)(content - scrollbar->view_height) ); - - float range = scrollbar->view_height - scrollbar->bar_height; - return ((float)scrollbar->py / range) * overlap; -} - static void ui_push_image( ui_ctx *ctx, ui_rect rc, GLuint image ) { struct ui_image *img = &ctx->images[ ctx->image_count ++ ]; @@ -871,7 +823,7 @@ static void ui_push_image( ui_ctx *ctx, ui_rect rc, GLuint image ) img->image = image; } -// Shortnames +/* Shortnames */ #define gui_draw(...) ui_draw( &ui_global_ctx, __VA_ARGS__) #define gui_current(...) ui_current( &ui_global_ctx, __VA_ARGS__) #define gui_new_node() ui_new_node( &ui_global_ctx ) @@ -900,5 +852,4 @@ static void ui_push_image( ui_ctx *ctx, ui_rect rc, GLuint image ) #define gui_window(...) ui_window( &ui_global_ctx, __VA_ARGS__) #define gui_want_mouse() ui_want_mouse( &ui_global_ctx ) #define gui_push_image(...) ui_push_image( &ui_global_ctx, __VA_ARGS__ ) -#define gui_scrollbar(...) ui_scrollbar( &ui_global_ctx, __VA_ARGS__) #define gui_reset_colours(...) ui_reset_colours( &ui_global_ctx )