gl_common: add vertex shader

Also use an attribute for the texture coordinates.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-03-13 23:26:24 +00:00
parent 18f6a20bf4
commit d64aab7d40
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
2 changed files with 47 additions and 14 deletions

View File

@ -259,7 +259,8 @@ void gl_compose(backend_t *base, void *image_data, int dst_x, int dst_y,
GLint vy[] = {vy1, vy1, vy2, vy2}; GLint vy[] = {vy1, vy1, vy2, vy2};
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
glTexCoord2f(texture_x[i], texture_y[i]); glVertexAttrib2f(gd->win_shader.in_texcoord, texture_x[i],
texture_y[i]);
glVertex3i(vx[i], vy[i], 0); glVertex3i(vx[i], vy[i], 0);
} }
} }
@ -386,7 +387,7 @@ bool gl_blur(backend_t *base, double opacity, const region_t *reg_blur,
GLint vy[] = {vy1, vy1, vy2, vy2}; GLint vy[] = {vy1, vy1, vy2, vy2};
for (int k = 0; k < 4; k++) { for (int k = 0; k < 4; k++) {
glTexCoord2f(texture_x[k], texture_y[k]); glVertexAttrib2f(p->in_texcoord, texture_x[k], texture_y[k]);
glVertex3i(vx[k], vy[k], 0); glVertex3i(vx[k], vy[k], 0);
} }
} }
@ -418,6 +419,19 @@ static GLint glGetUniformLocationChecked(GLuint p, const char *name) {
return ret; return ret;
} }
// clang-format off
const char *vertex_shader = GLSL(130,
uniform mat4 projection;
in vec2 in_texcoord;
out vec2 texcoord;
void main() {
gl_Position = projection * gl_Vertex;
texcoord = in_texcoord;
}
);
// clang-format on
/** /**
* Load a GLSL main program from shader strings. * Load a GLSL main program from shader strings.
*/ */
@ -435,6 +449,7 @@ static int gl_win_shader_from_string(const char *vshader_str, const char *fshade
ret->unifm_invert_color = glGetUniformLocationChecked(ret->prog, "invert_color"); ret->unifm_invert_color = glGetUniformLocationChecked(ret->prog, "invert_color");
ret->unifm_tex = glGetUniformLocationChecked(ret->prog, "tex"); ret->unifm_tex = glGetUniformLocationChecked(ret->prog, "tex");
ret->unifm_dim = glGetUniformLocationChecked(ret->prog, "dim"); ret->unifm_dim = glGetUniformLocationChecked(ret->prog, "dim");
ret->in_texcoord = glGetAttribLocation(ret->prog, "in_texcoord");
gl_check_err(); gl_check_err();
@ -446,15 +461,13 @@ static int gl_win_shader_from_string(const char *vshader_str, const char *fshade
*/ */
void gl_resize(struct gl_data *gd, int width, int height) { void gl_resize(struct gl_data *gd, int width, int height) {
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, 0, height, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gd->height = height; gd->height = height;
gd->width = width; gd->width = width;
// Note: OpenGL matrices are column major
GLfloat projection_matrix[4][4] = {
{2.0 / width, 0, 0, 0}, {0, 2.0 / height, 0, 0}, {0, 0, 0, 0}, {-1, -1, 0, 1}};
if (gd->npasses > 0) { if (gd->npasses > 0) {
// Resize the temporary textures used for blur // Resize the temporary textures used for blur
glBindTexture(GL_TEXTURE_2D, gd->blur_texture[0]); glBindTexture(GL_TEXTURE_2D, gd->blur_texture[0]);
@ -465,8 +478,23 @@ void gl_resize(struct gl_data *gd, int width, int height) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gd->width, gd->height, 0, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gd->width, gd->height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, NULL); GL_BGRA, GL_UNSIGNED_BYTE, NULL);
} }
// Update projection matrices in the blur shaders
for (int i = 0; i < gd->npasses; i++) {
assert(gd->blur_shader[i].prog);
glUseProgram(gd->blur_shader[i].prog);
int pml = glGetUniformLocationChecked(gd->blur_shader[i].prog,
"projection");
glUniformMatrix4fv(pml, 1, false, projection_matrix[0]);
} }
} }
// Update projection matrix in the win shader
glUseProgram(gd->win_shader.prog);
int pml = glGetUniformLocationChecked(gd->win_shader.prog, "projection");
glUniformMatrix4fv(pml, 1, false, projection_matrix[0]);
gl_check_err();
}
void gl_fill(backend_t *base, double r, double g, double b, double a, const region_t *clip) { void gl_fill(backend_t *base, double r, double g, double b, double a, const region_t *clip) {
int nrects; int nrects;
@ -503,6 +531,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
uniform float offset_y; uniform float offset_y;
uniform sampler2D tex_scr; uniform sampler2D tex_scr;
uniform float opacity; uniform float opacity;
in vec2 texcoord;
out vec4 out_color; out vec4 out_color;
void main() { void main() {
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0); vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
@ -512,8 +541,8 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
); );
static const char *FRAG_SHADER_BLUR_ADD = QUOTE( static const char *FRAG_SHADER_BLUR_ADD = QUOTE(
sum += float(%.7g) * sum += float(%.7g) *
texture2D(tex_scr, vec2(gl_TexCoord[0].x + offset_x * float(%d), texture2D(tex_scr, vec2(texcoord.x + offset_x * float(%d),
gl_TexCoord[0].y + offset_y * float(%d))); texcoord.y + offset_y * float(%d)));
); );
// clang-format on // clang-format on
@ -562,7 +591,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
free(shader_body); free(shader_body);
// Build program // Build program
pass->prog = gl_create_program_from_str(NULL, shader_str); pass->prog = gl_create_program_from_str(vertex_shader, shader_str);
free(shader_str); free(shader_str);
if (!pass->prog) { if (!pass->prog) {
log_error("Failed to create GLSL program."); log_error("Failed to create GLSL program.");
@ -576,6 +605,7 @@ static bool gl_init_blur(struct gl_data *gd, conv *const *const kernels) {
pass->unifm_offset_y = pass->unifm_offset_y =
glGetUniformLocationChecked(pass->prog, "offset_y"); glGetUniformLocationChecked(pass->prog, "offset_y");
pass->unifm_opacity = glGetUniformLocationChecked(pass->prog, "opacity"); pass->unifm_opacity = glGetUniformLocationChecked(pass->prog, "opacity");
pass->in_texcoord = glGetAttribLocation(pass->prog, "in_texcoord");
} }
free(extension); free(extension);
@ -611,14 +641,15 @@ err:
} }
// clang-format off // clang-format off
const char *win_shader_glsl = GLSL(110, const char *win_shader_glsl = GLSL(130,
uniform float opacity; uniform float opacity;
uniform float dim; uniform float dim;
uniform bool invert_color; uniform bool invert_color;
in vec2 texcoord;
uniform sampler2D tex; uniform sampler2D tex;
void main() { void main() {
vec4 c = texture2D(tex, gl_TexCoord[0].xy); vec4 c = texture2D(tex, texcoord.xy);
if (invert_color) { if (invert_color) {
c = vec4(c.aaa - c.rgb, c.a); c = vec4(c.aaa - c.rgb, c.a);
} }
@ -652,7 +683,7 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
gd->npasses = 0; gd->npasses = 0;
gl_win_shader_from_string(NULL, win_shader_glsl, &gd->win_shader); gl_win_shader_from_string(vertex_shader, win_shader_glsl, &gd->win_shader);
if (!gl_init_blur(gd, ps->o.blur_kerns)) { if (!gl_init_blur(gd, ps->o.blur_kerns)) {
return false; return false;
} }

View File

@ -21,6 +21,7 @@ typedef struct {
GLint unifm_invert_color; GLint unifm_invert_color;
GLint unifm_tex; GLint unifm_tex;
GLint unifm_dim; GLint unifm_dim;
GLint in_texcoord;
} gl_win_shader_t; } gl_win_shader_t;
// Program and uniforms for blur shader // Program and uniforms for blur shader
@ -29,6 +30,7 @@ typedef struct {
GLint unifm_offset_x; GLint unifm_offset_x;
GLint unifm_offset_y; GLint unifm_offset_y;
GLint unifm_opacity; GLint unifm_opacity;
GLint in_texcoord;
} gl_blur_shader_t; } gl_blur_shader_t;
/// @brief Wrapper of a binded GLX texture. /// @brief Wrapper of a binded GLX texture.