style: unified rounded quad shaders

This commit is contained in:
Will McKinnon 2023-04-03 20:16:54 -04:00
parent 4d1af65004
commit 41df328325
7 changed files with 63 additions and 74 deletions

View file

@ -7,11 +7,16 @@
enum corner_location { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, NONE }; enum corner_location { ALL, TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT, NONE };
enum fx_gles2_shader_source { enum fx_tex_shader_source {
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA = 1, SHADER_SOURCE_TEXTURE_RGBA = 1,
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX = 2, SHADER_SOURCE_TEXTURE_RGBX = 2,
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 3, SHADER_SOURCE_TEXTURE_EXTERNAL = 3,
WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE = 4, };
enum fx_rounded_quad_shader_source {
SHADER_SOURCE_QUAD_ROUND = 1,
SHADER_SOURCE_QUAD_ROUND_TOP_LEFT = 2,
SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT = 3,
}; };
struct decoration_data { struct decoration_data {

View file

@ -22,8 +22,6 @@
#include "corner_frag_src.h" #include "corner_frag_src.h"
#include "quad_frag_src.h" #include "quad_frag_src.h"
#include "quad_round_frag_src.h" #include "quad_round_frag_src.h"
#include "quad_round_tl_frag_src.h"
#include "quad_round_tr_frag_src.h"
#include "tex_frag_src.h" #include "tex_frag_src.h"
static const GLfloat verts[] = { static const GLfloat verts[] = {
@ -98,9 +96,9 @@ static void matrix_projection(float mat[static 9], int width, int height,
mat[8] = 1.0f; mat[8] = 1.0f;
} }
static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len) { static GLuint compile_shader(GLuint type, const GLchar *src) {
GLuint shader = glCreateShader(type); GLuint shader = glCreateShader(type);
glShaderSource(shader, srcs_len, srcs, NULL); glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader); glCompileShader(shader);
GLint ok; GLint ok;
@ -114,24 +112,14 @@ static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len)
return shader; return shader;
} }
static GLuint link_program(const GLchar *frag_src, enum fx_gles2_shader_source source) { static GLuint link_program(const GLchar *frag_src) {
const GLchar *vert_src = common_vert_src; const GLchar *vert_src = common_vert_src;
GLuint vert = compile_shader(GL_VERTEX_SHADER, &vert_src, 1); GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src);
if (!vert) { if (!vert) {
goto error; goto error;
} }
GLuint frag; GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src);
if (source != WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE) {
static char frag_preamble[1024];
snprintf(frag_preamble, sizeof(frag_preamble),
"#define SOURCE %d\n", source);
const GLchar *frag_srcs[2] = { frag_preamble, frag_src };
frag = compile_shader(GL_FRAGMENT_SHADER, frag_srcs, 2);
} else {
frag = compile_shader(GL_FRAGMENT_SHADER, &frag_src, 1);
}
if (!frag) { if (!frag) {
glDeleteShader(vert); glDeleteShader(vert);
goto error; goto error;
@ -162,11 +150,13 @@ error:
} }
static bool link_tex_program(struct fx_renderer *renderer, static bool link_tex_program(struct fx_renderer *renderer,
struct gles2_tex_shader *shader, enum fx_gles2_shader_source source) { struct gles2_tex_shader *shader, enum fx_tex_shader_source source) {
GLuint prog; GLchar frag_src[2048];
const GLchar *frag_src = tex_frag_src; snprintf(frag_src, sizeof(frag_src),
"#define SOURCE %d\n%s", source, tex_frag_src);
shader->program = prog = link_program(frag_src, source); GLuint prog;
shader->program = prog = link_program(frag_src);
if (!shader->program) { if (!shader->program) {
return false; return false;
} }
@ -187,18 +177,25 @@ static bool link_tex_program(struct fx_renderer *renderer,
return true; return true;
} }
// initializes a provided rounded quad shader and returns false if unsuccessful static bool link_rounded_quad_program(struct fx_renderer *renderer,
bool init_rounded_quad_shader(struct rounded_quad_shader *shader, GLuint prog) { struct rounded_quad_shader *shader, enum fx_rounded_quad_shader_source source) {
shader->program = prog; GLchar quad_src[2048];
snprintf(quad_src, sizeof(quad_src),
"#define SOURCE %d\n%s", source, quad_round_frag_src);
GLuint prog;
shader->program = prog = link_program(quad_src);
if (!shader->program) { if (!shader->program) {
return false; return false;
} }
shader->proj = glGetUniformLocation(prog, "proj"); shader->proj = glGetUniformLocation(prog, "proj");
shader->color = glGetUniformLocation(prog, "color"); shader->color = glGetUniformLocation(prog, "color");
shader->pos_attrib = glGetAttribLocation(prog, "pos"); shader->pos_attrib = glGetAttribLocation(prog, "pos");
shader->size = glGetUniformLocation(prog, "size"); shader->size = glGetUniformLocation(prog, "size");
shader->position = glGetUniformLocation(prog, "position"); shader->position = glGetUniformLocation(prog, "position");
shader->radius = glGetUniformLocation(prog, "radius"); shader->radius = glGetUniformLocation(prog, "radius");
return true; return true;
} }
@ -269,7 +266,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
GLuint prog; GLuint prog;
// quad fragment shader // quad fragment shader
prog = link_program(quad_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); prog = link_program(quad_frag_src);
renderer->shaders.quad.program = prog; renderer->shaders.quad.program = prog;
if (!renderer->shaders.quad.program) { if (!renderer->shaders.quad.program) {
goto error; goto error;
@ -279,21 +276,21 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos"); renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
// rounded quad fragment shaders // rounded quad fragment shaders
prog = link_program(quad_round_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_quad,
if (!init_rounded_quad_shader(&renderer->shaders.rounded_quad, prog)) { SHADER_SOURCE_QUAD_ROUND)) {
goto error; goto error;
} }
prog = link_program(quad_round_tl_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tl_quad,
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tl_quad, prog)) { SHADER_SOURCE_QUAD_ROUND_TOP_LEFT)) {
goto error; goto error;
} }
prog = link_program(quad_round_tr_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); if (!link_rounded_quad_program(renderer, &renderer->shaders.rounded_tr_quad,
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tr_quad, prog)) { SHADER_SOURCE_QUAD_ROUND_TOP_RIGHT)) {
goto error; goto error;
} }
// Border corner shader // Border corner shader
prog = link_program(corner_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); prog = link_program(corner_frag_src);
renderer->shaders.corner.program = prog; renderer->shaders.corner.program = prog;
if (!renderer->shaders.corner.program) { if (!renderer->shaders.corner.program) {
goto error; goto error;
@ -311,7 +308,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
renderer->shaders.corner.half_thickness = glGetUniformLocation(prog, "half_thickness"); renderer->shaders.corner.half_thickness = glGetUniformLocation(prog, "half_thickness");
// box shadow shader // box shadow shader
prog = link_program(box_shadow_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE); prog = link_program(box_shadow_frag_src);
renderer->shaders.box_shadow.program = prog; renderer->shaders.box_shadow.program = prog;
if (!renderer->shaders.box_shadow.program) { if (!renderer->shaders.box_shadow.program) {
goto error; goto error;
@ -326,15 +323,15 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
// fragment shaders // fragment shaders
if (!link_tex_program(renderer, &renderer->shaders.tex_rgba, if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) { SHADER_SOURCE_TEXTURE_RGBA)) {
goto error; goto error;
} }
if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx, if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) { SHADER_SOURCE_TEXTURE_RGBX)) {
goto error; goto error;
} }
if (!link_tex_program(renderer, &renderer->shaders.tex_ext, if (!link_tex_program(renderer, &renderer->shaders.tex_ext,
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) { SHADER_SOURCE_TEXTURE_EXTERNAL)) {
goto error; goto error;
} }

View file

@ -6,8 +6,6 @@ shaders = [
'corner.frag', 'corner.frag',
'quad.frag', 'quad.frag',
'quad_round.frag', 'quad_round.frag',
'quad_round_tl.frag',
'quad_round_tr.frag',
'tex.frag', 'tex.frag',
] ]

View file

@ -1,3 +1,11 @@
#define SOURCE_QUAD_ROUND 1
#define SOURCE_QUAD_ROUND_TOP_LEFT 2
#define SOURCE_QUAD_ROUND_TOP_RIGHT 3
#if !defined(SOURCE)
#error "Missing shader preamble"
#endif
precision mediump float; precision mediump float;
varying vec4 v_color; varying vec4 v_color;
varying vec2 v_texcoord; varying vec2 v_texcoord;
@ -6,9 +14,19 @@ uniform vec2 size;
uniform vec2 position; uniform vec2 position;
uniform float radius; uniform float radius;
void main() { vec2 getCornerDist() {
#if SOURCE == SOURCE_QUAD_ROUND
vec2 half_size = size * 0.5; vec2 half_size = size * 0.5;
vec2 q = abs(gl_FragCoord.xy - position - half_size) - half_size + radius; return abs(gl_FragCoord.xy - position - half_size) - half_size + radius;
#elif SOURCE == SOURCE_QUAD_ROUND_TOP_LEFT
return abs(gl_FragCoord.xy - position - size) - size + radius;
#elif SOURCE == SOURCE_QUAD_ROUND_TOP_RIGHT
return abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius;
#endif
}
void main() {
vec2 q = getCornerDist();
float dist = min(max(q.x,q.y), 0.0) + length(max(q, 0.0)) - radius; float dist = min(max(q.x,q.y), 0.0) + length(max(q, 0.0)) - radius;
float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, dist); float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, dist);
gl_FragColor = mix(vec4(0), v_color, smoothedAlpha); gl_FragColor = mix(vec4(0), v_color, smoothedAlpha);

View file

@ -1,14 +0,0 @@
precision mediump float;
varying vec4 v_color;
varying vec2 v_texcoord;
uniform vec2 size;
uniform vec2 position;
uniform float radius;
void main() {
vec2 q = abs(gl_FragCoord.xy - position - size) - size + radius;
float distance = min(max(q.x,q.y),0.0) + length(max(q,0.0)) - radius;
float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, distance);
gl_FragColor = mix(vec4(0), v_color, smoothedAlpha);
}

View file

@ -1,14 +0,0 @@
precision mediump float;
varying vec4 v_color;
varying vec2 v_texcoord;
uniform vec2 size;
uniform vec2 position;
uniform float radius;
void main() {
vec2 q = abs(gl_FragCoord.xy - position - vec2(0, size.y)) - size + radius;
float distance = min(max(q.x,q.y),0.0) + length(max(q,0.0)) - radius;
float smoothedAlpha = 1.0 - smoothstep(-1.0, 0.5, distance);
gl_FragColor = mix(vec4(0), v_color, smoothedAlpha);
}

View file

@ -1,4 +1,3 @@
/* enum wlr_gles2_shader_source */
#define SOURCE_TEXTURE_RGBA 1 #define SOURCE_TEXTURE_RGBA 1
#define SOURCE_TEXTURE_RGBX 2 #define SOURCE_TEXTURE_RGBX 2
#define SOURCE_TEXTURE_EXTERNAL 3 #define SOURCE_TEXTURE_EXTERNAL 3