summaryrefslogtreecommitdiff
path: root/src/plasma-node.c
blob: 1eb4c7aca02d7a13cccec5396e1e5c3b3a438ffd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 *  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 <play.h>
#include <stage.h>

#include "glad.h"
#include "plasma-node.h"
#include "shader-node.h"
#include "m4f.h"


static const char	*plasma_vs = ""
	"#version 120\n"

	"uniform mat4	projection_x;"

	"attribute vec3 vertex;"
	"attribute vec2 texcoord;"

	"void main()"
	"{"
	"	gl_TexCoord[0].xy = texcoord;"
	"	gl_Position = projection_x * vec4(vertex, 1.f);"
	"}"
"";


// derived from https://www.bidouille.org/prog/plasma
static const char	*plasma_fs = ""
	"#version 120\n"

	"#define PI 3.1415926535897932384626433832795\n"

	"uniform float alpha;"
	"uniform float time;"

	"void main() {"
	"	float v;"
	"	float stime = sin(time * .01f) * 100.f;"

	"	vec2 c = gl_TexCoord[0].st;"

	// this zooms the texture coords in and out a bit with time
	"	c *= (sin(stime * .01f) *.5f + .5f) * 3.f + 1.f;"

	// plasma calculations, stime instead of time directly to vary directions and speed
	"	v = sin((c.x + stime));"
	"	v += sin((c.y + stime) * .5f);"
	"	v += sin((c.x + c.y +stime) * .5f);"

	"	c += vec2(sin(stime * .33f), cos(stime * .5f)) * 3.f;"

	"	v += sin(sqrt(c.x * c.x + c.y * c.y + 1.f) + stime);"

	"	vec3 col = vec3(cos(PI * v + sin(time)), sin(PI * v + cos(time * .33f)), cos(PI * v + sin(time * .66f)));"
	"	gl_FragColor = vec4(col * .5f + .5f, alpha);"
	"}"
"";


static void plasma_uniforms(void *uniforms_ctxt, void *render_ctxt, unsigned n_uniforms, const int *uniforms, const m4f_t *model_x, float alpha)
{
	play_t	*play = render_ctxt;

	glUniform1f(uniforms[0], alpha);
	glUniform1f(uniforms[1], play_ticks(play, PLAY_TICKS_TIMER0) * .001f); // FIXME KLUDGE ALERT
	glUniformMatrix4fv(uniforms[2], 1, GL_FALSE, &model_x->m[0][0]);
}


/* create plasma rendering stage */
stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x)
{
	return	shader_node_new_src(conf, plasma_vs, plasma_fs, projection_x, plasma_uniforms, NULL, 3,
			(const char *[]){
				"alpha",
				"time",
				"projection_x",
			}
		);
}
© All Rights Reserved