commit a5db2ccfe67eafd2190706e6017c57b22b05716e
parent e9877da533f6161b1d7f679fc70012ceb329431a
Author: Brian Swetland <swetland@frotz.net>
Date: Sun, 1 Sep 2013 02:25:46 -0700
shaders: auto-bind uniform blocks and samplers
Uniform blocks named "block[0-3]" are bound to bind points 0..3
Sampler uniforms named "sampler[0-3]" are bound to texture units 0..3
Diffstat:
2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/common/app.h b/common/app.h
@@ -83,9 +83,11 @@ struct GeometryShader {
struct Program {
unsigned id;
- Program() : id(0) {};
+ unsigned bound;
+ Program() : id(0), bound(0) {};
~Program() { if (id) { glDeleteProgram(id); } };
- void use(void) { glUseProgram(id); }
+ void use(void) { glUseProgram(id); if (!bound) bind(); }
+ void bind(void);
int link(VertexShader *vs, PixelShader *ps);
int link(VertexShader *vs, GeometryShader *gs, PixelShader *ps);
int load(const char *vsfn, const char *psfn);
diff --git a/common/shaders.cc b/common/shaders.cc
@@ -53,6 +53,13 @@ int Program::link(VertexShader *vs, PixelShader *ps) {
return link(vs, NULL, ps);
}
+static const char *_blocknames[] = {
+ "block0", "block1", "block2", "block3",
+};
+static const char *_samplernames[] = {
+ "sampler0", "sampler1", "sampler2", "sampler3",
+};
+
int Program::link(VertexShader *vs, GeometryShader *gs, PixelShader *ps) {
unsigned n;
int r;
@@ -71,7 +78,29 @@ int Program::link(VertexShader *vs, GeometryShader *gs, PixelShader *ps) {
if (id)
glDeleteProgram(id);
id = n;
- return 0;
+
+ /* bind uniform block indices to bindpoints based on their name */
+ for (n = 0; n < sizeof(_blocknames) / sizeof(_blocknames[0]); n++) {
+ r = glGetUniformBlockIndex(id, _blocknames[n]);
+ if (r != GL_INVALID_INDEX) {
+ fprintf(stderr,"found %s @ %d\n", _blocknames[n], r);
+ glUniformBlockBinding(id, r, n);
+ }
+ }
+}
+
+/* defer final link steps until the first time glUseProgram() is called, */
+void Program::bind() {
+ unsigned n;
+ int r;
+ for (n = 0; n < sizeof(_samplernames) / sizeof(_samplernames[0]); n++) {
+ r = glGetUniformLocation(id, _samplernames[n]);
+ if (r != -1) {
+ fprintf(stderr,"found %s @ %d\n", _samplernames[0], r);
+ glUniform1i(r, n);
+ }
+ }
+ bound = 1;
}
int Program::load(const char *vsfn, const char *gsfn, const char *psfn) {