13#ifndef CSCI441_SHADER_PROGRAM_HPP
14#define CSCI441_SHADER_PROGRAM_HPP
19#include <glm/gtc/type_ptr.hpp>
54 const char *fragmentShaderFilename );
64 const char *fragmentShaderFilename,
76 const char *tessellationControlShaderFilename,
77 const char *tessellationEvaluationShaderFilename,
78 const char *geometryShaderFilename,
79 const char *fragmentShaderFilename );
92 const char *tessellationControlShaderFilename,
93 const char *tessellationEvaluationShaderFilename,
94 const char *geometryShaderFilename,
95 const char *fragmentShaderFilename,
107 const char *tessellationControlShaderFilename,
108 const char *tessellationEvaluationShaderFilename,
109 const char *fragmentShaderFilename );
121 const char *tessellationControlShaderFilename,
122 const char *tessellationEvaluationShaderFilename,
123 const char *fragmentShaderFilename,
133 const char *geometryShaderFilename,
134 const char *fragmentShaderFilename );
145 const char *geometryShaderFilename,
146 const char *fragmentShaderFilename,
161 bool vertexPresent,
bool tessellationPresent,
bool geometryPresent,
bool fragmentPresent,
231 [[maybe_unused]] virtual GLubyte*
getUniformBlockBuffer( const GLchar *uniformBlockName ) const final;
246 [[maybe_unused]] virtual GLint*
getUniformBlockOffsets( const GLchar *uniformBlockName, const GLchar *names[] ) const final;
286 [[maybe_unused]] virtual GLuint
getSubroutineIndex( GLenum shaderStage, const GLchar *subroutineName ) const final;
306 [[maybe_unused]] virtual
void setSubroutineIndices( GLenum shaderStage, GLsizei numIndices, const GLuint *indices ) final;
314 [[maybe_unused]] virtual GLint
getImageBinding(const GLchar* imageName) const final;
350 [[maybe_unused]] [[nodiscard]] virtual GLuint
getNumUniforms() const final;
360 [[maybe_unused]] [[nodiscard]] virtual GLuint
getNumAttributes() const final;
371 [[maybe_unused]] virtual
void useProgram() const final;
378 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0) const final;
384 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0) const final;
390 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0) const final;
396 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2 mtx) const final;
402 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3 mtx) const final;
408 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4 mtx) const final;
414 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2x3 mtx) const final;
420 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3x2 mtx) const final;
426 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2x4 mtx) const final;
432 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4x2 mtx) const final;
438 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3x4 mtx) const final;
444 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4x3 mtx) const final;
452 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1) const final;
459 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1) const final;
466 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1) const final;
475 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2) const final;
483 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2) const final;
491 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2) const final;
501 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
510 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2, GLint v3) const final;
519 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
526 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec2 value) const final;
532 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const final;
538 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const final;
545 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec3 value) const final;
551 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const final;
557 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const final;
564 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec4 value) const final;
570 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const final;
576 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const final;
585 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLfloat *value) const final;
593 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLint *value) const final;
601 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLuint *value) const final;
608 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0) const final;
614 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0) const final;
620 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0) const final;
626 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2 mtx) const final;
632 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3 mtx) const final;
638 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4 mtx) const final;
644 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2x3 mtx) const final;
650 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3x2 mtx) const final;
656 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2x4 mtx) const final;
662 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4x2 mtx) const final;
668 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3x4 mtx) const final;
674 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4x3 mtx) const final;
682 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1) const final;
689 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1) const final;
696 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1) const final;
705 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2) const final;
713 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2) const final;
721 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2) const final;
731 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
740 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2, GLint v3) const final;
749 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
756 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec2 value) const final;
762 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec2 value) const final;
768 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec2 value) const final;
775 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec3 value) const final;
781 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec3 value) const final;
787 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec3 value) const final;
794 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec4 value) const final;
800 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec4 value) const final;
806 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec4 value) const final;
815 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLfloat *value) const final;
823 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLint *value) const final;
831 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLuint *value) const final;
837 [[maybe_unused]] [[nodiscard]] virtual GLbitfield
getProgramStages() const final;
897 const
char *tessellationControlShaderFilename,
898 const
char *tessellationEvaluationShaderFilename,
899 const
char *geometryShaderFilename,
900 const
char *fragmentShaderFilename,
901 bool isSeparable ) final;
917 CSCI441_INTERNAL::ShaderUtils::enableDebugMessages();
923 CSCI441_INTERNAL::ShaderUtils::disableDebugMessages();
927 const char *vertexShaderFilename,
928 const char *fragmentShaderFilename
936 const char *vertexShaderFilename,
937 const char *fragmentShaderFilename,
938 const bool isSeparable
946 const char *vertexShaderFilename,
947 const char *tessellationControlShaderFilename,
948 const char *tessellationEvaluationShaderFilename,
949 const char *geometryShaderFilename,
950 const char *fragmentShaderFilename
952 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
953 geometryShaderFilename, fragmentShaderFilename,
false);
958 const char *vertexShaderFilename,
959 const char *tessellationControlShaderFilename,
960 const char *tessellationEvaluationShaderFilename,
961 const char *geometryShaderFilename,
962 const char *fragmentShaderFilename,
963 const bool isSeparable
965 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
966 geometryShaderFilename, fragmentShaderFilename, isSeparable);
971 const char *vertexShaderFilename,
972 const char *tessellationControlShaderFilename,
973 const char *tessellationEvaluationShaderFilename,
974 const char *fragmentShaderFilename
976 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
977 "", fragmentShaderFilename,
false);
982 const char *vertexShaderFilename,
983 const char *tessellationControlShaderFilename,
984 const char *tessellationEvaluationShaderFilename,
985 const char *fragmentShaderFilename,
986 const bool isSeparable
988 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
989 "", fragmentShaderFilename, isSeparable);
993 const char *vertexShaderFilename,
994 const char *geometryShaderFilename,
995 const char *fragmentShaderFilename
997 mRegisterShaderProgram(vertexShaderFilename,
"",
"", geometryShaderFilename, fragmentShaderFilename,
false);
1002 const char *vertexShaderFilename,
1003 const char *geometryShaderFilename,
1004 const char *fragmentShaderFilename,
1005 const bool isSeparable
1007 mRegisterShaderProgram(vertexShaderFilename,
"",
"", geometryShaderFilename, fragmentShaderFilename, isSeparable);
1012 const char **shaderFilenames,
1013 const bool vertexPresent,
const bool tessellationPresent,
const bool geometryPresent,
const bool fragmentPresent,
1014 const bool isSeparable
1016 if( vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1017 if( !isSeparable ) {
1018 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1022 }
else if( vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1023 if( !isSeparable ) {
1024 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1028 }
else if( vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1029 if( !isSeparable ) {
1030 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1032 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3],
"", isSeparable);
1034 }
else if( vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1035 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], shaderFilenames[4], isSeparable);
1036 }
else if( vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1037 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2],
"", shaderFilenames[3], isSeparable);
1038 }
else if( vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1039 if( !isSeparable ) {
1040 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1044 }
else if( vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1046 }
else if( vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1048 }
else if( !vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1049 if( !isSeparable ) {
1050 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1054 }
else if( !vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1055 if( !isSeparable ) {
1056 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1060 }
else if( !vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1061 if( !isSeparable ) {
1062 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1064 mRegisterShaderProgram(
"", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], isSeparable);
1066 }
else if( !vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1067 if( !isSeparable ) {
1068 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1072 }
else if( !vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1073 if( !isSeparable ) {
1074 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1078 }
else if( !vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1079 if( !isSeparable ) {
1080 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1084 }
else if( !vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1085 if( !isSeparable ) {
1086 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1090 }
else if( !vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1091 fprintf(stderr,
"[ERROR]: At least one shader must be present.\n");
1093 fprintf(stderr,
"[ERROR]: Unknown state.\n");
1098 const char *vertexShaderFilename,
1099 const char *tessellationControlShaderFilename,
1100 const char *tessellationEvaluationShaderFilename,
1101 const char *geometryShaderFilename,
1102 const char *fragmentShaderFilename,
1103 const bool isSeparable
1106 glGetIntegerv(GL_MAJOR_VERSION, &major);
1107 glGetIntegerv(GL_MINOR_VERSION, &minor);
1109 if( sDEBUG ) printf(
"\n[INFO]: /--------------------------------------------------------\\\n");
1112 if( strcmp( vertexShaderFilename,
"" ) != 0 ) {
1113 if( sDEBUG ) printf(
"[INFO]: | Vertex Shader: %39s |\n", vertexShaderFilename );
1114 mVertexShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(vertexShaderFilename, GL_VERTEX_SHADER );
1116 mVertexShaderHandle = 0;
1119 if(strcmp(tessellationControlShaderFilename,
"" ) != 0 ) {
1120 if( sDEBUG ) printf(
"[INFO]: | Tess Control Shader: %33s |\n", tessellationControlShaderFilename );
1122 printf(
"[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1123 mTessellationControlShaderHandle = 0;
1125 mTessellationControlShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationControlShaderFilename, GL_TESS_CONTROL_SHADER );
1128 mTessellationControlShaderHandle = 0;
1131 if(strcmp(tessellationEvaluationShaderFilename,
"" ) != 0 ) {
1132 if( sDEBUG ) printf(
"[INFO]: | Tess Evaluation Shader: %30s |\n", tessellationEvaluationShaderFilename );
1134 printf(
"[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1135 mTessellationEvaluationShaderHandle = 0;
1137 mTessellationEvaluationShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationEvaluationShaderFilename, GL_TESS_EVALUATION_SHADER );
1140 mTessellationEvaluationShaderHandle = 0;
1143 if( strcmp( geometryShaderFilename,
"" ) != 0 ) {
1144 if( sDEBUG ) printf(
"[INFO]: | Geometry Shader: %37s |\n", geometryShaderFilename );
1145 if( major < 3 || (major == 3 && minor < 2) ) {
1146 printf(
"[ERROR]:| GEOMETRY SHADER NOT SUPPORTED!!! UPGRADE TO v3.2+ |\n" );
1147 mGeometryShaderHandle = 0;
1149 mGeometryShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(geometryShaderFilename, GL_GEOMETRY_SHADER );
1152 mGeometryShaderHandle = 0;
1155 if( strcmp( fragmentShaderFilename,
"" ) != 0 ) {
1156 if( sDEBUG ) printf(
"[INFO]: | Fragment Shader: %37s |\n", fragmentShaderFilename );
1157 mFragmentShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(fragmentShaderFilename, GL_FRAGMENT_SHADER );
1159 mFragmentShaderHandle = 0;
1162 mShaderProgramHandle = glCreateProgram();
1166 glProgramParameteri(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, GL_TRUE );
1170 if(mVertexShaderHandle != 0 ) {
1171 glAttachShader(mShaderProgramHandle, mVertexShaderHandle );
1173 if(mTessellationControlShaderHandle != 0 ) {
1174 glAttachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1176 if(mTessellationEvaluationShaderHandle != 0 ) {
1177 glAttachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1179 if(mGeometryShaderHandle != 0 ) {
1180 glAttachShader(mShaderProgramHandle, mGeometryShaderHandle );
1182 if(mFragmentShaderHandle != 0 ) {
1183 glAttachShader(mShaderProgramHandle, mFragmentShaderHandle );
1187 glLinkProgram(mShaderProgramHandle );
1189 if( sDEBUG ) printf(
"[INFO]: | Shader Program: %41s",
"|\n" );
1192 CSCI441_INTERNAL::ShaderUtils::printProgramLog(mShaderProgramHandle );
1195 if(mVertexShaderHandle != 0 ) {
1196 glDetachShader(mShaderProgramHandle, mVertexShaderHandle );
1197 glDeleteShader(mVertexShaderHandle );
1199 if(mTessellationControlShaderHandle != 0 ) {
1200 glDetachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1201 glDeleteShader(mTessellationControlShaderHandle );
1203 if(mTessellationEvaluationShaderHandle != 0 ) {
1204 glDetachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1205 glDeleteShader(mTessellationEvaluationShaderHandle );
1207 if(mGeometryShaderHandle != 0 ) {
1208 glDetachShader(mShaderProgramHandle, mGeometryShaderHandle );
1209 glDeleteShader(mGeometryShaderHandle );
1211 if(mFragmentShaderHandle != 0 ) {
1212 glDetachShader(mShaderProgramHandle, mFragmentShaderHandle );
1213 glDeleteShader(mFragmentShaderHandle );
1218 mpUniformLocationsMap =
new std::map<std::string, GLint>();
1220 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniforms);
1221 GLint max_uniform_name_size;
1222 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_size);
1223 if( numUniforms > 0 ) {
1224 for(GLint i = 0; i < numUniforms; i++) {
1225 auto name =
new GLchar[max_uniform_name_size];
1226 int actual_length = 0;
1229 glGetActiveUniform(mShaderProgramHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
1232 for(
int j = 0; j < size; j++) {
1233 const int max_array_size = actual_length + 4 + 2 + 1;
1234 auto array_name =
new GLchar[max_array_size];
1235 snprintf(array_name, max_array_size,
"%s[%i]", name, j);
1236 location = glGetUniformLocation(mShaderProgramHandle, array_name);
1237 mpUniformLocationsMap->emplace(array_name, location);
1238 delete[] array_name;
1241 location = glGetUniformLocation(mShaderProgramHandle, name);
1242 mpUniformLocationsMap->emplace(name, location);
1249 mpAttributeLocationsMap =
new std::map<std::string, GLint>();
1250 GLint numAttributes;
1251 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttributes );
1252 GLint max_attr_name_size;
1253 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_size);
1254 if( numAttributes > 0 ) {
1255 for(GLint i = 0; i < numAttributes; i++) {
1256 auto name =
new GLchar[max_attr_name_size];
1257 int actual_length = 0;
1260 glGetActiveAttrib(mShaderProgramHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
1263 for(
int j = 0; j < size; j++ ) {
1264 const int max_array_size = actual_length + 4 + 2 + 1;
1265 auto array_name =
new GLchar[max_array_size];
1266 snprintf( array_name, max_array_size,
"%s[%i]", name, j );
1267 location = glGetAttribLocation(mShaderProgramHandle, array_name );
1268 mpAttributeLocationsMap->emplace(array_name, location);
1269 delete[] array_name;
1272 location = glGetAttribLocation(mShaderProgramHandle, name );
1273 mpAttributeLocationsMap->emplace(name, location);
1279 GLint separable = GL_FALSE;
1280 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, &separable );
1282 if( sDEBUG ) printf(
"[INFO]: | Program Separable: %35s |\n", (separable ?
"Yes" :
"No"));
1285 glGetProgramiv(mShaderProgramHandle, GL_LINK_STATUS, &linkStatus );
1288 if(linkStatus == 1) {
1289 CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(mShaderProgramHandle, mVertexShaderHandle != 0,
1290 mTessellationControlShaderHandle != 0,
1291 mTessellationEvaluationShaderHandle != 0,
1292 mGeometryShaderHandle != 0, mFragmentShaderHandle != 0,
1296 return mShaderProgramHandle != 0;
1300 const GLint uniformLoc = glGetUniformLocation(mShaderProgramHandle, uniformName );
1301 if( uniformLoc == GL_INVALID_VALUE )
1302 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle );
1307 const GLint uniformBlockLoc = glGetUniformBlockIndex(mShaderProgramHandle, uniformBlockName );
1308 if( uniformBlockLoc == GL_INVALID_INDEX )
1309 fprintf(stderr,
"[ERROR]: Could not find uniform block \"%s\" for Shader Program %u\n", uniformBlockName, mShaderProgramHandle );
1310 return uniformBlockLoc;
1315 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1321 const GLint blockSize = getUniformBlockSize( uniformBlockName );
1322 return (GLubyte*)malloc(blockSize);
1327 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1332 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1337 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1339 const auto indices = (GLuint*)malloc(numUniforms*
sizeof(GLuint));
1340 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1342 const auto offsets = (GLint*)malloc(numUniforms*
sizeof(GLint));
1343 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1349 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1351 const auto indices = (GLuint*)malloc(numUniforms*
sizeof(GLuint));
1352 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1354 const auto offsets = (GLint*)malloc(numUniforms*
sizeof(GLint));
1355 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1360 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1365 const auto attribIter = mpAttributeLocationsMap->find(attributeName);
1366 if(attribIter == mpAttributeLocationsMap->end() ) {
1367 fprintf(stderr,
"[ERROR]: Could not find attribute \"%s\" for Shader Program %u\n", attributeName, mShaderProgramHandle );
1370 return attribIter->second;
1375 const GLuint subroutineIndex = glGetSubroutineIndex(mShaderProgramHandle, shaderStage, subroutineName );
1376 if( subroutineIndex == GL_INVALID_INDEX )
1377 fprintf(stderr,
"[ERROR]: Could not find subroutine \"%s\" in %s for Shader Program %u\n", subroutineName, CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(shaderStage), mShaderProgramHandle );
1378 return subroutineIndex;
1383 const GLint subroutineUniform = glGetSubroutineUniformLocation(mShaderProgramHandle, shaderStage, subroutineName );
1384 if ( subroutineUniform == GL_INVALID_VALUE )
1385 fprintf(stderr,
"[ERROR]: Could not find subroutine \"%s\" in %s for Shader Program %u\n", subroutineName, CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(shaderStage), mShaderProgramHandle );
1386 return subroutineUniform;
1391 glUniformSubroutinesuiv( shaderStage, numIndices, indices );
1397 const GLint imageLoc = getUniformLocation(imageName);
1399 if(imageLoc == GL_INVALID_INDEX) {
1400 fprintf(stderr,
"[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1405 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1407 return bindingPoint;
1412 const GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1414 if(ssboIndex == GL_INVALID_INDEX) {
1415 fprintf(stderr,
"[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1419 constexpr GLenum props = GL_BUFFER_BINDING;
1421 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, 1, &props, 1,
nullptr, &binding);
1428 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1430 if(uniformIndex == GL_INVALID_INDEX) {
1431 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1435 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1436 GLint atomicIndex, binding;
1437 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1,
nullptr, &atomicIndex);
1438 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
1445 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1447 if(uniformIndex == GL_INVALID_INDEX) {
1448 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1453 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1459 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1461 if(uniformIndex == GL_INVALID_INDEX) {
1462 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1466 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1467 GLint atomicIndex, bufferSize;
1468 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1,
nullptr, &atomicIndex);
1469 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize);
1476 GLint numUniform = 0;
1477 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1483 GLint numUniformBlocks = 0;
1484 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1485 return numUniformBlocks;
1491 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1496 return mShaderProgramHandle;
1501 glUseProgram(mShaderProgramHandle );
1506 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1507 if(uniformIter != mpUniformLocationsMap->end()) {
1508 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1510 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1516 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1517 if(uniformIter != mpUniformLocationsMap->end()) {
1518 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1520 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1526 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1531 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1532 if(uniformIter != mpUniformLocationsMap->end()) {
1533 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1535 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1541 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1546 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1547 if(uniformIter != mpUniformLocationsMap->end()) {
1548 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1550 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1556 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1560 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1561 if(uniformIter != mpUniformLocationsMap->end()) {
1564 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1567 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1570 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1573 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1576 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1580 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1586 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1587 if(uniformIter != mpUniformLocationsMap->end()) {
1588 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1590 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1596 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1597 if(uniformIter != mpUniformLocationsMap->end()) {
1598 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1600 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1606 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1607 if(uniformIter != mpUniformLocationsMap->end()) {
1608 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1610 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1616 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1617 if(uniformIter != mpUniformLocationsMap->end()) {
1618 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1620 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1626 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1627 if(uniformIter != mpUniformLocationsMap->end()) {
1628 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1630 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1636 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1637 if(uniformIter != mpUniformLocationsMap->end()) {
1638 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1640 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1646 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1647 if(uniformIter != mpUniformLocationsMap->end()) {
1648 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1650 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1656 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1657 if(uniformIter != mpUniformLocationsMap->end()) {
1660 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1663 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1666 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1669 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1672 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1676 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1682 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1683 if(uniformIter != mpUniformLocationsMap->end()) {
1684 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1686 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1692 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1693 if(uniformIter != mpUniformLocationsMap->end()) {
1694 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1696 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1702 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1703 if(uniformIter != mpUniformLocationsMap->end()) {
1704 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1706 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1712 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1713 if(uniformIter != mpUniformLocationsMap->end()) {
1714 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1716 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1722 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1723 if(uniformIter != mpUniformLocationsMap->end()) {
1724 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1726 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1732 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1733 if(uniformIter != mpUniformLocationsMap->end()) {
1734 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1736 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1742 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1743 if(uniformIter != mpUniformLocationsMap->end()) {
1744 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1746 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1752 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1753 if(uniformIter != mpUniformLocationsMap->end()) {
1756 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1759 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1762 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1765 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1768 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1772 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1778 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1779 if(uniformIter != mpUniformLocationsMap->end()) {
1780 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1782 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1788 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1789 if(uniformIter != mpUniformLocationsMap->end()) {
1790 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1792 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1798 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1799 if(uniformIter != mpUniformLocationsMap->end()) {
1800 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1802 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1808 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1809 if(uniformIter != mpUniformLocationsMap->end()) {
1810 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1812 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1818 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1819 if(uniformIter != mpUniformLocationsMap->end()) {
1820 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1822 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1828 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1829 if(uniformIter != mpUniformLocationsMap->end()) {
1830 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1832 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1838 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1839 if(uniformIter != mpUniformLocationsMap->end()) {
1840 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1842 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1848 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1849 if(uniformIter != mpUniformLocationsMap->end()) {
1850 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1852 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1858 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1859 if(uniformIter != mpUniformLocationsMap->end()) {
1860 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1862 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1868 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1873 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1878 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1883 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1888 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1893 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1898 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1904 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1907 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1910 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1913 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1916 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1923 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1928 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1933 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1938 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1943 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1948 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1953 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
1959 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
1962 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
1965 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
1968 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
1971 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1978 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
1983 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
1988 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1993 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1998 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
2003 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2008 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2014 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
2017 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
2020 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
2023 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
2026 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2033 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2038 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2043 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2048 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2053 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2058 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2063 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2068 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2073 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2078 GLbitfield shaderBits = 0;
2079 if( mVertexShaderHandle != 0 ) shaderBits |= GL_VERTEX_SHADER_BIT;
2080 if( mTessellationControlShaderHandle != 0 ) shaderBits |= GL_TESS_CONTROL_SHADER_BIT;
2081 if( mTessellationEvaluationShaderHandle != 0 ) shaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
2082 if( mGeometryShaderHandle != 0 ) shaderBits |= GL_GEOMETRY_SHADER_BIT;
2083 if( mFragmentShaderHandle != 0 ) shaderBits |= GL_FRAGMENT_SHADER_BIT;
2088 mVertexShaderHandle(0),
2089 mTessellationControlShaderHandle(0), mTessellationEvaluationShaderHandle(0),
2090 mGeometryShaderHandle(0),
2091 mFragmentShaderHandle(0),
2092 mShaderProgramHandle(0),
2093 mpUniformLocationsMap(nullptr), mpAttributeLocationsMap(nullptr)
2105 _moveFromSource(src);
2111 _moveFromSource(src);
2116inline void CSCI441::ShaderProgram::_cleanupSelf() {
2118 GLint infoLogLength = 0;
2119 constexpr int maxLength = 1000;
2121 glDeleteProgram(mShaderProgramHandle );
2124 const auto infoLog =
new GLchar[maxLength];
2126 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2129 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2131 if(infoLogLength > 0 ) {
2133 if( sDEBUG ) printf(
"[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ?
"Success" :
" Error"), infoLog );
2136 delete mpUniformLocationsMap;
2137 delete mpAttributeLocationsMap;
2140 mVertexShaderHandle = 0;
2141 mTessellationControlShaderHandle = 0;
2142 mTessellationEvaluationShaderHandle = 0;
2143 mGeometryShaderHandle = 0;
2144 mFragmentShaderHandle = 0;
2145 mShaderProgramHandle = 0;
2146 mpUniformLocationsMap =
nullptr;
2147 mpAttributeLocationsMap =
nullptr;
2150inline void CSCI441::ShaderProgram::_moveFromSource(ShaderProgram &src) {
2151 mVertexShaderHandle = src.mVertexShaderHandle;
2152 src.mVertexShaderHandle = 0;
2154 mTessellationControlShaderHandle = src.mTessellationControlShaderHandle;
2155 src.mTessellationControlShaderHandle = 0;
2157 mTessellationEvaluationShaderHandle = src.mTessellationEvaluationShaderHandle;
2158 src.mTessellationEvaluationShaderHandle = 0;
2160 mGeometryShaderHandle = src.mGeometryShaderHandle;
2161 src.mGeometryShaderHandle = 0;
2163 mFragmentShaderHandle = src.mFragmentShaderHandle;
2164 src.mFragmentShaderHandle = 0;
2166 mShaderProgramHandle = src.mShaderProgramHandle;
2167 src.mShaderProgramHandle = 0;
2169 mpUniformLocationsMap = src.mpUniformLocationsMap;
2170 src.mpUniformLocationsMap =
nullptr;
2172 mpAttributeLocationsMap = src.mpAttributeLocationsMap;
2173 src.mpAttributeLocationsMap =
nullptr;
2179 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2181 fprintf(stderr,
"[ERROR]: Driver does not support any binary formats.\n");
2187 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2190 std::vector<GLubyte> buffer(length);
2192 glGetProgramBinary(mShaderProgramHandle, length,
nullptr, &format, buffer.data());
2195 fprintf(stdout,
"[INFO]: Writing to %s, binary format %d\n",BINARY_FILE_NAME, format);
2196 std::ofstream out(BINARY_FILE_NAME, std::ios::binary);
2197 out.write(
reinterpret_cast<char *
>(buffer.data()), length );
2205 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2207 fprintf(stderr,
"[ERROR]: Driver does not support any binary formats.\n");
2211 const GLuint program = glCreateProgram();
2214 std::ifstream inputStream(BINARY_FILE_NAME, std::ios::binary);
2215 const std::istreambuf_iterator<char> startIt(inputStream);
2216 constexpr std::istreambuf_iterator<char> endIt;
2217 const std::vector<char> buffer(startIt, endIt);
2218 inputStream.close();
2221 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2225 glGetProgramiv(program, GL_LINK_STATUS, &status);
2226 if( GL_FALSE == status ) {
2227 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2232 shaderProgram->mShaderProgramHandle = program;
2233 return shaderProgram;
Helper functions to work with OpenGL Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:35
GLuint mTessellationEvaluationShaderHandle
handle to the tessellation evaluation shader stage
Definition: ShaderProgram.hpp:862
virtual GLint * getUniformBlockOffsets(const GLchar *uniformBlockName) const final
Returns an array of offsets into the buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1326
GLuint mVertexShaderHandle
handle to the vertex shader stage
Definition: ShaderProgram.hpp:854
virtual GLubyte * getUniformBlockBuffer(const GLchar *uniformBlockName) const final
Returns an allocated buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1320
virtual void setProgramUniform(const GLchar *uniformName, GLfloat v0) const final
sets the program uniform consisting of one float
Definition: ShaderProgram.hpp:1505
static ShaderProgram * loadShaderProgramFromBinaryFile(const char *BINARY_FILE_NAME, GLenum format)
loads precompiled shader program binary from external file
Definition: ShaderProgram.hpp:2203
virtual GLint getAttributeLocation(const GLchar *attributeName) const final
Returns the location of the given attribute in this shader program.
Definition: ShaderProgram.hpp:1364
GLuint mShaderProgramHandle
handle to the shader program
Definition: ShaderProgram.hpp:875
GLuint mTessellationControlShaderHandle
handle to the tessellation control shader stage
Definition: ShaderProgram.hpp:858
virtual void useProgram() const final
Sets the Shader Program to be active.
Definition: ShaderProgram.hpp:1500
virtual GLuint getNumAttributes() const final
Returns the number of active attributes in this shader program.
Definition: ShaderProgram.hpp:1489
virtual void setUniformBlockBinding(const GLchar *uniformBlockName, GLuint binding) const final
Set the binding point for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1359
std::map< std::string, GLint > * mpUniformLocationsMap
caches locations of uniform names within shader program
Definition: ShaderProgram.hpp:880
virtual GLint getUniformBlockIndex(const GLchar *uniformBlockName) const final
Returns the index of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1306
virtual GLint getAtomicCounterBufferOffset(const GLchar *atomicName) const final
Returns the offset into the buffer for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1444
ShaderProgram & operator=(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual GLbitfield getProgramStages() const final
returns a single value corresponding to which shader stages are present in this shader program
Definition: ShaderProgram.hpp:2077
virtual GLuint getNumUniforms() const final
Returns the number of active uniforms in this shader program.
Definition: ShaderProgram.hpp:1475
virtual GLint getSubroutineUniformLocation(GLenum shaderStage, const GLchar *subroutineName) const final
Returns the uniform location within the subroutine array for a given subroutine.
Definition: ShaderProgram.hpp:1382
virtual GLint getImageBinding(const GLchar *imageName) const final
Returns the binding point for the corresponding image uniform.
Definition: ShaderProgram.hpp:1396
virtual ~ShaderProgram()
Clean up memory associated with the Shader Program.
Definition: ShaderProgram.hpp:2098
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1495
GLuint mGeometryShaderHandle
handle to the geometry shader stage
Definition: ShaderProgram.hpp:866
virtual GLint getAtomicCounterBufferBinding(const GLchar *atomicName) const final
Returns the binding point for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1427
static bool sDEBUG
if DEBUG information should be printed or not
Definition: ShaderProgram.hpp:849
virtual GLuint getSubroutineIndex(GLenum shaderStage, const GLchar *subroutineName) const final
Returns the index of the given subroutine for a shader stage in this shader program.
Definition: ShaderProgram.hpp:1374
virtual void setSubroutineIndices(GLenum shaderStage, GLsizei numIndices, const GLuint *indices) final
Sets the subroutines to use for a given shader stage.
Definition: ShaderProgram.hpp:1390
virtual GLint getShaderStorageBlockBinding(const GLchar *ssboName) const final
Returns the binding point for the corresponding shader storage block.
Definition: ShaderProgram.hpp:1411
virtual bool writeShaderProgramBinaryToFile(const char *BINARY_FILE_NAME) const final
writes precompiled shader program binary to external file
Definition: ShaderProgram.hpp:2177
static void disableDebugMessages()
Disables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:921
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1313
static void enableDebugMessages()
Enables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:915
std::map< std::string, GLint > * mpAttributeLocationsMap
caches locations of attribute names within shader program
Definition: ShaderProgram.hpp:884
virtual GLuint getNumUniformBlocks() const final
Returns the number of active uniform blocks in this shader program.
Definition: ShaderProgram.hpp:1482
ShaderProgram(const ShaderProgram &)=delete
do not allow shader programs to be copied
GLuint mFragmentShaderHandle
handle to the fragment shader stage
Definition: ShaderProgram.hpp:870
ShaderProgram()
creates an empty shader program object
Definition: ShaderProgram.hpp:2087
virtual GLint getUniformLocation(const GLchar *uniformName) const final
Returns the location of the given uniform in this shader program.
Definition: ShaderProgram.hpp:1299
virtual bool mRegisterShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename, bool isSeparable) final
registers a shader program with the GPU
Definition: ShaderProgram.hpp:1097
virtual GLint getAtomicCounterBufferSize(const GLchar *atomicName) const final
Returns the full buffer size for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1458
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17