CSCI441 OpenGL Library 5.17.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 final;
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 }
1316 // return handle
1317 return mShaderProgramHandle != 0;
1318}
1319
1320inline GLint CSCI441::ShaderProgram::getUniformLocation( const GLchar *uniformName ) const {
1321 const GLint uniformLoc = glGetUniformLocation(mShaderProgramHandle, uniformName );
1322 if( uniformLoc == GL_INVALID_VALUE )
1323 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle );
1324 return uniformLoc;
1325}
1326
1327inline GLint CSCI441::ShaderProgram::getUniformBlockIndex( const GLchar *uniformBlockName ) const {
1328 const GLint uniformBlockLoc = glGetUniformBlockIndex(mShaderProgramHandle, uniformBlockName );
1329 if( uniformBlockLoc == GL_INVALID_INDEX )
1330 fprintf(stderr, "[ERROR]: Could not find uniform block \"%s\" for Shader Program %u\n", uniformBlockName, mShaderProgramHandle );
1331 return uniformBlockLoc;
1332}
1333
1334inline GLint CSCI441::ShaderProgram::getUniformBlockSize( const GLchar *uniformBlockName ) const {
1335 GLint blockSize;
1336 glGetActiveUniformBlockiv(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), GL_UNIFORM_BLOCK_DATA_SIZE, &blockSize );
1337 return blockSize;
1338}
1339
1340[[maybe_unused]]
1341inline GLubyte* CSCI441::ShaderProgram::getUniformBlockBuffer( const GLchar *uniformBlockName ) const {
1342 const GLint blockSize = getUniformBlockSize( uniformBlockName );
1343 return (GLubyte*)malloc(blockSize);
1344}
1345
1346[[maybe_unused]]
1347inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName ) const {
1348 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName));
1349}
1350
1351[[maybe_unused]]
1352inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets( const GLchar* uniformBlockName, const GLchar *names[] ) const {
1353 return getUniformBlockOffsets(getUniformBlockIndex(uniformBlockName), names);
1354}
1355
1356inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex ) const {
1357 GLint numUniforms;
1358 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1359
1360 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1361 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
1362
1363 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1364 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1365 return offsets;
1366}
1367
1368inline GLint* CSCI441::ShaderProgram::getUniformBlockOffsets(const GLint uniformBlockIndex, const GLchar * names[] ) const {
1369 GLint numUniforms;
1370 glGetActiveUniformBlockiv(mShaderProgramHandle, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUniforms );
1371
1372 const auto indices = (GLuint*)malloc(numUniforms*sizeof(GLuint));
1373 glGetUniformIndices(mShaderProgramHandle, numUniforms, names, indices );
1374
1375 const auto offsets = (GLint*)malloc(numUniforms*sizeof(GLint));
1376 glGetActiveUniformsiv(mShaderProgramHandle, numUniforms, indices, GL_UNIFORM_OFFSET, offsets );
1377 return offsets;
1378}
1379
1380inline void CSCI441::ShaderProgram::setUniformBlockBinding( const GLchar* uniformBlockName, const GLuint binding ) const {
1381 glUniformBlockBinding(mShaderProgramHandle, getUniformBlockIndex(uniformBlockName), binding );
1382}
1383
1384[[maybe_unused]]
1385inline GLint CSCI441::ShaderProgram::getAttributeLocation( const GLchar* attributeName ) const {
1386 const auto attribIter = mpAttributeLocationsMap->find(attributeName);
1387 if(attribIter == mpAttributeLocationsMap->end() ) {
1388 fprintf(stderr, "[ERROR]: Could not find attribute \"%s\" for Shader Program %u\n", attributeName, mShaderProgramHandle );
1389 return -1;
1390 }
1391 return attribIter->second;
1392}
1393
1394[[maybe_unused]]
1395inline GLuint CSCI441::ShaderProgram::getSubroutineIndex( const GLenum shaderStage, const GLchar* const subroutineName ) const {
1396 const GLuint subroutineIndex = glGetSubroutineIndex(mShaderProgramHandle, shaderStage, subroutineName );
1397 if( subroutineIndex == GL_INVALID_INDEX )
1398 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 );
1399 return subroutineIndex;
1400}
1401
1402[[maybe_unused]]
1403inline GLint CSCI441::ShaderProgram::getSubroutineUniformLocation( const GLenum shaderStage, const GLchar* const subroutineName ) const {
1404 const GLint subroutineUniform = glGetSubroutineUniformLocation(mShaderProgramHandle, shaderStage, subroutineName );
1405 if ( subroutineUniform == GL_INVALID_VALUE )
1406 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 );
1407 return subroutineUniform;
1408}
1409
1410[[maybe_unused]]
1411inline void CSCI441::ShaderProgram::setSubroutineIndices( const GLenum shaderStage, const GLsizei numIndices, const GLuint * const indices ) {
1412 glUniformSubroutinesuiv( shaderStage, numIndices, indices );
1413}
1414
1415// images are opaque types that are not considered program resources
1416[[maybe_unused]]
1417inline GLint CSCI441::ShaderProgram::getImageBinding(const GLchar* imageName) const {
1418 const GLint imageLoc = getUniformLocation(imageName);
1419
1420 if(imageLoc == GL_INVALID_INDEX) {
1421 fprintf(stderr, "[ERROR]: Could not find image \"%s\" for Shader Program %u\n", imageName, mShaderProgramHandle);
1422 return -1;
1423 }
1424
1425 GLint bindingPoint;
1426 glGetUniformiv(mShaderProgramHandle, imageLoc, &bindingPoint);
1427
1428 return bindingPoint;
1429}
1430
1431[[maybe_unused]]
1432inline GLint CSCI441::ShaderProgram::getShaderStorageBlockBinding(const GLchar* ssboName) const {
1433 const GLuint ssboIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
1434
1435 if(ssboIndex == GL_INVALID_INDEX) {
1436 fprintf(stderr, "[ERROR]: Could not find shader storage block \"%s\" for Shader Program %u\n", ssboName, mShaderProgramHandle);
1437 return -1;
1438 }
1439
1440 constexpr GLenum props = GL_BUFFER_BINDING;
1441 GLint binding;
1442 glGetProgramResourceiv(mShaderProgramHandle, GL_SHADER_STORAGE_BLOCK, ssboIndex, 1, &props, 1, nullptr, &binding);
1443
1444 return binding;
1445}
1446
1447[[maybe_unused]]
1448inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferBinding(const GLchar* atomicName) const {
1449 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1450
1451 if(uniformIndex == GL_INVALID_INDEX) {
1452 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1453 return -1;
1454 }
1455
1456 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1457 GLint atomicIndex, binding;
1458 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1459 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_BINDING, &binding);
1460
1461 return binding;
1462}
1463
1464[[maybe_unused]]
1465inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferOffset(const GLchar* atomicName) const {
1466 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1467
1468 if(uniformIndex == GL_INVALID_INDEX) {
1469 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1470 return -1;
1471 }
1472
1473 GLint offset;
1474 glGetActiveUniformsiv(mShaderProgramHandle, 1, &uniformIndex, GL_UNIFORM_OFFSET, &offset);
1475 return offset;
1476}
1477
1478[[maybe_unused]]
1479inline GLint CSCI441::ShaderProgram::getAtomicCounterBufferSize(const GLchar* atomicName) const {
1480 const GLuint uniformIndex = glGetProgramResourceIndex(mShaderProgramHandle, GL_UNIFORM, atomicName);
1481
1482 if(uniformIndex == GL_INVALID_INDEX) {
1483 fprintf(stderr, "[ERROR]: Could not find atomic counter \"%s\" for Shader Program %u\n", atomicName, mShaderProgramHandle);
1484 return -1;
1485 }
1486
1487 constexpr GLenum props = GL_ATOMIC_COUNTER_BUFFER_INDEX;
1488 GLint atomicIndex, bufferSize;
1489 glGetProgramResourceiv(mShaderProgramHandle, GL_UNIFORM, uniformIndex, 1, &props, 1, nullptr, &atomicIndex);
1490 glGetActiveAtomicCounterBufferiv(mShaderProgramHandle, atomicIndex, GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE, &bufferSize);
1491
1492 return bufferSize;
1493}
1494
1495[[maybe_unused]]
1497 GLint numUniform = 0;
1498 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORMS, &numUniform );
1499 return numUniform;
1500}
1501
1502[[maybe_unused]]
1504 GLint numUniformBlocks = 0;
1505 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_UNIFORM_BLOCKS, &numUniformBlocks );
1506 return numUniformBlocks;
1507}
1508
1509[[maybe_unused]]
1511 GLint numAttr = 0;
1512 glGetProgramiv(mShaderProgramHandle, GL_ACTIVE_ATTRIBUTES, &numAttr );
1513 return numAttr;
1514}
1515
1516[[maybe_unused]]
1517inline GLint CSCI441::ShaderProgram::getFragmentDataLocation(const GLchar *name) const {
1518 return glGetFragDataLocation(mShaderProgramHandle, name);
1519}
1520
1521[[maybe_unused]]
1522inline GLint CSCI441::ShaderProgram::getFragmentDataIndex(const GLchar *name) const {
1523 return glGetFragDataIndex(mShaderProgramHandle, name);
1524}
1525
1527 return mShaderProgramHandle;
1528}
1529
1530inline GLboolean CSCI441::ShaderProgram::validate() const {
1531 if (mShaderProgramHandle == 0) {
1532 return GL_FALSE;
1533 }
1534
1535 glValidateProgram(mShaderProgramHandle);
1536 GLint validateStatus = GL_FALSE;
1537 glGetProgramiv(mShaderProgramHandle, GL_VALIDATE_STATUS, &validateStatus);
1538
1539 if (validateStatus == GL_FALSE && sDEBUG) {
1540 CSCI441_INTERNAL::ShaderUtils::printProgramInfoLog(mShaderProgramHandle);
1541 }
1542
1543 return (validateStatus == GL_TRUE);
1544}
1545
1546[[maybe_unused]]
1548 glUseProgram(mShaderProgramHandle );
1549}
1550
1551[[maybe_unused]]
1552inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0 ) const {
1553 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1554 if(uniformIter != mpUniformLocationsMap->end()) {
1555 glProgramUniform1f(mShaderProgramHandle, uniformIter->second, v0 );
1556 } else {
1557 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1558 }
1559}
1560
1561[[maybe_unused]]
1562inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1 ) const {
1563 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1564 if(uniformIter != mpUniformLocationsMap->end()) {
1565 glProgramUniform2f(mShaderProgramHandle, uniformIter->second, v0, v1 );
1566 } else {
1567 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1568 }
1569}
1570
1571[[maybe_unused]]
1572inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec2 value ) const {
1573 setProgramUniform( uniformName, 2, 1, glm::value_ptr(value) );
1574}
1575
1576[[maybe_unused]]
1577inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1578 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1579 if(uniformIter != mpUniformLocationsMap->end()) {
1580 glProgramUniform3f(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1581 } else {
1582 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1583 }
1584}
1585
1586[[maybe_unused]]
1587inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec3 value ) const {
1588 setProgramUniform( uniformName, 3, 1, glm::value_ptr(value) );
1589}
1590
1591[[maybe_unused]]
1592inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) const {
1593 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1594 if(uniformIter != mpUniformLocationsMap->end()) {
1595 glProgramUniform4f(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1596 } else {
1597 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1598 }
1599}
1600
1601[[maybe_unused]]
1602inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::vec4 value ) const {
1603 setProgramUniform( uniformName, 4, 1, glm::value_ptr(value) );
1604}
1605
1606inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1607 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1608 if(uniformIter != mpUniformLocationsMap->end()) {
1609 switch(dim) {
1610 case 1:
1611 glProgramUniform1fv(mShaderProgramHandle, uniformIter->second, count, value );
1612 break;
1613 case 2:
1614 glProgramUniform2fv(mShaderProgramHandle, uniformIter->second, count, value );
1615 break;
1616 case 3:
1617 glProgramUniform3fv(mShaderProgramHandle, uniformIter->second, count, value );
1618 break;
1619 case 4:
1620 glProgramUniform4fv(mShaderProgramHandle, uniformIter->second, count, value );
1621 break;
1622 default:
1623 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1624 break;
1625 }
1626 } else {
1627 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1628 }
1629}
1630
1631[[maybe_unused]]
1632inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0 ) const {
1633 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1634 if(uniformIter != mpUniformLocationsMap->end()) {
1635 glProgramUniform1i(mShaderProgramHandle, uniformIter->second, v0 );
1636 } else {
1637 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1638 }
1639}
1640
1641[[maybe_unused]]
1642inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1 ) const {
1643 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1644 if(uniformIter != mpUniformLocationsMap->end()) {
1645 glProgramUniform2i(mShaderProgramHandle, uniformIter->second, v0, v1 );
1646 } else {
1647 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1648 }
1649}
1650
1651[[maybe_unused]]
1652inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec2 value) const {
1653 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1654 if(uniformIter != mpUniformLocationsMap->end()) {
1655 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1656 } else {
1657 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1658 }
1659}
1660
1661[[maybe_unused]]
1662inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2 ) const {
1663 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1664 if(uniformIter != mpUniformLocationsMap->end()) {
1665 glProgramUniform3i(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1666 } else {
1667 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1668 }
1669}
1670
1671[[maybe_unused]]
1672inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec3 value) const {
1673 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1674 if(uniformIter != mpUniformLocationsMap->end()) {
1675 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1676 } else {
1677 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1678 }
1679}
1680
1681[[maybe_unused]]
1682inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1683 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1684 if(uniformIter != mpUniformLocationsMap->end()) {
1685 glProgramUniform4i(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1686 } else {
1687 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1688 }
1689}
1690
1691[[maybe_unused]]
1692inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::ivec4 value) const {
1693 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1694 if(uniformIter != mpUniformLocationsMap->end()) {
1695 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1696 } else {
1697 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1698 }
1699}
1700
1701[[maybe_unused]]
1702inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLint *value) const {
1703 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1704 if(uniformIter != mpUniformLocationsMap->end()) {
1705 switch(dim) {
1706 case 1:
1707 glProgramUniform1iv(mShaderProgramHandle, uniformIter->second, count, value );
1708 break;
1709 case 2:
1710 glProgramUniform2iv(mShaderProgramHandle, uniformIter->second, count, value );
1711 break;
1712 case 3:
1713 glProgramUniform3iv(mShaderProgramHandle, uniformIter->second, count, value );
1714 break;
1715 case 4:
1716 glProgramUniform4iv(mShaderProgramHandle, uniformIter->second, count, value );
1717 break;
1718 default:
1719 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1720 break;
1721 }
1722 } else {
1723 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1724 }
1725}
1726
1727[[maybe_unused]]
1728inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0 ) const {
1729 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1730 if(uniformIter != mpUniformLocationsMap->end()) {
1731 glProgramUniform1ui(mShaderProgramHandle, uniformIter->second, v0 );
1732 } else {
1733 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1734 }
1735}
1736
1737[[maybe_unused]]
1738inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1 ) const {
1739 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1740 if(uniformIter != mpUniformLocationsMap->end()) {
1741 glProgramUniform2ui(mShaderProgramHandle, uniformIter->second, v0, v1 );
1742 } else {
1743 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1744 }
1745}
1746
1747[[maybe_unused]]
1748inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec2 value) const {
1749 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1750 if(uniformIter != mpUniformLocationsMap->end()) {
1751 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1752 } else {
1753 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1754 }
1755}
1756
1757[[maybe_unused]]
1758inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
1759 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1760 if(uniformIter != mpUniformLocationsMap->end()) {
1761 glProgramUniform3ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2 );
1762 } else {
1763 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1764 }
1765}
1766
1767[[maybe_unused]]
1768inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec3 value) const {
1769 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1770 if(uniformIter != mpUniformLocationsMap->end()) {
1771 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1772 } else {
1773 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1774 }
1775}
1776
1777[[maybe_unused]]
1778inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
1779 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1780 if(uniformIter != mpUniformLocationsMap->end()) {
1781 glProgramUniform4ui(mShaderProgramHandle, uniformIter->second, v0, v1, v2, v3 );
1782 } else {
1783 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1784 }
1785}
1786
1787[[maybe_unused]]
1788inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, glm::uvec4 value) const {
1789 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1790 if(uniformIter != mpUniformLocationsMap->end()) {
1791 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, 1, glm::value_ptr(value) );
1792 } else {
1793 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1794 }
1795}
1796
1797[[maybe_unused]]
1798inline void CSCI441::ShaderProgram::setProgramUniform(const GLchar* uniformName, const GLuint dim, const GLsizei count, const GLuint * const value) const {
1799 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1800 if(uniformIter != mpUniformLocationsMap->end()) {
1801 switch(dim) {
1802 case 1:
1803 glProgramUniform1uiv(mShaderProgramHandle, uniformIter->second, count, value );
1804 break;
1805 case 2:
1806 glProgramUniform2uiv(mShaderProgramHandle, uniformIter->second, count, value );
1807 break;
1808 case 3:
1809 glProgramUniform3uiv(mShaderProgramHandle, uniformIter->second, count, value );
1810 break;
1811 case 4:
1812 glProgramUniform4uiv(mShaderProgramHandle, uniformIter->second, count, value );
1813 break;
1814 default:
1815 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %s in Shader Program %u. Dimension must be [1,4]\n", dim, uniformName, mShaderProgramHandle);
1816 break;
1817 }
1818 } else {
1819 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1820 }
1821}
1822
1823[[maybe_unused]]
1824inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2 mtx ) const {
1825 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1826 if(uniformIter != mpUniformLocationsMap->end()) {
1827 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1828 } else {
1829 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1830 }
1831}
1832
1833[[maybe_unused]]
1834inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3 mtx ) const {
1835 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1836 if(uniformIter != mpUniformLocationsMap->end()) {
1837 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1838 } else {
1839 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1840 }
1841}
1842
1843[[maybe_unused]]
1844inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4 mtx ) const {
1845 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1846 if(uniformIter != mpUniformLocationsMap->end()) {
1847 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1848 } else {
1849 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1850 }
1851}
1852
1853[[maybe_unused]]
1854inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x3 mtx ) const {
1855 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1856 if(uniformIter != mpUniformLocationsMap->end()) {
1857 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1858 } else {
1859 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1860 }
1861}
1862
1863[[maybe_unused]]
1864inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x2 mtx ) const {
1865 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1866 if(uniformIter != mpUniformLocationsMap->end()) {
1867 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1868 } else {
1869 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1870 }
1871}
1872
1873[[maybe_unused]]
1874inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat2x4 mtx ) const {
1875 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1876 if(uniformIter != mpUniformLocationsMap->end()) {
1877 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1878 } else {
1879 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1880 }
1881}
1882
1883[[maybe_unused]]
1884inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x2 mtx ) const {
1885 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1886 if(uniformIter != mpUniformLocationsMap->end()) {
1887 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1888 } else {
1889 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1890 }
1891}
1892
1893[[maybe_unused]]
1894inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat3x4 mtx ) const {
1895 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1896 if(uniformIter != mpUniformLocationsMap->end()) {
1897 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1898 } else {
1899 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1900 }
1901}
1902
1903[[maybe_unused]]
1904inline void CSCI441::ShaderProgram::setProgramUniform( const GLchar* uniformName, glm::mat4x3 mtx ) const {
1905 auto uniformIter = mpUniformLocationsMap->find(uniformName);
1906 if(uniformIter != mpUniformLocationsMap->end()) {
1907 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformIter->second, 1, GL_FALSE, glm::value_ptr(mtx) );
1908 } else {
1909 fprintf(stderr, "[ERROR]: Could not find uniform \"%s\" for Shader Program %u\n", uniformName, mShaderProgramHandle);
1910 }
1911}
1912
1913[[maybe_unused]]
1914inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0 ) const {
1915 glProgramUniform1f(mShaderProgramHandle, uniformLocation, v0 );
1916}
1917
1918[[maybe_unused]]
1919inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1 ) const {
1920 glProgramUniform2f(mShaderProgramHandle, uniformLocation, v0, v1 );
1921}
1922
1923[[maybe_unused]]
1924inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec2 value ) const {
1925 setProgramUniform( uniformLocation, 2, 1, glm::value_ptr(value) );
1926}
1927
1928[[maybe_unused]]
1929inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2 ) const {
1930 glProgramUniform3f(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1931}
1932
1933[[maybe_unused]]
1934inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec3 value ) const {
1935 setProgramUniform( uniformLocation, 3, 1, glm::value_ptr(value) );
1936}
1937
1938[[maybe_unused]]
1939inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLfloat v0, const GLfloat v1, const GLfloat v2, const GLfloat v3 ) const {
1940 glProgramUniform4f(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1941}
1942
1943[[maybe_unused]]
1944inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::vec4 value ) const {
1945 setProgramUniform( uniformLocation, 4, 1, glm::value_ptr(value) );
1946}
1947
1948inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLfloat * const value) const {
1949 switch(dim) {
1950 case 1:
1951 glProgramUniform1fv(mShaderProgramHandle, uniformLocation, count, value );
1952 break;
1953 case 2:
1954 glProgramUniform2fv(mShaderProgramHandle, uniformLocation, count, value );
1955 break;
1956 case 3:
1957 glProgramUniform3fv(mShaderProgramHandle, uniformLocation, count, value );
1958 break;
1959 case 4:
1960 glProgramUniform4fv(mShaderProgramHandle, uniformLocation, count, value );
1961 break;
1962 default:
1963 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
1964 break;
1965 }
1966}
1967
1968[[maybe_unused]]
1969inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0 ) const {
1970 glProgramUniform1i(mShaderProgramHandle, uniformLocation, v0 );
1971}
1972
1973[[maybe_unused]]
1974inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1 ) const {
1975 glProgramUniform2i(mShaderProgramHandle, uniformLocation, v0, v1 );
1976}
1977
1978[[maybe_unused]]
1979inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec2 value) const {
1980 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
1981}
1982
1983[[maybe_unused]]
1984inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2 ) const {
1985 glProgramUniform3i(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
1986}
1987
1988[[maybe_unused]]
1989inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec3 value) const {
1990 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
1991}
1992
1993[[maybe_unused]]
1994inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLint v0, const GLint v1, const GLint v2, const GLint v3 ) const {
1995 glProgramUniform4i(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
1996}
1997
1998[[maybe_unused]]
1999inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::ivec4 value) const {
2000 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2001}
2002
2003inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLint * const value) const {
2004 switch(dim) {
2005 case 1:
2006 glProgramUniform1iv(mShaderProgramHandle, uniformLocation, count, value );
2007 break;
2008 case 2:
2009 glProgramUniform2iv(mShaderProgramHandle, uniformLocation, count, value );
2010 break;
2011 case 3:
2012 glProgramUniform3iv(mShaderProgramHandle, uniformLocation, count, value );
2013 break;
2014 case 4:
2015 glProgramUniform4iv(mShaderProgramHandle, uniformLocation, count, value );
2016 break;
2017 default:
2018 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2019 break;
2020 }
2021}
2022
2023[[maybe_unused]]
2024inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0 ) const {
2025 glProgramUniform1ui(mShaderProgramHandle, uniformLocation, v0 );
2026}
2027
2028[[maybe_unused]]
2029inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1 ) const {
2030 glProgramUniform2ui(mShaderProgramHandle, uniformLocation, v0, v1 );
2031}
2032
2033[[maybe_unused]]
2034inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const glm::uvec2 value) const {
2035 setProgramUniform(uniformLocation, 2, 1, glm::value_ptr(value));
2036}
2037
2038[[maybe_unused]]
2039inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2 ) const {
2040 glProgramUniform3ui(mShaderProgramHandle, uniformLocation, v0, v1, v2 );
2041}
2042
2043[[maybe_unused]]
2044inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec3 value) const {
2045 setProgramUniform(uniformLocation, 3, 1, glm::value_ptr(value));
2046}
2047
2048[[maybe_unused]]
2049inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint v0, const GLuint v1, const GLuint v2, const GLuint v3 ) const {
2050 glProgramUniform4ui(mShaderProgramHandle, uniformLocation, v0, v1, v2, v3 );
2051}
2052
2053[[maybe_unused]]
2054inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::uvec4 value) const {
2055 setProgramUniform(uniformLocation, 4, 1, glm::value_ptr(value));
2056}
2057
2058inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, const GLuint dim, const GLsizei count, const GLuint * const value) const {
2059 switch(dim) {
2060 case 1:
2061 glProgramUniform1uiv(mShaderProgramHandle, uniformLocation, count, value );
2062 break;
2063 case 2:
2064 glProgramUniform2uiv(mShaderProgramHandle, uniformLocation, count, value );
2065 break;
2066 case 3:
2067 glProgramUniform3uiv(mShaderProgramHandle, uniformLocation, count, value );
2068 break;
2069 case 4:
2070 glProgramUniform4uiv(mShaderProgramHandle, uniformLocation, count, value );
2071 break;
2072 default:
2073 fprintf(stderr, "[ERROR]: invalid dimension %u for uniform %i in Shader Program %u. Dimension must be [1,4]\n", dim, uniformLocation, mShaderProgramHandle);
2074 break;
2075 }
2076}
2077
2078[[maybe_unused]]
2079inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2 mtx ) const {
2080 glProgramUniformMatrix2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2081}
2082
2083[[maybe_unused]]
2084inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3 mtx ) const {
2085 glProgramUniformMatrix3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2086}
2087
2088[[maybe_unused]]
2089inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4 mtx ) const {
2090 glProgramUniformMatrix4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2091}
2092
2093[[maybe_unused]]
2094inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x3 mtx ) const {
2095 glProgramUniformMatrix2x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2096}
2097
2098[[maybe_unused]]
2099inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x2 mtx ) const {
2100 glProgramUniformMatrix3x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2101}
2102
2103[[maybe_unused]]
2104inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat2x4 mtx ) const {
2105 glProgramUniformMatrix2x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2106}
2107
2108[[maybe_unused]]
2109inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x2 mtx ) const {
2110 glProgramUniformMatrix4x2fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2111}
2112
2113[[maybe_unused]]
2114inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat3x4 mtx ) const {
2115 glProgramUniformMatrix3x4fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2116}
2117
2118[[maybe_unused]]
2119inline void CSCI441::ShaderProgram::setProgramUniform(const GLint uniformLocation, glm::mat4x3 mtx ) const {
2120 glProgramUniformMatrix4x3fv(mShaderProgramHandle, uniformLocation, 1, GL_FALSE, glm::value_ptr(mtx) );
2121}
2122
2123[[maybe_unused]]
2125 GLbitfield shaderBits = 0;
2126 if( mVertexShaderHandle != 0 ) shaderBits |= GL_VERTEX_SHADER_BIT;
2127 if( mTessellationControlShaderHandle != 0 ) shaderBits |= GL_TESS_CONTROL_SHADER_BIT;
2128 if( mTessellationEvaluationShaderHandle != 0 ) shaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
2129 if( mGeometryShaderHandle != 0 ) shaderBits |= GL_GEOMETRY_SHADER_BIT;
2130 if( mFragmentShaderHandle != 0 ) shaderBits |= GL_FRAGMENT_SHADER_BIT;
2131 return shaderBits;
2132}
2133
2135 mVertexShaderHandle(0),
2136 mTessellationControlShaderHandle(0), mTessellationEvaluationShaderHandle(0),
2137 mGeometryShaderHandle(0),
2138 mFragmentShaderHandle(0),
2139 mShaderProgramHandle(0),
2140 mpUniformLocationsMap(nullptr), mpAttributeLocationsMap(nullptr)
2141{
2142
2143}
2144
2146 _cleanupSelf();
2147}
2148
2150 ShaderProgram&& src
2151) noexcept : ShaderProgram() {
2152 _moveFromSource(src);
2153}
2154
2156 if (this != &src) { // guard against self moving
2157 _cleanupSelf(); // cleanup existing instance
2158 _moveFromSource(src); // move from source instance
2159 }
2160 return *this; // return self
2161}
2162
2163inline void CSCI441::ShaderProgram::_cleanupSelf() {
2164 GLint status;
2165 GLint infoLogLength = 0;
2166 constexpr int maxLength = 1000;
2167
2168 glDeleteProgram(mShaderProgramHandle );
2169
2170 // create a buffer of designated length
2171 const auto infoLog = new GLchar[maxLength];
2172
2173 glGetProgramiv(mShaderProgramHandle, GL_DELETE_STATUS, &status );
2174
2175 // get the info log for the vertex/tessellation/geometry/fragment/compute shader
2176 glGetProgramInfoLog(mShaderProgramHandle, maxLength, &infoLogLength, infoLog );
2177
2178 if(infoLogLength > 0 ) {
2179 // print info to terminal
2180 if( sDEBUG ) printf("[INFO]: Program Handle %d Delete Status %s: %s\n", mShaderProgramHandle, (status == GL_TRUE ? "Success" : " Error"), infoLog );
2181 }
2182
2183 delete mpUniformLocationsMap;
2184 delete mpAttributeLocationsMap;
2185 delete[] infoLog;
2186
2187 mVertexShaderHandle = 0;
2188 mTessellationControlShaderHandle = 0;
2189 mTessellationEvaluationShaderHandle = 0;
2190 mGeometryShaderHandle = 0;
2191 mFragmentShaderHandle = 0;
2192 mShaderProgramHandle = 0;
2193 mpUniformLocationsMap = nullptr;
2194 mpAttributeLocationsMap = nullptr;
2195}
2196
2197inline void CSCI441::ShaderProgram::_moveFromSource(ShaderProgram &src) {
2198 mVertexShaderHandle = src.mVertexShaderHandle;
2199 src.mVertexShaderHandle = 0;
2200
2201 mTessellationControlShaderHandle = src.mTessellationControlShaderHandle;
2202 src.mTessellationControlShaderHandle = 0;
2203
2204 mTessellationEvaluationShaderHandle = src.mTessellationEvaluationShaderHandle;
2205 src.mTessellationEvaluationShaderHandle = 0;
2206
2207 mGeometryShaderHandle = src.mGeometryShaderHandle;
2208 src.mGeometryShaderHandle = 0;
2209
2210 mFragmentShaderHandle = src.mFragmentShaderHandle;
2211 src.mFragmentShaderHandle = 0;
2212
2213 mShaderProgramHandle = src.mShaderProgramHandle;
2214 src.mShaderProgramHandle = 0;
2215
2216 mpUniformLocationsMap = src.mpUniformLocationsMap;
2217 src.mpUniformLocationsMap = nullptr;
2218
2219 mpAttributeLocationsMap = src.mpAttributeLocationsMap;
2220 src.mpAttributeLocationsMap = nullptr;
2221}
2222
2223
2224inline bool CSCI441::ShaderProgram::writeShaderProgramBinaryToFile(const char* BINARY_FILE_NAME) const {
2225 GLint formats = 0;
2226 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2227 if( formats < 1 ) {
2228 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2229 return false;
2230 }
2231
2232 // Get the binary length
2233 GLint length = 0;
2234 glGetProgramiv(mShaderProgramHandle, GL_PROGRAM_BINARY_LENGTH, &length);
2235
2236 // Retrieve the binary code
2237 std::vector<GLubyte> buffer(length);
2238 GLenum format = 0;
2239 glGetProgramBinary(mShaderProgramHandle, length, nullptr, &format, buffer.data());
2240
2241 // Write the binary to a file.
2242 fprintf(stdout, "[INFO]: Writing to %s, binary format %d\n",BINARY_FILE_NAME, format);
2243 std::ofstream out(BINARY_FILE_NAME, std::ios::binary);
2244 out.write( reinterpret_cast<char *>(buffer.data()), length );
2245 out.close();
2246
2247 return true;
2248}
2249
2250inline CSCI441::ShaderProgram* CSCI441::ShaderProgram::loadShaderProgramFromBinaryFile(const char* BINARY_FILE_NAME, const GLenum FORMAT) {
2251 GLint formats = 0;
2252 glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
2253 if( formats < 1 ) {
2254 fprintf(stderr, "[ERROR]: Driver does not support any binary formats.\n");
2255 return nullptr;
2256 }
2257
2258 const GLuint program = glCreateProgram();
2259
2260 // Load binary from file
2261 std::ifstream inputStream(BINARY_FILE_NAME, std::ios::binary);
2262 const std::istreambuf_iterator<char> startIt(inputStream);
2263 constexpr std::istreambuf_iterator<char> endIt;
2264 const std::vector<char> buffer(startIt, endIt); // Load file
2265 inputStream.close();
2266
2267 // Install shader binary
2268 glProgramBinary(program, FORMAT, buffer.data(), buffer.size() );
2269
2270 // Check for success/failure
2271 GLint status;
2272 glGetProgramiv(program, GL_LINK_STATUS, &status);
2273 if( GL_FALSE == status ) {
2274 CSCI441_INTERNAL::ShaderUtils::printProgramLog(program);
2275 return nullptr;
2276 }
2277
2278 const auto shaderProgram = new CSCI441::ShaderProgram();
2279 shaderProgram->mShaderProgramHandle = program;
2280 return shaderProgram;
2281}
2282
2283#endif // CSCI441_SHADER_PROGRAM_HPP
Helper functions to work with OpenGL Shaders.
Handles registration and compilation of Shaders.
Definition: ShaderProgram.hpp:36
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:1347
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:1341
virtual void setProgramUniform(const GLchar *uniformName, GLfloat v0) const final
sets the program uniform consisting of one float
Definition: ShaderProgram.hpp:1552
static ShaderProgram * loadShaderProgramFromBinaryFile(const char *BINARY_FILE_NAME, GLenum format)
loads precompiled shader program binary from external file
Definition: ShaderProgram.hpp:2250
virtual GLint getAttributeLocation(const GLchar *attributeName) const final
Returns the location of the given attribute in this shader program.
Definition: ShaderProgram.hpp:1385
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:1547
virtual GLuint getNumAttributes() const final
Returns the number of active attributes in this shader program.
Definition: ShaderProgram.hpp:1510
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:1380
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:1327
virtual GLint getAtomicCounterBufferOffset(const GLchar *atomicName) const final
Returns the offset into the buffer for the corresponding atomic counter buffer.
Definition: ShaderProgram.hpp:1465
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:2124
virtual GLuint getNumUniforms() const final
Returns the number of active uniforms in this shader program.
Definition: ShaderProgram.hpp:1496
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:1403
virtual GLint getImageBinding(const GLchar *imageName) const final
Returns the binding point for the corresponding image uniform.
Definition: ShaderProgram.hpp:1417
virtual ~ShaderProgram()
Clean up memory associated with the Shader Program.
Definition: ShaderProgram.hpp:2145
virtual GLuint getShaderProgramHandle() const final
Returns the handle for this shader program.
Definition: ShaderProgram.hpp:1526
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:1448
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:1395
virtual void setSubroutineIndices(GLenum shaderStage, GLsizei numIndices, const GLuint *indices) final
Sets the subroutines to use for a given shader stage.
Definition: ShaderProgram.hpp:1411
virtual GLint getShaderStorageBlockBinding(const GLchar *ssboName) const final
Returns the binding point for the corresponding shader storage block.
Definition: ShaderProgram.hpp:1432
virtual bool writeShaderProgramBinaryToFile(const char *BINARY_FILE_NAME) const final
writes precompiled shader program binary to external file
Definition: ShaderProgram.hpp:2224
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:1334
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:1530
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:1503
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:1517
GLuint mFragmentShaderHandle
handle to the fragment shader stage
Definition: ShaderProgram.hpp:891
ShaderProgram()
creates an empty shader program object
Definition: ShaderProgram.hpp:2134
virtual GLint getFragmentDataIndex(const GLchar *name) const final
query the bindings of color indices to user-defined varying out variables
Definition: ShaderProgram.hpp:1522
virtual GLint getUniformLocation(const GLchar *uniformName) const final
Returns the location of the given uniform in this shader program.
Definition: ShaderProgram.hpp:1320
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:1479
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17