Add --pipe flag

This commit is contained in:
Jarcode
2019-03-14 21:39:50 -07:00
parent 04a4da4993
commit aa56b89ddf
7 changed files with 339 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
SHELL := /bin/bash
.SHELLFLAGS="-O extglob -c"
.SHELLFLAGS = -O extglob -c
src = $(wildcard *.c)
obj = $(src:.c=.o)

102
glava.c
View File

@@ -182,7 +182,12 @@ static const char* help_str =
" appropriate backend will be used for the underlying windowing\n"
" system.\n"
"-a, --audio=BACKEND specifies an audio input backend to use.\n"
"-i, --stdin[=FORMAT] specifies a format for input to be read from stdin. The input\n"
"-p, --pipe[=FORMAT] binds a value to be read from stdin. The input my be read using\n"
" `@name` or `@name:default` syntax within shader sources.\n"
" A stream of inputs (each overriding the previous) must be\n"
" assigned with the `name = value` syntax and separated by\n"
" newline (\'\\n\') characters.\n"
"-i, --stdin[=OLDFORMAT] specifies a format for input to be read from stdin. The input\n"
" may be read from the STDIN macro from within shader sources.\n"
" A stream of inputs (each overriding the previous) must be\n"
" separated by newline (\'\\n\') characters.\n"
@@ -200,12 +205,12 @@ static const char* help_str =
"The BACKEND argument may be any of the following strings (for this particular build):\n"
"%s"
"\n"
"The FORMAT argument must be a valid GLSL type. If `--stdin` is used without an argument,\n"
"The OLDFORMAT argument must be a valid GLSL type. If `--stdin` is used without an argument,\n"
"the default type is `vec4` (type used for RGBA colors)\n"
"\n"
GLAVA_VERSION_STRING "\n";
static const char* opt_str = "dhvVe:Cm:b:r:a:i::";
static const char* opt_str = "dhvVe:Cm:b:r:a:i::p::";
static struct option p_opts[] = {
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, 'v'},
@@ -216,6 +221,7 @@ static struct option p_opts[] = {
{"force-mod", required_argument, 0, 'm'},
{"copy-config", no_argument, 0, 'C'},
{"backend", required_argument, 0, 'b'},
{"pipe", optional_argument, 0, 'p'},
{"stdin", optional_argument, 0, 'i'},
{"version", no_argument, 0, 'V'},
#ifdef GLAVA_DEBUG
@@ -233,10 +239,11 @@ static void handle_term(int signum) {
}
}
static inline void append_buf(char** buf, size_t* sz_store, char* str) {
buf = realloc(buf, ++(*sz_store) * sizeof(char*));
buf[*sz_store - 1] = str;
}
#define append_buf(buf, sz_store, ...) \
({ \
buf = realloc(buf, ++(*sz_store) * sizeof(*buf)); \
buf[*sz_store - 1] = __VA_ARGS__; \
})
int main(int argc, char** argv) {
@@ -251,8 +258,10 @@ int main(int argc, char** argv) {
const char* system_shader_paths[] = { user_path, install_path, NULL };
int stdin_type = STDIN_TYPE_NONE;
char** requests = malloc(1);
size_t requests_sz = 0;
char** requests = malloc(1);
size_t requests_sz = 0;
struct rd_bind* binds = malloc(1);
size_t binds_sz = 0;
bool verbose = false, copy_mode = false, desktop = false;
@@ -283,21 +292,77 @@ int main(int argc, char** argv) {
exit(EXIT_SUCCESS);
break;
}
case 'i': {
case 'p': {
if (stdin_type != STDIN_TYPE_NONE) goto conflict_error;
char* parsed_name = NULL;
const char* parsed_type = NULL;
size_t in_sz = strlen(optarg);
int sep = -1;
for (size_t t = 0; t < in_sz; ++t) {
switch (optarg[t]) {
case ' ': optarg[t] = '\0'; goto after;
case ':': sep = (int) t; break;
}
}
after:
if (sep >= 0) {
parsed_type = strdup(optarg + sep + 1);
optarg[sep] = '\0';
}
parsed_name = optarg;
for (size_t t = 0; t < binds_sz; ++t) {
if (!strcmp(binds[t].name, parsed_name)) {
fprintf(stderr, "Error: attempted to re-bind pipe argument: \"%s\"\n", parsed_name);
exit(EXIT_FAILURE);
}
}
int type = -1;
if (parsed_type == NULL || strlen(parsed_type) == 0) {
type = STDIN_TYPE_VEC4;
parsed_type = bind_types[STDIN_TYPE_VEC4].n;
} else {
for (size_t t = 0 ; bind_types[t].n != NULL; ++t) {
if (!strcmp(bind_types[t].n, parsed_type)) {
type = bind_types[t].i;
parsed_type = bind_types[t].n;
break;
}
}
}
if (type == -1) {
fprintf(stderr, "Error: Unsupported `--pipe` GLSL type: \"%s\"\n", parsed_type);
exit(EXIT_FAILURE);
}
struct rd_bind bd = {
.name = parsed_name,
.type = type,
.stype = parsed_type
};
append_buf(binds, &binds_sz, bd);
break;
}
case 'i': { /* TODO: remove */
if (binds_sz > 0) goto conflict_error;
stdin_type = -1;
for (size_t t = 0 ; stdin_types[t].n != NULL; ++t) {
if (optarg == NULL) {
stdin_type = STDIN_TYPE_VEC4;
} else if (!strcmp(stdin_types[t].n, optarg)) {
stdin_type = stdin_types[t].i;
break;
if (optarg == NULL) {
stdin_type = STDIN_TYPE_VEC4;
} else {
for (size_t t = 0 ; bind_types[t].n != NULL; ++t) {
if (!strcmp(bind_types[t].n, optarg)) {
stdin_type = bind_types[t].i;
break;
}
}
}
if (stdin_type == -1) {
fprintf(stderr, "Unsupported `--stdin` GLSL type: \"%s\"\n", optarg);
fprintf(stderr, "Error: Unsupported `--stdin` GLSL type: \"%s\"\n", optarg);
exit(EXIT_FAILURE);
}
break;
}
conflict_error:
fprintf(stderr, "Error: cannot use `--pipe` and `--stdin` together\n");
exit(EXIT_FAILURE);
#ifdef GLAVA_DEBUG
case 'T': {
entry = "test_rc.glsl";
@@ -322,9 +387,10 @@ int main(int argc, char** argv) {
/* Null terminate array arguments */
append_buf(requests, &requests_sz, NULL);
append_buf(binds, &binds_sz, (struct rd_bind) { .name = NULL });
rd = rd_new(system_shader_paths, entry, (const char**) requests,
backend, stdin_type, desktop, verbose);
backend, binds, stdin_type, desktop, verbose);
struct sigaction action = { .sa_handler = handle_term };
sigaction(SIGTERM, &action, NULL);

View File

@@ -13,6 +13,7 @@
#include <fcntl.h>
#include <unistd.h>
#include "render.h"
#include "glsl_ext.h"
#define LINE_START 0
@@ -22,6 +23,7 @@
#define INCLUDE 4
#define COLOR 5
#define DEFINE 6
#define BIND 7
struct sbuf {
char* buf;
@@ -65,12 +67,16 @@ static void se_append(struct sbuf* sbuf, size_t elen, const char* fmt, ...) {
}
#define parse_error(line, f, fmt, ...) \
fprintf(stderr, "[%s:%d] " fmt "\n", f, (int) line, __VA_ARGS__); \
abort()
do { \
fprintf(stderr, "[%s:%d] " fmt "\n", f, (int) line, __VA_ARGS__); \
abort(); \
} while (0)
#define parse_error_s(line, f, s) \
fprintf(stderr, "[%s:%d] " s "\n", f, (int) line); \
abort()
#define parse_error_s(line, f, s) \
do { \
fprintf(stderr, "[%s:%d] " s "\n", f, (int) line); \
abort(); \
} while (0)
struct schar {
char* buf;
@@ -196,7 +202,8 @@ static struct schar directive(struct glsl_ext* ext, char** args,
.cd = ext->cd,
.cfd = ext->cfd,
.dd = ext->dd,
.handlers = ext->handlers
.handlers = ext->handlers,
.binds = ext->binds
};
/* recursively process */
@@ -306,10 +313,12 @@ void ext_process(struct glsl_ext* ext, const char* f) {
size_t t;
char at;
int state = LINE_START;
size_t macro_start_idx, arg_start_idx, cbuf_idx;
size_t macro_start_idx, arg_start_idx, cbuf_idx, bbuf_idx;
size_t line = 1;
bool quoted = false, arg_start;
bool quoted = false, arg_start, b_sep = false, b_spc = false;
int b_br = 0;
char cbuf[9];
char bbuf[128];
char** args = malloc(sizeof(char*));
size_t args_sz = 0;
@@ -385,6 +394,17 @@ void ext_process(struct glsl_ext* ext, const char* f) {
continue;
} else goto normal_char;
}
case '@': {
/* handle bind syntax */
if (!comment && !string && ext->binds != NULL) {
state = BIND;
b_sep = false;
b_spc = false;
b_br = 0;
bbuf_idx = 0;
continue;
} else goto normal_char;
}
case '\n':
if (comment && comment_line) {
comment = false;
@@ -425,6 +445,83 @@ void ext_process(struct glsl_ext* ext, const char* f) {
continue;
else goto copy; /* copy character if it ended the sequence */
}
}
case BIND: { /* parse bind syntax (@name:default -> __IN_name | default)*/
switch (at) {
default:
if (b_br > 0) goto handle_bind; /* store characters in braces */
else goto emit_bind; /* emit on unexpected char outside braces */
case '(':
if (b_sep) {
++b_br; goto handle_bind; /* inc. brace level */
} else goto emit_bind; /* emit if wrong context: `@sym(`, `@(` (no ':') */
case ')':
if (b_br <= 0 || !b_sep) goto emit_bind; /* start emitting on unexpected ')': `@sym:v)`, `@s)` */
else {
--b_br;
if (b_br == 0) goto emit_bind; /* emit after reading brace contents */
else goto handle_bind; /* continue reading if nested */
}
case ' ': if (b_br <= 0) b_spc = true; /* flag a non-braced space */
case '#':
if (b_sep) goto handle_bind; /* handle color syntax only for defaults */
else goto emit_bind; /* if '#' is encountered, skip to emit */
case ':': b_sep = true;
handle_bind: /* use character for binding syntax */
case 'a' ... 'z':
case 'A' ... 'Z':
case '0' ... '9': {
if (b_spc && b_br <= 0)
goto emit_bind; /* skip non-braced characters after space: `@sym:vec4 c` */
bbuf[bbuf_idx] = at;
++bbuf_idx;
if (bbuf_idx >= sizeof(bbuf) - 1)
goto emit_bind; /* start emitting if buffer was filled */
else continue;
}
emit_bind: /* end binding syntax with current char */
case '\n':
case '\0': {
const char* parsed_name = NULL;
const char* parsed_default = NULL;
bbuf[bbuf_idx] = '\0'; /* null terminate */
int sep = -1;
for (size_t p = 0; p < bbuf_idx; ++p)
if (bbuf[p] == ':') sep = p;
if (sep >= 0) {
parsed_default = strdup(bbuf + sep + 1);
bbuf[sep] = '\0';
}
parsed_name = bbuf;
bool m = false;
for (struct rd_bind* bd = ext->binds; bd->name != NULL; ++bd) {
if (!strcmp(parsed_name, bd->name)) {
se_append(&sbuf, 128, " __IN_%s ", parsed_name);
m = true;
break;
}
}
if (!m) {
if (parsed_default) {
if (parsed_default[0] == '#') {
++parsed_default;
float r = 0.0F, g = 0.0F, b = 0.0F, a = 1.0F;
if (ext_parse_color(parsed_default, 2, (float*[]) { &r, &g, &b, &a })) {
se_append(&sbuf, 64, " vec4(%.6f, %.6f, %.6f, %.6f) ", r, g, b, a);
} else {
parse_error(line, f, "Invalid color format '#%s' while "
"parsing GLSL color syntax extension", parsed_default);
}
} else se_append(&sbuf, 260, " %s ", parsed_default);
} else parse_error(line, f, "Unexpected `--pipe` binding name '@%s' while parsing GLSL."
" Try assigning a default or binding the value.", parsed_name);
}
state = at == '\n' ? LINE_START : GLSL;
if (bbuf_idx >= sizeof(bbuf) - 1)
continue;
else goto copy; /* copy character if it ended the sequence */
}
}
}
/* emit contents from start of macro to current index and resume regular parsing*/
#define skip_macro() \
@@ -444,7 +541,8 @@ void ext_process(struct glsl_ext* ext, const char* f) {
(!strncmp("#" lower, &ext->source[macro_start_idx], t - macro_start_idx) \
|| !strncmp("#" upper, &ext->source[macro_start_idx], t - macro_start_idx))
#define DIRECTIVE_CASE(lower, upper) \
do { if (state == MACRO && DIRECTIVE_CMP(#lower, #upper)) { state = upper; goto prepare_arg_parse; } } while (0)
({ if (state == MACRO && DIRECTIVE_CMP(#lower, #upper)) \
{ state = upper; goto prepare_arg_parse; } })
DIRECTIVE_CASE(request, REQUEST);
DIRECTIVE_CASE(include, INCLUDE);

View File

@@ -24,11 +24,12 @@ struct glsl_ext {
char* processed; /* OUT: null terminated processed source */
size_t p_len; /* OUT: length of processed buffer, excluding null char */
const char* source; /* IN: raw data passed via ext_process */
size_t source_len; /* IN: raw source len */
size_t source_len; /* IN: raw source len */
const char* cd; /* IN: current directory */
const char* cfd; /* IN: config directory, if NULL it is assumed to cd */
const char* dd; /* IN: default directory */
void** destruct; /* internal */
const char* dd; /* IN: default directory */
struct rd_bind* binds; /* OPT IN: --pipe binds */
void** destruct; /* internal */
size_t destruct_sz; /* internal */
/* IN: NULL (where the last element's 'name' member is NULL) terminated

161
render.c
View File

@@ -20,7 +20,7 @@
#include "xwin.h"
#include "glsl_ext.h"
typeof(stdin_types) stdin_types = {
typeof(bind_types) bind_types = {
[STDIN_TYPE_NONE] = { .n = "NONE", .i = STDIN_TYPE_NONE },
[STDIN_TYPE_INT] = { .n = "int", .i = STDIN_TYPE_INT },
[STDIN_TYPE_FLOAT] = { .n = "float", .i = STDIN_TYPE_FLOAT },
@@ -106,6 +106,7 @@ struct gl_sfbo {
bool indirect, nativeonly;
const char* name;
struct gl_bind* binds;
GLuint* pipe_uniforms;
size_t binds_sz;
};
@@ -139,6 +140,7 @@ struct gl_data {
float* interpolate_buf[6];
int geometry[4];
int stdin_type;
struct rd_bind* binds;
#ifdef GLAVA_DEBUG
struct {
float r, g, b, a;
@@ -205,6 +207,19 @@ static GLuint shaderload(const char* rpath,
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &max_uniforms);
const GLchar* map = raw ? shader : mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
char* bind_header = malloc(1);
bind_header[0] = '\0';
size_t bh_idx = 0;
const char* fmt = "uniform %s __IN_%s;\n";
for (struct rd_bind* bd = gl->binds; bd->name != NULL; ++bd) {
size_t inc = snprintf(NULL, 0, fmt, bd->stype, bd->name);
bind_header = realloc(bind_header, bh_idx + inc + 1);
snprintf(bind_header + bh_idx, inc + 1, fmt, bd->stype, bd->name);
bh_idx += inc;
}
static const GLchar* header_fmt =
"#version %d\n"
@@ -216,7 +231,8 @@ static GLuint shaderload(const char* rpath,
"#define USE_STDIN %d\n"
"#if USE_STDIN == 1\n"
"uniform %s STDIN;\n"
"#endif\n";
"#endif\n"
"%s";
struct glsl_ext ext = {
.source = raw ? NULL : map,
@@ -226,7 +242,8 @@ static GLuint shaderload(const char* rpath,
.dd = defaults,
.handlers = handlers,
.processed = (char*) (raw ? shader : NULL),
.p_len = raw ? s_len : 0
.p_len = raw ? s_len : 0,
.binds = gl->binds
};
/* If this is raw input, skip processing */
@@ -237,7 +254,8 @@ static GLuint shaderload(const char* rpath,
int written = snprintf(buf, blen, header_fmt, (int) shader_version, (int) max_uniforms,
gl->smooth_pass ? 1 : 0, (double) gl->smooth_factor,
1, gl->premultiply_alpha ? 1 : 0,
gl->stdin_type != STDIN_TYPE_NONE, stdin_types[gl->stdin_type].n);
gl->stdin_type != STDIN_TYPE_NONE, bind_types[gl->stdin_type].n,
bind_header);
if (written < 0) {
fprintf(stderr, "snprintf() encoding error while prepending header to shader '%s'\n", path);
return 0;
@@ -753,10 +771,10 @@ static struct gl_bind_src* lookup_bind_src(const char* str) {
return NULL;
}
struct renderer* rd_new(const char** paths, const char* entry,
const char** requests, const char* force_backend,
int stdin_type, bool auto_desktop,
bool verbose) {
struct renderer* rd_new(const char** paths, const char* entry,
const char** requests, const char* force_backend,
struct rd_bind* bindings, int stdin_type,
bool auto_desktop, bool verbose) {
xwin_wait_for_wm();
@@ -806,6 +824,7 @@ struct renderer* rd_new(const char** paths, const char* entry,
.clear_color = { 0.0F, 0.0F, 0.0F, 0.0F },
.clickthrough = false,
.stdin_type = stdin_type,
.binds = bindings,
#ifdef GLAVA_DEBUG
.test_eval_color = { 0.0F, 0.0F, 0.0F, 0.0F },
.debug_verbose = verbose
@@ -1337,6 +1356,11 @@ struct renderer* rd_new(const char** paths, const char* entry,
} while (found);
stages = malloc(sizeof(struct gl_sfbo) * count);
size_t pipe_binds_len = 0;
for (struct rd_bind* bd = gl->binds; bd->name != NULL; ++bd)
++pipe_binds_len;
idx = 1;
do {
@@ -1351,12 +1375,13 @@ struct renderer* rd_new(const char** paths, const char* entry,
struct gl_sfbo* s = &stages[idx - 1];
*s = (struct gl_sfbo) {
.name = strdup(d->d_name),
.shader = 0,
.indirect = false,
.nativeonly = false,
.binds = malloc(1),
.binds_sz = 0
.name = strdup(d->d_name),
.shader = 0,
.indirect = false,
.nativeonly = false,
.binds = malloc(1),
.binds_sz = 0,
.pipe_uniforms = malloc(sizeof(GLuint) * pipe_binds_len)
};
current = s;
@@ -1387,6 +1412,17 @@ struct renderer* rd_new(const char** paths, const char* entry,
if (gl->stdin_type != STDIN_TYPE_NONE) {
s->stdin_uniform = glGetUniformLocation(id, "STDIN");
}
size_t u = 0;
for (struct rd_bind* bd = gl->binds; bd->name != NULL; ++bd) {
char buf[128];
if (snprintf(buf, 128, "__IN_%s", bd->name) > 0) {
s->pipe_uniforms[u] = glGetUniformLocation(id, buf);
} else {
fprintf(stderr, "failed to format binding: \"%s\"\n", bd->name);
exit(EXIT_FAILURE);
}
++u;
}
glBindFragDataLocation(id, 1, "fragment");
glUseProgram(0);
}
@@ -1575,7 +1611,15 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
glViewport(0, 0, ww, wh);
static bool stdin_uniform_ready = false;
static char stdin_buf_store[128] = {};
static char* stdin_buf = stdin_buf_store;
static int stdin_select = STDIN_TYPE_NONE;
static size_t stdin_idx = 0;
static bool stdin_uniform_ready = false;
static size_t stdin_bind_off = 0;
static char* stdin_name = NULL;
static size_t stdin_name_len = 0;
static bool pipe_eof = false;
static union {
bool b;
int i;
@@ -1583,9 +1627,7 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
} stdin_parsed;
/* Parse stdin data, if nessecary */
if (gl->stdin_type != STDIN_TYPE_NONE) {
static char stdin_buf[64] = {};
static size_t stdin_idx = 0;
if (!pipe_eof && (gl->stdin_type != STDIN_TYPE_NONE || gl->binds[0].name != NULL)) {
int c, n, p;
setvbuf(stdin, NULL, _IOLBF, 64);
@@ -1597,13 +1639,65 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
for (p = 0; n > 0; ++p) {
c = getchar();
if (stdin_idx >= (sizeof(stdin_buf) / sizeof(*stdin_buf)) - 1)
if (stdin_idx >= (sizeof(stdin_buf_store) / sizeof(*stdin_buf_store)) - 1)
break;
if (c != EOF && c != '\n')
stdin_buf[stdin_idx++] = c;
else {
stdin_buf[stdin_idx] = '\0';
switch (gl->stdin_type) {
stdin_select = gl->stdin_type;
if (gl->stdin_type == STDIN_TYPE_NONE) {
bool v = false;
bool valid = false;
while (*stdin_buf == ' ') ++stdin_buf; /* advance to first char */
for (int h = 0; stdin_buf[h] != '\0'; ++h) {
int l;
if (!v && stdin_buf[h] == '=') {
for (l = h - 1; l >= 0; --l)
if (stdin_buf[l] != ' ')
break;
stdin_name = stdin_buf;
stdin_name_len = l + 1;
v = true;
} else if (v && stdin_buf[h] != ' ') {
stdin_buf += h;
for (l = strlen(stdin_buf) - 1; stdin_buf[l] == ' '; --l);
stdin_buf[l + 1] = '\0';
valid = true;
break;
}
}
if (!valid && !v) {
/* no assignment, just a default value */
stdin_name = "";
stdin_name_len = 0;
valid = true;
}
if (!valid) {
fprintf(stderr, "Bad assignment format for \"%s\"\n", stdin_buf);
goto reset;
}
bool bound = false;
size_t u = 0;
for (struct rd_bind* bd = gl->binds; bd->name != NULL; ++bd) {
if (!strncmp(bd->name, stdin_name, stdin_name_len)) {
bound = true;
stdin_bind_off = u;
stdin_select = bd->type;
break;
}
++u;
}
if (!bound) {
fprintf(stderr, "Variable name not bound: \"%.*s\"\n",
(int) stdin_name_len, stdin_name);
stdin_select = STDIN_TYPE_NONE;
}
}
switch (stdin_select) {
case STDIN_TYPE_BOOL:
if (!strcmp("true", stdin_buf) ||
!strcmp("TRUE", stdin_buf) ||
@@ -1617,6 +1711,8 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
!strcmp("0", stdin_buf)) {
stdin_parsed.b = false;
stdin_uniform_ready = true;
} else {
fprintf(stderr, "Bad format for boolean: \"%s\"\n", stdin_buf);
}
break;
case STDIN_TYPE_INT:
@@ -1658,13 +1754,16 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
&stdin_parsed.f[2], &stdin_parsed.f[3]))
stdin_uniform_ready = true;
break;
default: break;
}
reset:
stdin_buf = stdin_buf_store;
stdin_buf[0] = '\0';
stdin_idx = 0;
stdin_idx = 0;
break;
if (c == EOF) {
gl->stdin_type = STDIN_TYPE_NONE;
pipe_eof = true;
break;
}
};
@@ -1739,29 +1838,31 @@ bool rd_update(struct renderer* r, float* lb, float* rb, size_t bsz, bool modifi
/* Select the program associated with this pass */
glUseProgram(current->shader);
/* Pass STDIN unfirom if one has been parsed */
/* Pass uniform if one has been parsed */
if (stdin_uniform_ready) {
switch (gl->stdin_type) {
GLuint handle = gl->stdin_type != STDIN_TYPE_NONE ? current->stdin_uniform :
current->pipe_uniforms[stdin_bind_off];
switch (stdin_select) {
case STDIN_TYPE_BOOL:
glUniform1i(current->stdin_uniform, (int) stdin_parsed.b);
glUniform1i(handle, (int) stdin_parsed.b);
break;
case STDIN_TYPE_INT:
glUniform1i(current->stdin_uniform, stdin_parsed.i);
glUniform1i(handle, stdin_parsed.i);
break;
case STDIN_TYPE_FLOAT:
glUniform1f(current->stdin_uniform, stdin_parsed.f[0]);
glUniform1f(handle, stdin_parsed.f[0]);
break;
case STDIN_TYPE_VEC2:
glUniform2f(current->stdin_uniform,
glUniform2f(handle,
stdin_parsed.f[0], stdin_parsed.f[1]);
break;
case STDIN_TYPE_VEC3:
glUniform3f(current->stdin_uniform,
glUniform3f(handle,
stdin_parsed.f[0], stdin_parsed.f[1],
stdin_parsed.f[2]);
break;
case STDIN_TYPE_VEC4:
glUniform4f(current->stdin_uniform,
glUniform4f(handle,
stdin_parsed.f[0], stdin_parsed.f[1],
stdin_parsed.f[2], stdin_parsed.f[3]);
break;

View File

@@ -5,7 +5,7 @@
extern const struct {
const char* n;
int i;
} stdin_types[];
} bind_types[];
#define STDIN_TYPE_NONE 0
#define STDIN_TYPE_INT 1
@@ -24,16 +24,22 @@ typedef struct renderer {
struct gl_data* gl;
} renderer;
struct rd_bind {
const char* name;
const char* stype;
int type;
};
#ifdef GLAVA_DEBUG
void rd_enable_test_mode(void);
bool rd_get_test_mode (void);
bool rd_test_evaluate (struct renderer*);
#endif
struct renderer* rd_new (const char** paths, const char* entry,
const char** requests, const char* force_backend,
int stdin_type, bool auto_desktop,
bool verbose);
struct renderer* rd_new (const char** paths, const char* entry,
const char** requests, const char* force_backend,
struct rd_bind* bindings, int stdin_type,
bool auto_desktop, bool verbose);
bool rd_update (struct renderer*, float* lb, float* rb,
size_t bsz, bool modified);
void rd_destroy (struct renderer*);

View File

@@ -13,7 +13,7 @@
#define AMPLIFY 300
/* Whether the current settings use the alpha channel;
enabling this is required for alpha to function
correctly on X11 with `"native"` transparency. */
correctly on X11 with `"native"` transparency */
#define USE_ALPHA 0
/* How strong the gradient changes */
#define GRADIENT_POWER 60