ui gpu clipping
[fishladder.git] / vg / vg_ui.h
index 56ece6b85d75fb7897e7b8cfbf593ec54a62c28b..a2cc77057af0da407c4681fe83333acdbd3a5570 100644 (file)
@@ -6,16 +6,22 @@ SHADER_DEFINE( shader_ui,
        "layout (location=0) in vec2 a_co;"                     // i16, i16, .. ?
        "layout (location=1) in vec2 a_uv;"                     // i8, i8
        "layout (location=2) in vec4 a_colour;" // u32
+       "layout (location=3) in vec4 a_clip;"           // i16, i16, i16, i16
        "uniform mat3 uPv;"
        ""
        "out vec2 aTexCoords;"
        "out vec4 aColour;"
+       "out vec2 aWsp;"
+       "out vec4 aClip;"
        ""
        "void main()"
        "{"
                "gl_Position = vec4( uPv * vec3( a_co, 1.0 ), 1.0 );"
-               "aTexCoords = a_uv * 0.01388888888;"
+               "aTexCoords = a_uv * 0.0078125;"
                "aColour = a_colour;"
+               
+               "aWsp = a_co;"
+               "aClip = a_clip;"
        "}",
        
        // FRAGMENT
@@ -25,10 +31,15 @@ SHADER_DEFINE( shader_ui,
        "in vec2 aTexCoords;"
        "in vec4 aColour;"
        ""
+       "in vec2 aWsp;"
+       "in vec4 aClip;"
+       ""
        "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 );"
+       
                "vec4 glyph = texture( uTexGlyphs, aTexCoords );"
-               "FragColor = aColour * vec4( 1.0, 1.0, 1.0, glyph.r );"
+               "FragColor = aColour * vec4( 1.0, 1.0, 1.0, glyph.r * clip_blend );"
        "}"
        ,
        UNIFORMS({ "uPv", "uTexGlyphs" })
@@ -61,17 +72,21 @@ struct ui_ctx
        #pragma pack(push,1)
        struct ui_vert
        {
-               ui_px co[2];
-               u8 uv[2];
-               u32 colour;
+               ui_px co[2];    //32 4
+               u8 uv[2];               //16 2
+               u32 colour;             //32 4
+               ui_rect clip;   //64 8
        }
        *verts;
        #pragma pack(pop)
        
+       u32 override_colour;
+       
        u32 num_verts;
        u16 *indices;
        u32 num_indices;
        
+       ui_rect clipping;
        ui_rect cursor;
        u32 stack_count;
        u32 capture_mouse_id;
@@ -172,7 +187,7 @@ static void ui_default_init(void)
                u32 const stride = sizeof( struct ui_vert );
                
                // XY
-               glVertexAttribPointer( 0, 2, GL_UNSIGNED_SHORT, GL_FALSE, stride, (void *)offsetof( struct ui_vert, co ) );
+               glVertexAttribPointer( 0, 2, GL_SHORT, GL_FALSE, stride, (void *)offsetof( struct ui_vert, co ) );
                glEnableVertexAttribArray( 0 );
                
                // UV
@@ -182,6 +197,10 @@ static void ui_default_init(void)
                // 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 );
        }
        
        // Initialize default context
@@ -204,7 +223,7 @@ static void ui_default_free(void)
        free( ui_global_ctx.indices );
 }
 
-static void ui_draw( ui_ctx *ctx )
+static void ui_draw( ui_ctx *ctx, m3x3f view_override )
 {
        glBindVertexArray( ui_vao );
        
@@ -221,9 +240,16 @@ static void ui_draw( ui_ctx *ctx )
        SHADER_USE( shader_ui );
        
        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 } );
-       glUniformMatrix3fv( SHADER_UNIFORM( shader_ui, "uPv" ), 1, GL_FALSE, (float *)view );
+       
+       if( !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 } );
+       }
+       
+       glUniformMatrix3fv( SHADER_UNIFORM( shader_ui, "uPv" ), 1, GL_FALSE, (float *)view_override );
        
        glActiveTexture( GL_TEXTURE0 );
        glBindTexture( GL_TEXTURE_2D, ui_glyph_texture );
@@ -394,6 +420,22 @@ static void ui_capture_mouse( ui_ctx *ctx, u32 id )
        }
 }
 
+static void ui_set_clip( ui_ctx *ctx, ui_rect clip )
+{
+       ctx->clipping[0] = clip[0];
+       ctx->clipping[1] = clip[1];
+       ctx->clipping[2] = clip[0] + clip[2];
+       ctx->clipping[3] = clip[1] + clip[3];
+}
+
+static void ui_release_clip( ui_ctx *ctx )
+{
+       ctx->clipping[0] = -32000;
+       ctx->clipping[1] = -32000;
+       ctx->clipping[2] =  32000;
+       ctx->clipping[3] =  32000;
+}
+
 // Drawing
 // ===========================================================================================================
 
@@ -423,6 +465,11 @@ static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, u32 colour, u
        u16 ind_start = ctx->num_verts;
        u16 *indices = &ctx->indices[ ctx->num_indices ];
        
+       ui_rect_copy( ctx->clipping, vertices[0].clip );
+       ui_rect_copy( ctx->clipping, vertices[1].clip );
+       ui_rect_copy( ctx->clipping, vertices[2].clip );
+       ui_rect_copy( ctx->clipping, vertices[3].clip );
+       
        indices[0] = ind_start+0;
        indices[1] = ind_start+2;
        indices[2] = ind_start+1;
@@ -439,7 +486,7 @@ static struct ui_vert *ui_fill_rect_uv( ui_ctx *ctx, ui_rect rect, u32 colour, u
 
 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]){ 66, 72-66, 66, 72-66 } );
+       return ui_fill_rect_uv( ctx, rect, colour, (ui_px[4]){ 4,124,4,124 } );
 }
 
 static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment )
@@ -448,10 +495,10 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment )
 
        text_cursor[0] = ctx->cursor[0];
        text_cursor[1] = ctx->cursor[1];
-       text_cursor[2] = 7*scale;
-       text_cursor[3] = 7*scale;
+       text_cursor[2] = scale*8;
+       text_cursor[3] = scale*8;
 
-       u32 current_colour = 0xffffffff;
+       u32 current_colour = ctx->override_colour;
 
        const char *_c = str;
        char c;
@@ -467,13 +514,19 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment )
                {
                        u8 glyph_base[2];
                        u8 glyph_index = c - 32;
-                       glyph_base[0] = glyph_index%10;
-                       glyph_base[1] = (glyph_index-glyph_base[0])/10;
+                       glyph_base[0] = glyph_index&0xf;
+                       glyph_base[1] = (glyph_index-glyph_base[0])>>4;
                        
-                       glyph_base[0] *= 7;
-                       glyph_base[1] *= 7;
+                       glyph_base[0] *= 8;
+                       glyph_base[1] *= 8;
                        
-                       ui_fill_rect_uv( ctx, text_cursor, current_colour, (ui_px[4]){glyph_base[0],72-glyph_base[1],glyph_base[0]+7,72-(glyph_base[1]+7)} );
+                       ui_fill_rect_uv( ctx, text_cursor, current_colour, 
+                               (ui_px[4]){
+                                       glyph_base[0],
+                                       128-glyph_base[1],
+                                       glyph_base[0]+8,
+                                       128-(glyph_base[1]+8)
+                               });
                }
                else if( c == '\x1B' )
                {
@@ -510,9 +563,10 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment )
                                        break;
                                }
                        }
+                       continue;
                }
                
-               text_cursor[0] += ui_glyph_spacing_x*scale;
+               text_cursor[0] += (ui_glyph_spacing_x*scale)/2;
        }
 }
 
@@ -533,6 +587,8 @@ static void ui_begin( ui_ctx *ctx, ui_px res_x, ui_px res_y )
        
        ctx->num_verts = 0;
        ctx->num_indices = 0;
+       
+       ui_release_clip( ctx );
 }
 
 static void ui_resolve( ui_ctx *ctx )