CSCI441 OpenGL Library 5.9.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
183 virtual bool writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const final;
184
191 static ShaderProgram* loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, GLenum format);
192
199 virtual GLint getUniformLocation( const char *uniformName ) const final;
200
207 virtual GLint getUniformBlockIndex( const char *uniformBlockName ) const final;
214 virtual GLint getUniformBlockSize( const char *uniformBlockName ) const final;
221 [[maybe_unused]] virtual GLubyte* getUniformBlockBuffer( const char *uniformBlockName ) const final;
228 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const char *uniformBlockName ) const final;
236 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const char *uniformBlockName, const char *names[] ) const final;
243 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex ) const final;
251 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex, const char *names[] ) const final;
258 virtual void setUniformBlockBinding( const char *uniformBlockName, GLuint binding ) const final;
259
266 [[maybe_unused]] virtual GLint getAttributeLocation( const char *attributeName ) const final;
267
276 [[maybe_unused]] virtual GLuint getSubroutineIndex( GLenum shaderStage, const char *subroutineName ) const final;
277
284 [[maybe_unused]] virtual GLint getImageBinding(const char* imageName) const final;
285
292 [[maybe_unused]] virtual GLint getShaderStorageBlockBinding(const char* ssboName) const final;
293
300 [[maybe_unused]] virtual GLint getAtomicCounterBufferBinding(const char* atomicName) const final;
307 [[maybe_unused]] virtual GLint getAtomicCounterBufferOffset(const char* atomicName) const final;
314 [[maybe_unused]] virtual GLint getAtomicCounterBufferSize(const char* atomicName) const final;
315
320 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniforms() const final;
325 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniformBlocks() const final;
330 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumAttributes() const final;
331
336 [[nodiscard]] virtual GLuint getShaderProgramHandle() const final;
337
341 [[maybe_unused]] virtual void useProgram() const final;
342
348 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLfloat v0) const final;
354 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLint v0) const final;
360 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint v0) const final;
366 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat2 mtx) const final;
372 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat3 mtx) const final;
378 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat4 mtx) const final;
384 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat2x3 mtx) const final;
390 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat3x2 mtx) const final;
396 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat2x4 mtx) const final;
402 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat4x2 mtx) const final;
408 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat3x4 mtx) const final;
414 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::mat4x3 mtx) const final;
415
422 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLfloat v0, GLfloat v1) const final;
429 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLint v0, GLint v1) const final;
436 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint v0, GLuint v1) const final;
437
445 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLfloat v0, GLfloat v1, GLfloat v2) const final;
453 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLint v0, GLint v1, GLint v2) const final;
461 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint v0, GLuint v1, GLuint v2) const final;
462
471 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
480 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLint v0, GLint v1, GLint v2, GLint v3) const final;
489 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
490
496 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::vec2 value) const final;
502 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::ivec2 value) const final;
508 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::uvec2 value) const final;
509
515 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::vec3 value) const final;
521 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::ivec3 value) const final;
527 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::uvec3 value) const final;
528
534 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::vec4 value) const final;
540 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::ivec4 value) const final;
546 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, glm::uvec4 value) const final;
547
555 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLfloat *value) const final;
563 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLint *value) const final;
571 [[maybe_unused]] virtual void setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLuint *value) const final;
572
578 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0) const final;
584 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0) const final;
590 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0) const final;
596 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2 mtx) const final;
602 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3 mtx) const final;
608 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4 mtx) const final;
614 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2x3 mtx) const final;
620 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3x2 mtx) const final;
626 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2x4 mtx) const final;
632 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4x2 mtx) const final;
638 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3x4 mtx) const final;
644 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4x3 mtx) const final;
645
652 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1) const final;
659 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1) const final;
666 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1) const final;
667
675 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2) const final;
683 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2) const final;
691 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2) const final;
692
701 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
710 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2, GLint v3) const final;
719 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
720
726 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec2 value) const final;
732 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec2 value) const final;
738 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec2 value) const final;
739
745 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec3 value) const final;
751 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec3 value) const final;
757 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec3 value) const final;
758
764 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec4 value) const final;
770 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec4 value) const final;
776 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec4 value) const final;
777
785 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLfloat *value) const final;
793 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLint *value) const final;
801 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLuint *value) const final;
802
807 [[maybe_unused]] [[nodiscard]] virtual GLbitfield getProgramStages() const final;
808
809 protected:
814
819 static bool sDEBUG;
820
841
846
850 std::map<std::string, GLint> *mpUniformLocationsMap;
854 std::map<std::string, GLint> *mpAttributeLocationsMap;
855
866 virtual bool mRegisterShaderProgram(const char *vertexShaderFilename,
867 const char *tessellationControlShaderFilename,
868 const char *tessellationEvaluationShaderFilename,
869 const char *geometryShaderFilename,
870 const char *fragmentShaderFilename,
871 bool isSeparable ) final;
872
873 private:
874 void _initialize();
875 };
876
877}
878
880
881inline bool CSCI441::ShaderProgram::sDEBUG = true;
882
883[[maybe_unused]]
885 sDEBUG = true;
886}
887
888[[maybe_unused]]
890 sDEBUG = false;
891}
892
893inline CSCI441::ShaderProgram::ShaderProgram( const char *vertexShaderFilename, const char *fragmentShaderFilename ) {
894 _initialize();
895 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, false);
896}
897
898[[maybe_unused]]
899inline CSCI441::ShaderProgram::ShaderProgram( const char *vertexShaderFilename, const char *fragmentShaderFilename, const bool isSeparable ) {
900 _initialize();
901 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, isSeparable);
902}
903
904[[maybe_unused]]
905inline CSCI441::ShaderProgram::ShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename ) {
906 _initialize();
907 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
908 geometryShaderFilename, fragmentShaderFilename, false);
909}
910
911[[maybe_unused]]
912inline CSCI441::ShaderProgram::ShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename, bool isSeparable ) {
913 _initialize();
914 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
915 geometryShaderFilename, fragmentShaderFilename, isSeparable);
916}
917
918[[maybe_unused]]
919inline CSCI441::ShaderProgram::ShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *fragmentShaderFilename ) {
920 _initialize();
921 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
922 "", fragmentShaderFilename, false);
923}
924
925[[maybe_unused]]
926inline CSCI441::ShaderProgram::ShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *fragmentShaderFilename, bool isSeparable ) {
927 _initialize();
928 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
929 "", fragmentShaderFilename, isSeparable);
930}
931
932inline CSCI441::ShaderProgram::ShaderProgram( const char *vertexShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename ) {
933 _initialize();
934 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, false);
935}
936
937[[maybe_unused]]
938inline CSCI441::ShaderProgram::ShaderProgram( const char *vertexShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename, bool isSeparable ) {
939 _initialize();
940 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, isSeparable);
941}
942
943[[maybe_unused]]
944inline CSCI441::ShaderProgram::ShaderProgram( const char **shaderFilenames,
945 const bool vertexPresent, const bool tessellationPresent, const bool geometryPresent, const bool fragmentPresent,
946 const bool isSeparable ) {
947 _initialize();
948 if( vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
949 if( !isSeparable ) {
950 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
951 } else {
952 mRegisterShaderProgram(shaderFilenames[0], "", "", "", "", isSeparable);
953 }
954 } else if( vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
955 if( !isSeparable ) {
956 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
957 } else {
958 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", "", isSeparable);
959 }
960 } else if( vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
961 if( !isSeparable ) {
962 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
963 } else {
964 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], "",
965 isSeparable);
966 }
967 } else if( vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
968 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3],
969 shaderFilenames[4], isSeparable);
970 } else if( vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
971 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", shaderFilenames[3],
972 isSeparable);
973 } else if( vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
974 if( !isSeparable ) {
975 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
976 } else {
977 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], "", isSeparable);
978 }
979 } else if( vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
980 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], shaderFilenames[2], isSeparable);
981 } else if( vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
982 mRegisterShaderProgram(shaderFilenames[0], "", "", "", shaderFilenames[1], isSeparable);
983 } else if( !vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
984 if( !isSeparable ) {
985 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
986 } else {
987 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", "", isSeparable);
988 }
989 } else if( !vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
990 if( !isSeparable ) {
991 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
992 } else {
993 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", isSeparable);
994 }
995 } else if( !vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
996 if( !isSeparable ) {
997 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
998 } else {
999 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3],
1000 isSeparable);
1001 }
1002 } else if( !vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1003 if( !isSeparable ) {
1004 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1005 } else {
1006 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", shaderFilenames[2], isSeparable);
1007 }
1008 } else if( !vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1009 if( !isSeparable ) {
1010 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1011 } else {
1012 mRegisterShaderProgram("", "", "", shaderFilenames[0], "", isSeparable);
1013 }
1014 } else if( !vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1015 if( !isSeparable ) {
1016 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1017 } else {
1018 mRegisterShaderProgram("", "", "", shaderFilenames[0], shaderFilenames[1], isSeparable);
1019 }
1020 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1021 if( !isSeparable ) {
1022 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1023 } else {
1024 mRegisterShaderProgram("", "", "", "", shaderFilenames[0], isSeparable);
1025 }
1026 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1027 fprintf(stderr, "[ERROR]: At least one shader must be present.\n");
1028 } else {
1029 fprintf(stderr, "[ERROR]: Unknown state.\n");
1030 }
1031}
1032
1033inline bool CSCI441::ShaderProgram::mRegisterShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename, const bool isSeparable ) {
1034 GLint major, minor;
1035 glGetIntegerv(GL_MAJOR_VERSION, &major);
1036 glGetIntegerv(GL_MINOR_VERSION, &minor);
1037
1038 if( sDEBUG ) printf( "\n[INFO]: /--------------------------------------------------------\\\n");
1039
1040 /* compile each one of our shaders */
1041 if( strcmp( vertexShaderFilename, "" ) != 0 ) {
1042 if( sDEBUG ) printf( "[INFO]: | Vertex Shader: %39s |\n", vertexShaderFilename );
1043 mVertexShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(vertexShaderFilename, GL_VERTEX_SHADER );
1044 } else {
1046 }
1047
1048 if(strcmp(tessellationControlShaderFilename, "" ) != 0 ) {
1049 if( sDEBUG ) printf("[INFO]: | Tess Control Shader: %33s |\n", tessellationControlShaderFilename );
1050 if( major < 4 ) {
1051 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1053 } else {
1054 mTessellationControlShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationControlShaderFilename, GL_TESS_CONTROL_SHADER );
1055 }
1056 } else {
1058 }
1059
1060 if(strcmp(tessellationEvaluationShaderFilename, "" ) != 0 ) {
1061 if( sDEBUG ) printf("[INFO]: | Tess Evaluation Shader: %30s |\n", tessellationEvaluationShaderFilename );
1062 if( major < 4 ) {
1063 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1065 } else {
1066 mTessellationEvaluationShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationEvaluationShaderFilename, GL_TESS_EVALUATION_SHADER );
1067 }
1068 } else {
1070 }
1071
1072 if( strcmp( geometryShaderFilename, "" ) != 0 ) {
1073 if( sDEBUG ) printf( "[INFO]: | Geometry Shader: %37s |\n", geometryShaderFilename );
1074 if( major < 3 || (major == 3 && minor < 2) ) {
1075 printf( "[ERROR]:| GEOMETRY SHADER NOT SUPPORTED!!! UPGRADE TO v3.2+ |\n" );
1077 } else {
1078 mGeometryShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(geometryShaderFilename, GL_GEOMETRY_SHADER );
1079 }
1080 } else {
1082 }
1083
1084 if( strcmp( fragmentShaderFilename, "" ) != 0 ) {
1085 if( sDEBUG ) printf( "[INFO]: | Fragment Shader: %37s |\n", fragmentShaderFilename );
1086 mFragmentShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(fragmentShaderFilename, GL_FRAGMENT_SHADER );
1087 } else {
1089 }
1090 /* get a handle to a shader program */
1091 mShaderProgramHandle = glCreateProgram();
1092
1093 /* if program is separable, make it so */
1094 if( isSeparable ) {
1095 glProgramParameteri(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, GL_TRUE );
1096 }
1097
1098 /* attach the vertex and fragment shaders to the shader program */
1099 if(mVertexShaderHandle != 0 ) {
1100 glAttachShader(mShaderProgramHandle, mVertexShaderHandle );
1101 }
1104 }
1107 }
1108 if(mGeometryShaderHandle != 0 ) {
1110 }
1111 if(mFragmentShaderHandle != 0 ) {
1113 }
1114
1115 /* link all the programs together on the GPU */
1116 glLinkProgram(mShaderProgramHandle );
1117
1118 if( sDEBUG ) printf( "[INFO]: | Shader Program: %41s", "|\n" );
1119
1120 /* check the program log */
1121 CSCI441_INTERNAL::ShaderUtils::printProgramLog(mShaderProgramHandle );
1122
1123 /* detach & delete the vertex and fragment shaders to the shader program */
1124 if(mVertexShaderHandle != 0 ) {
1125 glDetachShader(mShaderProgramHandle, mVertexShaderHandle );
1126 glDeleteShader(mVertexShaderHandle );
1127 }
1130 glDeleteShader(mTessellationControlShaderHandle );
1131 }
1134 glDeleteShader(mTessellationEvaluationShaderHandle );
1135 }
1136 if(mGeometryShaderHandle != 0 ) {
1138 glDeleteShader(mGeometryShaderHandle );
1139 }
1140 if(mFragmentShaderHandle != 0 ) {
1142 glDeleteShader(mFragmentShaderHandle );
1143 }
1144
1145
1146 // map uniforms
1147 mpUniformLocationsMap = new std::map<std::string, GLint>();
1148 GLint numUniforms;
1149 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniforms);
1150 GLint max_uniform_name_size;
1151 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_size);
1152 if( numUniforms > 0 ) {
1153 for(GLint i = 0; i < numUniforms; i++) {
1154 char* name = (char*) malloc(max_uniform_name_size * sizeof(char));
1155 int actual_length = 0;
1156 int size = 0;
1157 GLenum type;
1158 glGetActiveUniform(mShaderProgramHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
1159 GLint location = -1;
1160 if(size > 1) {
1161 for(int j = 0; j < size; j++) {
1162 int max_array_size = actual_length + 4 + 2 + 1;
1163 char* array_name = (char*) malloc(max_array_size * sizeof(char));
1164 snprintf(array_name, max_array_size, "%s[%i]", name, j);
1165 location = glGetUniformLocation(mShaderProgramHandle, array_name);
1166 mpUniformLocationsMap->emplace(array_name, location);
1167 free(array_name);
1168 }
1169 } else {
1170 location = glGetUniformLocation(mShaderProgramHandle, name);
1171 mpUniformLocationsMap->emplace(name, location);
1172 }
1173 free(name);
1174 }
1175 }
1176
1177 // map attributes
1178 mpAttributeLocationsMap = new std::map<std::string, GLint>();
1179 GLint numAttributes;
1180 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttributes );
1181 GLint max_attr_name_size;
1182 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_size);
1183 if( numAttributes > 0 ) {
1184 for(GLint i = 0; i < numAttributes; i++) {
1185 char* name = (char*) malloc(max_attr_name_size * sizeof(char));
1186 int actual_length = 0;
1187 int size = 0;
1188 GLenum type;
1189 glGetActiveAttrib(mShaderProgramHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
1190 GLint location = -1;
1191 if( size > 1 ) {
1192 for( int j = 0; j < size; j++ ) {
1193 int max_array_size = actual_length + 4 + 2 + 1;
1194 char* array_name = (char*) malloc(max_array_size * sizeof(char));
1195 snprintf( array_name, max_array_size, "%s[%i]", name, j );
1196 location = glGetAttribLocation(mShaderProgramHandle, array_name );
1197 mpAttributeLocationsMap->emplace(array_name, location);
1198 free(array_name);
1199 }
1200 } else {
1201 location = glGetAttribLocation(mShaderProgramHandle, name );
1202 mpAttributeLocationsMap->emplace(name, location);
1203 }
1204 free(name);
1205 }
1206 }
1207
1208 GLint separable = GL_FALSE;
1209 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, &separable );
1210
1211 if( sDEBUG ) printf( "[INFO]: | Program Separable: %35s |\n", (separable ? "Yes" : "No"));
1212
1213 GLint linkStatus;
1214 glGetProgramiv(mShaderProgramHandle, GL_LINK_STATUS, &linkStatus );
1215
1216 /* print shader info for uniforms & attributes */
1217 if(linkStatus == 1) {
1218 CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(mShaderProgramHandle, mVertexShaderHandle != 0,
1222 false, true);
1223 }
1224 /* return handle */
1225 return mShaderProgramHandle != 0;
1226}
1227
1228inline GLint CSCI441::ShaderProgram::getUniformLocation( const char *uniformName ) const {
1229 GLint uniformLoc = glGetUniformLocation(mShaderProgramHandle, uniformName );
1230 if( uniformLoc == -1 )
1231 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle );
1232 return uniformLoc;
1233}
1234
1235inline GLint CSCI441::ShaderProgram::getUniformBlockIndex( const char *uniformBlockName ) const {
1236 GLint uniformBlockLoc = glGetUniformBlockIndex(mShaderProgramHandle, uniformBlockName );
1237 if( uniformBlockLoc == -1 )
1238 fprintf(stderr, "[ERROR]: Could not find uniform block \"%s\" for Shader Program %u\n", uniformBlockName, mShaderProgramHandle );
1239 return uniformBlockLoc;
1240}
1241
1242inline GLint CSCI441::ShaderProgram::getUniformBlockSize( const char *uniformBlockName ) const {
1243 GLint blockSize;
1244 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1245 return blockSize;
1246}
1247
1248[[maybe_unused]]
1249inline GLubyte* CSCI441::ShaderProgram::getUniformBlockBuffer( const char *uniformBlockName ) const {
1250 GLubyte *blockBuffer;
1251
1252 GLint blockSize = getUniformBlockSize( uniformBlockName );
1253
1254 blockBuffer = (GLubyte*)malloc(blockSize);
1255
1256 return blockBuffer;
1257}
1258
1259[[maybe_unused]]
1260inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const char *uniformBlockName ) const {
1261 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1262}
1263
1264[[maybe_unused]]
1265inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const char *uniformBlockName, const char *names[] ) const {
1266 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1267}
1268
1269inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(GLint uniformBlockIndex ) const {
1270 GLint numUniforms;
1271 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1272
1273 auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1274 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1275
1276 auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1277 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1278 return offsets;
1279}
1280
1281inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(GLint uniformBlockIndex, const char *names[] ) const {
1282 GLint numUniforms;
1283 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1284
1285 auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1286 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1287
1288 auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1289 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1290 return offsets;
1291}
1292
1293inline void CSCI441::ShaderProgram::setUniformBlockBinding( const char *uniformBlockName, GLuint binding ) const {
1294 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1295}
1296
1297[[maybe_unused]]
1298inline GLint CSCI441::ShaderProgram::getAttributeLocation( const char *attributeName ) const {
1299 auto attribIter = mpAttributeLocationsMap->find(attributeName);
1300 if(attribIter == mpAttributeLocationsMap->end() ) {
1301 fprintf(stderr, "[ERROR]: Could not find attribute \"%s\" for Shader Program %u\n", attributeName, mShaderProgramHandle );
1302 return -1;
1303 }
1304 return attribIter->second;
1305}
1306
1307[[maybe_unused]]
1308inline GLuint CSCI441::ShaderProgram::getSubroutineIndex( GLenum shaderStage, const char *subroutineName ) const {
1309 GLuint subroutineIndex = glGetSubroutineIndex(mShaderProgramHandle, shaderStage, subroutineName );
1310 if( subroutineIndex == GL_INVALID_INDEX )
1311 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 );
1312 return subroutineIndex;
1313}
1314
1315// images are opaque types that are not considered program resources
1316[[maybe_unused]]
1317inline GLint CSCI441::ShaderProgram::getImageBinding(const char* imageName) const {
1318 GLint imageLoc = getUniformLocation(imageName);
1319
1320 if(imageLoc == -1) {
1321 fprintf(stderr, "[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1322 return -1;
1323 }
1324
1325 GLint bindingPoint;
1326 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1327
1328 return bindingPoint;
1329}
1330
1331[[maybe_unused]]
1332inline GLint CSCI441::ShaderProgram::getShaderStorageBlockBinding(const char* ssboName) const {
1333 GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1334
1335 if(ssboIndex == GL_INVALID_INDEX) {
1336 fprintf(stderr, "[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1337 return -1;
1338 }
1339
1340 const int NUM_PROPS = 1;
1341 GLenum props[NUM_PROPS] = {GL_BUFFER_BINDING};
1342 GLint results[NUM_PROPS];
1343 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, NUM_PROPS, props, NUM_PROPS, nullptr, results);
1344
1345 return results[0];
1346}
1347
1348[[maybe_unused]]
1349inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferBinding(const char* atomicName) const {
1350 GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1351
1352 if(uniformIndex == GL_INVALID_INDEX) {
1353 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1354 return -1;
1355 }
1356
1357 GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1358 GLint atomicIndex, binding;
1359 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1360 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
1361
1362 return binding;
1363}
1364
1365[[maybe_unused]]
1366inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferOffset(const char* atomicName) const {
1367 GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1368
1369 if(uniformIndex == GL_INVALID_INDEX) {
1370 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1371 return -1;
1372 }
1373
1374 GLint offset;
1375 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1376 return offset;
1377}
1378
1379[[maybe_unused]]
1380inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferSize(const char* atomicName) const {
1381 GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1382
1383 if(uniformIndex == GL_INVALID_INDEX) {
1384 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1385 return -1;
1386 }
1387
1388 GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1389 GLint atomicIndex, bufferSize;
1390 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1391 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize);
1392
1393 return bufferSize;
1394}
1395
1396[[maybe_unused]]
1398 int numUniform = 0;
1399 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1400 return numUniform;
1401}
1402
1403[[maybe_unused]]
1405 int numUniformBlocks = 0;
1406 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1407 return numUniformBlocks;
1408}
1409
1410[[maybe_unused]]
1412 int numAttr = 0;
1413 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1414 return numAttr;
1415}
1416
1418 return mShaderProgramHandle;
1419}
1420
1421[[maybe_unused]]
1423 glUseProgram(mShaderProgramHandle );
1424}
1425
1426[[maybe_unused]]
1427inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLfloat v0 ) const {
1428 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1429 if(uniformIter != mpUniformLocationsMap->end()) {
1430 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1431 } else {
1432 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1433 }
1434}
1435
1436[[maybe_unused]]
1437inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLfloat v0, GLfloat v1 ) const {
1438 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1439 if(uniformIter != mpUniformLocationsMap->end()) {
1440 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1441 } else {
1442 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1443 }
1444}
1445
1446[[maybe_unused]]
1447inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::vec2 value ) const {
1448 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1449}
1450
1451[[maybe_unused]]
1452inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLfloat v0, GLfloat v1, GLfloat v2 ) const {
1453 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1454 if(uniformIter != mpUniformLocationsMap->end()) {
1455 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1456 } else {
1457 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1458 }
1459}
1460
1461[[maybe_unused]]
1462inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::vec3 value ) const {
1463 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1464}
1465
1466[[maybe_unused]]
1467inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) const {
1468 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1469 if(uniformIter != mpUniformLocationsMap->end()) {
1470 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1471 } else {
1472 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1473 }
1474}
1475
1476[[maybe_unused]]
1477inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::vec4 value ) const {
1478 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1479}
1480
1481inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLfloat *value) const {
1482 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1483 if(uniformIter != mpUniformLocationsMap->end()) {
1484 switch(dim) {
1485 case 1:
1486 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1487 break;
1488 case 2:
1489 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1490 break;
1491 case 3:
1492 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1493 break;
1494 case 4:
1495 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1496 break;
1497 default:
1498 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1499 break;
1500 }
1501 } else {
1502 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1503 }
1504}
1505
1506[[maybe_unused]]
1507inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLint v0 ) const {
1508 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1509 if(uniformIter != mpUniformLocationsMap->end()) {
1510 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1511 } else {
1512 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1513 }
1514}
1515
1516[[maybe_unused]]
1517inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLint v0, GLint v1 ) const {
1518 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1519 if(uniformIter != mpUniformLocationsMap->end()) {
1520 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1521 } else {
1522 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1523 }
1524}
1525
1526[[maybe_unused]]
1527inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::ivec2 value) const {
1528 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1529 if(uniformIter != mpUniformLocationsMap->end()) {
1530 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1531 } else {
1532 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1533 }
1534}
1535
1536[[maybe_unused]]
1537inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLint v0, GLint v1, GLint v2 ) const {
1538 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1539 if(uniformIter != mpUniformLocationsMap->end()) {
1540 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1541 } else {
1542 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1543 }
1544}
1545
1546[[maybe_unused]]
1547inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::ivec3 value) const {
1548 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1549 if(uniformIter != mpUniformLocationsMap->end()) {
1550 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1551 } else {
1552 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1553 }
1554}
1555
1556[[maybe_unused]]
1557inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLint v0, GLint v1, GLint v2, GLint v3 ) const {
1558 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1559 if(uniformIter != mpUniformLocationsMap->end()) {
1560 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1561 } else {
1562 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1563 }
1564}
1565
1566[[maybe_unused]]
1567inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::ivec4 value) const {
1568 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1569 if(uniformIter != mpUniformLocationsMap->end()) {
1570 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1571 } else {
1572 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1573 }
1574}
1575
1576[[maybe_unused]]
1577inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLint *value) const {
1578 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1579 if(uniformIter != mpUniformLocationsMap->end()) {
1580 switch(dim) {
1581 case 1:
1582 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1583 break;
1584 case 2:
1585 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1586 break;
1587 case 3:
1588 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1589 break;
1590 case 4:
1591 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1592 break;
1593 default:
1594 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1595 break;
1596 }
1597 } else {
1598 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1599 }
1600}
1601
1602[[maybe_unused]]
1603inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLuint v0 ) const {
1604 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1605 if(uniformIter != mpUniformLocationsMap->end()) {
1606 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1607 } else {
1608 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1609 }
1610}
1611
1612[[maybe_unused]]
1613inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLuint v0, GLuint v1 ) const {
1614 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1615 if(uniformIter != mpUniformLocationsMap->end()) {
1616 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1617 } else {
1618 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1619 }
1620}
1621
1622[[maybe_unused]]
1623inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::uvec2 value) const {
1624 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1625 if(uniformIter != mpUniformLocationsMap->end()) {
1626 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1627 } else {
1628 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1629 }
1630}
1631
1632[[maybe_unused]]
1633inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLuint v0, GLuint v1, GLuint v2 ) const {
1634 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1635 if(uniformIter != mpUniformLocationsMap->end()) {
1636 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1637 } else {
1638 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1639 }
1640}
1641
1642[[maybe_unused]]
1643inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::uvec3 value) const {
1644 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1645 if(uniformIter != mpUniformLocationsMap->end()) {
1646 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1647 } else {
1648 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1649 }
1650}
1651
1652[[maybe_unused]]
1653inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, GLuint v0, GLuint v1, GLuint v2, GLuint v3 ) const {
1654 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1655 if(uniformIter != mpUniformLocationsMap->end()) {
1656 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1657 } else {
1658 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1659 }
1660}
1661
1662[[maybe_unused]]
1663inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, glm::uvec4 value) const {
1664 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1665 if(uniformIter != mpUniformLocationsMap->end()) {
1666 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1667 } else {
1668 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1669 }
1670}
1671
1672[[maybe_unused]]
1673inline void CSCI441::ShaderProgram::setProgramUniform(const char* uniformName, GLuint dim, GLsizei count, const GLuint *value) const {
1674 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1675 if(uniformIter != mpUniformLocationsMap->end()) {
1676 switch(dim) {
1677 case 1:
1678 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1679 break;
1680 case 2:
1681 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1682 break;
1683 case 3:
1684 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1685 break;
1686 case 4:
1687 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1688 break;
1689 default:
1690 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1691 break;
1692 }
1693 } else {
1694 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1695 }
1696}
1697
1698[[maybe_unused]]
1699inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat2 mtx ) const {
1700 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1701 if(uniformIter != mpUniformLocationsMap->end()) {
1702 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1703 } else {
1704 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1705 }
1706}
1707
1708[[maybe_unused]]
1709inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat3 mtx ) const {
1710 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1711 if(uniformIter != mpUniformLocationsMap->end()) {
1712 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1713 } else {
1714 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1715 }
1716}
1717
1718[[maybe_unused]]
1719inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat4 mtx ) const {
1720 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1721 if(uniformIter != mpUniformLocationsMap->end()) {
1722 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1723 } else {
1724 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1725 }
1726}
1727
1728[[maybe_unused]]
1729inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat2x3 mtx ) const {
1730 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1731 if(uniformIter != mpUniformLocationsMap->end()) {
1732 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1733 } else {
1734 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1735 }
1736}
1737
1738[[maybe_unused]]
1739inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat3x2 mtx ) const {
1740 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1741 if(uniformIter != mpUniformLocationsMap->end()) {
1742 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1743 } else {
1744 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1745 }
1746}
1747
1748[[maybe_unused]]
1749inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat2x4 mtx ) const {
1750 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1751 if(uniformIter != mpUniformLocationsMap->end()) {
1752 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1753 } else {
1754 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1755 }
1756}
1757
1758[[maybe_unused]]
1759inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat4x2 mtx ) const {
1760 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1761 if(uniformIter != mpUniformLocationsMap->end()) {
1762 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1763 } else {
1764 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1765 }
1766}
1767
1768[[maybe_unused]]
1769inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat3x4 mtx ) const {
1770 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1771 if(uniformIter != mpUniformLocationsMap->end()) {
1772 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1773 } else {
1774 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1775 }
1776}
1777
1778[[maybe_unused]]
1779inline void CSCI441::ShaderProgram::setProgramUniform( const char *uniformName, glm::mat4x3 mtx ) const {
1780 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1781 if(uniformIter != mpUniformLocationsMap->end()) {
1782 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1783 } else {
1784 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1785 }
1786}
1787
1788[[maybe_unused]]
1789inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLfloat v0 ) const {
1790 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1791}
1792
1793[[maybe_unused]]
1794inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLfloat v0, GLfloat v1 ) const {
1795 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1796}
1797
1798[[maybe_unused]]
1799inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::vec2 value ) const {
1800 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1801}
1802
1803[[maybe_unused]]
1804inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2 ) const {
1805 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1806}
1807
1808[[maybe_unused]]
1809inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::vec3 value ) const {
1810 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1811}
1812
1813[[maybe_unused]]
1814inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) const {
1815 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1816}
1817
1818[[maybe_unused]]
1819inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::vec4 value ) const {
1820 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1821}
1822
1823inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLfloat *value) const {
1824 switch(dim) {
1825 case 1:
1826 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1827 break;
1828 case 2:
1829 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1830 break;
1831 case 3:
1832 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1833 break;
1834 case 4:
1835 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1836 break;
1837 default:
1838 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1839 break;
1840 }
1841}
1842
1843[[maybe_unused]]
1844inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLint v0 ) const {
1845 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1846}
1847
1848[[maybe_unused]]
1849inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLint v0, GLint v1 ) const {
1850 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1851}
1852
1853[[maybe_unused]]
1854inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::ivec2 value) const {
1855 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1856}
1857
1858[[maybe_unused]]
1859inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLint v0, GLint v1, GLint v2 ) const {
1860 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1861}
1862
1863[[maybe_unused]]
1864inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::ivec3 value) const {
1865 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1866}
1867
1868[[maybe_unused]]
1869inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLint v0, GLint v1, GLint v2, GLint v3 ) const {
1870 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1871}
1872
1873[[maybe_unused]]
1874inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::ivec4 value) const {
1875 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
1876}
1877
1878inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLint *value) const {
1879 switch(dim) {
1880 case 1:
1881 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
1882 break;
1883 case 2:
1884 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
1885 break;
1886 case 3:
1887 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
1888 break;
1889 case 4:
1890 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
1891 break;
1892 default:
1893 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1894 break;
1895 }
1896}
1897
1898[[maybe_unused]]
1899inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLuint v0 ) const {
1900 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
1901}
1902
1903[[maybe_unused]]
1904inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLuint v0, GLuint v1 ) const {
1905 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
1906}
1907
1908[[maybe_unused]]
1909inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::uvec2 value) const {
1910 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1911}
1912
1913[[maybe_unused]]
1914inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2 ) const {
1915 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1916}
1917
1918[[maybe_unused]]
1919inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::uvec3 value) const {
1920 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1921}
1922
1923[[maybe_unused]]
1924inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2, GLuint v3 ) const {
1925 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1926}
1927
1928[[maybe_unused]]
1929inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, glm::uvec4 value) const {
1930 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
1931}
1932
1933inline void CSCI441::ShaderProgram::setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLuint *value) const {
1934 switch(dim) {
1935 case 1:
1936 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
1937 break;
1938 case 2:
1939 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
1940 break;
1941 case 3:
1942 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
1943 break;
1944 case 4:
1945 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
1946 break;
1947 default:
1948 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1949 break;
1950 }
1951}
1952
1953[[maybe_unused]]
1954inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat2 mtx ) const {
1955 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1956}
1957
1958[[maybe_unused]]
1959inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat3 mtx ) const {
1960 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1961}
1962
1963[[maybe_unused]]
1964inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat4 mtx ) const {
1965 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1966}
1967
1968[[maybe_unused]]
1969inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat2x3 mtx ) const {
1970 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1971}
1972
1973[[maybe_unused]]
1974inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat3x2 mtx ) const {
1975 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1976}
1977
1978[[maybe_unused]]
1979inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat2x4 mtx ) const {
1980 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1981}
1982
1983[[maybe_unused]]
1984inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat4x2 mtx ) const {
1985 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1986}
1987
1988[[maybe_unused]]
1989inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat3x4 mtx ) const {
1990 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1991}
1992
1993[[maybe_unused]]
1994inline void CSCI441::ShaderProgram::setProgramUniform( GLint uniformLocation, glm::mat4x3 mtx ) const {
1995 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
1996}
1997
1998[[maybe_unused]]
2000 GLbitfield shaderBits = 0;
2001 if( mVertexShaderHandle != 0 ) shaderBits |= GL_VERTEX_SHADER_BIT;
2002 if( mTessellationControlShaderHandle != 0 ) shaderBits |= GL_TESS_CONTROL_SHADER_BIT;
2003 if( mTessellationEvaluationShaderHandle != 0 ) shaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
2004 if( mGeometryShaderHandle != 0 ) shaderBits |= GL_GEOMETRY_SHADER_BIT;
2005 if( mFragmentShaderHandle != 0 ) shaderBits |= GL_FRAGMENT_SHADER_BIT;
2006 return shaderBits;
2007}
2008
2010 _initialize();
2011}
2012
2013inline void CSCI441::ShaderProgram::_initialize() {
2020 mpUniformLocationsMap = nullptr;
2021 mpAttributeLocationsMap = nullptr;
2022}
2023
2025 int status;
2026 int infoLogLength = 0;
2027 int maxLength = 1000;
2028
2029 glDeleteProgram(mShaderProgramHandle );
2030
2031 // create a buffer of designated length
2032 char* infoLog = new char[maxLength];
2033
2034 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2035
2036 // get the info log for the vertex/tessellation/geometry/fragment/compute shader
2037 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2038
2039 if(infoLogLength > 0 ) {
2040 // print info to terminal
2041 if( sDEBUG ) printf("[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ? "Success" : " Error"), infoLog );
2042 }
2043
2044 delete mpUniformLocationsMap;
2046 delete[] infoLog;
2047}
2048
2049inline bool CSCI441::ShaderProgram::writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const {
2050 GLint formats = 0;
2051 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2052 if( formats < 1 ) {
2053 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2054 return false;
2055 }
2056
2057 // Get the binary length
2058 GLint length = 0;
2059 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2060
2061 // Retrieve the binary code
2062 std::vector<GLubyte> buffer(length);
2063 GLenum format = 0;
2064 glGetProgramBinary(mShaderProgramHandle, length, nullptr, &format, buffer.data());
2065
2066 // Write the binary to a file.
2067 fprintf(stdout, "[INFO]: Writing to %s, binary format %d\n",BINARY_FILE_NAME, format);
2068 std::ofstream out(BINARY_FILE_NAME, std::ios::binary);
2069 out.write( reinterpret_cast<char *>(buffer.data()), length );
2070 out.close();
2071
2072 return true;
2073}
2074
2075inline CSCI441::ShaderProgram* CSCI441::ShaderProgram::loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, const GLenum FORMAT) {
2076 GLint formats = 0;
2077 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2078 if( formats < 1 ) {
2079 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2080 return nullptr;
2081 }
2082
2083 GLuint program = glCreateProgram();
2084
2085 // Load binary from file
2086 std::ifstream inputStream(BINARY_FILE_NAME, std::ios::binary);
2087 std::istreambuf_iterator<char> startIt(inputStream), endIt;
2088 std::vector<char> buffer(startIt, endIt); // Load file
2089 inputStream.close();
2090
2091 // Install shader binary
2092 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2093
2094 // Check for success/failure
2095 GLint status;
2096 glGetProgramiv(program, GL_LINK_STATUS, &status);
2097 if( GL_FALSE == status ) {
2098 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2099 return nullptr;
2100 }
2101
2102 auto shaderProgram = new CSCI441::ShaderProgram();
2103 shaderProgram->mShaderProgramHandle = program;
2104 return shaderProgram;
2105}
2106
2107#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:832
virtual GLint getAtomicCounterBufferOffset(const char *atomicName) const final
Returns the offset into the buffer for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1366
GLuint mVertexShaderHandle
handle to the vertex shader stage
Definition: ShaderProgram.hpp:824
static ShaderProgram * loadShaderProgramFromBinaryFile(const char *BINARY_FILE_NAME, GLenum format)
loads precompiled shader program binary from external file
Definition: ShaderProgram.hpp:2075
virtual GLint getAtomicCounterBufferBinding(const char *atomicName) const final
Returns the binding point for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1349
GLuint mShaderProgramHandle
handle to the shader program
Definition: ShaderProgram.hpp:845
GLuint mTessellationControlShaderHandle
handle to the tessellation control shader stage
Definition: ShaderProgram.hpp:828
virtual void useProgram() const final
Sets the Shader Program to be active.
Definition: ShaderProgram.hpp:1422
virtual GLuint getNumAttributes() const final
Returns the number of active attributes in this shader program.
Definition: ShaderProgram.hpp:1411
std::map< std::string, GLint > * mpUniformLocationsMap
caches locations of uniform names within shader program
Definition: ShaderProgram.hpp:850
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:1999
virtual GLuint getNumUniforms() const final
Returns the number of active uniforms in this shader program.
Definition: ShaderProgram.hpp:1397
virtual GLubyte * getUniformBlockBuffer(const char *uniformBlockName) const final
Returns an allocated buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1249
virtual GLint getImageBinding(const char *imageName) const final
Returns the binding point for the corresponding image uniform.
Definition: ShaderProgram.hpp:1317
virtual GLint getUniformLocation(const char *uniformName) const final
Returns the location of the given uniform in this shader program.
Definition: ShaderProgram.hpp:1228
virtual ~ShaderProgram()
Clean up memory associated with the Shader Program.
Definition: ShaderProgram.hpp:2024
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1417
GLuint mGeometryShaderHandle
handle to the geometry shader stage
Definition: ShaderProgram.hpp:836
virtual GLuint getSubroutineIndex(GLenum shaderStage, const char *subroutineName) const final
Returns the index of the given subroutine for a shader stage in this shader program.
Definition: ShaderProgram.hpp:1308
virtual GLint getAttributeLocation(const char *attributeName) const final
Returns the location of the given attribute in this shader program.
Definition: ShaderProgram.hpp:1298
static bool sDEBUG
if DEBUG information should be printed or not
Definition: ShaderProgram.hpp:819
virtual bool writeShaderProgramBinaryToFile(const char *BINARY_FILE_NAME) const final
writes precompiled shader program binary to external file
Definition: ShaderProgram.hpp:2049
static void disableDebugMessages()
Disables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:889
static void enableDebugMessages()
Enables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:884
virtual GLint getAtomicCounterBufferSize(const char *atomicName) const final
Returns the full buffer size for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1380
std::map< std::string, GLint > * mpAttributeLocationsMap
caches locations of attribute names within shader program
Definition: ShaderProgram.hpp:854
virtual void setProgramUniform(const char *uniformName, GLfloat v0) const final
sets the program uniform consisting of one float
Definition: ShaderProgram.hpp:1427
virtual GLuint getNumUniformBlocks() const final
Returns the number of active uniform blocks in this shader program.
Definition: ShaderProgram.hpp:1404
ShaderProgram(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual void setUniformBlockBinding(const char *uniformBlockName, GLuint binding) const final
Set the binding point for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1293
virtual GLint getUniformBlockSize(const char *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1242
GLuint mFragmentShaderHandle
handle to the fragment shader stage
Definition: ShaderProgram.hpp:840
virtual GLint * getUniformBlockOffsets(const char *uniformBlockName) const final
Returns an array of offsets into the buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1260
virtual GLint getUniformBlockIndex(const char *uniformBlockName) const final
Returns the index of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1235
ShaderProgram()
creates an empty shader program object
Definition: ShaderProgram.hpp:2009
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:1033
virtual GLint getShaderStorageBlockBinding(const char *ssboName) const final
Returns the binding point for the corresponding shader storage block.
Definition: ShaderProgram.hpp:1332
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17