25 #include "glfShaderProgram.hh"
26 #include "glfUniformNotFoundException.hh"
42 for (
unsigned int i = 0; i < shaders_attached_as_object_.size(); i++)
44 glDetachShader(id_, shaders_attached_as_object_[i]);
49 for (
unsigned int i = 0; i < shaders_attached_from_source_.size(); i++)
51 delete shaders_attached_from_source_[i];
54 shaders_attached_as_object_.clear();
55 shaders_attached_from_source_.clear();
76 id_ = glCreateProgram();
79 GLF_THROW_ON_OPENGL_ERROR;
87 GLF_THROW_ON_OPENGL_ERROR;
89 if(glIsProgram(id_)==GL_FALSE) {
90 GLF_THROW_EXCEPTION(
"not a valid program id!");
94 GLF_THROW_EXCEPTION(
"not a valid shader id!");
99 glGetAttachedShaders(id_, 50, &count, shaders);
100 bool alreadyAttached=
false;
101 for (
int i=0; i<count; i++) {
102 alreadyAttached = alreadyAttached || (shaders[i]==shader.
GetShaderID());
109 GLF_THROW_ON_OPENGL_ERROR;
110 shaders_attached_as_object_.push_back(shader.
GetShaderID());
112 GLF_THROW_ON_OPENGL_ERROR;
117 const std::string& sourceCode)
120 shader->
Create(type, sourceCode);
122 shaders_attached_from_source_.push_back(shader);
123 AttachShader(*shader);
132 shaders_attached_from_source_.push_back(shader);
133 AttachShader(*shader);
139 BIASASSERT(id_ != 0);
144 glGetProgramiv(id_, GL_LINK_STATUS, &linkSuccess);
145 if (linkSuccess == GL_FALSE)
147 GLF_THROW_EXCEPTION(
"Failed to link shader program: "
148 << endl << GetInfoLog());
151 GLF_THROW_ON_OPENGL_ERROR;
157 BIASASSERT(id_ != 0);
160 glGetProgramiv(id_, GL_INFO_LOG_LENGTH, &logLength);
161 char* infoLog =
new char[logLength];
162 glGetProgramInfoLog(id_, logLength, NULL, infoLog);
163 std::string out = infoLog;
166 GLF_THROW_ON_OPENGL_ERROR;
175 GLboolean glValue = (value) ? GL_TRUE : GL_FALSE;
177 GLint loc = GetUniformLocation_(varName);
178 glUniform1i(loc, glValue);
185 GLF_THROW_ON_OPENGL_ERROR_INFO(varName);
194 GLint loc = GetUniformLocation_(varName);
195 glUniform1f(loc, value);
202 GLF_THROW_ON_OPENGL_ERROR_INFO(varName);
208 SetUniform(varName, (
float) value);
216 GLint loc = GetUniformLocation_(varName);
217 glUniform1i(loc, value);
224 GLF_THROW_ON_OPENGL_ERROR_INFO(varName);
232 GLint loc = GetUniformLocation_(varName);
233 glUniform1iv(loc, count, value);
240 GLF_THROW_ON_OPENGL_ERROR_INFO(varName);
246 GLint loc = GetUniformLocation_(varName);
247 glUniform1fv(loc, count, value);
254 GLF_THROW_ON_OPENGL_ERROR_INFO(varName);
263 GLint loc = GetUniformLocation_(varName);
267 glUniform1fv(loc, 1, v.
GetData());
270 glUniform2fv(loc, 1, v.
GetData());
273 glUniform3fv(loc, 1, v.
GetData());
276 glUniform4fv(loc, 1, v.
GetData());
279 GLF_THROW_EXCEPTION(
"Invalid vector size "<<v.
GetNumElements()<<
" for uniform "<<varName)
284 GLF_THROW_ON_OPENGL_ERROR;
292 for (
int i = 0; i < v.GetNumElements(); i++)
294 vf[i] = (float) v[i];
296 SetUniform(varName, vf);
305 GLint loc = GetUniformLocation_(varName);
310 glUniform1iv(loc, 1, v.
GetData());
313 glUniform2iv(loc, 1, v.
GetData());
316 glUniform3iv(loc, 1, v.
GetData());
319 glUniform4iv(loc, 1, v.
GetData());
322 GLF_THROW_EXCEPTION(
"Invalid vector size for uniform")
331 GLF_THROW_ON_OPENGL_ERROR;
341 GLint loc = GetUniformLocation_(varName);
348 glUniformMatrix2fv(loc, 1, GL_FALSE, m.
GetData());
353 GLF_THROW_EXCEPTION(
"Invalid number of columns for uniform matrix")
363 glUniformMatrix3fv(loc, 1, GL_FALSE, m.
GetData());
367 GLF_THROW_EXCEPTION(
"Invalid number of columns for uniform matrix")
378 glUniformMatrix4fv(loc, 1, GL_FALSE, m.
GetData());
381 GLF_THROW_EXCEPTION(
"Invalid number of columns for uniform matrix")
387 GLF_THROW_EXCEPTION(
"Invalid number of rows for uniform matrix")
396 GLF_THROW_ON_OPENGL_ERROR;
404 for (
unsigned int i = 1; i <= m.GetRows(); i++)
406 for (
unsigned int j = 1; j <= m.GetCols(); j++)
408 mf(i, j) = (float) m(i, j);
411 SetUniform(varName, mf);
419 GLint loc = GetUniformLocation_(varName);
420 glUniformMatrix4fv(loc, 1, GL_FALSE, m.
GetArray());
432 BIASASSERT(id_ != 0);
437 glfShaderProgram::IsSamplerType_(GLenum type) {
438 bool isSampler =
false;
443 case GL_SAMPLER_CUBE :
444 case GL_SAMPLER_1D_SHADOW :
445 case GL_SAMPLER_2D_SHADOW :
449 BIASWARN(
"Sampler Type List is incomplete!");
459 BIASASSERT(id_ != 0);
460 GLint numActiveUniforms;
461 glGetProgramiv(id_, GL_ACTIVE_UNIFORMS, &numActiveUniforms);
462 GLF_THROW_ON_OPENGL_ERROR_DEBUG;
466 const int bufSize = 50;
470 for(
int i=0; i<numActiveUniforms; i++) {
471 glGetActiveUniform(id_, i, bufSize, &length, &uniformSize, &uniformType, name);
472 if(IsSamplerType_(uniformType)) {
474 SetUniform(name, assignTU++);
477 GLF_THROW_ON_OPENGL_ERROR;
481 glfShaderProgram::GetUniformLocation_(
const std::string& varName)
483 BIASASSERT(id_ != 0);
484 GLint loc = glGetUniformLocation(id_, varName.c_str());
486 std::stringstream msg;
487 msg <<
"no active uniform named "
489 <<
"! Check: 1. Is Program Linked?, 2. Typo?, 3. Correct shader?";
499 BIASASSERT(id_ != 0);
500 GLint loc = glGetUniformLocation(id_, varName.c_str());
502 std::stringstream msg;
503 msg <<
"no active uniform named "
505 <<
"! Check: 1. Is Program Linked?, 2. Typo?, 3. Correct shader?";
517 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &TUs);
519 return static_cast<GLint
> (TUs);
522 #ifdef GL_VERSION_3_0
524 glfShaderProgram::BindAttribLocation(GLuint indexSlot,
const std::string& VertexAttributeName)
526 BIASASSERT(id_ != 0);
527 glBindAttribLocation(id_, indexSlot, VertexAttributeName.c_str());
static int GetMaxCombinedTextureUnits()
void AttachShaderFromSource(GLenum type, const std::string &sourceCode)
Attaches a shader to the program, without the need to create an instance of the glfShader class...
void Create()
Creates the shader program.
void SetUniform(const std::string &varName, float value)
std::string GetInfoLog() const
Returns the info log containing information about the linking of the shader program.
void Link()
Links the attached shaders.
void AttachShader(const glfShader &shader)
Attaches a shader to the program.
Matrix< T > Transpose() const
transpose function, storing data destination matrix
void CreateFromFile(GLenum type, const std::string &fileName)
Creates the shader from GLSL source code loaded from a file.
void Create(GLenum type)
Creates the shader without the GLSL source code, use other Create() methods to upload source afterwar...
GLint GetUniformLocation(const std::string &varName)
Exception class used for run-time errors in the OpenGLFramework.
GLuint GetShaderID() const
Returns the OpenGL id of the shader.
const std::string & GetMessageString() const
Returns the description of the error including the file name and line number where the error occured...
void Bind() const
Binds the shader program.
A shader program composed of several shaders.
A GLSL vertex shader or fragment shader, which must be linked in a shader program.
unsigned int GetRows() const
int GetNumElements() const
conformance interface JW
T * GetData()
get the pointer to the data array of the matrix (for faster direct memeory access) ...
unsigned int GetCols() const
T * GetData() const
get the pointer to the data array of the vector (for faster direct memory access) ...
void AutoSetSamplerUniforms()
Finds all sampler uniforms and automatically assigns them texture unit indices.
matrix class with arbitrary size, indexing is row major.
A 4x4 matrix in native OpenGL format.
void AttachShaderFromFile(GLenum type, const std::string &fileName)
Attaches a shader to the program, without the need to create an instance of the glfShader class...
const GLfloat * GetArray() const