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