"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
"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" })
#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;
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
// 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
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 );
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 );
}
}
+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
// ===========================================================================================================
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;
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 )
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;
{
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' )
{
break;
}
}
+ continue;
}
- text_cursor[0] += ui_glyph_spacing_x*scale;
+ text_cursor[0] += (ui_glyph_spacing_x*scale)/2;
}
}
ctx->num_verts = 0;
ctx->num_indices = 0;
+
+ ui_release_clip( ctx );
}
static void ui_resolve( ui_ctx *ctx )