=== modified file 'src/composite-test-simple-base.cc'
@@ -91,8 +91,8 @@
program_.errorMessage().c_str());
return;
}
- vertexIndex_ = program_.getAttribIndex(position_name_);
- texcoordIndex_ = program_.getAttribIndex(texcoord_name_);
+ vertexIndex_ = program_[position_name_].location();
+ texcoordIndex_ = program_[texcoord_name_].location();
// Initialize our vertex buffer object
using LibMatrix::vec2;
@@ -129,7 +129,7 @@
program_.start();
int texUnit(0);
- program_.loadUniformScalar(texUnit, texture0_name_);
+ program_[texture0_name_] = texUnit;
glClearColor(0.1, 0.1, 0.3, 1.0);
=== modified file 'src/composite-test-simple-brick.cc'
@@ -43,9 +43,9 @@
lightPos_ = LibMatrix::vec4(0.0, 1.0, 1.0, 0.0);
- program_.loadUniformVector(brickSize_, brickSizeName_);
- program_.loadUniformVector(brickPct_, brickPctName_);
- program_.loadUniformVector(lightPos_, lightPosName_);
+ program_[brickSizeName_] = brickSize_;
+ program_[brickPctName_] = brickPct_;
+ program_[lightPosName_] = lightPos_;
}
void
@@ -63,8 +63,7 @@
glEnableVertexAttribArray(vertexIndex_);
glEnableVertexAttribArray(texcoordIndex_);
- program_.loadUniformMatrix(projection_matrix.getCurrent(),
- projection_matrix_name_);
+ program_[projection_matrix_name_] = projection_matrix.getCurrent();
/* Find out how many windows are visible and calculate the angular step */
GLuint visible_windows(num_visible_windows(window_list));
@@ -83,8 +82,7 @@
sin(angular_step * i), 0);
/* Load shader ModelView uniform */
- program_.loadUniformMatrix(model_view_matrix.getCurrent(),
- model_view_matrix_name_);
+ program_[model_view_matrix_name_] = model_view_matrix.getCurrent();
Log::debug("Drawing Win: 0x%x Tex: 0x%x\n",
comp_win->get_xwindow(), comp_win->get_texture().i);
@@ -111,5 +109,5 @@
if (x <= 0.0) { x = 0.0; y += 0.1; }
lightPos_.x(x);
lightPos_.y(y);
- program_.loadUniformVector(lightPos_, lightPosName_);
+ program_[lightPosName_] = lightPos_;
}
=== modified file 'src/composite-test-simple-default.cc'
@@ -44,8 +44,7 @@
glEnableVertexAttribArray(vertexIndex_);
glEnableVertexAttribArray(texcoordIndex_);
- program_.loadUniformMatrix(projection_matrix.getCurrent(),
- projection_matrix_name_);
+ program_[projection_matrix_name_] = projection_matrix.getCurrent();
/* Find out how many windows are visible and calculate the angular step */
GLuint visible_windows(num_visible_windows(window_list));
@@ -64,8 +63,7 @@
sin(angular_step * i), 0);
/* Load shader ModelView uniform */
- program_.loadUniformMatrix(model_view_matrix.getCurrent(),
- model_view_matrix_name_);
+ program_[model_view_matrix_name_] = model_view_matrix.getCurrent();
Log::debug("Drawing Win: 0x%x Tex: 0x%x\n",
comp_win->get_xwindow(), comp_win->get_texture().i);
=== modified file 'src/libmatrix/program.cc'
@@ -32,7 +32,7 @@
ifstream inputFile(filename.c_str());
if (!inputFile)
{
- Log::error("Failed to open \"%s\"\n", filename.c_str());
+ std::cerr << "Failed to open \"" << filename << "\"" << std::endl;
return false;
}
@@ -171,6 +171,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_);
@@ -254,101 +261,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
@@ -362,3 +285,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::Invalid;
+ }
+ }
+ mapIt = symbols_.insert(mapIt, std::make_pair(name, new Symbol(name, location, type)));
+ }
+ return *(*mapIt).second;
+}
=== modified file 'src/libmatrix/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
+ {
+ Invalid,
+ 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_;
+ int 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_;