refactor: merged tex shaders
This commit is contained in:
parent
f1e3fe92ce
commit
1a10c61165
|
@ -7,6 +7,13 @@
|
||||||
|
|
||||||
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 {
|
||||||
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA = 1,
|
||||||
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX = 2,
|
||||||
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL = 3,
|
||||||
|
WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE = 4,
|
||||||
|
};
|
||||||
|
|
||||||
struct decoration_data {
|
struct decoration_data {
|
||||||
float alpha;
|
float alpha;
|
||||||
float saturation;
|
float saturation;
|
||||||
|
|
|
@ -25,9 +25,8 @@
|
||||||
#include "quad_round_tr_frag_src.h"
|
#include "quad_round_tr_frag_src.h"
|
||||||
#include "corner_frag_src.h"
|
#include "corner_frag_src.h"
|
||||||
#include "box_shadow_frag_src.h"
|
#include "box_shadow_frag_src.h"
|
||||||
#include "tex_rgba_frag_src.h"
|
//#include "tex_frag_src.h"
|
||||||
#include "tex_rgbx_frag_src.h"
|
#include "tex_decorated_frag_src.h"
|
||||||
#include "tex_external_frag_src.h"
|
|
||||||
|
|
||||||
static const GLfloat verts[] = {
|
static const GLfloat verts[] = {
|
||||||
1, 0, // top right
|
1, 0, // top right
|
||||||
|
@ -101,9 +100,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 *src) {
|
static GLuint compile_shader(GLuint type, const GLchar **srcs, size_t srcs_len) {
|
||||||
GLuint shader = glCreateShader(type);
|
GLuint shader = glCreateShader(type);
|
||||||
glShaderSource(shader, 1, &src, NULL);
|
glShaderSource(shader, srcs_len, srcs, NULL);
|
||||||
glCompileShader(shader);
|
glCompileShader(shader);
|
||||||
|
|
||||||
GLint ok;
|
GLint ok;
|
||||||
|
@ -117,13 +116,24 @@ static GLuint compile_shader(GLuint type, const GLchar *src) {
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint link_program(const GLchar *vert_src, const GLchar *frag_src) {
|
static GLuint link_program(const GLchar *frag_src, enum fx_gles2_shader_source source) {
|
||||||
GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src);
|
const GLchar *vert_src = common_vert_src;
|
||||||
|
GLuint vert = compile_shader(GL_VERTEX_SHADER, &vert_src, 1);
|
||||||
if (!vert) {
|
if (!vert) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src);
|
GLuint frag;
|
||||||
|
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;
|
||||||
|
@ -153,12 +163,16 @@ error:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// initializes a provided fragment shader and returns false if unsuccessful
|
static bool link_tex_program(struct fx_renderer *renderer,
|
||||||
bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) {
|
struct gles2_tex_shader *shader, enum fx_gles2_shader_source source) {
|
||||||
shader->program = prog;
|
GLuint prog;
|
||||||
|
const GLchar *frag_src = tex_decorated_frag_src;
|
||||||
|
|
||||||
|
shader->program = prog = link_program(frag_src, source);
|
||||||
if (!shader->program) {
|
if (!shader->program) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->proj = glGetUniformLocation(prog, "proj");
|
shader->proj = glGetUniformLocation(prog, "proj");
|
||||||
shader->tex = glGetUniformLocation(prog, "tex");
|
shader->tex = glGetUniformLocation(prog, "tex");
|
||||||
shader->alpha = glGetUniformLocation(prog, "alpha");
|
shader->alpha = glGetUniformLocation(prog, "alpha");
|
||||||
|
@ -171,6 +185,7 @@ bool init_frag_shader(struct gles2_tex_shader *shader, GLuint prog) {
|
||||||
shader->radius = glGetUniformLocation(prog, "radius");
|
shader->radius = glGetUniformLocation(prog, "radius");
|
||||||
shader->saturation = glGetUniformLocation(prog, "saturation");
|
shader->saturation = glGetUniformLocation(prog, "saturation");
|
||||||
shader->has_titlebar = glGetUniformLocation(prog, "has_titlebar");
|
shader->has_titlebar = glGetUniformLocation(prog, "has_titlebar");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +271,7 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
|
||||||
GLuint prog;
|
GLuint prog;
|
||||||
|
|
||||||
// quad fragment shader
|
// quad fragment shader
|
||||||
prog = link_program(common_vert_src, quad_frag_src);
|
prog = link_program(quad_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
renderer->shaders.quad.program = prog;
|
renderer->shaders.quad.program = prog;
|
||||||
if (!renderer->shaders.quad.program) {
|
if (!renderer->shaders.quad.program) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -266,21 +281,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(common_vert_src, quad_round_frag_src);
|
prog = link_program(quad_round_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
if (!init_rounded_quad_shader(&renderer->shaders.rounded_quad, prog)) {
|
if (!init_rounded_quad_shader(&renderer->shaders.rounded_quad, prog)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
prog = link_program(common_vert_src, quad_round_tl_frag_src);
|
prog = link_program(quad_round_tl_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tl_quad, prog)) {
|
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tl_quad, prog)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
prog = link_program(common_vert_src, quad_round_tr_frag_src);
|
prog = link_program(quad_round_tr_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tr_quad, prog)) {
|
if (!init_rounded_quad_shader(&renderer->shaders.rounded_tr_quad, prog)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Border corner shader
|
// Border corner shader
|
||||||
prog = link_program(common_vert_src, corner_frag_src);
|
prog = link_program(corner_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
renderer->shaders.corner.program = prog;
|
renderer->shaders.corner.program = prog;
|
||||||
if (!renderer->shaders.corner.program) {
|
if (!renderer->shaders.corner.program) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -298,7 +313,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(common_vert_src, box_shadow_frag_src);
|
prog = link_program(box_shadow_frag_src, WLR_GLES2_SHADER_SOURCE_NOT_TEXTURE);
|
||||||
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;
|
||||||
|
@ -312,19 +327,20 @@ struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
|
||||||
renderer->shaders.box_shadow.corner_radius = glGetUniformLocation(prog, "corner_radius");
|
renderer->shaders.box_shadow.corner_radius = glGetUniformLocation(prog, "corner_radius");
|
||||||
|
|
||||||
// fragment shaders
|
// fragment shaders
|
||||||
prog = link_program(common_vert_src, tex_rgba_frag_src);
|
if (!link_tex_program(renderer, &renderer->shaders.tex_rgba,
|
||||||
if (!init_frag_shader(&renderer->shaders.tex_rgba, prog)) {
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBA)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
prog = link_program(common_vert_src, tex_rgbx_frag_src);
|
if (!link_tex_program(renderer, &renderer->shaders.tex_rgbx,
|
||||||
if (!init_frag_shader(&renderer->shaders.tex_rgbx, prog)) {
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_RGBX)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
prog = link_program(common_vert_src, tex_external_frag_src);
|
if (!link_tex_program(renderer, &renderer->shaders.tex_ext,
|
||||||
if (!init_frag_shader(&renderer->shaders.tex_ext, prog)) {
|
WLR_GLES2_SHADER_SOURCE_TEXTURE_EXTERNAL)) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!eglMakeCurrent(wlr_egl_get_display(renderer->egl),
|
if (!eglMakeCurrent(wlr_egl_get_display(renderer->egl),
|
||||||
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
|
||||||
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
|
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not unset current EGL");
|
||||||
|
|
|
@ -8,9 +8,7 @@ shaders = [
|
||||||
'quad_round_tr.frag',
|
'quad_round_tr.frag',
|
||||||
'corner.frag',
|
'corner.frag',
|
||||||
'box_shadow.frag',
|
'box_shadow.frag',
|
||||||
'tex_rgba.frag',
|
'tex_decorated.frag',
|
||||||
'tex_rgbx.frag',
|
|
||||||
'tex_external.frag',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach name : shaders
|
foreach name : shaders
|
||||||
|
|
36
sway/desktop/shaders/tex.frag
Normal file
36
sway/desktop/shaders/tex.frag
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* enum wlr_gles2_shader_source */
|
||||||
|
#define SOURCE_TEXTURE_RGBA 1
|
||||||
|
#define SOURCE_TEXTURE_RGBX 2
|
||||||
|
#define SOURCE_TEXTURE_EXTERNAL 3
|
||||||
|
|
||||||
|
#if !defined(SOURCE)
|
||||||
|
#error "Missing shader preamble"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
#extension GL_OES_EGL_image_external : require
|
||||||
|
#endif
|
||||||
|
|
||||||
|
precision mediump float;
|
||||||
|
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
uniform samplerExternalOES tex;
|
||||||
|
#elif SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_RGBX
|
||||||
|
uniform sampler2D tex;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
vec4 sample_texture() {
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
return texture2D(tex, v_texcoord);
|
||||||
|
#elif SOURCE == SOURCE_TEXTURE_RGBX
|
||||||
|
return vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_FragColor = sample_texture() * alpha;
|
||||||
|
}
|
|
@ -1,19 +1,47 @@
|
||||||
|
/* enum wlr_gles2_shader_source */
|
||||||
|
#define SOURCE_TEXTURE_RGBA 1
|
||||||
|
#define SOURCE_TEXTURE_RGBX 2
|
||||||
|
#define SOURCE_TEXTURE_EXTERNAL 3
|
||||||
|
|
||||||
|
#if !defined(SOURCE)
|
||||||
|
#error "Missing shader preamble"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
#extension GL_OES_EGL_image_external : require
|
||||||
|
#endif
|
||||||
|
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
varying vec2 v_texcoord;
|
varying vec2 v_texcoord;
|
||||||
|
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
uniform samplerExternalOES tex;
|
||||||
|
#elif SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_RGBX
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform float alpha;
|
uniform float alpha;
|
||||||
uniform float dim;
|
uniform float dim;
|
||||||
uniform vec4 dim_color;
|
uniform vec4 dim_color;
|
||||||
|
|
||||||
uniform vec2 size;
|
uniform vec2 size;
|
||||||
uniform vec2 position;
|
uniform vec2 position;
|
||||||
uniform float radius;
|
uniform float radius;
|
||||||
uniform bool has_titlebar;
|
uniform bool has_titlebar;
|
||||||
uniform float saturation;
|
uniform float saturation;
|
||||||
|
|
||||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
||||||
|
|
||||||
|
vec4 sample_texture() {
|
||||||
|
#if SOURCE == SOURCE_TEXTURE_RGBA || SOURCE == SOURCE_TEXTURE_EXTERNAL
|
||||||
|
return texture2D(tex, v_texcoord);
|
||||||
|
#elif SOURCE == SOURCE_TEXTURE_RGBX
|
||||||
|
return vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 color = texture2D(tex, v_texcoord);
|
vec4 color = sample_texture();
|
||||||
// Saturation
|
// Saturation
|
||||||
if (saturation != 1.0) {
|
if (saturation != 1.0) {
|
||||||
vec4 pixColor = texture2D(tex, v_texcoord);
|
vec4 pixColor = texture2D(tex, v_texcoord);
|
|
@ -1,37 +0,0 @@
|
||||||
#extension GL_OES_EGL_image_external : require
|
|
||||||
|
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform samplerExternalOES texture0;
|
|
||||||
uniform float alpha;
|
|
||||||
uniform float dim;
|
|
||||||
uniform vec4 dim_color;
|
|
||||||
|
|
||||||
uniform vec2 size;
|
|
||||||
uniform vec2 position;
|
|
||||||
uniform float radius;
|
|
||||||
uniform bool has_titlebar;
|
|
||||||
uniform float saturation;
|
|
||||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 color = texture2D(texture0, v_texcoord);
|
|
||||||
// Saturation
|
|
||||||
if (saturation != 1.0) {
|
|
||||||
vec4 pixColor = texture2D(texture0, v_texcoord);
|
|
||||||
vec3 irgb = pixColor.rgb;
|
|
||||||
vec3 target = vec3(dot(irgb, saturation_weight));
|
|
||||||
color = vec4(mix(target, irgb, saturation), pixColor.a);
|
|
||||||
}
|
|
||||||
// Dimming
|
|
||||||
gl_FragColor = mix(color, dim_color, dim) * alpha;
|
|
||||||
|
|
||||||
if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
|
|
||||||
vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
|
|
||||||
if (max(corner_distance.x, corner_distance.y) < radius) {
|
|
||||||
float d = radius - distance(corner_distance, vec2(radius));
|
|
||||||
float smooth = smoothstep(-1.0f, 0.5f, d);
|
|
||||||
gl_FragColor = mix(vec4(0), gl_FragColor, smooth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
precision mediump float;
|
|
||||||
varying vec2 v_texcoord;
|
|
||||||
uniform sampler2D tex;
|
|
||||||
uniform float alpha;
|
|
||||||
uniform float dim;
|
|
||||||
uniform vec4 dim_color;
|
|
||||||
|
|
||||||
uniform vec2 size;
|
|
||||||
uniform vec2 position;
|
|
||||||
uniform float radius;
|
|
||||||
uniform bool has_titlebar;
|
|
||||||
uniform float saturation;
|
|
||||||
const vec3 saturation_weight = vec3(0.2125, 0.7154, 0.0721);
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
vec4 color = vec4(texture2D(tex, v_texcoord).rgb, 1.0);
|
|
||||||
// Saturation
|
|
||||||
if (saturation != 1.0) {
|
|
||||||
vec3 irgb = texture2D(tex, v_texcoord).rgb;
|
|
||||||
vec3 target = vec3(dot(irgb, saturation_weight));
|
|
||||||
color = vec4(mix(target, irgb, saturation), 1.0);
|
|
||||||
}
|
|
||||||
// Dimming
|
|
||||||
gl_FragColor = mix(color, dim_color, dim) * alpha;
|
|
||||||
|
|
||||||
if (!has_titlebar || gl_FragCoord.y - position.y > radius) {
|
|
||||||
vec2 corner_distance = min(gl_FragCoord.xy - position, size + position - gl_FragCoord.xy);
|
|
||||||
if (max(corner_distance.x, corner_distance.y) < radius) {
|
|
||||||
float d = radius - distance(corner_distance, vec2(radius));
|
|
||||||
float smooth = smoothstep(-1.0f, 0.5f, d);
|
|
||||||
gl_FragColor = mix(vec4(0), gl_FragColor, smooth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue