gl renderer: Implement unblurred outset shadows

This commit is contained in:
Timm Bäder 2017-12-01 08:30:11 +01:00
parent 5c7838e168
commit 47c4bf5be0
4 changed files with 95 additions and 5 deletions

View File

@ -170,6 +170,7 @@ struct _GskGLRenderer
Program linear_gradient_program;
Program blur_program;
Program inset_shadow_program;
Program outset_shadow_program;
};
};
@ -272,6 +273,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
{ "linear gradient", "blit.vs.glsl", "linear_gradient.fs.glsl" },
{ "blur", "blit.vs.glsl", "blur.fs.glsl" },
{ "inset shadow", "blit.vs.glsl", "inset_shadow.fs.glsl" },
{ "outset shadow", "blit.vs.glsl", "outset_shadow.fs.glsl" },
};
builder = gsk_shader_builder_new ();
@ -374,6 +376,14 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION2 (inset_shadow, corner_widths);
INIT_PROGRAM_UNIFORM_LOCATION2 (inset_shadow, corner_heights);
/* outset shadow */
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, color);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, spread);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, offset);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, outline);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_widths);
INIT_PROGRAM_UNIFORM_LOCATION2 (outset_shadow, corner_heights);
g_object_unref (builder);
return TRUE;
}
@ -1012,12 +1022,36 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
}
break;
case GSK_OUTSET_SHADOW_NODE:
{
RenderOp op;
/* TODO: Implement blurred outset shadows as well */
if (gsk_outset_shadow_node_get_blur_radius (node) > 0)
goto do_default;
op.op = OP_CHANGE_OUTSET_SHADOW;
rgba_to_float (gsk_outset_shadow_node_peek_color (node), op.outset_shadow.color);
rounded_rect_to_floats (gsk_outset_shadow_node_peek_outline (node),
op.outset_shadow.outline,
op.outset_shadow.corner_widths,
op.outset_shadow.corner_heights);
op.outset_shadow.radius = gsk_outset_shadow_node_get_blur_radius (node);
op.outset_shadow.spread = gsk_outset_shadow_node_get_spread (node);
op.outset_shadow.offset[0] = gsk_outset_shadow_node_get_dx (node);
op.outset_shadow.offset[1] = -gsk_outset_shadow_node_get_dy (node);
ops_set_program (builder, &self->outset_shadow_program);
ops_add (builder, &op);
ops_draw (builder, vertex_data);
}
break;
do_default:
case GSK_REPEATING_LINEAR_GRADIENT_NODE:
case GSK_BORDER_NODE:
case GSK_OUTSET_SHADOW_NODE:
case GSK_SHADOW_NODE:
case GSK_BORDER_NODE:
case GSK_CROSS_FADE_NODE:
case GSK_BLEND_NODE:
case GSK_REPEAT_NODE:
@ -1323,6 +1357,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
glUniform4fv (program->inset_shadow.corner_heights_location, 1, op->inset_shadow.corner_heights);
break;
case OP_CHANGE_OUTSET_SHADOW:
g_assert (program == &self->outset_shadow_program);
glUniform4fv (program->outset_shadow.color_location, 1, op->outset_shadow.color);
glUniform2fv (program->outset_shadow.offset_location, 1, op->outset_shadow.offset);
glUniform1f (program->outset_shadow.spread_location, op->outset_shadow.spread);
glUniform4fv (program->outset_shadow.outline_location, 1, op->outset_shadow.outline);
glUniform4fv (program->outset_shadow.corner_widths_location, 1, op->outset_shadow.corner_widths);
glUniform4fv (program->outset_shadow.corner_heights_location, 1, op->outset_shadow.corner_heights);
break;
case OP_DRAW:
OP_PRINT (" -> draw %ld, size %ld and program %s\n",
op->draw.vao_offset, op->draw.vao_size, program->name);

View File

@ -10,7 +10,7 @@
#include "gskglrendererprivate.h"
#define GL_N_VERTICES 6
#define GL_N_PROGRAMS 8
#define GL_N_PROGRAMS 9
enum {
OP_NONE,
@ -28,8 +28,9 @@ enum {
OP_CHANGE_COLOR_MATRIX = 12,
OP_CHANGE_BLUR = 13,
OP_CHANGE_INSET_SHADOW = 14,
OP_CLEAR = 15,
OP_DRAW = 16,
OP_CHANGE_OUTSET_SHADOW = 15,
OP_CLEAR = 16,
OP_DRAW = 17,
};
typedef struct
@ -81,6 +82,14 @@ typedef struct
int corner_widths_location;
int corner_heights_location;
} inset_shadow;
struct {
int color_location;
int spread_location;
int offset_location;
int outline_location;
int corner_widths_location;
int corner_heights_location;
} outset_shadow;
};
} Program;
@ -128,6 +137,15 @@ typedef struct
float offset[2];
float color[4];
} inset_shadow;
struct {
float outline[4];
float corner_widths[4];
float corner_heights[4];
float radius;
float spread;
float offset[2];
float color[4];
} outset_shadow;
};
} RenderOp;

View File

@ -10,6 +10,7 @@ gsk_private_source_shaders = [
'resources/glsl/blur.vs.glsl',
'resources/glsl/blur.fs.glsl',
'resources/glsl/inset_shadow.fs.glsl',
'resources/glsl/outset_shadow.fs.glsl',
'resources/glsl/es2_common.fs.glsl',
'resources/glsl/es2_common.vs.glsl',
'resources/glsl/gl3_common.fs.glsl',

View File

@ -0,0 +1,27 @@
uniform float u_spread;
uniform float u_blur_radius;
uniform vec4 u_color;
uniform vec2 u_offset;
uniform vec4 u_outline;
uniform vec4 u_corner_widths;
uniform vec4 u_corner_heights;
void main() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
RoundedRect outline = RoundedRect(vec4(u_outline.xy, u_outline.xy + u_outline.zw),
u_corner_widths, u_corner_heights);
RoundedRect outside = rounded_rect_shrink(outline, vec4(- u_spread));
vec2 offset = vec2(u_offset.x, - u_offset.y);
vec4 color = vec4(u_color.rgb * u_color.a, u_color.a);
color = color * clamp (rounded_rect_coverage (outside, f.xy - offset) -
rounded_rect_coverage (outline, f.xy),
0.0, 1.0);
setOutputColor(color);
}