=== modified file 'program.cc'
@@ -169,6 +169,13 @@
// Clear out the error string to make sure we don't return anything stale.
message_.clear();
+ // Release all of the symbol map resources.
+ for (std::map<string, Symbol*>::iterator symbolIt = symbols_.begin(); symbolIt != symbols_.end(); symbolIt++)
+ {
+ delete (*symbolIt).second;
+ }
+ symbols_.clear();
+
if (handle_)
{
glDeleteProgram(handle_);
@@ -252,101 +259,17 @@
glUseProgram(0);
}
-void
-Program::loadUniformMatrix(const mat4& m, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- // Our matrix representation is column-major, so transpose is false here.
- glUniformMatrix4fv(location, 1, GL_FALSE, m);
- ready_ = true;
-}
-
-void
-Program::loadUniformVector(const vec2& v, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- glUniform2fv(location, 1, v);
- ready_ = true;
-}
-
-void
-Program::loadUniformVector(const vec3& v, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- glUniform3fv(location, 1, v);
- ready_ = true;
-}
-
-void
-Program::loadUniformVector(const vec4& v, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- glUniform4fv(location, 1, v);
- ready_ = true;
-}
-
-void
-Program::loadUniformScalar(const float& f, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- glUniform1f(location, f);
- ready_ = true;
-}
-
-void
-Program::loadUniformScalar(const int& i, const string& name)
-{
- ready_ = false;
- GLint location = glGetUniformLocation(handle_, name.c_str());
- if (location < 0)
- {
- message_ = string("Failed to get uniform location for \"") + name +
- string("\"");
- return;
- }
-
- glUniform1i(location, i);
- ready_ = true;
+
+int
+Program::getUniformLocation(const string& name)
+{
+ GLint location = glGetUniformLocation(handle_, name.c_str());
+ if (location < 0)
+ {
+ message_ = string("Failed to get uniform location for \"") + name +
+ string("\"");
+ }
+ return location;
}
int
@@ -360,3 +283,87 @@
}
return index;
}
+
+Program::Symbol&
+Program::Symbol::operator=(const mat4& m)
+{
+ if (type_ == Uniform)
+ {
+ // Our matrix representation is column-major, so transpose is false here.
+ glUniformMatrix4fv(location_, 1, GL_FALSE, m);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec2& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform2fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec3& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform3fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const vec4& v)
+{
+ if (type_ == Uniform)
+ {
+ glUniform4fv(location_, 1, v);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const float& f)
+{
+ if (type_ == Uniform)
+ {
+ glUniform1f(location_, f);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::Symbol::operator=(const int& i)
+{
+ if (type_ == Uniform)
+ {
+ glUniform1i(location_, i);
+ }
+ return *this;
+}
+
+Program::Symbol&
+Program::operator[](const std::string& name)
+{
+ std::map<std::string, Symbol*>::iterator mapIt = symbols_.find(name);
+ if (mapIt == symbols_.end())
+ {
+ Program::Symbol::SymbolType type(Program::Symbol::Attribute);
+ int location = getAttribIndex(name);
+ if (location < 0)
+ {
+ // No attribute found by that name. Let's try a uniform...
+ type = Program::Symbol::Uniform;
+ location = getUniformLocation(name);
+ if (location < 0)
+ {
+ type = Program::Symbol::None;
+ }
+ }
+ mapIt = symbols_.insert(mapIt, std::make_pair(name, new Symbol(name, location, type)));
+ }
+ return *(*mapIt).second;
+}
=== modified file 'program.h'
@@ -14,6 +14,7 @@
#include <string>
#include <vector>
+#include <map>
#include "mat.h"
// Simple shader container. Abstracts all of the OpenGL bits, but leaves
@@ -108,26 +109,38 @@
// using it).
void stop();
- // These members cause data to be bound to program variables, so
- // the program must be bound for use for these to be effective.
- //
- // Load a matrix into the named uniform variable in the program.
- void loadUniformMatrix(const LibMatrix::mat4& m, const std::string& name);
- // Load a vector into the named uniform variable in the program.
- void loadUniformVector(const LibMatrix::vec2& v, const std::string& name);
- // Load a vector into the named uniform variable in the program.
- void loadUniformVector(const LibMatrix::vec3& v, const std::string& name);
- // Load a vector into the named uniform variable in the program.
- void loadUniformVector(const LibMatrix::vec4& v, const std::string& name);
- // Load a scalar into the named uniform variable in the program.
- void loadUniformScalar(const float& f, const std::string& name);
- // Load a scalar into the named uniform variable in the program.
- void loadUniformScalar(const int& i, const std::string& name);
-
+ class Symbol
+ {
+public:
+ enum SymbolType
+ {
+ None,
+ Attribute,
+ Uniform
+ };
+ Symbol(const std::string& name, int location, SymbolType type) :
+ type_(type),
+ location_(location),
+ name_(name) {}
+ int location() const { return location_; }
+ // These members cause data to be bound to program variables, so
+ // the program must be bound for use for these to be effective.
+ Symbol& operator=(const LibMatrix::mat4& m);
+ Symbol& operator=(const LibMatrix::vec2& v);
+ Symbol& operator=(const LibMatrix::vec3& v);
+ Symbol& operator=(const LibMatrix::vec4& v);
+ Symbol& operator=(const float& f);
+ Symbol& operator=(const int& i);
+private:
+ Symbol();
+ SymbolType type_;
+ GLint location_;
+ std::string name_;
+ };
// Get the handle to a named program input (the location in OpenGL
// vernacular). Typically used in conjunction with various VertexAttrib
- // interfaces.
- int getAttribIndex(const std::string& name);
+ // interfaces. Equality operators are used to load uniform data.
+ Symbol& operator[](const std::string& name);
// If "valid" then the program has successfully been created.
// If "ready" then the program has successfully been built.
@@ -138,7 +151,10 @@
const std::string& errorMessage() const { return message_; }
private:
+ int getAttribIndex(const std::string& name);
+ int getUniformLocation(const std::string& name);
unsigned int handle_;
+ std::map<std::string, Symbol*> symbols_;
std::vector<Shader> shaders_;
std::string message_;
bool ready_;