CSCI441 OpenGL Library 5.13.0
CS@Mines CSCI441 Computer Graphics Course Library
Loading...
Searching...
No Matches
ShaderProgram.hpp
Go to the documentation of this file.
1
13#ifndef CSCI441_SHADER_PROGRAM_HPP
14#define CSCI441_SHADER_PROGRAM_HPP
15
16#include "ShaderUtils.hpp"
17
18#include <glm/glm.hpp>
19#include <glm/gtc/type_ptr.hpp> // for glm::value_ptr()
20
21#include <cstdlib>
22#include <fstream>
23#include <map>
24#include <string>
25#include <vector>
26
28
29namespace CSCI441 {
30
36 public:
41 [[maybe_unused]] static void enableDebugMessages();
46 [[maybe_unused]] static void disableDebugMessages();
47
53 ShaderProgram( const char *vertexShaderFilename,
54 const char *fragmentShaderFilename );
55
62 [[maybe_unused]]
63 ShaderProgram( const char *vertexShaderFilename,
64 const char *fragmentShaderFilename,
65 bool isSeparable );
66
74 [[maybe_unused]]
75 ShaderProgram( const char *vertexShaderFilename,
76 const char *tessellationControlShaderFilename,
77 const char *tessellationEvaluationShaderFilename,
78 const char *geometryShaderFilename,
79 const char *fragmentShaderFilename );
80
90 [[maybe_unused]]
91 ShaderProgram( const char *vertexShaderFilename,
92 const char *tessellationControlShaderFilename,
93 const char *tessellationEvaluationShaderFilename,
94 const char *geometryShaderFilename,
95 const char *fragmentShaderFilename,
96 bool isSeparable );
97
105 [[maybe_unused]]
106 ShaderProgram( const char *vertexShaderFilename,
107 const char *tessellationControlShaderFilename,
108 const char *tessellationEvaluationShaderFilename,
109 const char *fragmentShaderFilename );
110
119 [[maybe_unused]]
120 ShaderProgram( const char *vertexShaderFilename,
121 const char *tessellationControlShaderFilename,
122 const char *tessellationEvaluationShaderFilename,
123 const char *fragmentShaderFilename,
124 bool isSeparable);
125
132 ShaderProgram( const char *vertexShaderFilename,
133 const char *geometryShaderFilename,
134 const char *fragmentShaderFilename );
135
143 [[maybe_unused]]
144 ShaderProgram( const char *vertexShaderFilename,
145 const char *geometryShaderFilename,
146 const char *fragmentShaderFilename,
147 bool isSeparable );
148
159 [[maybe_unused]]
160 ShaderProgram( const char **shaderFilenames,
161 bool vertexPresent, bool tessellationPresent, bool geometryPresent, bool fragmentPresent,
162 bool isSeparable );
163
167 virtual ~ShaderProgram();
168
172 ShaderProgram(const ShaderProgram&) = delete;
177
181 ShaderProgram(ShaderProgram&&) noexcept;
186 ShaderProgram& operator=(ShaderProgram&&) noexcept;
187
193 virtual bool writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const final;
194
201 static ShaderProgram* loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, GLenum format);
202
209 virtual GLint getUniformLocation( const GLchar *uniformName ) const final;
210
217 virtual GLint getUniformBlockIndex( const GLchar *uniformBlockName ) const final;
224 virtual GLint getUniformBlockSize( const GLchar *uniformBlockName ) const final;
231 [[maybe_unused]] virtual GLubyte* getUniformBlockBuffer( const GLchar *uniformBlockName ) const final;
238 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const GLchar *uniformBlockName ) const final;
246 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const GLchar *uniformBlockName, const GLchar *names[] ) const final;
253 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex ) const final;
261 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex, const GLchar *names[] ) const final;
268 virtual void setUniformBlockBinding( const GLchar *uniformBlockName, GLuint binding ) const final;
269
276 [[maybe_unused]] virtual GLint getAttributeLocation( const GLchar *attributeName ) const final;
277
286 [[maybe_unused]] virtual GLuint getSubroutineIndex( GLenum shaderStage, const GLchar *subroutineName ) const final;
287
296 [[maybe_unused]] virtual GLint getSubroutineUniformLocation( GLenum shaderStage, const GLchar *subroutineName ) const final;
297
306 [[maybe_unused]] virtual void setSubroutineIndices( GLenum shaderStage, GLsizei numIndices, const GLuint *indices ) final;
307
314 [[maybe_unused]] virtual GLint getImageBinding(const GLchar* imageName) const final;
315
322 [[maybe_unused]] virtual GLint getShaderStorageBlockBinding(const GLchar* ssboName) const final;
323
330 [[maybe_unused]] virtual GLint getAtomicCounterBufferBinding(const GLchar* atomicName) const final;
337 [[maybe_unused]] virtual GLint getAtomicCounterBufferOffset(const GLchar* atomicName) const final;
344 [[maybe_unused]] virtual GLint getAtomicCounterBufferSize(const GLchar* atomicName) const final;
345
350 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniforms() const final;
355 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniformBlocks() const final;
360 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumAttributes() const final;
361
366 [[nodiscard]] virtual GLuint getShaderProgramHandle() const final;
367
371 [[maybe_unused]] virtual void useProgram() const final;
372
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;
445
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;
467
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;
492
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;
520
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;
539
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;
558
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;
577
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;
602
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;
675
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;
697
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;
722
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;
750
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;
769
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;
788
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;
807
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;
832
837 [[maybe_unused]] [[nodiscard]] virtual GLbitfield getProgramStages() const final;
838
839 protected:
844
849 static bool sDEBUG;
850
871
876
880 std::map<std::string, GLint> *mpUniformLocationsMap;
884 std::map<std::string, GLint> *mpAttributeLocationsMap;
885
896 virtual bool mRegisterShaderProgram(const char *vertexShaderFilename,
897 const char *tessellationControlShaderFilename,
898 const char *tessellationEvaluationShaderFilename,
899 const char *geometryShaderFilename,
900 const char *fragmentShaderFilename,
901 bool isSeparable ) final;
902
903 private:
904 void _cleanupSelf();
905 void _moveFromSource(ShaderProgram& src);
906 };
907
908}
909
911
912inline bool CSCI441::ShaderProgram::sDEBUG = true;
913
914[[maybe_unused]]
916 sDEBUG = true;
917 CSCI441_INTERNAL::ShaderUtils::enableDebugMessages();
918}
919
920[[maybe_unused]]
922 sDEBUG = false;
923 CSCI441_INTERNAL::ShaderUtils::disableDebugMessages();
924}
925
927 const char *vertexShaderFilename,
928 const char *fragmentShaderFilename
929) : ShaderProgram()
930{
931 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, false);
932}
933
934[[maybe_unused]]
936 const char *vertexShaderFilename,
937 const char *fragmentShaderFilename,
938 const bool isSeparable
939) : ShaderProgram()
940{
941 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, isSeparable);
942}
943
944[[maybe_unused]]
946 const char *vertexShaderFilename,
947 const char *tessellationControlShaderFilename,
948 const char *tessellationEvaluationShaderFilename,
949 const char *geometryShaderFilename,
950 const char *fragmentShaderFilename
951) : ShaderProgram() {
952 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
953 geometryShaderFilename, fragmentShaderFilename, false);
954}
955
956[[maybe_unused]]
958 const char *vertexShaderFilename,
959 const char *tessellationControlShaderFilename,
960 const char *tessellationEvaluationShaderFilename,
961 const char *geometryShaderFilename,
962 const char *fragmentShaderFilename,
963 const bool isSeparable
964) : ShaderProgram() {
965 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
966 geometryShaderFilename, fragmentShaderFilename, isSeparable);
967}
968
969[[maybe_unused]]
971 const char *vertexShaderFilename,
972 const char *tessellationControlShaderFilename,
973 const char *tessellationEvaluationShaderFilename,
974 const char *fragmentShaderFilename
975) : ShaderProgram() {
976 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
977 "", fragmentShaderFilename, false);
978}
979
980[[maybe_unused]]
982 const char *vertexShaderFilename,
983 const char *tessellationControlShaderFilename,
984 const char *tessellationEvaluationShaderFilename,
985 const char *fragmentShaderFilename,
986 const bool isSeparable
987) : ShaderProgram() {
988 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
989 "", fragmentShaderFilename, isSeparable);
990}
991
993 const char *vertexShaderFilename,
994 const char *geometryShaderFilename,
995 const char *fragmentShaderFilename
996) : ShaderProgram() {
997 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, false);
998}
999
1000[[maybe_unused]]
1002 const char *vertexShaderFilename,
1003 const char *geometryShaderFilename,
1004 const char *fragmentShaderFilename,
1005 const bool isSeparable
1006) : ShaderProgram() {
1007 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, isSeparable);
1008}
1009
1010[[maybe_unused]]
1012 const char **shaderFilenames,
1013 const bool vertexPresent, const bool tessellationPresent, const bool geometryPresent, const bool fragmentPresent,
1014 const bool isSeparable
1015) : ShaderProgram() {
1016 if( vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1017 if( !isSeparable ) {
1018 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1019 } else {
1020 mRegisterShaderProgram(shaderFilenames[0], "", "", "", "", isSeparable);
1021 }
1022 } else if( vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1023 if( !isSeparable ) {
1024 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1025 } else {
1026 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", "", isSeparable);
1027 }
1028 } else if( vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1029 if( !isSeparable ) {
1030 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1031 } else {
1032 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], "", isSeparable);
1033 }
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");
1041 } else {
1042 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], "", isSeparable);
1043 }
1044 } else if( vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1045 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], shaderFilenames[2], isSeparable);
1046 } else if( vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1047 mRegisterShaderProgram(shaderFilenames[0], "", "", "", shaderFilenames[1], isSeparable);
1048 } else if( !vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1049 if( !isSeparable ) {
1050 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1051 } else {
1052 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", "", isSeparable);
1053 }
1054 } else if( !vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1055 if( !isSeparable ) {
1056 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1057 } else {
1058 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", isSeparable);
1059 }
1060 } else if( !vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1061 if( !isSeparable ) {
1062 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1063 } else {
1064 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], isSeparable);
1065 }
1066 } else if( !vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1067 if( !isSeparable ) {
1068 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1069 } else {
1070 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", shaderFilenames[2], isSeparable);
1071 }
1072 } else if( !vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1073 if( !isSeparable ) {
1074 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1075 } else {
1076 mRegisterShaderProgram("", "", "", shaderFilenames[0], "", isSeparable);
1077 }
1078 } else if( !vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1079 if( !isSeparable ) {
1080 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1081 } else {
1082 mRegisterShaderProgram("", "", "", shaderFilenames[0], shaderFilenames[1], isSeparable);
1083 }
1084 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1085 if( !isSeparable ) {
1086 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1087 } else {
1088 mRegisterShaderProgram("", "", "", "", shaderFilenames[0], isSeparable);
1089 }
1090 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1091 fprintf(stderr, "[ERROR]: At least one shader must be present.\n");
1092 } else {
1093 fprintf(stderr, "[ERROR]: Unknown state.\n");
1094 }
1095}
1096
1098 const char *vertexShaderFilename,
1099 const char *tessellationControlShaderFilename,
1100 const char *tessellationEvaluationShaderFilename,
1101 const char *geometryShaderFilename,
1102 const char *fragmentShaderFilename,
1103 const bool isSeparable
1104) {
1105 GLint major, minor;
1106 glGetIntegerv(GL_MAJOR_VERSION, &major);
1107 glGetIntegerv(GL_MINOR_VERSION, &minor);
1108
1109 if( sDEBUG ) printf( "\n[INFO]: /--------------------------------------------------------\\\n");
1110
1111 // compile each one of our shaders
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 );
1115 } else {
1116 mVertexShaderHandle = 0;
1117 }
1118
1119 if(strcmp(tessellationControlShaderFilename, "" ) != 0 ) {
1120 if( sDEBUG ) printf("[INFO]: | Tess Control Shader: %33s |\n", tessellationControlShaderFilename );
1121 if( major < 4 ) {
1122 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1123 mTessellationControlShaderHandle = 0;
1124 } else {
1125 mTessellationControlShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationControlShaderFilename, GL_TESS_CONTROL_SHADER );
1126 }
1127 } else {
1128 mTessellationControlShaderHandle = 0;
1129 }
1130
1131 if(strcmp(tessellationEvaluationShaderFilename, "" ) != 0 ) {
1132 if( sDEBUG ) printf("[INFO]: | Tess Evaluation Shader: %30s |\n", tessellationEvaluationShaderFilename );
1133 if( major < 4 ) {
1134 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1135 mTessellationEvaluationShaderHandle = 0;
1136 } else {
1137 mTessellationEvaluationShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationEvaluationShaderFilename, GL_TESS_EVALUATION_SHADER );
1138 }
1139 } else {
1140 mTessellationEvaluationShaderHandle = 0;
1141 }
1142
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;
1148 } else {
1149 mGeometryShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(geometryShaderFilename, GL_GEOMETRY_SHADER );
1150 }
1151 } else {
1152 mGeometryShaderHandle = 0;
1153 }
1154
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 );
1158 } else {
1159 mFragmentShaderHandle = 0;
1160 }
1161 // get a handle to a shader program
1162 mShaderProgramHandle = glCreateProgram();
1163
1164 // if program is separable, make it so
1165 if( isSeparable ) {
1166 glProgramParameteri(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, GL_TRUE );
1167 }
1168
1169 // attach the vertex and fragment shaders to the shader program
1170 if(mVertexShaderHandle != 0 ) {
1171 glAttachShader(mShaderProgramHandle, mVertexShaderHandle );
1172 }
1173 if(mTessellationControlShaderHandle != 0 ) {
1174 glAttachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1175 }
1176 if(mTessellationEvaluationShaderHandle != 0 ) {
1177 glAttachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1178 }
1179 if(mGeometryShaderHandle != 0 ) {
1180 glAttachShader(mShaderProgramHandle, mGeometryShaderHandle );
1181 }
1182 if(mFragmentShaderHandle != 0 ) {
1183 glAttachShader(mShaderProgramHandle, mFragmentShaderHandle );
1184 }
1185
1186 // link all the programs together on the GPU
1187 glLinkProgram(mShaderProgramHandle );
1188
1189 if( sDEBUG ) printf( "[INFO]: | Shader Program: %41s", "|\n" );
1190
1191 // check the program log
1192 CSCI441_INTERNAL::ShaderUtils::printProgramLog(mShaderProgramHandle );
1193
1194 // detach & delete the vertex and fragment shaders to the shader program
1195 if(mVertexShaderHandle != 0 ) {
1196 glDetachShader(mShaderProgramHandle, mVertexShaderHandle );
1197 glDeleteShader(mVertexShaderHandle );
1198 }
1199 if(mTessellationControlShaderHandle != 0 ) {
1200 glDetachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1201 glDeleteShader(mTessellationControlShaderHandle );
1202 }
1203 if(mTessellationEvaluationShaderHandle != 0 ) {
1204 glDetachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1205 glDeleteShader(mTessellationEvaluationShaderHandle );
1206 }
1207 if(mGeometryShaderHandle != 0 ) {
1208 glDetachShader(mShaderProgramHandle, mGeometryShaderHandle );
1209 glDeleteShader(mGeometryShaderHandle );
1210 }
1211 if(mFragmentShaderHandle != 0 ) {
1212 glDetachShader(mShaderProgramHandle, mFragmentShaderHandle );
1213 glDeleteShader(mFragmentShaderHandle );
1214 }
1215
1216
1217 // map uniforms
1218 mpUniformLocationsMap = new std::map<std::string, GLint>();
1219 GLint numUniforms;
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;
1227 int size = 0;
1228 GLenum type;
1229 glGetActiveUniform(mShaderProgramHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
1230 GLint location;
1231 if(size > 1) {
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;
1239 }
1240 } else {
1241 location = glGetUniformLocation(mShaderProgramHandle, name);
1242 mpUniformLocationsMap->emplace(name, location);
1243 }
1244 delete[] name;
1245 }
1246 }
1247
1248 // map attributes
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;
1258 int size = 0;
1259 GLenum type;
1260 glGetActiveAttrib(mShaderProgramHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
1261 GLint location;
1262 if( size > 1 ) {
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;
1270 }
1271 } else {
1272 location = glGetAttribLocation(mShaderProgramHandle, name );
1273 mpAttributeLocationsMap->emplace(name, location);
1274 }
1275 delete[] name;
1276 }
1277 }
1278
1279 GLint separable = GL_FALSE;
1280 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, &separable );
1281
1282 if( sDEBUG ) printf( "[INFO]: | Program Separable: %35s |\n", (separable ? "Yes" : "No"));
1283
1284 GLint linkStatus;
1285 glGetProgramiv(mShaderProgramHandle, GL_LINK_STATUS, &linkStatus );
1286
1287 // print shader info for uniforms & attributes
1288 if(linkStatus == 1) {
1289 CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(mShaderProgramHandle, mVertexShaderHandle != 0,
1290 mTessellationControlShaderHandle != 0,
1291 mTessellationEvaluationShaderHandle != 0,
1292 mGeometryShaderHandle != 0, mFragmentShaderHandle != 0,
1293 false, true);
1294 }
1295 // return handle
1296 return mShaderProgramHandle != 0;
1297}
1298
1299inline GLint CSCI441::ShaderProgram::getUniformLocation( const GLchar *uniformName ) const {
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 );
1303 return uniformLoc;
1304}
1305
1306inline GLint CSCI441::ShaderProgram::getUniformBlockIndex( const GLchar *uniformBlockName ) const {
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;
1311}
1312
1313inline GLint CSCI441::ShaderProgram::getUniformBlockSize( const GLchar *uniformBlockName ) const {
1314 GLint blockSize;
1315 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1316 return blockSize;
1317}
1318
1319[[maybe_unused]]
1320inline GLubyte* CSCI441::ShaderProgram::getUniformBlockBuffer( const GLchar *uniformBlockName ) const {
1321 const GLint blockSize = getUniformBlockSize( uniformBlockName );
1322 return (GLubyte*)malloc(blockSize);
1323}
1324
1325[[maybe_unused]]
1326inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName ) const {
1327 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1328}
1329
1330[[maybe_unused]]
1331inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName, const char *names[] ) const {
1332 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1333}
1334
1335inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex ) const {
1336 GLint numUniforms;
1337 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1338
1339 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1340 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1341
1342 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1343 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1344 return offsets;
1345}
1346
1347inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex, const char * names[] ) const {
1348 GLint numUniforms;
1349 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1350
1351 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1352 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1353
1354 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1355 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1356 return offsets;
1357}
1358
1359inline void CSCI441::ShaderProgram::setUniformBlockBinding( const GLchar* uniformBlockName, const GLuint binding ) const {
1360 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1361}
1362
1363[[maybe_unused]]
1364inline GLint CSCI441::ShaderProgram::getAttributeLocation( const GLchar* attributeName ) const {
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 );
1368 return -1;
1369 }
1370 return attribIter->second;
1371}
1372
1373[[maybe_unused]]
1374inline GLuint CSCI441::ShaderProgram::getSubroutineIndex( const GLenum shaderStage, const GLchar* const subroutineName ) const {
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;
1379}
1380
1381[[maybe_unused]]
1382inline GLint CSCI441::ShaderProgram::getSubroutineUniformLocation( const GLenum shaderStage, const GLchar* const subroutineName ) const {
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;
1387}
1388
1389[[maybe_unused]]
1390inline void CSCI441::ShaderProgram::setSubroutineIndices( const GLenum shaderStage, const GLsizei numIndices, const GLuint * const indices ) {
1391 glUniformSubroutinesuiv( shaderStage, numIndices, indices );
1392}
1393
1394// images are opaque types that are not considered program resources
1395[[maybe_unused]]
1396inline GLint CSCI441::ShaderProgram::getImageBinding(const GLchar* imageName) const {
1397 const GLint imageLoc = getUniformLocation(imageName);
1398
1399 if(imageLoc == GL_INVALID_INDEX) {
1400 fprintf(stderr, "[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1401 return -1;
1402 }
1403
1404 GLint bindingPoint;
1405 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1406
1407 return bindingPoint;
1408}
1409
1410[[maybe_unused]]
1411inline GLint CSCI441::ShaderProgram::getShaderStorageBlockBinding(const GLchar* ssboName) const {
1412 const GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1413
1414 if(ssboIndex == GL_INVALID_INDEX) {
1415 fprintf(stderr, "[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1416 return -1;
1417 }
1418
1419 constexpr GLenum props = GL_BUFFER_BINDING;
1420 GLint binding;
1421 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, 1, &props, 1, nullptr, &binding);
1422
1423 return binding;
1424}
1425
1426[[maybe_unused]]
1427inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferBinding(const GLchar* atomicName) const {
1428 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1429
1430 if(uniformIndex == GL_INVALID_INDEX) {
1431 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1432 return -1;
1433 }
1434
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);
1439
1440 return binding;
1441}
1442
1443[[maybe_unused]]
1444inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferOffset(const GLchar* atomicName) const {
1445 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1446
1447 if(uniformIndex == GL_INVALID_INDEX) {
1448 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1449 return -1;
1450 }
1451
1452 GLint offset;
1453 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1454 return offset;
1455}
1456
1457[[maybe_unused]]
1458inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferSize(const GLchar* atomicName) const {
1459 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1460
1461 if(uniformIndex == GL_INVALID_INDEX) {
1462 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1463 return -1;
1464 }
1465
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);
1470
1471 return bufferSize;
1472}
1473
1474[[maybe_unused]]
1476 GLint numUniform = 0;
1477 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1478 return numUniform;
1479}
1480
1481[[maybe_unused]]
1483 GLint numUniformBlocks = 0;
1484 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1485 return numUniformBlocks;
1486}
1487
1488[[maybe_unused]]
1490 GLint numAttr = 0;
1491 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1492 return numAttr;
1493}
1494
1496 return mShaderProgramHandle;
1497}
1498
1499[[maybe_unused]]
1501 glUseProgram(mShaderProgramHandle );
1502}
1503
1504[[maybe_unused]]
1505inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0 ) const {
1506 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1507 if(uniformIter != mpUniformLocationsMap->end()) {
1508 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1509 } else {
1510 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1511 }
1512}
1513
1514[[maybe_unused]]
1515inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1 ) const {
1516 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1517 if(uniformIter != mpUniformLocationsMap->end()) {
1518 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1519 } else {
1520 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1521 }
1522}
1523
1524[[maybe_unused]]
1525inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec2 value ) const {
1526 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1527}
1528
1529[[maybe_unused]]
1530inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1531 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1532 if(uniformIter != mpUniformLocationsMap->end()) {
1533 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1534 } else {
1535 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1536 }
1537}
1538
1539[[maybe_unused]]
1540inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec3 value ) const {
1541 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1542}
1543
1544[[maybe_unused]]
1545inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) const {
1546 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1547 if(uniformIter != mpUniformLocationsMap->end()) {
1548 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1549 } else {
1550 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1551 }
1552}
1553
1554[[maybe_unused]]
1555inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec4 value ) const {
1556 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1557}
1558
1559inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1560 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1561 if(uniformIter != mpUniformLocationsMap->end()) {
1562 switch(dim) {
1563 case 1:
1564 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1565 break;
1566 case 2:
1567 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1568 break;
1569 case 3:
1570 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1571 break;
1572 case 4:
1573 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1574 break;
1575 default:
1576 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1577 break;
1578 }
1579 } else {
1580 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1581 }
1582}
1583
1584[[maybe_unused]]
1585inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0 ) const {
1586 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1587 if(uniformIter != mpUniformLocationsMap->end()) {
1588 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1589 } else {
1590 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1591 }
1592}
1593
1594[[maybe_unused]]
1595inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1 ) const {
1596 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1597 if(uniformIter != mpUniformLocationsMap->end()) {
1598 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1599 } else {
1600 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1601 }
1602}
1603
1604[[maybe_unused]]
1605inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const {
1606 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1607 if(uniformIter != mpUniformLocationsMap->end()) {
1608 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1609 } else {
1610 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1611 }
1612}
1613
1614[[maybe_unused]]
1615inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2 ) const {
1616 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1617 if(uniformIter != mpUniformLocationsMap->end()) {
1618 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1619 } else {
1620 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1621 }
1622}
1623
1624[[maybe_unused]]
1625inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const {
1626 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1627 if(uniformIter != mpUniformLocationsMap->end()) {
1628 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1629 } else {
1630 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1631 }
1632}
1633
1634[[maybe_unused]]
1635inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1636 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1637 if(uniformIter != mpUniformLocationsMap->end()) {
1638 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1639 } else {
1640 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1641 }
1642}
1643
1644[[maybe_unused]]
1645inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const {
1646 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1647 if(uniformIter != mpUniformLocationsMap->end()) {
1648 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1649 } else {
1650 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1651 }
1652}
1653
1654[[maybe_unused]]
1655inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLint *value) const {
1656 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1657 if(uniformIter != mpUniformLocationsMap->end()) {
1658 switch(dim) {
1659 case 1:
1660 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1661 break;
1662 case 2:
1663 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1664 break;
1665 case 3:
1666 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1667 break;
1668 case 4:
1669 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1670 break;
1671 default:
1672 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1673 break;
1674 }
1675 } else {
1676 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1677 }
1678}
1679
1680[[maybe_unused]]
1681inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0 ) const {
1682 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1683 if(uniformIter != mpUniformLocationsMap->end()) {
1684 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1685 } else {
1686 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1687 }
1688}
1689
1690[[maybe_unused]]
1691inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1 ) const {
1692 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1693 if(uniformIter != mpUniformLocationsMap->end()) {
1694 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1695 } else {
1696 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1697 }
1698}
1699
1700[[maybe_unused]]
1701inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const {
1702 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1703 if(uniformIter != mpUniformLocationsMap->end()) {
1704 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1705 } else {
1706 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1707 }
1708}
1709
1710[[maybe_unused]]
1711inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
1712 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1713 if(uniformIter != mpUniformLocationsMap->end()) {
1714 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1715 } else {
1716 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1717 }
1718}
1719
1720[[maybe_unused]]
1721inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const {
1722 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1723 if(uniformIter != mpUniformLocationsMap->end()) {
1724 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1725 } else {
1726 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1727 }
1728}
1729
1730[[maybe_unused]]
1731inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
1732 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1733 if(uniformIter != mpUniformLocationsMap->end()) {
1734 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1735 } else {
1736 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1737 }
1738}
1739
1740[[maybe_unused]]
1741inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const {
1742 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1743 if(uniformIter != mpUniformLocationsMap->end()) {
1744 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1745 } else {
1746 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1747 }
1748}
1749
1750[[maybe_unused]]
1751inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLuint * const value) const {
1752 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1753 if(uniformIter != mpUniformLocationsMap->end()) {
1754 switch(dim) {
1755 case 1:
1756 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1757 break;
1758 case 2:
1759 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1760 break;
1761 case 3:
1762 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1763 break;
1764 case 4:
1765 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1766 break;
1767 default:
1768 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1769 break;
1770 }
1771 } else {
1772 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1773 }
1774}
1775
1776[[maybe_unused]]
1777inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2 mtx ) const {
1778 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1779 if(uniformIter != mpUniformLocationsMap->end()) {
1780 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1781 } else {
1782 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1783 }
1784}
1785
1786[[maybe_unused]]
1787inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3 mtx ) const {
1788 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1789 if(uniformIter != mpUniformLocationsMap->end()) {
1790 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1791 } else {
1792 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1793 }
1794}
1795
1796[[maybe_unused]]
1797inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4 mtx ) const {
1798 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1799 if(uniformIter != mpUniformLocationsMap->end()) {
1800 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1801 } else {
1802 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1803 }
1804}
1805
1806[[maybe_unused]]
1807inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x3 mtx ) const {
1808 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1809 if(uniformIter != mpUniformLocationsMap->end()) {
1810 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1811 } else {
1812 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1813 }
1814}
1815
1816[[maybe_unused]]
1817inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x2 mtx ) const {
1818 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1819 if(uniformIter != mpUniformLocationsMap->end()) {
1820 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1821 } else {
1822 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1823 }
1824}
1825
1826[[maybe_unused]]
1827inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x4 mtx ) const {
1828 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1829 if(uniformIter != mpUniformLocationsMap->end()) {
1830 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1831 } else {
1832 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1833 }
1834}
1835
1836[[maybe_unused]]
1837inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x2 mtx ) const {
1838 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1839 if(uniformIter != mpUniformLocationsMap->end()) {
1840 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1841 } else {
1842 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1843 }
1844}
1845
1846[[maybe_unused]]
1847inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x4 mtx ) const {
1848 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1849 if(uniformIter != mpUniformLocationsMap->end()) {
1850 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1851 } else {
1852 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1853 }
1854}
1855
1856[[maybe_unused]]
1857inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x3 mtx ) const {
1858 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1859 if(uniformIter != mpUniformLocationsMap->end()) {
1860 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1861 } else {
1862 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1863 }
1864}
1865
1866[[maybe_unused]]
1867inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0 ) const {
1868 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1869}
1870
1871[[maybe_unused]]
1872inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1 ) const {
1873 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1874}
1875
1876[[maybe_unused]]
1877inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec2 value ) const {
1878 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1879}
1880
1881[[maybe_unused]]
1882inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1883 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1884}
1885
1886[[maybe_unused]]
1887inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec3 value ) const {
1888 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1889}
1890
1891[[maybe_unused]]
1892inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2, const GLfloat v3 ) const {
1893 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1894}
1895
1896[[maybe_unused]]
1897inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec4 value ) const {
1898 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1899}
1900
1901inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1902 switch(dim) {
1903 case 1:
1904 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1905 break;
1906 case 2:
1907 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1908 break;
1909 case 3:
1910 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1911 break;
1912 case 4:
1913 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1914 break;
1915 default:
1916 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1917 break;
1918 }
1919}
1920
1921[[maybe_unused]]
1922inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0 ) const {
1923 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1924}
1925
1926[[maybe_unused]]
1927inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1 ) const {
1928 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1929}
1930
1931[[maybe_unused]]
1932inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec2 value) const {
1933 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1934}
1935
1936[[maybe_unused]]
1937inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2 ) const {
1938 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1939}
1940
1941[[maybe_unused]]
1942inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec3 value) const {
1943 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1944}
1945
1946[[maybe_unused]]
1947inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1948 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1949}
1950
1951[[maybe_unused]]
1952inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec4 value) const {
1953 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
1954}
1955
1956inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLint * const value) const {
1957 switch(dim) {
1958 case 1:
1959 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
1960 break;
1961 case 2:
1962 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
1963 break;
1964 case 3:
1965 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
1966 break;
1967 case 4:
1968 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
1969 break;
1970 default:
1971 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1972 break;
1973 }
1974}
1975
1976[[maybe_unused]]
1977inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0 ) const {
1978 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
1979}
1980
1981[[maybe_unused]]
1982inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1 ) const {
1983 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
1984}
1985
1986[[maybe_unused]]
1987inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const glm::uvec2 value) const {
1988 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1989}
1990
1991[[maybe_unused]]
1992inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
1993 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1994}
1995
1996[[maybe_unused]]
1997inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec3 value) const {
1998 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1999}
2000
2001[[maybe_unused]]
2002inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
2003 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2004}
2005
2006[[maybe_unused]]
2007inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec4 value) const {
2008 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2009}
2010
2011inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLuint * const value) const {
2012 switch(dim) {
2013 case 1:
2014 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
2015 break;
2016 case 2:
2017 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
2018 break;
2019 case 3:
2020 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
2021 break;
2022 case 4:
2023 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
2024 break;
2025 default:
2026 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2027 break;
2028 }
2029}
2030
2031[[maybe_unused]]
2032inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2 mtx ) const {
2033 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2034}
2035
2036[[maybe_unused]]
2037inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3 mtx ) const {
2038 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2039}
2040
2041[[maybe_unused]]
2042inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4 mtx ) const {
2043 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2044}
2045
2046[[maybe_unused]]
2047inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x3 mtx ) const {
2048 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2049}
2050
2051[[maybe_unused]]
2052inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x2 mtx ) const {
2053 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2054}
2055
2056[[maybe_unused]]
2057inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x4 mtx ) const {
2058 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2059}
2060
2061[[maybe_unused]]
2062inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x2 mtx ) const {
2063 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2064}
2065
2066[[maybe_unused]]
2067inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x4 mtx ) const {
2068 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2069}
2070
2071[[maybe_unused]]
2072inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x3 mtx ) const {
2073 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2074}
2075
2076[[maybe_unused]]
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;
2084 return shaderBits;
2085}
2086
2088 mVertexShaderHandle(0),
2089 mTessellationControlShaderHandle(0), mTessellationEvaluationShaderHandle(0),
2090 mGeometryShaderHandle(0),
2091 mFragmentShaderHandle(0),
2092 mShaderProgramHandle(0),
2093 mpUniformLocationsMap(nullptr), mpAttributeLocationsMap(nullptr)
2094{
2095
2096}
2097
2099 _cleanupSelf();
2100}
2101
2103 ShaderProgram&& src
2104) noexcept : ShaderProgram() {
2105 _moveFromSource(src);
2106}
2107
2109 if (this != &src) { // guard against self moving
2110 _cleanupSelf(); // cleanup existing instance
2111 _moveFromSource(src); // move from source instance
2112 }
2113 return *this; // return self
2114}
2115
2116inline void CSCI441::ShaderProgram::_cleanupSelf() {
2117 GLint status;
2118 GLint infoLogLength = 0;
2119 constexpr int maxLength = 1000;
2120
2121 glDeleteProgram(mShaderProgramHandle );
2122
2123 // create a buffer of designated length
2124 const auto infoLog = new GLchar[maxLength];
2125
2126 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2127
2128 // get the info log for the vertex/tessellation/geometry/fragment/compute shader
2129 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2130
2131 if(infoLogLength > 0 ) {
2132 // print info to terminal
2133 if( sDEBUG ) printf("[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ? "Success" : " Error"), infoLog );
2134 }
2135
2136 delete mpUniformLocationsMap;
2137 delete mpAttributeLocationsMap;
2138 delete[] infoLog;
2139
2140 mVertexShaderHandle = 0;
2141 mTessellationControlShaderHandle = 0;
2142 mTessellationEvaluationShaderHandle = 0;
2143 mGeometryShaderHandle = 0;
2144 mFragmentShaderHandle = 0;
2145 mShaderProgramHandle = 0;
2146 mpUniformLocationsMap = nullptr;
2147 mpAttributeLocationsMap = nullptr;
2148}
2149
2150inline void CSCI441::ShaderProgram::_moveFromSource(ShaderProgram &src) {
2151 mVertexShaderHandle = src.mVertexShaderHandle;
2152 src.mVertexShaderHandle = 0;
2153
2154 mTessellationControlShaderHandle = src.mTessellationControlShaderHandle;
2155 src.mTessellationControlShaderHandle = 0;
2156
2157 mTessellationEvaluationShaderHandle = src.mTessellationEvaluationShaderHandle;
2158 src.mTessellationEvaluationShaderHandle = 0;
2159
2160 mGeometryShaderHandle = src.mGeometryShaderHandle;
2161 src.mGeometryShaderHandle = 0;
2162
2163 mFragmentShaderHandle = src.mFragmentShaderHandle;
2164 src.mFragmentShaderHandle = 0;
2165
2166 mShaderProgramHandle = src.mShaderProgramHandle;
2167 src.mShaderProgramHandle = 0;
2168
2169 mpUniformLocationsMap = src.mpUniformLocationsMap;
2170 src.mpUniformLocationsMap = nullptr;
2171
2172 mpAttributeLocationsMap = src.mpAttributeLocationsMap;
2173 src.mpAttributeLocationsMap = nullptr;
2174}
2175
2176
2177inline bool CSCI441::ShaderProgram::writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const {
2178 GLint formats = 0;
2179 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2180 if( formats < 1 ) {
2181 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2182 return false;
2183 }
2184
2185 // Get the binary length
2186 GLint length = 0;
2187 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2188
2189 // Retrieve the binary code
2190 std::vector<GLubyte> buffer(length);
2191 GLenum format = 0;
2192 glGetProgramBinary(mShaderProgramHandle, length, nullptr, &format, buffer.data());
2193
2194 // Write the binary to a file.
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 );
2198 out.close();
2199
2200 return true;
2201}
2202
2203inline CSCI441::ShaderProgram* CSCI441::ShaderProgram::loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, const GLenum FORMAT) {
2204 GLint formats = 0;
2205 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2206 if( formats < 1 ) {
2207 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2208 return nullptr;
2209 }
2210
2211 const GLuint program = glCreateProgram();
2212
2213 // Load binary from file
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); // Load file
2218 inputStream.close();
2219
2220 // Install shader binary
2221 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2222
2223 // Check for success/failure
2224 GLint status;
2225 glGetProgramiv(program, GL_LINK_STATUS, &status);
2226 if( GL_FALSE == status ) {
2227 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2228 return nullptr;
2229 }
2230
2231 const auto shaderProgram = new CSCI441::ShaderProgram();
2232 shaderProgram->mShaderProgramHandle = program;
2233 return shaderProgram;
2234}
2235
2236#endif // CSCI441_SHADER_PROGRAM_HPP
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