graphics

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 3a85c12f0accf7d80ada058144ed23bd5db6f2ff
parent cd82c62716831100266a005836323ce0838b52b8
Author: Brian Swetland <swetland@frotz.net>
Date:   Wed,  4 Sep 2013 03:58:56 -0700

shaders/effects: allow #defines to be passed in at compilation

- Effects may be invoked by effectname+FOO+BAR which will cause
  #define FOO
  #define BAR
  to be inserted into the shader source after the common and global parts
- *Shader::load() takes a second defines paramter to make this happen

Diffstat:
Mcommon/Effect.cc | 46++++++++++++++++++++++++++++++++++++++--------
Mcommon/core.h | 6+++---
Mcommon/shaders.cc | 34++++++++++++++++++----------------
3 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/common/Effect.cc b/common/Effect.cc @@ -15,6 +15,7 @@ #include <string> +#include "util.h" #include "Effect.h" void Effect::apply(void) { @@ -22,14 +23,43 @@ void Effect::apply(void) { } int Effect::init(const char *name) { - std::string vname(name); - std::string fname(name); - vname.append(".vertex"); - fname.append(".fragment"); - if (vs.load(vname.c_str())) - return -1; - if (ps.load(fname.c_str())) - return -1; + const char *x = strchr(name, '+'); + if (x) { + std::string vname(name, x - name); + std::string fname(name, x - name); + vname.append(".vertex"); + fname.append(".fragment"); + x++; + std::string defines; + while (*x) { + const char *n = x; + x = strchr(n, '+'); + defines.append("#define "); + if (x) { + defines.append(n, x-n); + defines.append("\n"); + x++; + } else { + defines.append(n); + defines.append("\n"); + break; + } + } + printx("EXTRAS---\n%s",defines.c_str()); + if (vs.load(vname.c_str(), defines.c_str())) + return -1; + if (ps.load(fname.c_str(), defines.c_str())) + return -1; + } else { + std::string vname(name); + std::string fname(name); + vname.append(".vertex"); + fname.append(".fragment"); + if (vs.load(vname.c_str())) + return -1; + if (ps.load(fname.c_str())) + return -1; + } if (pgm.link(&vs, &ps)) return -1; return 0; diff --git a/common/core.h b/common/core.h @@ -55,21 +55,21 @@ struct VertexShader { unsigned id; VertexShader() : id(0) {}; ~VertexShader() { if (id) { glDeleteShader(id); } }; - int load(const char *fn); + int load(const char *fn, const char *defines = ""); }; struct PixelShader { unsigned id; PixelShader() : id(0) {}; ~PixelShader() { if (id) glDeleteShader(id); }; - int load(const char *fn); + int load(const char *fn, const char *defines = ""); }; struct GeometryShader { unsigned id; GeometryShader() : id(0) {}; ~GeometryShader() { if (id) glDeleteShader(id); }; - int load(const char *fn); + int load(const char *fn, const char *defines = ""); }; struct Program { diff --git a/common/shaders.cc b/common/shaders.cc @@ -252,10 +252,10 @@ static struct source *load_shader_source(const char *fn) { return src; } -static int compile_shader_source(source *src, const char *name, unsigned id) { +static int compile_shader_source(source *src, const char *name, const char *defines, unsigned id) { char misc[128]; - const char *data[4]; - int size[4]; + const char *data[5]; + int size[5]; section *part; for (part = src->sections; part; part = part->next) { @@ -267,18 +267,20 @@ static int compile_shader_source(source *src, const char *name, unsigned id) { size[0] = src->common.len; data[1] = shader_globals; size[1] = strlen(shader_globals); - data[2] = misc; - size[2] = strlen(misc); - data[3] = part->str; - size[3] = part->len; - glShaderSource(id, 4, data, size); + data[2] = defines; + size[2] = strlen(defines); + data[3] = misc; + size[3] = strlen(misc); + data[4] = part->str; + size[4] = part->len; + glShaderSource(id, 5, data, size); return 0; } } return error("cannot find section '%s'", name); } -static int _load_shader(unsigned *out, const char *fn, unsigned type) { +static int _load_shader(unsigned *out, const char *fn, const char *defines, unsigned type) { unsigned id; source *src; const char *x; @@ -294,7 +296,7 @@ static int _load_shader(unsigned *out, const char *fn, unsigned type) { return error("cannot load shader source '%s'", fn); id = glCreateShader(type); - if (compile_shader_source(src, x, id)) { + if (compile_shader_source(src, x, defines, id)) { glDeleteShader(id); return -1; } @@ -311,15 +313,15 @@ static int _load_shader(unsigned *out, const char *fn, unsigned type) { return 0; } -int VertexShader::load(const char *fn) { - return _load_shader(&id, fn, GL_VERTEX_SHADER); +int VertexShader::load(const char *fn, const char *defines) { + return _load_shader(&id, fn, defines, GL_VERTEX_SHADER); } -int PixelShader::load(const char *fn) { - return _load_shader(&id, fn, GL_FRAGMENT_SHADER); +int PixelShader::load(const char *fn, const char *defines) { + return _load_shader(&id, fn, defines, GL_FRAGMENT_SHADER); } -int GeometryShader::load(const char *fn) { - return _load_shader(&id, fn, GL_GEOMETRY_SHADER); +int GeometryShader::load(const char *fn, const char *defines) { + return _load_shader(&id, fn, defines, GL_GEOMETRY_SHADER); }