diff options
Diffstat (limited to 'src/sad-node.c')
-rw-r--r-- | src/sad-node.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/sad-node.c b/src/sad-node.c new file mode 100644 index 0000000..6ec7a6c --- /dev/null +++ b/src/sad-node.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2018-2020 - Vito Caputo - <vcaputo@pengaru.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <SDL.h> + +#include <stage.h> + +#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", + } + ); +} |