summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game.c2
-rw-r--r--src/plasma-node.c137
-rw-r--r--src/plasma-node.h2
-rw-r--r--src/shader-node.c106
-rw-r--r--src/shader-node.h23
5 files changed, 209 insertions, 61 deletions
diff --git a/src/game.c b/src/game.c
index f4216ab..65b8d62 100644
--- a/src/game.c
+++ b/src/game.c
@@ -227,7 +227,7 @@ typedef struct game_t {
mask_t *mask;
teepee_t *teepee;
entity_t *new_infections;
- int is_maga;
+ unsigned is_maga;
float infections_rate, infections_rate_smoothed; /* 0-1 for none-max */
virus_t *viruses[GAME_NUM_VIRUSES];
m4f_t score_digits_x[10];
diff --git a/src/plasma-node.c b/src/plasma-node.c
index 8afdb75..24b799a 100644
--- a/src/plasma-node.c
+++ b/src/plasma-node.c
@@ -26,7 +26,7 @@
#include "m4f.h"
typedef struct plasma_node_t {
- int *maga;
+ unsigned *maga;
float *gloom;
} plasma_node_t;
@@ -74,7 +74,6 @@ static const char *plasma_fs = ""
"uniform float alpha;"
"uniform float time;"
"uniform float gloom;"
- "uniform int maga;"
" float dostar(vec2 uv, float size) {"
" uv.x = abs(uv.x);"
@@ -98,6 +97,7 @@ static const char *plasma_fs = ""
"void main() {"
" float v;"
" float stime = sin(time * .01) * 100.0;"
+ " vec3 col;"
#ifdef __EMSCRIPTEN__
" vec2 c = UV;"
@@ -118,24 +118,84 @@ static const char *plasma_fs = ""
" v += sin(sqrt(c.x * c.x + c.y * c.y + 1.0) + stime);"
- " if (maga == 1) {"
- " float r, g, b;"
- " float star = dostar(mod(cc, .2) - .1, (sin(time + c.x + c.y) * .5 + .5) * .01 + .01);"
- " b = smoothstep(.25, .8, cos(2.666 * PI + PI * v + sin(time)));"
- " star *= b;"
- " b = max(star, b);"
- " r = max(smoothstep(.25, .8, cos(PI * v + sin(time))), star);"
- " g = max(smoothstep(.25, .8, cos(1.333 * PI + PI * v + sin(time))), star);"
-
- " gl_FragColor = vec4(max(r, g), g, max(b, g), 1.);"
- " } else {"
- " vec3 col = vec3(cos(PI * v + sin(time)), sin(PI * v + cos(time * .33)), cos(PI * v + sin(time * .66)));"
- " gl_FragColor = vec4((col * .5 + .5) * (1. - gloom), alpha);"
- " }"
+ " col = vec3(cos(PI * v + sin(time)), sin(PI * v + cos(time * .33)), cos(PI * v + sin(time * .66)));"
+ " gl_FragColor = vec4((col * .5 + .5) * (1. - gloom), alpha);"
"}"
"";
+static const char *plasma_maga_fs = ""
+#ifdef __EMSCRIPTEN__
+ "#version 100\n"
+#else
+ "#version 120\n"
+#endif
+
+ "#define PI 3.1415926535897932384626433832795\n"
+
+#ifdef __EMSCRIPTEN__
+ "precision mediump float;"
+ "varying vec2 UV;"
+#endif
+
+ "uniform float alpha;"
+ "uniform float time;"
+ "uniform float gloom;"
+
+" float dostar(vec2 uv, float size) {"
+" uv.x = abs(uv.x);"
+" float a = 6.2832/5.;"
+" float d1 = dot(uv, vec2(sin(a), cos(a)));"
+" a = 3. * 6.2832/5.;"
+" float d2 = dot(uv, vec2(sin(a), cos(a)));"
+" a = 2. * 6.2832/5.;"
+" float d4 = dot(uv, vec2(sin(a), cos(a)));"
+" float d = min(max(d1, d2), max(uv.y, d4));"
+#ifdef __EMSCRIPTEN__
+ /* GLSL 1.0 lacks fwidth() */
+" float w = .001;"
+#else
+" float w = fwidth(d);"
+#endif
+
+" return smoothstep(w, -w, d - size);"
+" }"
+
+ "void main() {"
+ " float v;"
+ " float stime = sin(time * .01) * 100.0;"
+ " float star, r, g, b;"
+
+#ifdef __EMSCRIPTEN__
+ " vec2 c = UV;"
+#else
+ " vec2 c = gl_TexCoord[0].st;"
+#endif
+ " vec2 cc = c;"
+
+ // this zooms the texture coords in and out a bit with time
+ " c *= (sin(stime * .01) *.5 + .5) * 3.0 + 1.0;"
+
+ // plasma calculations, stime instead of time directly to vary directions and speed
+ " v = sin((c.x + stime));"
+ " v += sin((c.y + stime) * .5);"
+ " v += sin((c.x + c.y +stime) * .5);"
+
+ " c += vec2(sin(stime * .33), cos(stime * .5)) * 3.0;"
+
+ " v += sin(sqrt(c.x * c.x + c.y * c.y + 1.0) + stime);"
+
+ " star = dostar(mod(cc, .2) - .1, (sin(time + c.x + c.y) * .5 + .5) * .01 + .01);"
+ " b = smoothstep(.25, .8, cos(2.666 * PI + PI * v + sin(time)));"
+ " star *= b;"
+ " b = max(star, b);"
+ " r = max(smoothstep(.25, .8, cos(PI * v + sin(time))), star);"
+ " g = max(smoothstep(.25, .8, cos(1.333 * PI + PI * v + sin(time))), star);"
+
+ " gl_FragColor = vec4(max(r, g), g, max(b, g), 1.);"
+ "}"
+"";
+
static void plasma_uniforms(void *uniforms_ctxt, void *render_ctxt, unsigned n_uniforms, const int *uniforms, const m4f_t *model_x, float alpha)
{
plasma_node_t *plasma = uniforms_ctxt;
@@ -145,12 +205,11 @@ static void plasma_uniforms(void *uniforms_ctxt, void *render_ctxt, unsigned n_u
glUniform1f(uniforms[1], play_ticks(play, PLAY_TICKS_TIMER0) * .001f); // FIXME KLUDGE ALERT
glUniformMatrix4fv(uniforms[2], 1, GL_FALSE, &model_x->m[0][0]);
glUniform1f(uniforms[3], *(plasma->gloom));
- glUniform1i(uniforms[4], *(plasma->maga));
}
/* create plasma rendering stage */
-stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x, float *gloom, int *maga)
+stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x, float *gloom, unsigned *maga)
{
plasma_node_t *ctxt;
@@ -170,15 +229,37 @@ stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x, float *
fatal_if(!ctxt, "unable to allocate plasma_node_t");
ctxt->gloom = gloom;
- ctxt->maga = maga;
-
- return shader_node_new_src(conf, plasma_vs, plasma_fs, projection_x, plasma_uniforms, ctxt, 5,
- (const char *[]){
- "alpha",
- "time",
- "projection_x",
- "gloom",
- "maga",
- }
+
+ return shader_node_new_srcv(conf, 2,
+ (shader_src_conf_t[]){
+ {
+ .vs_src = plasma_vs,
+ .fs_src = plasma_fs,
+ .transform = projection_x,
+ .uniforms_func = plasma_uniforms,
+ .uniforms_ctxt = ctxt,
+ .n_uniforms = 4,
+ .uniforms = (const char *[]){
+ "alpha",
+ "time",
+ "projection_x",
+ "gloom",
+ },
+ }, {
+ .vs_src = plasma_vs,
+ .fs_src = plasma_maga_fs,
+ .transform = projection_x,
+ .uniforms_func = plasma_uniforms,
+ .uniforms_ctxt = ctxt,
+ .n_uniforms = 4,
+ .uniforms = (const char *[]){
+ "alpha",
+ "time",
+ "projection_x",
+ "gloom",
+ },
+ },
+ },
+ maga
);
}
diff --git a/src/plasma-node.h b/src/plasma-node.h
index 8db8664..6094207 100644
--- a/src/plasma-node.h
+++ b/src/plasma-node.h
@@ -21,6 +21,6 @@ typedef struct m4f_t m4f_t;
typedef struct stage_t stage_t;
typedef struct stage_conf_t stage_conf_t;
-stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x, float *gloom, int *maga);
+stage_t * plasma_node_new(const stage_conf_t *conf, m4f_t *projection_x, float *gloom, unsigned *maga);
#endif
diff --git a/src/shader-node.c b/src/shader-node.c
index 5ac8c47..ef49807 100644
--- a/src/shader-node.c
+++ b/src/shader-node.c
@@ -26,11 +26,16 @@
#include "shader-node.h"
#include "v2f.h"
+
typedef struct shader_node_t {
- shader_t *shader;
- shader_node_uniforms_func_t *uniforms_func;
- void *uniforms_ctxt;
- const m4f_t *transform;
+ unsigned *index_ptr;
+ unsigned n_shaders;
+ struct {
+ shader_t *shader;
+ shader_node_uniforms_func_t *uniforms_func;
+ void *uniforms_ctxt;
+ const m4f_t *transform;
+ } shaders[];
} shader_node_t;
static unsigned vbo, tcbo;
@@ -65,14 +70,20 @@ static stage_render_func_ret_t shader_node_render(const stage_t *stage, void *ob
shader_node_t *shader_node = object;
unsigned n_uniforms;
int *uniforms, *attributes;
+ unsigned idx = 0;
assert(stage);
assert(shader_node);
- shader_use(shader_node->shader, &n_uniforms, &uniforms, NULL, &attributes);
+ if (shader_node->index_ptr)
+ idx = *(shader_node->index_ptr);
+
+ assert(idx < shader_node->n_shaders);
+
+ shader_use(shader_node->shaders[idx].shader, &n_uniforms, &uniforms, NULL, &attributes);
- if (shader_node->uniforms_func)
- shader_node->uniforms_func(shader_node->uniforms_ctxt, render_ctxt, n_uniforms, uniforms, shader_node->transform, alpha);
+ if (shader_node->shaders[idx].uniforms_func)
+ shader_node->shaders[idx].uniforms_func(shader_node->shaders[idx].uniforms_ctxt, render_ctxt, n_uniforms, uniforms, shader_node->shaders[idx].transform, alpha);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(attributes[0], 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
@@ -106,7 +117,8 @@ static void shader_node_free(const stage_t *stage, void *object)
assert(shader_node);
/* XXX FIXME: hmm, maybe the caller should supply a shader_t ** instead */
- (void) shader_free(shader_node->shader);
+ for (unsigned i = 0; i < shader_node->n_shaders; i++)
+ (void) shader_free(shader_node->shaders[i].shader);
free(shader_node);
}
@@ -117,14 +129,20 @@ static const stage_ops_t shader_node_ops = {
};
-/* return a new shader stage node from an already compiled and linked shader program */
-stage_t * shader_node_new_shader(const stage_conf_t *conf, shader_t *shader, const m4f_t *transform, shader_node_uniforms_func_t *uniforms_func, void *uniforms_ctxt)
+/* return a new shader stage node from a vector of already compiled and linked shader programs.
+ * When n_shader_confs is > 1, index_ptr must point somewhere valid for the lifetime of this node,
+ * and serves as the index into the vector for selecting which shader_conf to use @ render time.
+ * When n_shader_confs is 1, index_ptr may be NULL.
+ */
+stage_t * shader_node_new_shaderv(const stage_conf_t *conf, unsigned n_shader_confs, const shader_conf_t *shader_confs, unsigned *index_ptr)
{
shader_node_t *shader_node;
stage_t *stage;
assert(conf);
- assert(shader);
+ assert(shader_confs);
+ assert(n_shader_confs > 0);
+ assert(index_ptr || n_shader_confs == 1);
if (!vbo) {
/* common to all shader nodes */
@@ -138,13 +156,17 @@ stage_t * shader_node_new_shader(const stage_conf_t *conf, shader_t *shader, con
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
- shader_node = calloc(1, sizeof(shader_node_t));
+ shader_node = calloc(1, sizeof(shader_node_t) + n_shader_confs * sizeof(shader_node->shaders[0]));
fatal_if(!shader_node, "Unable to allocate shader_node");
- shader_node->shader = shader_ref(shader);
- shader_node->uniforms_func = uniforms_func;
- shader_node->uniforms_ctxt = uniforms_ctxt;
- shader_node->transform = transform;
+ shader_node->index_ptr = index_ptr;
+ shader_node->n_shaders = n_shader_confs;
+ for (unsigned i = 0; i < n_shader_confs; i++) {
+ shader_node->shaders[i].shader = shader_ref(shader_confs[i].shader);
+ shader_node->shaders[i].uniforms_func = shader_confs[i].uniforms_func;
+ shader_node->shaders[i].uniforms_ctxt = shader_confs[i].uniforms_ctxt;
+ shader_node->shaders[i].transform = shader_confs[i].transform;
+ }
stage = stage_new(conf, &shader_node_ops, shader_node);
fatal_if(!stage, "Unable to create stage \"%s\"", conf->name);
@@ -153,23 +175,49 @@ stage_t * shader_node_new_shader(const stage_conf_t *conf, shader_t *shader, con
}
-/* return a new shader stage node from source */
-stage_t * shader_node_new_src(const stage_conf_t *conf, const char *vs_src, const char *fs_src, const m4f_t *transform, shader_node_uniforms_func_t *uniforms_func, void *uniforms_ctxt, unsigned n_uniforms, const char **uniforms)
+/* return a new shader stage node from an already compiled and linked shader program */
+stage_t * shader_node_new_shader(const stage_conf_t *conf, const shader_conf_t *shader_conf)
+{
+ return shader_node_new_shaderv(conf, 1, shader_conf, NULL);
+}
+
+
+/* return a new shader stage node from source vector, see shader_node_new_shaderv() comment */
+stage_t * shader_node_new_srcv(const stage_conf_t *conf, unsigned n_shader_src_confs, const shader_src_conf_t *shader_src_confs, unsigned *index_ptr)
{
+ shader_conf_t shader_confs[n_shader_src_confs];
stage_t *stage;
- shader_t *shader;
- assert(vs_src);
- assert(fs_src);
+ assert(n_shader_src_confs > 0);
+ assert(shader_src_confs);
+
+ for (unsigned i = 0; i < n_shader_src_confs; i++) {
+ shader_confs[i].shader = shader_pair_new(
+ shader_src_confs[i].vs_src,
+ shader_src_confs[i].fs_src,
+ shader_src_confs[i].n_uniforms,
+ shader_src_confs[i].uniforms,
+ 2,
+ (const char *[]) {
+ "vertex",
+ "texcoord",
+ }
+ );
+ shader_confs[i].transform = shader_src_confs[i].transform;
+ shader_confs[i].uniforms_func = shader_src_confs[i].uniforms_func;
+ shader_confs[i].uniforms_ctxt = shader_src_confs[i].uniforms_ctxt;
+ }
- shader = shader_pair_new(vs_src, fs_src, n_uniforms, uniforms,
- 2,
- (const char *[]) {
- "vertex",
- "texcoord",
- });
- stage = shader_node_new_shader(conf, shader, transform, uniforms_func, uniforms_ctxt);
- shader_free(shader);
+ stage = shader_node_new_shaderv(conf, n_shader_src_confs, shader_confs, index_ptr);
+ for (unsigned i = 0; i < n_shader_src_confs; i++)
+ shader_free(shader_confs[i].shader);
return stage;
}
+
+
+/* return a new shader stage node from source */
+stage_t * shader_node_new_src(const stage_conf_t *conf, const shader_src_conf_t *shader_src_conf)
+{
+ return shader_node_new_srcv(conf, 1, shader_src_conf, NULL);
+}
diff --git a/src/shader-node.h b/src/shader-node.h
index 34fccc2..7c93c81 100644
--- a/src/shader-node.h
+++ b/src/shader-node.h
@@ -24,7 +24,26 @@ typedef struct m4f_t m4f_t;
typedef void (shader_node_uniforms_func_t)(void *uniforms_ctxt, void *render_ctxt, unsigned n_uniforms, const int *uniforms, const m4f_t *transform, float alpha);
-stage_t * shader_node_new_shader(const stage_conf_t *conf, shader_t *shader, const m4f_t *transform, shader_node_uniforms_func_t *uniforms_func, void *uniforms_ctxt);
-stage_t * shader_node_new_src(const stage_conf_t *conf, const char *vs_src, const char *fs_src, const m4f_t *transform, shader_node_uniforms_func_t *uniforms_func, void *uniforms_ctxt, unsigned n_uniforms, const char **uniforms);
+typedef struct shader_conf_t {
+ shader_t *shader;
+ const m4f_t *transform;
+ shader_node_uniforms_func_t *uniforms_func;
+ void *uniforms_ctxt;
+} shader_conf_t;
+
+typedef struct shader_src_conf_t {
+ const char *vs_src, *fs_src;
+ const m4f_t *transform;
+ shader_node_uniforms_func_t *uniforms_func;
+ void *uniforms_ctxt;
+ unsigned n_uniforms;
+ const char **uniforms;
+} shader_src_conf_t;
+
+stage_t * shader_node_new_shaderv(const stage_conf_t *conf, unsigned n_shader_confs, const shader_conf_t *shader_confs, unsigned *index_ptr);
+stage_t * shader_node_new_shader(const stage_conf_t *conf, const shader_conf_t *shader_conf);
+
+stage_t * shader_node_new_srcv(const stage_conf_t *conf, unsigned n_shader_src_confs, const shader_src_conf_t *shader_src_conf, unsigned *index_ptr);
+stage_t * shader_node_new_src(const stage_conf_t *conf, const shader_src_conf_t *shader_src_conf);
#endif
© All Rights Reserved