CSCI441 OpenGL Library 5.22.0.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 "constants.h"
17#include "ShaderUtils.hpp"
18
19#include <glm/glm.hpp>
20#include <glm/gtc/type_ptr.hpp> // for glm::value_ptr()
21
22#include <cstdlib>
23#include <fstream>
24#include <map>
25#include <string>
26#include <vector>
27
29
30namespace CSCI441 {
31
37 public:
42 [[maybe_unused]] static void enableDebugMessages();
47 [[maybe_unused]] static void disableDebugMessages();
48
54 ShaderProgram( const char *vertexShaderFilename,
55 const char *fragmentShaderFilename );
56
63 [[maybe_unused]]
64 ShaderProgram( const char *vertexShaderFilename,
65 const char *fragmentShaderFilename,
66 bool isSeparable );
67
75 [[maybe_unused]]
76 ShaderProgram( const char *vertexShaderFilename,
77 const char *tessellationControlShaderFilename,
78 const char *tessellationEvaluationShaderFilename,
79 const char *geometryShaderFilename,
80 const char *fragmentShaderFilename );
81
91 [[maybe_unused]]
92 ShaderProgram( const char *vertexShaderFilename,
93 const char *tessellationControlShaderFilename,
94 const char *tessellationEvaluationShaderFilename,
95 const char *geometryShaderFilename,
96 const char *fragmentShaderFilename,
97 bool isSeparable );
98
106 [[maybe_unused]]
107 ShaderProgram( const char *vertexShaderFilename,
108 const char *tessellationControlShaderFilename,
109 const char *tessellationEvaluationShaderFilename,
110 const char *fragmentShaderFilename );
111
120 [[maybe_unused]]
121 ShaderProgram( const char *vertexShaderFilename,
122 const char *tessellationControlShaderFilename,
123 const char *tessellationEvaluationShaderFilename,
124 const char *fragmentShaderFilename,
125 bool isSeparable);
126
133 ShaderProgram( const char *vertexShaderFilename,
134 const char *geometryShaderFilename,
135 const char *fragmentShaderFilename );
136
144 [[maybe_unused]]
145 ShaderProgram( const char *vertexShaderFilename,
146 const char *geometryShaderFilename,
147 const char *fragmentShaderFilename,
148 bool isSeparable );
149
160 [[maybe_unused]]
161 ShaderProgram( const char **shaderFilenames,
162 bool vertexPresent, bool tessellationPresent, bool geometryPresent, bool fragmentPresent,
163 bool isSeparable );
164
168 virtual ~ShaderProgram();
169
173 ShaderProgram(const ShaderProgram&) = delete;
178
182 ShaderProgram(ShaderProgram&&) noexcept;
187 ShaderProgram& operator=(ShaderProgram&&) noexcept;
188
194 virtual bool writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const final;
195
202 static ShaderProgram* loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, GLenum format);
203
210 virtual GLint getUniformLocation( const GLchar *uniformName ) const final;
211
218 virtual GLint getUniformBlockIndex( const GLchar *uniformBlockName ) const final;
225 virtual GLint getUniformBlockSize( const GLchar *uniformBlockName ) const final;
232 [[maybe_unused]] virtual GLubyte* getUniformBlockBuffer( const GLchar *uniformBlockName ) const final;
239 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const GLchar *uniformBlockName ) const final;
247 [[maybe_unused]] virtual GLint* getUniformBlockOffsets( const GLchar *uniformBlockName, const GLchar *names[] ) const final;
254 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex ) const final;
262 [[nodiscard]] virtual GLint* getUniformBlockOffsets(GLint uniformBlockIndex, const GLchar *names[] ) const final;
269 virtual void setUniformBlockBinding( const GLchar *uniformBlockName, GLuint binding ) const final;
270
277 [[maybe_unused]] virtual GLint getAttributeLocation( const GLchar *attributeName ) const final;
278
287 [[maybe_unused]] virtual GLuint getSubroutineIndex( GLenum shaderStage, const GLchar *subroutineName ) const final;
288
297 [[maybe_unused]] virtual GLint getSubroutineUniformLocation( GLenum shaderStage, const GLchar *subroutineName ) const final;
298
307 [[maybe_unused]] virtual void setSubroutineIndices( GLenum shaderStage, GLsizei numIndices, const GLuint *indices ) final;
308
315 [[maybe_unused]] virtual GLint getImageBinding(const GLchar* imageName) const final;
316
323 [[maybe_unused]] virtual GLint getShaderStorageBlockBinding(const GLchar* ssboName) const final;
324
331 [[maybe_unused]] virtual GLint getAtomicCounterBufferBinding(const GLchar* atomicName) const final;
338 [[maybe_unused]] virtual GLint getAtomicCounterBufferOffset(const GLchar* atomicName) const final;
345 [[maybe_unused]] virtual GLint getAtomicCounterBufferSize(const GLchar* atomicName) const final;
346
351 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniforms() const final;
356 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumUniformBlocks() const final;
361 [[maybe_unused]] [[nodiscard]] virtual GLuint getNumAttributes() const final;
362
368 [[maybe_unused]] [[nodiscard]] virtual GLint getFragmentDataLocation(const GLchar* name) const final;
369
375 [[maybe_unused]] [[nodiscard]] virtual GLint getFragmentDataIndex(const GLchar* name) const final;
376
381 [[nodiscard]] virtual GLuint getShaderProgramHandle() const final;
382
387 [[nodiscard]] virtual GLboolean validate() const final;
388
392 [[maybe_unused]] virtual void useProgram() const final;
393
399 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLfloat v0) const final;
405 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLint v0) const final;
411 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint v0) const final;
417 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat2 mtx) const final;
423 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat3 mtx) const final;
429 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat4 mtx) const final;
435 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat2x3 mtx) const final;
441 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat3x2 mtx) const final;
447 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat2x4 mtx) const final;
453 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat4x2 mtx) const final;
459 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat3x4 mtx) const final;
465 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::mat4x3 mtx) const final;
466
473 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1) const final;
480 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1) const final;
487 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1) const final;
488
496 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2) const final;
504 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2) const final;
512 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2) const final;
513
522 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
531 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLint v0, GLint v1, GLint v2, GLint v3) const final;
540 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
541
547 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::vec2 value) const final;
553 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const final;
559 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const final;
560
566 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::vec3 value) const final;
572 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const final;
578 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const final;
579
585 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::vec4 value) const final;
591 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const final;
597 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const final;
598
606 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLfloat *value) const final;
614 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLint *value) const final;
622 [[maybe_unused]] virtual void setProgramUniform(const GLchar* uniformName, GLuint dim, GLsizei count, const GLuint *value) const final;
623
629 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0) const final;
635 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0) const final;
641 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0) const final;
647 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2 mtx) const final;
653 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3 mtx) const final;
659 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4 mtx) const final;
665 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2x3 mtx) const final;
671 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3x2 mtx) const final;
677 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat2x4 mtx) const final;
683 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4x2 mtx) const final;
689 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat3x4 mtx) const final;
695 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::mat4x3 mtx) const final;
696
703 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1) const final;
710 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1) const final;
717 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1) const final;
718
726 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2) const final;
734 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2) const final;
742 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2) const final;
743
752 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) const final;
761 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLint v0, GLint v1, GLint v2, GLint v3) const final;
770 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, GLuint v0, GLuint v1, GLuint v2, GLuint v3) const final;
771
777 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec2 value) const final;
783 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec2 value) const final;
789 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec2 value) const final;
790
796 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec3 value) const final;
802 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec3 value) const final;
808 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec3 value) const final;
809
815 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::vec4 value) const final;
821 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::ivec4 value) const final;
827 [[maybe_unused]] virtual void setProgramUniform(GLint uniformLocation, glm::uvec4 value) const final;
828
836 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLfloat *value) const final;
844 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLint *value) const final;
852 virtual void setProgramUniform(GLint uniformLocation, GLuint dim, GLsizei count, const GLuint *value) const final;
853
858 [[maybe_unused]] [[nodiscard]] virtual GLbitfield getProgramStages() const;
859
860 protected:
865
870 static bool sDEBUG;
871
892
897
901 std::map<std::string, GLint> *mpUniformLocationsMap;
905 std::map<std::string, GLint> *mpAttributeLocationsMap;
906
917 virtual bool mRegisterShaderProgram(const char *vertexShaderFilename,
918 const char *tessellationControlShaderFilename,
919 const char *tessellationEvaluationShaderFilename,
920 const char *geometryShaderFilename,
921 const char *fragmentShaderFilename,
922 bool isSeparable ) final;
923
924 private:
925 void _cleanupSelf();
926 void _moveFromSource(ShaderProgram& src);
927 };
928
929}
930
932
933inline bool CSCI441::ShaderProgram::sDEBUG = true;
934
935[[maybe_unused]]
937 sDEBUG = true;
938 CSCI441_INTERNAL::ShaderUtils::enableDebugMessages();
939}
940
941[[maybe_unused]]
943 sDEBUG = false;
944 CSCI441_INTERNAL::ShaderUtils::disableDebugMessages();
945}
946
948 const char *vertexShaderFilename,
949 const char *fragmentShaderFilename
950) : ShaderProgram()
951{
952 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, false);
953}
954
955[[maybe_unused]]
957 const char *vertexShaderFilename,
958 const char *fragmentShaderFilename,
959 const bool isSeparable
960) : ShaderProgram()
961{
962 mRegisterShaderProgram(vertexShaderFilename, "", "", "", fragmentShaderFilename, isSeparable);
963}
964
965[[maybe_unused]]
967 const char *vertexShaderFilename,
968 const char *tessellationControlShaderFilename,
969 const char *tessellationEvaluationShaderFilename,
970 const char *geometryShaderFilename,
971 const char *fragmentShaderFilename
972) : ShaderProgram() {
973 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
974 geometryShaderFilename, fragmentShaderFilename, false);
975}
976
977[[maybe_unused]]
979 const char *vertexShaderFilename,
980 const char *tessellationControlShaderFilename,
981 const char *tessellationEvaluationShaderFilename,
982 const char *geometryShaderFilename,
983 const char *fragmentShaderFilename,
984 const bool isSeparable
985) : ShaderProgram() {
986 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
987 geometryShaderFilename, fragmentShaderFilename, isSeparable);
988}
989
990[[maybe_unused]]
992 const char *vertexShaderFilename,
993 const char *tessellationControlShaderFilename,
994 const char *tessellationEvaluationShaderFilename,
995 const char *fragmentShaderFilename
996) : ShaderProgram() {
997 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
998 "", fragmentShaderFilename, false);
999}
1000
1001[[maybe_unused]]
1003 const char *vertexShaderFilename,
1004 const char *tessellationControlShaderFilename,
1005 const char *tessellationEvaluationShaderFilename,
1006 const char *fragmentShaderFilename,
1007 const bool isSeparable
1008) : ShaderProgram() {
1009 mRegisterShaderProgram(vertexShaderFilename, tessellationControlShaderFilename, tessellationEvaluationShaderFilename,
1010 "", fragmentShaderFilename, isSeparable);
1011}
1012
1014 const char *vertexShaderFilename,
1015 const char *geometryShaderFilename,
1016 const char *fragmentShaderFilename
1017) : ShaderProgram() {
1018 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, false);
1019}
1020
1021[[maybe_unused]]
1023 const char *vertexShaderFilename,
1024 const char *geometryShaderFilename,
1025 const char *fragmentShaderFilename,
1026 const bool isSeparable
1027) : ShaderProgram() {
1028 mRegisterShaderProgram(vertexShaderFilename, "", "", geometryShaderFilename, fragmentShaderFilename, isSeparable);
1029}
1030
1031[[maybe_unused]]
1033 const char **shaderFilenames,
1034 const bool vertexPresent, const bool tessellationPresent, const bool geometryPresent, const bool fragmentPresent,
1035 const bool isSeparable
1036) : ShaderProgram() {
1037 if( vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1038 if( !isSeparable ) {
1039 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1040 } else {
1041 mRegisterShaderProgram(shaderFilenames[0], "", "", "", "", isSeparable);
1042 }
1043 } else if( vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1044 if( !isSeparable ) {
1045 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1046 } else {
1047 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", "", isSeparable);
1048 }
1049 } else if( vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1050 if( !isSeparable ) {
1051 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1052 } else {
1053 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], "", isSeparable);
1054 }
1055 } else if( vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1056 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], shaderFilenames[4], isSeparable);
1057 } else if( vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1058 mRegisterShaderProgram(shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", shaderFilenames[3], isSeparable);
1059 } else if( vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1060 if( !isSeparable ) {
1061 fprintf(stderr, "[ERROR]: Fragment Shader not present. Program must be separable.\n");
1062 } else {
1063 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], "", isSeparable);
1064 }
1065 } else if( vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1066 mRegisterShaderProgram(shaderFilenames[0], "", "", shaderFilenames[1], shaderFilenames[2], isSeparable);
1067 } else if( vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1068 mRegisterShaderProgram(shaderFilenames[0], "", "", "", shaderFilenames[1], isSeparable);
1069 } else if( !vertexPresent && tessellationPresent && !geometryPresent && !fragmentPresent ) {
1070 if( !isSeparable ) {
1071 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1072 } else {
1073 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", "", isSeparable);
1074 }
1075 } else if( !vertexPresent && tessellationPresent && geometryPresent && !fragmentPresent ) {
1076 if( !isSeparable ) {
1077 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1078 } else {
1079 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], "", isSeparable);
1080 }
1081 } else if( !vertexPresent && tessellationPresent && geometryPresent && fragmentPresent ) {
1082 if( !isSeparable ) {
1083 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1084 } else {
1085 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], shaderFilenames[2], shaderFilenames[3], isSeparable);
1086 }
1087 } else if( !vertexPresent && tessellationPresent && !geometryPresent && fragmentPresent ) {
1088 if( !isSeparable ) {
1089 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1090 } else {
1091 mRegisterShaderProgram("", shaderFilenames[0], shaderFilenames[1], "", shaderFilenames[2], isSeparable);
1092 }
1093 } else if( !vertexPresent && !tessellationPresent && geometryPresent && !fragmentPresent ) {
1094 if( !isSeparable ) {
1095 fprintf(stderr, "[ERROR]: Vertex & Fragment Shaders not present. Program must be separable.\n");
1096 } else {
1097 mRegisterShaderProgram("", "", "", shaderFilenames[0], "", isSeparable);
1098 }
1099 } else if( !vertexPresent && !tessellationPresent && geometryPresent && fragmentPresent ) {
1100 if( !isSeparable ) {
1101 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1102 } else {
1103 mRegisterShaderProgram("", "", "", shaderFilenames[0], shaderFilenames[1], isSeparable);
1104 }
1105 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && fragmentPresent ) {
1106 if( !isSeparable ) {
1107 fprintf(stderr, "[ERROR]: Vertex Shader not present. Program must be separable.\n");
1108 } else {
1109 mRegisterShaderProgram("", "", "", "", shaderFilenames[0], isSeparable);
1110 }
1111 } else if( !vertexPresent && !tessellationPresent && !geometryPresent && !fragmentPresent ) {
1112 fprintf(stderr, "[ERROR]: At least one shader must be present.\n");
1113 } else {
1114 fprintf(stderr, "[ERROR]: Unknown state.\n");
1115 }
1116}
1117
1119 const char *vertexShaderFilename,
1120 const char *tessellationControlShaderFilename,
1121 const char *tessellationEvaluationShaderFilename,
1122 const char *geometryShaderFilename,
1123 const char *fragmentShaderFilename,
1124 const bool isSeparable
1125) {
1126 GLint major, minor;
1127 glGetIntegerv(GL_MAJOR_VERSION, &major);
1128 glGetIntegerv(GL_MINOR_VERSION, &minor);
1129
1130 if( sDEBUG ) printf( "\n[INFO]: /--------------------------------------------------------\\\n");
1131
1132 // compile each one of our shaders
1133 if( strcmp( vertexShaderFilename, "" ) != 0 ) {
1134 if( sDEBUG ) printf( "[INFO]: | Vertex Shader: %39s |\n", vertexShaderFilename );
1135 mVertexShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(vertexShaderFilename, GL_VERTEX_SHADER );
1136 } else {
1137 mVertexShaderHandle = 0;
1138 }
1139
1140 if(strcmp(tessellationControlShaderFilename, "" ) != 0 ) {
1141 if( sDEBUG ) printf("[INFO]: | Tess Control Shader: %33s |\n", tessellationControlShaderFilename );
1142 if( major < 4 ) {
1143 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1144 mTessellationControlShaderHandle = 0;
1145 } else {
1146 mTessellationControlShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationControlShaderFilename, GL_TESS_CONTROL_SHADER );
1147 }
1148 } else {
1149 mTessellationControlShaderHandle = 0;
1150 }
1151
1152 if(strcmp(tessellationEvaluationShaderFilename, "" ) != 0 ) {
1153 if( sDEBUG ) printf("[INFO]: | Tess Evaluation Shader: %30s |\n", tessellationEvaluationShaderFilename );
1154 if( major < 4 ) {
1155 printf( "[ERROR]:| TESSELLATION SHADER NOT SUPPORTED!! UPGRADE TO v4.0+ |\n" );
1156 mTessellationEvaluationShaderHandle = 0;
1157 } else {
1158 mTessellationEvaluationShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(tessellationEvaluationShaderFilename, GL_TESS_EVALUATION_SHADER );
1159 }
1160 } else {
1161 mTessellationEvaluationShaderHandle = 0;
1162 }
1163
1164 if( strcmp( geometryShaderFilename, "" ) != 0 ) {
1165 if( sDEBUG ) printf( "[INFO]: | Geometry Shader: %37s |\n", geometryShaderFilename );
1166 if( major < 3 || (major == 3 && minor < 2) ) {
1167 printf( "[ERROR]:| GEOMETRY SHADER NOT SUPPORTED!!! UPGRADE TO v3.2+ |\n" );
1168 mGeometryShaderHandle = 0;
1169 } else {
1170 mGeometryShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(geometryShaderFilename, GL_GEOMETRY_SHADER );
1171 }
1172 } else {
1173 mGeometryShaderHandle = 0;
1174 }
1175
1176 if( strcmp( fragmentShaderFilename, "" ) != 0 ) {
1177 if( sDEBUG ) printf( "[INFO]: | Fragment Shader: %37s |\n", fragmentShaderFilename );
1178 mFragmentShaderHandle = CSCI441_INTERNAL::ShaderUtils::compileShader(fragmentShaderFilename, GL_FRAGMENT_SHADER );
1179 } else {
1180 mFragmentShaderHandle = 0;
1181 }
1182 // get a handle to a shader program
1183 mShaderProgramHandle = glCreateProgram();
1184
1185 // if program is separable, make it so
1186 if( isSeparable ) {
1187 glProgramParameteri(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, GL_TRUE );
1188 }
1189
1190 // attach the vertex and fragment shaders to the shader program
1191 if(mVertexShaderHandle != 0 ) {
1192 glAttachShader(mShaderProgramHandle, mVertexShaderHandle );
1193 }
1194 if(mTessellationControlShaderHandle != 0 ) {
1195 glAttachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1196 }
1197 if(mTessellationEvaluationShaderHandle != 0 ) {
1198 glAttachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1199 }
1200 if(mGeometryShaderHandle != 0 ) {
1201 glAttachShader(mShaderProgramHandle, mGeometryShaderHandle );
1202 }
1203 if(mFragmentShaderHandle != 0 ) {
1204 glAttachShader(mShaderProgramHandle, mFragmentShaderHandle );
1205 }
1206
1207 // link all the programs together on the GPU
1208 glLinkProgram(mShaderProgramHandle );
1209
1210 if( sDEBUG ) printf( "[INFO]: | Shader Program: %41s", "|\n" );
1211
1212 // check the program log
1213 CSCI441_INTERNAL::ShaderUtils::printProgramLog(mShaderProgramHandle );
1214
1215 // detach & delete the vertex and fragment shaders to the shader program
1216 if(mVertexShaderHandle != 0 ) {
1217 glDetachShader(mShaderProgramHandle, mVertexShaderHandle );
1218 glDeleteShader(mVertexShaderHandle );
1219 }
1220 if(mTessellationControlShaderHandle != 0 ) {
1221 glDetachShader(mShaderProgramHandle, mTessellationControlShaderHandle );
1222 glDeleteShader(mTessellationControlShaderHandle );
1223 }
1224 if(mTessellationEvaluationShaderHandle != 0 ) {
1225 glDetachShader(mShaderProgramHandle, mTessellationEvaluationShaderHandle );
1226 glDeleteShader(mTessellationEvaluationShaderHandle );
1227 }
1228 if(mGeometryShaderHandle != 0 ) {
1229 glDetachShader(mShaderProgramHandle, mGeometryShaderHandle );
1230 glDeleteShader(mGeometryShaderHandle );
1231 }
1232 if(mFragmentShaderHandle != 0 ) {
1233 glDetachShader(mShaderProgramHandle, mFragmentShaderHandle );
1234 glDeleteShader(mFragmentShaderHandle );
1235 }
1236
1237
1238 // map uniforms
1239 mpUniformLocationsMap = new std::map<std::string, GLint>();
1240 GLint numUniforms;
1241 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniforms);
1242 GLint max_uniform_name_size;
1243 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_size);
1244 if( numUniforms > 0 ) {
1245 for(GLint i = 0; i < numUniforms; i++) {
1246 auto name = new GLchar[max_uniform_name_size];
1247 int actual_length = 0;
1248 int size = 0;
1249 GLenum type;
1250 glGetActiveUniform(mShaderProgramHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
1251 GLint location;
1252 if(size > 1) {
1253 for(int j = 0; j < size; j++) {
1254 const int max_array_size = actual_length + 4 + 2 + 1;
1255 auto array_name = new GLchar[max_array_size];
1256 snprintf(array_name, max_array_size, "%s[%i]", name, j);
1257 location = glGetUniformLocation(mShaderProgramHandle, array_name);
1258 mpUniformLocationsMap->emplace(array_name, location);
1259 delete[] array_name;
1260 }
1261 } else {
1262 location = glGetUniformLocation(mShaderProgramHandle, name);
1263 mpUniformLocationsMap->emplace(name, location);
1264 }
1265 delete[] name;
1266 }
1267 }
1268
1269 // map attributes
1270 mpAttributeLocationsMap = new std::map<std::string, GLint>();
1271 GLint numAttributes;
1272 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttributes );
1273 GLint max_attr_name_size;
1274 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_size);
1275 if( numAttributes > 0 ) {
1276 for(GLint i = 0; i < numAttributes; i++) {
1277 auto name = new GLchar[max_attr_name_size];
1278 int actual_length = 0;
1279 int size = 0;
1280 GLenum type;
1281 glGetActiveAttrib(mShaderProgramHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
1282 GLint location;
1283 if( size > 1 ) {
1284 for( int j = 0; j < size; j++ ) {
1285 const int max_array_size = actual_length + 4 + 2 + 1;
1286 auto array_name = new GLchar[max_array_size];
1287 snprintf( array_name, max_array_size, "%s[%i]", name, j );
1288 location = glGetAttribLocation(mShaderProgramHandle, array_name );
1289 mpAttributeLocationsMap->emplace(array_name, location);
1290 delete[] array_name;
1291 }
1292 } else {
1293 location = glGetAttribLocation(mShaderProgramHandle, name );
1294 mpAttributeLocationsMap->emplace(name, location);
1295 }
1296 delete[] name;
1297 }
1298 }
1299
1300 GLint separable = GL_FALSE;
1301 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_SEPARABLE, &separable );
1302
1303 if( sDEBUG ) printf( "[INFO]: | Program Separable: %35s |\n", (separable ? "Yes" : "No"));
1304
1305 GLint linkStatus;
1306 glGetProgramiv(mShaderProgramHandle, GL_LINK_STATUS, &linkStatus );
1307
1308 // print shader info for uniforms & attributes
1309 if(linkStatus == GL_TRUE) {
1310 CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(mShaderProgramHandle, mVertexShaderHandle != 0,
1311 mTessellationControlShaderHandle != 0,
1312 mTessellationEvaluationShaderHandle != 0,
1313 mGeometryShaderHandle != 0, mFragmentShaderHandle != 0,
1314 false, true);
1315 } else {
1316 if(sDEBUG) printf( "[INFO]: \\--------------------------------------------------------/\n\n");
1317 }
1318 // return handle
1319 return mShaderProgramHandle != 0;
1320}
1321
1322inline GLint CSCI441::ShaderProgram::getUniformLocation( const GLchar *uniformName ) const {
1323 const GLint uniformLoc = glGetUniformLocation(mShaderProgramHandle, uniformName );
1324 if( uniformLoc == GL_INVALID_VALUE )
1325 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle );
1326 return uniformLoc;
1327}
1328
1329inline GLint CSCI441::ShaderProgram::getUniformBlockIndex( const GLchar *uniformBlockName ) const {
1330 const GLint uniformBlockLoc = glGetUniformBlockIndex(mShaderProgramHandle, uniformBlockName );
1331 if( uniformBlockLoc == GL_INVALID_INDEX )
1332 fprintf(stderr, "[ERROR]: Could not find uniform block \"%s\" for Shader Program %u\n", uniformBlockName, mShaderProgramHandle );
1333 return uniformBlockLoc;
1334}
1335
1336inline GLint CSCI441::ShaderProgram::getUniformBlockSize( const GLchar *uniformBlockName ) const {
1337 GLint blockSize;
1338 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1339 return blockSize;
1340}
1341
1342[[maybe_unused]]
1343inline GLubyte* CSCI441::ShaderProgram::getUniformBlockBuffer( const GLchar *uniformBlockName ) const {
1344 const GLint blockSize = getUniformBlockSize( uniformBlockName );
1345 return (GLubyte*)malloc(blockSize);
1346}
1347
1348[[maybe_unused]]
1349inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName ) const {
1350 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1351}
1352
1353[[maybe_unused]]
1354inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName, const GLchar *names[] ) const {
1355 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1356}
1357
1358inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex ) const {
1359 GLint numUniforms;
1360 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1361
1362 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1363 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1364
1365 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1366 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1367 return offsets;
1368}
1369
1370inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex, const GLchar * names[] ) const {
1371 GLint numUniforms;
1372 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1373
1374 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1375 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1376
1377 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1378 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1379 return offsets;
1380}
1381
1382inline void CSCI441::ShaderProgram::setUniformBlockBinding( const GLchar* uniformBlockName, const GLuint binding ) const {
1383 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1384}
1385
1386[[maybe_unused]]
1387inline GLint CSCI441::ShaderProgram::getAttributeLocation( const GLchar* attributeName ) const {
1388 const auto attribIter = mpAttributeLocationsMap->find(attributeName);
1389 if(attribIter == mpAttributeLocationsMap->end() ) {
1390 fprintf(stderr, "[ERROR]: Could not find attribute \"%s\" for Shader Program %u\n", attributeName, mShaderProgramHandle );
1391 return -1;
1392 }
1393 return attribIter->second;
1394}
1395
1396[[maybe_unused]]
1397inline GLuint CSCI441::ShaderProgram::getSubroutineIndex( const GLenum shaderStage, const GLchar* const subroutineName ) const {
1398 const GLuint subroutineIndex = glGetSubroutineIndex(mShaderProgramHandle, shaderStage, subroutineName );
1399 if( subroutineIndex == GL_INVALID_INDEX )
1400 fprintf(stderr, "[ERROR]: Could not find subroutine \"%s\" in %s for Shader Program %u\n", subroutineName, CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(shaderStage), mShaderProgramHandle );
1401 return subroutineIndex;
1402}
1403
1404[[maybe_unused]]
1405inline GLint CSCI441::ShaderProgram::getSubroutineUniformLocation( const GLenum shaderStage, const GLchar* const subroutineName ) const {
1406 const GLint subroutineUniform = glGetSubroutineUniformLocation(mShaderProgramHandle, shaderStage, subroutineName );
1407 if ( subroutineUniform == GL_INVALID_VALUE )
1408 fprintf(stderr, "[ERROR]: Could not find subroutine \"%s\" in %s for Shader Program %u\n", subroutineName, CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(shaderStage), mShaderProgramHandle );
1409 return subroutineUniform;
1410}
1411
1412[[maybe_unused]]
1413inline void CSCI441::ShaderProgram::setSubroutineIndices( const GLenum shaderStage, const GLsizei numIndices, const GLuint * const indices ) {
1414 glUniformSubroutinesuiv( shaderStage, numIndices, indices );
1415}
1416
1417// images are opaque types that are not considered program resources
1418[[maybe_unused]]
1419inline GLint CSCI441::ShaderProgram::getImageBinding(const GLchar* imageName) const {
1420 const GLint imageLoc = getUniformLocation(imageName);
1421
1422 if(imageLoc == GL_INVALID_INDEX) {
1423 fprintf(stderr, "[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1424 return -1;
1425 }
1426
1427 GLint bindingPoint;
1428 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1429
1430 return bindingPoint;
1431}
1432
1433[[maybe_unused]]
1434inline GLint CSCI441::ShaderProgram::getShaderStorageBlockBinding(const GLchar* ssboName) const {
1435 const GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1436
1437 if(ssboIndex == GL_INVALID_INDEX) {
1438 fprintf(stderr, "[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1439 return -1;
1440 }
1441
1442 constexpr GLenum props = GL_BUFFER_BINDING;
1443 GLint binding;
1444 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, 1, &props, 1, nullptr, &binding);
1445
1446 return binding;
1447}
1448
1449[[maybe_unused]]
1450inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferBinding(const GLchar* atomicName) const {
1451 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1452
1453 if(uniformIndex == GL_INVALID_INDEX) {
1454 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1455 return -1;
1456 }
1457
1458 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1459 GLint atomicIndex, binding;
1460 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1461 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
1462
1463 return binding;
1464}
1465
1466[[maybe_unused]]
1467inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferOffset(const GLchar* atomicName) const {
1468 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1469
1470 if(uniformIndex == GL_INVALID_INDEX) {
1471 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1472 return -1;
1473 }
1474
1475 GLint offset;
1476 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1477 return offset;
1478}
1479
1480[[maybe_unused]]
1481inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferSize(const GLchar* atomicName) const {
1482 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1483
1484 if(uniformIndex == GL_INVALID_INDEX) {
1485 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1486 return -1;
1487 }
1488
1489 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1490 GLint atomicIndex, bufferSize;
1491 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1492 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize);
1493
1494 return bufferSize;
1495}
1496
1497[[maybe_unused]]
1499 GLint numUniform = 0;
1500 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1501 return numUniform;
1502}
1503
1504[[maybe_unused]]
1506 GLint numUniformBlocks = 0;
1507 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1508 return numUniformBlocks;
1509}
1510
1511[[maybe_unused]]
1513 GLint numAttr = 0;
1514 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1515 return numAttr;
1516}
1517
1518[[maybe_unused]]
1519inline GLint CSCI441::ShaderProgram::getFragmentDataLocation(const GLchar *name) const {
1520 return glGetFragDataLocation(mShaderProgramHandle, name);
1521}
1522
1523[[maybe_unused]]
1524inline GLint CSCI441::ShaderProgram::getFragmentDataIndex(const GLchar *name) const {
1525 return glGetFragDataIndex(mShaderProgramHandle, name);
1526}
1527
1529 return mShaderProgramHandle;
1530}
1531
1532inline GLboolean CSCI441::ShaderProgram::validate() const {
1533 if (mShaderProgramHandle == 0) {
1534 return GL_FALSE;
1535 }
1536
1537 glValidateProgram(mShaderProgramHandle);
1538 GLint validateStatus = GL_FALSE;
1539 glGetProgramiv(mShaderProgramHandle, GL_VALIDATE_STATUS, &validateStatus);
1540
1541 if (validateStatus == GL_FALSE && sDEBUG) {
1542 CSCI441_INTERNAL::ShaderUtils::printProgramInfoLog(mShaderProgramHandle);
1543 }
1544
1545 return (validateStatus == GL_TRUE);
1546}
1547
1548[[maybe_unused]]
1550 glUseProgram(mShaderProgramHandle );
1551}
1552
1553[[maybe_unused]]
1554inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0 ) const {
1555 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1556 if(uniformIter != mpUniformLocationsMap->end()) {
1557 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1558 } else {
1559 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1560 }
1561}
1562
1563[[maybe_unused]]
1564inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1 ) const {
1565 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1566 if(uniformIter != mpUniformLocationsMap->end()) {
1567 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1568 } else {
1569 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1570 }
1571}
1572
1573[[maybe_unused]]
1574inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec2 value ) const {
1575 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1576}
1577
1578[[maybe_unused]]
1579inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1580 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1581 if(uniformIter != mpUniformLocationsMap->end()) {
1582 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1583 } else {
1584 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1585 }
1586}
1587
1588[[maybe_unused]]
1589inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec3 value ) const {
1590 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1591}
1592
1593[[maybe_unused]]
1594inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) const {
1595 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1596 if(uniformIter != mpUniformLocationsMap->end()) {
1597 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1598 } else {
1599 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1600 }
1601}
1602
1603[[maybe_unused]]
1604inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec4 value ) const {
1605 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1606}
1607
1608inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1609 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1610 if(uniformIter != mpUniformLocationsMap->end()) {
1611 switch(dim) {
1612 case 1:
1613 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1614 break;
1615 case 2:
1616 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1617 break;
1618 case 3:
1619 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1620 break;
1621 case 4:
1622 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1623 break;
1624 default:
1625 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1626 break;
1627 }
1628 } else {
1629 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1630 }
1631}
1632
1633[[maybe_unused]]
1634inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0 ) const {
1635 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1636 if(uniformIter != mpUniformLocationsMap->end()) {
1637 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1638 } else {
1639 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1640 }
1641}
1642
1643[[maybe_unused]]
1644inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1 ) const {
1645 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1646 if(uniformIter != mpUniformLocationsMap->end()) {
1647 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1648 } else {
1649 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1650 }
1651}
1652
1653[[maybe_unused]]
1654inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const {
1655 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1656 if(uniformIter != mpUniformLocationsMap->end()) {
1657 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1658 } else {
1659 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1660 }
1661}
1662
1663[[maybe_unused]]
1664inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2 ) const {
1665 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1666 if(uniformIter != mpUniformLocationsMap->end()) {
1667 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1668 } else {
1669 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1670 }
1671}
1672
1673[[maybe_unused]]
1674inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const {
1675 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1676 if(uniformIter != mpUniformLocationsMap->end()) {
1677 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1678 } else {
1679 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1680 }
1681}
1682
1683[[maybe_unused]]
1684inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1685 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1686 if(uniformIter != mpUniformLocationsMap->end()) {
1687 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1688 } else {
1689 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1690 }
1691}
1692
1693[[maybe_unused]]
1694inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const {
1695 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1696 if(uniformIter != mpUniformLocationsMap->end()) {
1697 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1698 } else {
1699 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1700 }
1701}
1702
1703[[maybe_unused]]
1704inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLint *value) const {
1705 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1706 if(uniformIter != mpUniformLocationsMap->end()) {
1707 switch(dim) {
1708 case 1:
1709 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1710 break;
1711 case 2:
1712 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1713 break;
1714 case 3:
1715 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1716 break;
1717 case 4:
1718 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1719 break;
1720 default:
1721 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1722 break;
1723 }
1724 } else {
1725 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1726 }
1727}
1728
1729[[maybe_unused]]
1730inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0 ) const {
1731 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1732 if(uniformIter != mpUniformLocationsMap->end()) {
1733 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1734 } else {
1735 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1736 }
1737}
1738
1739[[maybe_unused]]
1740inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1 ) const {
1741 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1742 if(uniformIter != mpUniformLocationsMap->end()) {
1743 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1744 } else {
1745 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1746 }
1747}
1748
1749[[maybe_unused]]
1750inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const {
1751 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1752 if(uniformIter != mpUniformLocationsMap->end()) {
1753 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1754 } else {
1755 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1756 }
1757}
1758
1759[[maybe_unused]]
1760inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
1761 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1762 if(uniformIter != mpUniformLocationsMap->end()) {
1763 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1764 } else {
1765 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1766 }
1767}
1768
1769[[maybe_unused]]
1770inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const {
1771 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1772 if(uniformIter != mpUniformLocationsMap->end()) {
1773 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1774 } else {
1775 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1776 }
1777}
1778
1779[[maybe_unused]]
1780inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
1781 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1782 if(uniformIter != mpUniformLocationsMap->end()) {
1783 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1784 } else {
1785 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1786 }
1787}
1788
1789[[maybe_unused]]
1790inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const {
1791 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1792 if(uniformIter != mpUniformLocationsMap->end()) {
1793 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1794 } else {
1795 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1796 }
1797}
1798
1799[[maybe_unused]]
1800inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLuint * const value) const {
1801 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1802 if(uniformIter != mpUniformLocationsMap->end()) {
1803 switch(dim) {
1804 case 1:
1805 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1806 break;
1807 case 2:
1808 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1809 break;
1810 case 3:
1811 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1812 break;
1813 case 4:
1814 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1815 break;
1816 default:
1817 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1818 break;
1819 }
1820 } else {
1821 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1822 }
1823}
1824
1825[[maybe_unused]]
1826inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2 mtx ) const {
1827 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1828 if(uniformIter != mpUniformLocationsMap->end()) {
1829 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1830 } else {
1831 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1832 }
1833}
1834
1835[[maybe_unused]]
1836inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3 mtx ) const {
1837 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1838 if(uniformIter != mpUniformLocationsMap->end()) {
1839 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1840 } else {
1841 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1842 }
1843}
1844
1845[[maybe_unused]]
1846inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4 mtx ) const {
1847 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1848 if(uniformIter != mpUniformLocationsMap->end()) {
1849 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1850 } else {
1851 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1852 }
1853}
1854
1855[[maybe_unused]]
1856inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x3 mtx ) const {
1857 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1858 if(uniformIter != mpUniformLocationsMap->end()) {
1859 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1860 } else {
1861 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1862 }
1863}
1864
1865[[maybe_unused]]
1866inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x2 mtx ) const {
1867 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1868 if(uniformIter != mpUniformLocationsMap->end()) {
1869 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1870 } else {
1871 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1872 }
1873}
1874
1875[[maybe_unused]]
1876inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x4 mtx ) const {
1877 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1878 if(uniformIter != mpUniformLocationsMap->end()) {
1879 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1880 } else {
1881 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1882 }
1883}
1884
1885[[maybe_unused]]
1886inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x2 mtx ) const {
1887 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1888 if(uniformIter != mpUniformLocationsMap->end()) {
1889 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1890 } else {
1891 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1892 }
1893}
1894
1895[[maybe_unused]]
1896inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x4 mtx ) const {
1897 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1898 if(uniformIter != mpUniformLocationsMap->end()) {
1899 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1900 } else {
1901 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1902 }
1903}
1904
1905[[maybe_unused]]
1906inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x3 mtx ) const {
1907 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1908 if(uniformIter != mpUniformLocationsMap->end()) {
1909 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1910 } else {
1911 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1912 }
1913}
1914
1915[[maybe_unused]]
1916inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0 ) const {
1917 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1918}
1919
1920[[maybe_unused]]
1921inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1 ) const {
1922 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1923}
1924
1925[[maybe_unused]]
1926inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec2 value ) const {
1927 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1928}
1929
1930[[maybe_unused]]
1931inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1932 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1933}
1934
1935[[maybe_unused]]
1936inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec3 value ) const {
1937 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1938}
1939
1940[[maybe_unused]]
1941inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2, const GLfloat v3 ) const {
1942 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1943}
1944
1945[[maybe_unused]]
1946inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec4 value ) const {
1947 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1948}
1949
1950inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1951 switch(dim) {
1952 case 1:
1953 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1954 break;
1955 case 2:
1956 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1957 break;
1958 case 3:
1959 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1960 break;
1961 case 4:
1962 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1963 break;
1964 default:
1965 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1966 break;
1967 }
1968}
1969
1970[[maybe_unused]]
1971inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0 ) const {
1972 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1973}
1974
1975[[maybe_unused]]
1976inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1 ) const {
1977 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1978}
1979
1980[[maybe_unused]]
1981inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec2 value) const {
1982 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1983}
1984
1985[[maybe_unused]]
1986inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2 ) const {
1987 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1988}
1989
1990[[maybe_unused]]
1991inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec3 value) const {
1992 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1993}
1994
1995[[maybe_unused]]
1996inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1997 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1998}
1999
2000[[maybe_unused]]
2001inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec4 value) const {
2002 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2003}
2004
2005inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLint * const value) const {
2006 switch(dim) {
2007 case 1:
2008 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
2009 break;
2010 case 2:
2011 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
2012 break;
2013 case 3:
2014 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
2015 break;
2016 case 4:
2017 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
2018 break;
2019 default:
2020 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2021 break;
2022 }
2023}
2024
2025[[maybe_unused]]
2026inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0 ) const {
2027 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
2028}
2029
2030[[maybe_unused]]
2031inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1 ) const {
2032 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
2033}
2034
2035[[maybe_unused]]
2036inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const glm::uvec2 value) const {
2037 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
2038}
2039
2040[[maybe_unused]]
2041inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
2042 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
2043}
2044
2045[[maybe_unused]]
2046inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec3 value) const {
2047 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
2048}
2049
2050[[maybe_unused]]
2051inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
2052 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2053}
2054
2055[[maybe_unused]]
2056inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec4 value) const {
2057 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2058}
2059
2060inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLuint * const value) const {
2061 switch(dim) {
2062 case 1:
2063 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
2064 break;
2065 case 2:
2066 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
2067 break;
2068 case 3:
2069 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
2070 break;
2071 case 4:
2072 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
2073 break;
2074 default:
2075 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2076 break;
2077 }
2078}
2079
2080[[maybe_unused]]
2081inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2 mtx ) const {
2082 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2083}
2084
2085[[maybe_unused]]
2086inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3 mtx ) const {
2087 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2088}
2089
2090[[maybe_unused]]
2091inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4 mtx ) const {
2092 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2093}
2094
2095[[maybe_unused]]
2096inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x3 mtx ) const {
2097 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2098}
2099
2100[[maybe_unused]]
2101inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x2 mtx ) const {
2102 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2103}
2104
2105[[maybe_unused]]
2106inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x4 mtx ) const {
2107 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2108}
2109
2110[[maybe_unused]]
2111inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x2 mtx ) const {
2112 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2113}
2114
2115[[maybe_unused]]
2116inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x4 mtx ) const {
2117 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2118}
2119
2120[[maybe_unused]]
2121inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x3 mtx ) const {
2122 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2123}
2124
2125[[maybe_unused]]
2127 GLbitfield shaderBits = 0;
2128 if( mVertexShaderHandle != 0 ) shaderBits |= GL_VERTEX_SHADER_BIT;
2129 if( mTessellationControlShaderHandle != 0 ) shaderBits |= GL_TESS_CONTROL_SHADER_BIT;
2130 if( mTessellationEvaluationShaderHandle != 0 ) shaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
2131 if( mGeometryShaderHandle != 0 ) shaderBits |= GL_GEOMETRY_SHADER_BIT;
2132 if( mFragmentShaderHandle != 0 ) shaderBits |= GL_FRAGMENT_SHADER_BIT;
2133 return shaderBits;
2134}
2135
2137 mVertexShaderHandle(0),
2138 mTessellationControlShaderHandle(0), mTessellationEvaluationShaderHandle(0),
2139 mGeometryShaderHandle(0),
2140 mFragmentShaderHandle(0),
2141 mShaderProgramHandle(0),
2142 mpUniformLocationsMap(nullptr), mpAttributeLocationsMap(nullptr)
2143{
2144
2145}
2146
2148 _cleanupSelf();
2149}
2150
2152 ShaderProgram&& src
2153) noexcept : ShaderProgram() {
2154 _moveFromSource(src);
2155}
2156
2158 if (this != &src) { // guard against self moving
2159 _cleanupSelf(); // cleanup existing instance
2160 _moveFromSource(src); // move from source instance
2161 }
2162 return *this; // return self
2163}
2164
2165inline void CSCI441::ShaderProgram::_cleanupSelf() {
2166 GLint status;
2167 GLint infoLogLength = 0;
2168 constexpr int maxLength = 1000;
2169
2170 glDeleteProgram(mShaderProgramHandle );
2171
2172 // create a buffer of designated length
2173 const auto infoLog = new GLchar[maxLength];
2174
2175 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2176
2177 // get the info log for the vertex/tessellation/geometry/fragment/compute shader
2178 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2179
2180 if(infoLogLength > 0 ) {
2181 // print info to terminal
2182 if( sDEBUG ) printf("[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ? "Success" : " Error"), infoLog );
2183 }
2184
2185 delete mpUniformLocationsMap;
2186 delete mpAttributeLocationsMap;
2187 delete[] infoLog;
2188
2189 mVertexShaderHandle = 0;
2190 mTessellationControlShaderHandle = 0;
2191 mTessellationEvaluationShaderHandle = 0;
2192 mGeometryShaderHandle = 0;
2193 mFragmentShaderHandle = 0;
2194 mShaderProgramHandle = 0;
2195 mpUniformLocationsMap = nullptr;
2196 mpAttributeLocationsMap = nullptr;
2197}
2198
2199inline void CSCI441::ShaderProgram::_moveFromSource(ShaderProgram &src) {
2200 mVertexShaderHandle = src.mVertexShaderHandle;
2201 src.mVertexShaderHandle = 0;
2202
2203 mTessellationControlShaderHandle = src.mTessellationControlShaderHandle;
2204 src.mTessellationControlShaderHandle = 0;
2205
2206 mTessellationEvaluationShaderHandle = src.mTessellationEvaluationShaderHandle;
2207 src.mTessellationEvaluationShaderHandle = 0;
2208
2209 mGeometryShaderHandle = src.mGeometryShaderHandle;
2210 src.mGeometryShaderHandle = 0;
2211
2212 mFragmentShaderHandle = src.mFragmentShaderHandle;
2213 src.mFragmentShaderHandle = 0;
2214
2215 mShaderProgramHandle = src.mShaderProgramHandle;
2216 src.mShaderProgramHandle = 0;
2217
2218 mpUniformLocationsMap = src.mpUniformLocationsMap;
2219 src.mpUniformLocationsMap = nullptr;
2220
2221 mpAttributeLocationsMap = src.mpAttributeLocationsMap;
2222 src.mpAttributeLocationsMap = nullptr;
2223}
2224
2225
2226inline bool CSCI441::ShaderProgram::writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const {
2227 GLint formats = 0;
2228 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2229 if( formats < 1 ) {
2230 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2231 return false;
2232 }
2233
2234 // Get the binary length
2235 GLint length = 0;
2236 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2237
2238 // Retrieve the binary code
2239 std::vector<GLubyte> buffer(length);
2240 GLenum format = 0;
2241 glGetProgramBinary(mShaderProgramHandle, length, nullptr, &format, buffer.data());
2242
2243 // Write the binary to a file.
2244 fprintf(stdout, "[INFO]: Writing to %s, binary format %d\n",BINARY_FILE_NAME, format);
2245 std::ofstream out(BINARY_FILE_NAME, std::ios::binary);
2246 out.write( reinterpret_cast<char *>(buffer.data()), length );
2247 out.close();
2248
2249 return true;
2250}
2251
2252inline CSCI441::ShaderProgram* CSCI441::ShaderProgram::loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, const GLenum FORMAT) {
2253 GLint formats = 0;
2254 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2255 if( formats < 1 ) {
2256 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2257 return nullptr;
2258 }
2259
2260 const GLuint program = glCreateProgram();
2261
2262 // Load binary from file
2263 std::ifstream inputStream(BINARY_FILE_NAME, std::ios::binary);
2264 const std::istreambuf_iterator<char> startIt(inputStream);
2265 constexpr std::istreambuf_iterator<char> endIt;
2266 const std::vector<char> buffer(startIt, endIt); // Load file
2267 inputStream.close();
2268
2269 // Install shader binary
2270 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2271
2272 // Check for success/failure
2273 GLint status;
2274 glGetProgramiv(program, GL_LINK_STATUS, &status);
2275 if( GL_FALSE == status ) {
2276 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2277 return nullptr;
2278 }
2279
2280 const auto shaderProgram = new CSCI441::ShaderProgram();
2281 shaderProgram->mShaderProgramHandle = program;
2282 return shaderProgram;
2283}
2284
2285#endif // CSCI441_SHADER_PROGRAM_HPP
Helper functions to work with OpenGL Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:36
virtual GLbitfield getProgramStages() const
returns a single value corresponding to which shader stages are present in this shader program
Definition: ShaderProgram.hpp:2126
GLuint mTessellationEvaluationShaderHandle
handle to the tessellation evaluation shader stage
Definition: ShaderProgram.hpp:883
virtual GLint * getUniformBlockOffsets(const GLchar *uniformBlockName) const final
Returns an array of offsets into the buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1349
GLuint mVertexShaderHandle
handle to the vertex shader stage
Definition: ShaderProgram.hpp:875
virtual GLubyte * getUniformBlockBuffer(const GLchar *uniformBlockName) const final
Returns an allocated buffer for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1343
virtual void setProgramUniform(const GLchar *uniformName, GLfloat v0) const final
sets the program uniform consisting of one float
Definition: ShaderProgram.hpp:1554
static ShaderProgram * loadShaderProgramFromBinaryFile(const char *BINARY_FILE_NAME, GLenum format)
loads precompiled shader program binary from external file
Definition: ShaderProgram.hpp:2252
virtual GLint getAttributeLocation(const GLchar *attributeName) const final
Returns the location of the given attribute in this shader program.
Definition: ShaderProgram.hpp:1387
GLuint mShaderProgramHandle
handle to the shader program
Definition: ShaderProgram.hpp:896
GLuint mTessellationControlShaderHandle
handle to the tessellation control shader stage
Definition: ShaderProgram.hpp:879
virtual void useProgram() const final
Sets the Shader Program to be active.
Definition: ShaderProgram.hpp:1549
virtual GLuint getNumAttributes() const final
Returns the number of active attributes in this shader program.
Definition: ShaderProgram.hpp:1512
virtual void setUniformBlockBinding(const GLchar *uniformBlockName, GLuint binding) const final
Set the binding point for the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1382
std::map< std::string, GLint > * mpUniformLocationsMap
caches locations of uniform names within shader program
Definition: ShaderProgram.hpp:901
virtual GLint getUniformBlockIndex(const GLchar *uniformBlockName) const final
Returns the index of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1329
virtual GLint getAtomicCounterBufferOffset(const GLchar *atomicName) const final
Returns the offset into the buffer for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1467
ShaderProgram & operator=(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual GLuint getNumUniforms() const final
Returns the number of active uniforms in this shader program.
Definition: ShaderProgram.hpp:1498
virtual GLint getSubroutineUniformLocation(GLenum shaderStage, const GLchar *subroutineName) const final
Returns the uniform location within the subroutine array for a given subroutine.
Definition: ShaderProgram.hpp:1405
virtual GLint getImageBinding(const GLchar *imageName) const final
Returns the binding point for the corresponding image uniform.
Definition: ShaderProgram.hpp:1419
virtual ~ShaderProgram()
Clean up memory associated with the Shader Program.
Definition: ShaderProgram.hpp:2147
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1528
GLuint mGeometryShaderHandle
handle to the geometry shader stage
Definition: ShaderProgram.hpp:887
virtual GLint getAtomicCounterBufferBinding(const GLchar *atomicName) const final
Returns the binding point for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1450
static bool sDEBUG
if DEBUG information should be printed or not
Definition: ShaderProgram.hpp:870
virtual GLuint getSubroutineIndex(GLenum shaderStage, const GLchar *subroutineName) const final
Returns the index of the given subroutine for a shader stage in this shader program.
Definition: ShaderProgram.hpp:1397
virtual void setSubroutineIndices(GLenum shaderStage, GLsizei numIndices, const GLuint *indices) final
Sets the subroutines to use for a given shader stage.
Definition: ShaderProgram.hpp:1413
virtual GLint getShaderStorageBlockBinding(const GLchar *ssboName) const final
Returns the binding point for the corresponding shader storage block.
Definition: ShaderProgram.hpp:1434
virtual bool writeShaderProgramBinaryToFile(const char *BINARY_FILE_NAME) const final
writes precompiled shader program binary to external file
Definition: ShaderProgram.hpp:2226
static void disableDebugMessages()
Disables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:942
virtual GLint getUniformBlockSize(const GLchar *uniformBlockName) const final
Returns the size of the given uniform block in this shader program.
Definition: ShaderProgram.hpp:1336
static void enableDebugMessages()
Enables debug messages from Shader Program functions.
Definition: ShaderProgram.hpp:936
virtual GLboolean validate() const final
checks if program can execute in its current OpenGL state
Definition: ShaderProgram.hpp:1532
std::map< std::string, GLint > * mpAttributeLocationsMap
caches locations of attribute names within shader program
Definition: ShaderProgram.hpp:905
virtual GLuint getNumUniformBlocks() const final
Returns the number of active uniform blocks in this shader program.
Definition: ShaderProgram.hpp:1505
ShaderProgram(const ShaderProgram &)=delete
do not allow shader programs to be copied
virtual GLint getFragmentDataLocation(const GLchar *name) const final
query the bindings of color numbers to user-defined varying out variables
Definition: ShaderProgram.hpp:1519
GLuint mFragmentShaderHandle
handle to the fragment shader stage
Definition: ShaderProgram.hpp:891
ShaderProgram()
creates an empty shader program object
Definition: ShaderProgram.hpp:2136
virtual GLint getFragmentDataIndex(const GLchar *name) const final
query the bindings of color indices to user-defined varying out variables
Definition: ShaderProgram.hpp:1524
virtual GLint getUniformLocation(const GLchar *uniformName) const final
Returns the location of the given uniform in this shader program.
Definition: ShaderProgram.hpp:1322
virtual bool mRegisterShaderProgram(const char *vertexShaderFilename, const char *tessellationControlShaderFilename, const char *tessellationEvaluationShaderFilename, const char *geometryShaderFilename, const char *fragmentShaderFilename, bool isSeparable) final
registers a shader program with the GPU
Definition: ShaderProgram.hpp:1118
virtual GLint getAtomicCounterBufferSize(const GLchar *atomicName) const final
Returns the full buffer size for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1481
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17