/* * Copyright (C) 2018-2020 - Vito Caputo - * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include "glad.h" #include "m4f.h" #include "sad-node.h" #include "shader-node.h" #include "v3f.h" static const char *sad_vs = "" "#version 120\n" "uniform mat4 model_x;" "attribute vec3 i_vertex;" "attribute vec2 i_texcoord;" "void main()" "{" " gl_TexCoord[0].xy = i_texcoord;" " gl_Position = model_x * vec4(i_vertex, 1.f);" "}" ""; static const char *sad_fs = "" "#version 120\n" "uniform float alpha;" "uniform float time;" "uniform float T;" "uniform vec3 color;" "uniform float seed; " "uniform float rand;" "const vec2 leye = vec2(-.5f, .5f);" "const vec2 reye = vec2(.5f, .5f);" "const vec2 frown = vec2(0.f, -1.2f);" "const float eye_radius = .2f;" "const float frown_radius = 1.f;" "const float lip_thickness = .1f;" "void eye(in vec2 center, inout vec4 c)" "{" " float r = length(center - gl_TexCoord[0].st);" " if (r <= eye_radius) {" " float v = (1.f / eye_radius) * r;" " v = 1.f - pow(v, 20);" " c = vec4(color * v, v);" " }" "}" "void arc(vec2 center, inout vec4 c)" "{" " float r = length(center - gl_TexCoord[0].st);" " if (r >= frown_radius - lip_thickness &&" " r <= frown_radius + lip_thickness) {" " float v = cos((r - (frown_radius + lip_thickness)) * 1.f / (lip_thickness * 2.f) * 6.28) * .5f + .5f;" " v = 1.f - pow(v, 20);" " c = vec4(color * v, v);" " }" "}" "void main()" "{" " float r = length(gl_TexCoord[0].st);" " vec4 c = vec4(0.f, 0.f, 0.f, 0.f);" " eye(leye, c);" " eye(reye, c);" " arc(frown, c);" " gl_FragColor = c;" "}" ""; static void sad_uniforms(shader_t *shader, void *uniforms_ctxt, void *render_ctxt, unsigned n_uniforms, const int *uniforms, const m4f_t *model_x, float alpha) { v3f_t *color = uniforms_ctxt; glUniform1f(uniforms[0], alpha); glUniformMatrix4fv(uniforms[1], 1, GL_FALSE, &model_x->m[0][0]); glUniform3f(uniforms[2], color->x, color->y, color->z); } /* create sad face rendering stage */ stage_t * sad_node_new(const stage_conf_t *conf, const m4f_t *model_x, const v3f_t *color) { assert(model_x); assert(color); return shader_node_new_src(conf, sad_vs, sad_fs, model_x, sad_uniforms, (void *)color, 3, (const char *[]){ "alpha", "model_x", "color", } ); }