13#ifndef CSCI441_SHADER_PROGRAM_HPP
14#define CSCI441_SHADER_PROGRAM_HPP
20#include <glm/gtc/type_ptr.hpp>
55 const char *fragmentShaderFilename );
65 const char *fragmentShaderFilename,
77 const char *tessellationControlShaderFilename,
78 const char *tessellationEvaluationShaderFilename,
79 const char *geometryShaderFilename,
80 const char *fragmentShaderFilename );
93 const char *tessellationControlShaderFilename,
94 const char *tessellationEvaluationShaderFilename,
95 const char *geometryShaderFilename,
96 const char *fragmentShaderFilename,
108 const char *tessellationControlShaderFilename,
109 const char *tessellationEvaluationShaderFilename,
110 const char *fragmentShaderFilename );
122 const char *tessellationControlShaderFilename,
123 const char *tessellationEvaluationShaderFilename,
124 const char *fragmentShaderFilename,
134 const char *geometryShaderFilename,
135 const char *fragmentShaderFilename );
146 const char *geometryShaderFilename,
147 const char *fragmentShaderFilename,
162 bool vertexPresent,
bool tessellationPresent,
bool geometryPresent,
bool fragmentPresent,
232 [[maybe_unused]] virtual GLubyte*
getUniformBlockBuffer( const GLchar *uniformBlockName ) const final;
247 [[maybe_unused]] virtual GLint*
getUniformBlockOffsets( const GLchar *uniformBlockName, const GLchar *names[] ) const final;
262 [[nodiscard]] virtual GLint*
getUniformBlockOffsets(GLint uniformBlockIndex, const GLchar *names[] ) const final;
287 [[maybe_unused]] virtual GLuint
getSubroutineIndex( GLenum shaderStage, const GLchar *subroutineName ) const final;
307 [[maybe_unused]] virtual
void setSubroutineIndices( GLenum shaderStage, GLsizei numIndices, const GLuint *indices ) final;
315 [[maybe_unused]] virtual GLint
getImageBinding(const GLchar* imageName) const final;
351 [[maybe_unused]] [[nodiscard]] virtual GLuint
getNumUniforms() const final;
361 [[maybe_unused]] [[nodiscard]] virtual GLuint
getNumAttributes() const final;
375 [[maybe_unused]] [[nodiscard]] virtual GLint
getFragmentDataIndex(const GLchar* name) const final;
387 [[nodiscard]] virtual GLboolean
validate() const final;
392 [[maybe_unused]] virtual
void useProgram() const final;
399 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0) const final;
405 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0) const final;
411 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0) const final;
417 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2 mtx) const final;
423 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3 mtx) const final;
429 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4 mtx) const final;
435 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2x3 mtx) const final;
441 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3x2 mtx) const final;
447 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat2x4 mtx) const final;
453 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4x2 mtx) const final;
459 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat3x4 mtx) const final;
465 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::mat4x3 mtx) const final;
473 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1) const final;
480 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1) const final;
487 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1) const final;
496 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2) const final;
504 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2) const final;
512 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2) const final;
522 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
531 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2, GLint v3) const final;
540 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
547 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec2 value) const final;
553 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const final;
559 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const final;
566 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec3 value) const final;
572 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const final;
578 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const final;
585 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::vec4 value) const final;
591 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const final;
597 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const final;
606 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLfloat *value) const final;
614 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLint *value) const final;
622 [[maybe_unused]] virtual
void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLuint *value) const final;
629 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0) const final;
635 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0) const final;
641 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0) const final;
647 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2 mtx) const final;
653 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3 mtx) const final;
659 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4 mtx) const final;
665 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2x3 mtx) const final;
671 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3x2 mtx) const final;
677 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat2x4 mtx) const final;
683 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4x2 mtx) const final;
689 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat3x4 mtx) const final;
695 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::mat4x3 mtx) const final;
703 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1) const final;
710 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1) const final;
717 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1) const final;
726 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2) const final;
734 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2) const final;
742 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2) const final;
752 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
761 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2, GLint v3) const final;
770 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
777 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec2 value) const final;
783 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec2 value) const final;
789 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec2 value) const final;
796 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec3 value) const final;
802 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec3 value) const final;
808 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec3 value) const final;
815 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::vec4 value) const final;
821 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::ivec4 value) const final;
827 [[maybe_unused]] virtual
void setProgramUniform(GLint uniformLocation, glm::uvec4 value) const final;
836 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLfloat *value) const final;
844 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLint *value) const final;
852 virtual
void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLuint *value) const final;
918 const
char *tessellationControlShaderFilename,
919 const
char *tessellationEvaluationShaderFilename,
920 const
char *geometryShaderFilename,
921 const
char *fragmentShaderFilename,
922 bool isSeparable ) final;
938 CSCI441_INTERNAL::ShaderUtils::enableDebugMessages();
944 CSCI441_INTERNAL::ShaderUtils::disableDebugMessages();
948 const char *vertexShaderFilename,
949 const char *fragmentShaderFilename
957 const char *vertexShaderFilename,
958 const char *fragmentShaderFilename,
959 const bool isSeparable
967 const char *vertexShaderFilename,
968 const char *tessellationControlShaderFilename,
969 const char *tessellationEvaluationShaderFilename,
970 const char *geometryShaderFilename,
971 const char *fragmentShaderFilename
973 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
974 geometryShaderFilename, fragmentShaderFilename,
false);
979 const char *vertexShaderFilename,
980 const char *tessellationControlShaderFilename,
981 const char *tessellationEvaluationShaderFilename,
982 const char *geometryShaderFilename,
983 const char *fragmentShaderFilename,
984 const bool isSeparable
986 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
987 geometryShaderFilename, fragmentShaderFilename, isSeparable);
992 const char *vertexShaderFilename,
993 const char *tessellationControlShaderFilename,
994 const char *tessellationEvaluationShaderFilename,
995 const char *fragmentShaderFilename
997 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
998 "", fragmentShaderFilename,
false);
1003 const char *vertexShaderFilename,
1004 const char *tessellationControlShaderFilename,
1005 const char *tessellationEvaluationShaderFilename,
1006 const char *fragmentShaderFilename,
1007 const bool isSeparable
1009 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
1010 "", fragmentShaderFilename, isSeparable);
1014 const char *vertexShaderFilename,
1015 const char *geometryShaderFilename,
1016 const char *fragmentShaderFilename
1018 mRegisterShaderProgram(vertexShaderFilename,
"",
"", geometryShaderFilename, fragmentShaderFilename,
false);
1023 const char *vertexShaderFilename,
1024 const char *geometryShaderFilename,
1025 const char *fragmentShaderFilename,
1026 const bool isSeparable
1028 mRegisterShaderProgram(vertexShaderFilename,
"",
"", geometryShaderFilename, fragmentShaderFilename, isSeparable);
1033 const char **shaderFilenames,
1034 const bool vertexPresent,
const bool tessellationPresent,
const bool geometryPresent,
const bool fragmentPresent,
1035 const bool isSeparable
1037 if( vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1038 if( !isSeparable ) {
1039 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1043 }
else if( vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1044 if( !isSeparable ) {
1045 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1049 }
else if( vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1050 if( !isSeparable ) {
1051 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1053 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3],
"", isSeparable);
1055 }
else if( vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1056 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], shaderFilenames[4], isSeparable);
1057 }
else if( vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1058 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2],
"", shaderFilenames[3], isSeparable);
1059 }
else if( vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1060 if( !isSeparable ) {
1061 fprintf(stderr,
"[ERROR]: Fragment Shader not present. Program must be separable.\n");
1065 }
else if( vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1067 }
else if( vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1069 }
else if( !vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1070 if( !isSeparable ) {
1071 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1075 }
else if( !vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1076 if( !isSeparable ) {
1077 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1081 }
else if( !vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1082 if( !isSeparable ) {
1083 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1085 mRegisterShaderProgram(
"", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], isSeparable);
1087 }
else if( !vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1088 if( !isSeparable ) {
1089 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1093 }
else if( !vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1094 if( !isSeparable ) {
1095 fprintf(stderr,
"[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1099 }
else if( !vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1100 if( !isSeparable ) {
1101 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1105 }
else if( !vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1106 if( !isSeparable ) {
1107 fprintf(stderr,
"[ERROR]: Vertex Shader not present. Program must be separable.\n");
1111 }
else if( !vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1112 fprintf(stderr,
"[ERROR]: At least one shader must be present.\n");
1114 fprintf(stderr,
"[ERROR]: Unknown state.\n");
1119 const char *vertexShaderFilename,
1120 const char *tessellationControlShaderFilename,
1121 const char *tessellationEvaluationShaderFilename,
1122 const char *geometryShaderFilename,
1123 const char *fragmentShaderFilename,
1124 const bool isSeparable
1127 glGetIntegerv(GL_MAJOR_VERSION, &major);
1128 glGetIntegerv(GL_MINOR_VERSION, &minor);
1130 if( sDEBUG ) printf(
"\n[INFO]: /--------------------------------------------------------\\\n");
1133 if( strcmp( vertexShaderFilename,
"" ) != 0 ) {
1134 if( sDEBUG ) printf(
"[INFO]: | Vertex Shader: %39s |\n", vertexShaderFilename );
1135 mVertexShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(vertexShaderFilename, GL_VERTEX_SHADER );
1137 mVertexShaderHandle = 0;
1140 if(strcmp(tessellationControlShaderFilename,
"" ) != 0 ) {
1141 if( sDEBUG ) printf(
"[INFO]: | Tess Control Shader: %33s |\n", tessellationControlShaderFilename );
1143 printf(
"[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1144 mTessellationControlShaderHandle = 0;
1146 mTessellationControlShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationControlShaderFilename, GL_TESS_CONTROL_SHADER );
1149 mTessellationControlShaderHandle = 0;
1152 if(strcmp(tessellationEvaluationShaderFilename,
"" ) != 0 ) {
1153 if( sDEBUG ) printf(
"[INFO]: | Tess Evaluation Shader: %30s |\n", tessellationEvaluationShaderFilename );
1155 printf(
"[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1156 mTessellationEvaluationShaderHandle = 0;
1158 mTessellationEvaluationShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationEvaluationShaderFilename, GL_TESS_EVALUATION_SHADER );
1161 mTessellationEvaluationShaderHandle = 0;
1164 if( strcmp( geometryShaderFilename,
"" ) != 0 ) {
1165 if( sDEBUG ) printf(
"[INFO]: | Geometry Shader: %37s |\n", geometryShaderFilename );
1166 if( major < 3 || (major == 3 && minor < 2) ) {
1167 printf(
"[ERROR]:| GEOMETRY SHADER NOT SUPPORTED!!! UPGRADE TO v3.2+ |\n" );
1168 mGeometryShaderHandle = 0;
1170 mGeometryShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(geometryShaderFilename, GL_GEOMETRY_SHADER );
1173 mGeometryShaderHandle = 0;
1176 if( strcmp( fragmentShaderFilename,
"" ) != 0 ) {
1177 if( sDEBUG ) printf(
"[INFO]: | Fragment Shader: %37s |\n", fragmentShaderFilename );
1178 mFragmentShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(fragmentShaderFilename, GL_FRAGMENT_SHADER );
1180 mFragmentShaderHandle = 0;
1183 mShaderProgramHandle = glCreateProgram();
1187 glProgramParameteri(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, GL_TRUE );
1191 if(mVertexShaderHandle != 0 ) {
1192 glAttachShader(mShaderProgramHandle, mVertexShaderHandle );
1194 if(mTessellationControlShaderHandle != 0 ) {
1195 glAttachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1197 if(mTessellationEvaluationShaderHandle != 0 ) {
1198 glAttachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1200 if(mGeometryShaderHandle != 0 ) {
1201 glAttachShader(mShaderProgramHandle, mGeometryShaderHandle );
1203 if(mFragmentShaderHandle != 0 ) {
1204 glAttachShader(mShaderProgramHandle, mFragmentShaderHandle );
1208 glLinkProgram(mShaderProgramHandle );
1210 if( sDEBUG ) printf(
"[INFO]: | Shader Program: %41s",
"|\n" );
1213 CSCI441_INTERNAL::ShaderUtils::printProgramLog(mShaderProgramHandle );
1216 if(mVertexShaderHandle != 0 ) {
1217 glDetachShader(mShaderProgramHandle, mVertexShaderHandle );
1218 glDeleteShader(mVertexShaderHandle );
1220 if(mTessellationControlShaderHandle != 0 ) {
1221 glDetachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1222 glDeleteShader(mTessellationControlShaderHandle );
1224 if(mTessellationEvaluationShaderHandle != 0 ) {
1225 glDetachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1226 glDeleteShader(mTessellationEvaluationShaderHandle );
1228 if(mGeometryShaderHandle != 0 ) {
1229 glDetachShader(mShaderProgramHandle, mGeometryShaderHandle );
1230 glDeleteShader(mGeometryShaderHandle );
1232 if(mFragmentShaderHandle != 0 ) {
1233 glDetachShader(mShaderProgramHandle, mFragmentShaderHandle );
1234 glDeleteShader(mFragmentShaderHandle );
1239 mpUniformLocationsMap =
new std::map<std::string, GLint>();
1241 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniforms);
1242 GLint max_uniform_name_size;
1243 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_size);
1244 if( numUniforms > 0 ) {
1245 for(GLint i = 0; i < numUniforms; i++) {
1246 auto name =
new GLchar[max_uniform_name_size];
1247 int actual_length = 0;
1250 glGetActiveUniform(mShaderProgramHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
1253 for(
int j = 0; j < size; j++) {
1254 const int max_array_size = actual_length + 4 + 2 + 1;
1255 auto array_name =
new GLchar[max_array_size];
1256 snprintf(array_name, max_array_size,
"%s[%i]", name, j);
1257 location = glGetUniformLocation(mShaderProgramHandle, array_name);
1258 mpUniformLocationsMap->emplace(array_name, location);
1259 delete[] array_name;
1262 location = glGetUniformLocation(mShaderProgramHandle, name);
1263 mpUniformLocationsMap->emplace(name, location);
1270 mpAttributeLocationsMap =
new std::map<std::string, GLint>();
1271 GLint numAttributes;
1272 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttributes );
1273 GLint max_attr_name_size;
1274 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_size);
1275 if( numAttributes > 0 ) {
1276 for(GLint i = 0; i < numAttributes; i++) {
1277 auto name =
new GLchar[max_attr_name_size];
1278 int actual_length = 0;
1281 glGetActiveAttrib(mShaderProgramHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
1284 for(
int j = 0; j < size; j++ ) {
1285 const int max_array_size = actual_length + 4 + 2 + 1;
1286 auto array_name =
new GLchar[max_array_size];
1287 snprintf( array_name, max_array_size,
"%s[%i]", name, j );
1288 location = glGetAttribLocation(mShaderProgramHandle, array_name );
1289 mpAttributeLocationsMap->emplace(array_name, location);
1290 delete[] array_name;
1293 location = glGetAttribLocation(mShaderProgramHandle, name );
1294 mpAttributeLocationsMap->emplace(name, location);
1300 GLint separable = GL_FALSE;
1301 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, &separable );
1303 if( sDEBUG ) printf(
"[INFO]: | Program Separable: %35s |\n", (separable ?
"Yes" :
"No"));
1306 glGetProgramiv(mShaderProgramHandle, GL_LINK_STATUS, &linkStatus );
1309 if(linkStatus == GL_TRUE) {
1310 CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(mShaderProgramHandle, mVertexShaderHandle != 0,
1311 mTessellationControlShaderHandle != 0,
1312 mTessellationEvaluationShaderHandle != 0,
1313 mGeometryShaderHandle != 0, mFragmentShaderHandle != 0,
1316 if(sDEBUG) printf(
"[INFO]: \\--------------------------------------------------------/\n\n");
1319 return mShaderProgramHandle != 0;
1323 const GLint uniformLoc = glGetUniformLocation(mShaderProgramHandle, uniformName );
1324 if( uniformLoc == GL_INVALID_VALUE )
1325 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle );
1330 const GLint uniformBlockLoc = glGetUniformBlockIndex(mShaderProgramHandle, uniformBlockName );
1331 if( uniformBlockLoc == GL_INVALID_INDEX )
1332 fprintf(stderr,
"[ERROR]: Could not find uniform block \"%s\" for Shader Program %u\n", uniformBlockName, mShaderProgramHandle );
1333 return uniformBlockLoc;
1338 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1344 const GLint blockSize = getUniformBlockSize( uniformBlockName );
1345 return (GLubyte*)malloc(blockSize);
1350 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1355 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1360 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1362 const auto indices = (GLuint*)malloc(numUniforms*
sizeof(GLuint));
1363 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1365 const auto offsets = (GLint*)malloc(numUniforms*
sizeof(GLint));
1366 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1372 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1374 const auto indices = (GLuint*)malloc(numUniforms*
sizeof(GLuint));
1375 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1377 const auto offsets = (GLint*)malloc(numUniforms*
sizeof(GLint));
1378 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1383 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1388 const auto attribIter = mpAttributeLocationsMap->find(attributeName);
1389 if(attribIter == mpAttributeLocationsMap->end() ) {
1390 fprintf(stderr,
"[ERROR]: Could not find attribute \"%s\" for Shader Program %u\n", attributeName, mShaderProgramHandle );
1393 return attribIter->second;
1398 const GLuint subroutineIndex = glGetSubroutineIndex(mShaderProgramHandle, shaderStage, subroutineName );
1399 if( subroutineIndex == GL_INVALID_INDEX )
1400 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 );
1401 return subroutineIndex;
1406 const GLint subroutineUniform = glGetSubroutineUniformLocation(mShaderProgramHandle, shaderStage, subroutineName );
1407 if ( subroutineUniform == GL_INVALID_VALUE )
1408 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 );
1409 return subroutineUniform;
1414 glUniformSubroutinesuiv( shaderStage, numIndices, indices );
1420 const GLint imageLoc = getUniformLocation(imageName);
1422 if(imageLoc == GL_INVALID_INDEX) {
1423 fprintf(stderr,
"[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1428 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1430 return bindingPoint;
1435 const GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1437 if(ssboIndex == GL_INVALID_INDEX) {
1438 fprintf(stderr,
"[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1442 constexpr GLenum props = GL_BUFFER_BINDING;
1444 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, 1, &props, 1,
nullptr, &binding);
1451 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1453 if(uniformIndex == GL_INVALID_INDEX) {
1454 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1458 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1459 GLint atomicIndex, binding;
1460 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1,
nullptr, &atomicIndex);
1461 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
1468 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1470 if(uniformIndex == GL_INVALID_INDEX) {
1471 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1476 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1482 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1484 if(uniformIndex == GL_INVALID_INDEX) {
1485 fprintf(stderr,
"[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1489 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1490 GLint atomicIndex, bufferSize;
1491 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1,
nullptr, &atomicIndex);
1492 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize);
1499 GLint numUniform = 0;
1500 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1506 GLint numUniformBlocks = 0;
1507 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1508 return numUniformBlocks;
1514 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1520 return glGetFragDataLocation(mShaderProgramHandle, name);
1525 return glGetFragDataIndex(mShaderProgramHandle, name);
1529 return mShaderProgramHandle;
1533 if (mShaderProgramHandle == 0) {
1537 glValidateProgram(mShaderProgramHandle);
1538 GLint validateStatus = GL_FALSE;
1539 glGetProgramiv(mShaderProgramHandle, GL_VALIDATE_STATUS, &validateStatus);
1541 if (validateStatus == GL_FALSE && sDEBUG) {
1542 CSCI441_INTERNAL::ShaderUtils::printProgramInfoLog(mShaderProgramHandle);
1545 return (validateStatus == GL_TRUE);
1550 glUseProgram(mShaderProgramHandle );
1555 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1556 if(uniformIter != mpUniformLocationsMap->end()) {
1557 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1559 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1565 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1566 if(uniformIter != mpUniformLocationsMap->end()) {
1567 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1569 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1575 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1580 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1581 if(uniformIter != mpUniformLocationsMap->end()) {
1582 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1584 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1590 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1595 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1596 if(uniformIter != mpUniformLocationsMap->end()) {
1597 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1599 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1605 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1609 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1610 if(uniformIter != mpUniformLocationsMap->end()) {
1613 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1616 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1619 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1622 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1625 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1629 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1635 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1636 if(uniformIter != mpUniformLocationsMap->end()) {
1637 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1639 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1645 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1646 if(uniformIter != mpUniformLocationsMap->end()) {
1647 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1649 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1655 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1656 if(uniformIter != mpUniformLocationsMap->end()) {
1657 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1659 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1665 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1666 if(uniformIter != mpUniformLocationsMap->end()) {
1667 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1669 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1675 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1676 if(uniformIter != mpUniformLocationsMap->end()) {
1677 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1679 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1685 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1686 if(uniformIter != mpUniformLocationsMap->end()) {
1687 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1689 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1695 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1696 if(uniformIter != mpUniformLocationsMap->end()) {
1697 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1699 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1705 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1706 if(uniformIter != mpUniformLocationsMap->end()) {
1709 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1712 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1715 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1718 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1721 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1725 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1731 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1732 if(uniformIter != mpUniformLocationsMap->end()) {
1733 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1735 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1741 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1742 if(uniformIter != mpUniformLocationsMap->end()) {
1743 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1745 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1751 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1752 if(uniformIter != mpUniformLocationsMap->end()) {
1753 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1755 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1761 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1762 if(uniformIter != mpUniformLocationsMap->end()) {
1763 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1765 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1771 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1772 if(uniformIter != mpUniformLocationsMap->end()) {
1773 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1775 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1781 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1782 if(uniformIter != mpUniformLocationsMap->end()) {
1783 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1785 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1791 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1792 if(uniformIter != mpUniformLocationsMap->end()) {
1793 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1795 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1801 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1802 if(uniformIter != mpUniformLocationsMap->end()) {
1805 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1808 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1811 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1814 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1817 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1821 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1827 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1828 if(uniformIter != mpUniformLocationsMap->end()) {
1829 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1831 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1837 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1838 if(uniformIter != mpUniformLocationsMap->end()) {
1839 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1841 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1847 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1848 if(uniformIter != mpUniformLocationsMap->end()) {
1849 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1851 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1857 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1858 if(uniformIter != mpUniformLocationsMap->end()) {
1859 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1861 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1867 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1868 if(uniformIter != mpUniformLocationsMap->end()) {
1869 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1871 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1877 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1878 if(uniformIter != mpUniformLocationsMap->end()) {
1879 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1881 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1887 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1888 if(uniformIter != mpUniformLocationsMap->end()) {
1889 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1891 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1897 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1898 if(uniformIter != mpUniformLocationsMap->end()) {
1899 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1901 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1907 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1908 if(uniformIter != mpUniformLocationsMap->end()) {
1909 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1911 fprintf(stderr,
"[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1917 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1922 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1927 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1932 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1937 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1942 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1947 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1953 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1956 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1959 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1962 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1965 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1972 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1977 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1982 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1987 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1992 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1997 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2002 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2008 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
2011 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
2014 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
2017 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
2020 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2027 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
2032 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
2037 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
2042 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
2047 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
2052 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2057 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2063 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
2066 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
2069 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
2072 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
2075 fprintf(stderr,
"[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2082 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2087 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2092 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2097 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2102 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2107 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2112 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2117 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2122 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2127 GLbitfield shaderBits = 0;
2128 if( mVertexShaderHandle != 0 ) shaderBits |= GL_VERTEX_SHADER_BIT;
2129 if( mTessellationControlShaderHandle != 0 ) shaderBits |= GL_TESS_CONTROL_SHADER_BIT;
2130 if( mTessellationEvaluationShaderHandle != 0 ) shaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
2131 if( mGeometryShaderHandle != 0 ) shaderBits |= GL_GEOMETRY_SHADER_BIT;
2132 if( mFragmentShaderHandle != 0 ) shaderBits |= GL_FRAGMENT_SHADER_BIT;
2137 mVertexShaderHandle(0),
2138 mTessellationControlShaderHandle(0), mTessellationEvaluationShaderHandle(0),
2139 mGeometryShaderHandle(0),
2140 mFragmentShaderHandle(0),
2141 mShaderProgramHandle(0),
2142 mpUniformLocationsMap(nullptr), mpAttributeLocationsMap(nullptr)
2154 _moveFromSource(src);
2160 _moveFromSource(src);
2165inline void CSCI441::ShaderProgram::_cleanupSelf() {
2167 GLint infoLogLength = 0;
2168 constexpr int maxLength = 1000;
2170 glDeleteProgram(mShaderProgramHandle );
2173 const auto infoLog =
new GLchar[maxLength];
2175 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2178 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2180 if(infoLogLength > 0 ) {
2182 if( sDEBUG ) printf(
"[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ?
"Success" :
" Error"), infoLog );
2185 delete mpUniformLocationsMap;
2186 delete mpAttributeLocationsMap;
2189 mVertexShaderHandle = 0;
2190 mTessellationControlShaderHandle = 0;
2191 mTessellationEvaluationShaderHandle = 0;
2192 mGeometryShaderHandle = 0;
2193 mFragmentShaderHandle = 0;
2194 mShaderProgramHandle = 0;
2195 mpUniformLocationsMap =
nullptr;
2196 mpAttributeLocationsMap =
nullptr;
2199inline void CSCI441::ShaderProgram::_moveFromSource(ShaderProgram &src) {
2200 mVertexShaderHandle = src.mVertexShaderHandle;
2201 src.mVertexShaderHandle = 0;
2203 mTessellationControlShaderHandle = src.mTessellationControlShaderHandle;
2204 src.mTessellationControlShaderHandle = 0;
2206 mTessellationEvaluationShaderHandle = src.mTessellationEvaluationShaderHandle;
2207 src.mTessellationEvaluationShaderHandle = 0;
2209 mGeometryShaderHandle = src.mGeometryShaderHandle;
2210 src.mGeometryShaderHandle = 0;
2212 mFragmentShaderHandle = src.mFragmentShaderHandle;
2213 src.mFragmentShaderHandle = 0;
2215 mShaderProgramHandle = src.mShaderProgramHandle;
2216 src.mShaderProgramHandle = 0;
2218 mpUniformLocationsMap = src.mpUniformLocationsMap;
2219 src.mpUniformLocationsMap =
nullptr;
2221 mpAttributeLocationsMap = src.mpAttributeLocationsMap;
2222 src.mpAttributeLocationsMap =
nullptr;
2228 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2230 fprintf(stderr,
"[ERROR]: Driver does not support any binary formats.\n");
2236 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2239 std::vector<GLubyte> buffer(length);
2241 glGetProgramBinary(mShaderProgramHandle, length,
nullptr, &format, buffer.data());
2244 fprintf(stdout,
"[INFO]: Writing to %s, binary format %d\n",BINARY_FILE_NAME, format);
2245 std::ofstream out(BINARY_FILE_NAME, std::ios::binary);
2246 out.write(
reinterpret_cast<char *
>(buffer.data()), length );
2254 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2256 fprintf(stderr,
"[ERROR]: Driver does not support any binary formats.\n");
2260 const GLuint program = glCreateProgram();
2263 std::ifstream inputStream(BINARY_FILE_NAME, std::ios::binary);
2264 const std::istreambuf_iterator<char> startIt(inputStream);
2265 constexpr std::istreambuf_iterator<char> endIt;
2266 const std::vector<char> buffer(startIt, endIt);
2267 inputStream.close();
2270 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2274 glGetProgramiv(program, GL_LINK_STATUS, &status);
2275 if( GL_FALSE == status ) {
2276 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2281 shaderProgram->mShaderProgramHandle = program;
2282 return shaderProgram;
Helper functions to work with OpenGL Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:36
virtual GLbitfield getProgramStages() const
returns a single value corresponding to which shader stages are present in this shader program
Definition: ShaderProgram.hpp:2126
GLuint mTessellationEvaluationShaderHandle
handle to the tessellation evaluation shader stage
Definition: ShaderProgram.hpp:883
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:1349
GLuint mVertexShaderHandle
handle to the vertex shader stage
Definition: ShaderProgram.hpp:875
virtual GLubyte * getUniformBlockBuffer(const GLchar *uniformBlockName) const final
Returns an allocated buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1343
virtual void setProgramUniform(const GLchar *uniformName, GLfloat v0) const final
sets the program uniform consisting of one float
Definition: ShaderProgram.hpp:1554
static ShaderProgram * loadShaderProgramFromBinaryFile(const char *BINARY_FILE_NAME, GLenum format)
loads precompiled shader program binary from external file
Definition: ShaderProgram.hpp:2252
virtual GLint getAttributeLocation(const GLchar *attributeName) const final
Returns the location of the given attribute in this shader program.
Definition: ShaderProgram.hpp:1387
GLuint mShaderProgramHandle
handle to the shader program
Definition: ShaderProgram.hpp:896
GLuint mTessellationControlShaderHandle
handle to the tessellation control shader stage
Definition: ShaderProgram.hpp:879
virtual void useProgram() const final
Sets the Shader Program to be active.
Definition: ShaderProgram.hpp:1549
virtual GLuint getNumAttributes() const final
Returns the number of active attributes in this shader program.
Definition: ShaderProgram.hpp:1512
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:1382
std::map< std::string, GLint > * mpUniformLocationsMap
caches locations of uniform names within shader program
Definition: ShaderProgram.hpp:901
virtual GLint getUniformBlockIndex(const GLchar *uniformBlockName) const final
Returns the index of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1329
virtual GLint getAtomicCounterBufferOffset(const GLchar *atomicName) const final
Returns the offset into the buffer for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1467
ShaderProgram & operator=(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual GLuint getNumUniforms() const final
Returns the number of active uniforms in this shader program.
Definition: ShaderProgram.hpp:1498
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:1405
virtual GLint getImageBinding(const GLchar *imageName) const final
Returns the binding point for the corresponding image uniform.
Definition: ShaderProgram.hpp:1419
virtual ~ShaderProgram()
Clean up memory associated with the Shader Program.
Definition: ShaderProgram.hpp:2147
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1528
GLuint mGeometryShaderHandle
handle to the geometry shader stage
Definition: ShaderProgram.hpp:887
virtual GLint getAtomicCounterBufferBinding(const GLchar *atomicName) const final
Returns the binding point for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1450
static bool sDEBUG
if DEBUG information should be printed or not
Definition: ShaderProgram.hpp:870
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:1397
virtual void setSubroutineIndices(GLenum shaderStage, GLsizei numIndices, const GLuint *indices) final
Sets the subroutines to use for a given shader stage.
Definition: ShaderProgram.hpp:1413
virtual GLint getShaderStorageBlockBinding(const GLchar *ssboName) const final
Returns the binding point for the corresponding shader storage block.
Definition: ShaderProgram.hpp:1434
virtual bool writeShaderProgramBinaryToFile(const char *BINARY_FILE_NAME) const final
writes precompiled shader program binary to external file
Definition: ShaderProgram.hpp:2226
static void disableDebugMessages()
Disables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:942
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1336
static void enableDebugMessages()
Enables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:936
virtual GLboolean validate() const final
checks if program can execute in its current OpenGL state
Definition: ShaderProgram.hpp:1532
std::map< std::string, GLint > * mpAttributeLocationsMap
caches locations of attribute names within shader program
Definition: ShaderProgram.hpp:905
virtual GLuint getNumUniformBlocks() const final
Returns the number of active uniform blocks in this shader program.
Definition: ShaderProgram.hpp:1505
ShaderProgram(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual GLint getFragmentDataLocation(const GLchar *name) const final
query the bindings of color numbers to user-defined varying out variables
Definition: ShaderProgram.hpp:1519
GLuint mFragmentShaderHandle
handle to the fragment shader stage
Definition: ShaderProgram.hpp:891
ShaderProgram()
creates an empty shader program object
Definition: ShaderProgram.hpp:2136
virtual GLint getFragmentDataIndex(const GLchar *name) const final
query the bindings of color indices to user-defined varying out variables
Definition: ShaderProgram.hpp:1524
virtual GLint getUniformLocation(const GLchar *uniformName) const final
Returns the location of the given uniform in this shader program.
Definition: ShaderProgram.hpp:1322
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:1118
virtual GLint getAtomicCounterBufferSize(const GLchar *atomicName) const final
Returns the full buffer size for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1481
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17