14#ifndef CSCI441_SHADER_UTILS_HPP
15#define CSCI441_SHADER_UTILS_HPP
17#ifdef CSCI441_USE_GLEW
30namespace CSCI441_INTERNAL::ShaderUtils {
31 static bool sDEBUG =
true;
34 [[maybe_unused]]
void enableDebugMessages();
37 [[maybe_unused]]
void disableDebugMessages();
42 const char* GLSL_type_to_string( GLenum type );
47 const char* GL_shader_type_to_string( GLenum type );
52 const char* GL_primitive_type_to_string( GLenum type );
58 bool readTextFromFile(
const char* filename,
char* &output );
64 GLuint compileShader(
const char *filename, GLenum shaderType );
67 void printShaderLog( GLuint shaderHandle );
70 void printProgramLog( GLuint programHandle );
73 void printProgramPipelineLog( GLuint pipelineHandle );
79 GLboolean printSubroutineInfo(GLuint programHandle, GLenum shaderStage, GLboolean printHeader );
90 void printShaderProgramInfo( GLuint programHandle,
91 GLboolean hasVertexShader,
92 GLboolean hasTessControlShader, GLboolean hasTessEvalShader,
93 GLboolean hasGeometryShader,
94 GLboolean hasFragmentShader,
95 GLboolean hasComputeShader,
96 GLboolean useLastNewLine );
102inline void CSCI441_INTERNAL::ShaderUtils::enableDebugMessages() {
107inline void CSCI441_INTERNAL::ShaderUtils::disableDebugMessages() {
113inline bool CSCI441_INTERNAL::ShaderUtils::readTextFromFile(
114 const char *filename,
117 std::string buf = std::string(
"");
120 std::ifstream in(filename);
121 if( !in.is_open() ) {
122 fprintf( stderr,
"[ERROR]: Could not open file %s\n", filename );
125 while( std::getline(in, line) ) {
129 output =
new char[buf.length()+1];
130 strncpy(output, buf.c_str(), buf.length());
131 output[buf.length()] =
'\0';
138inline const char* CSCI441_INTERNAL::ShaderUtils::GLSL_type_to_string(
142 case GL_FLOAT:
return "float";
143 case GL_FLOAT_VEC2:
return "vec2";
144 case GL_FLOAT_VEC3:
return "vec3";
145 case GL_FLOAT_VEC4:
return "vec4";
146 case GL_DOUBLE:
return "double";
147 case GL_DOUBLE_VEC2:
return "dvec2";
148 case GL_DOUBLE_VEC3:
return "dvec3";
149 case GL_DOUBLE_VEC4:
return "dvec4";
150 case GL_INT:
return "int";
151 case GL_INT_VEC2:
return "ivec2";
152 case GL_INT_VEC3:
return "ivec3";
153 case GL_INT_VEC4:
return "ivec4";
154 case GL_UNSIGNED_INT:
return "unsigned int";
155 case GL_UNSIGNED_INT_VEC2:
return "uvec2";
156 case GL_UNSIGNED_INT_VEC3:
return "uvec3";
157 case GL_UNSIGNED_INT_VEC4:
return "uvec4";
158 case GL_BOOL:
return "bool";
159 case GL_BOOL_VEC2:
return "bvec2";
160 case GL_BOOL_VEC3:
return "bvec3";
161 case GL_BOOL_VEC4:
return "bvec4";
162 case GL_FLOAT_MAT2:
return "mat2";
163 case GL_FLOAT_MAT3:
return "mat3";
164 case GL_FLOAT_MAT4:
return "mat4";
165 case GL_FLOAT_MAT2x3:
return "mat2x3";
166 case GL_FLOAT_MAT2x4:
return "mat2x4";
167 case GL_FLOAT_MAT3x2:
return "mat3x2";
168 case GL_FLOAT_MAT3x4:
return "mat3x4";
169 case GL_FLOAT_MAT4x2:
return "mat4x2";
170 case GL_FLOAT_MAT4x3:
return "mat4x3";
171 case GL_DOUBLE_MAT2:
return "dmat2";
172 case GL_DOUBLE_MAT3:
return "dmat3";
173 case GL_DOUBLE_MAT4:
return "dmat4";
174 case GL_DOUBLE_MAT2x3:
return "dmat2x3";
175 case GL_DOUBLE_MAT2x4:
return "dmat2x4";
176 case GL_DOUBLE_MAT3x2:
return "dmat3x2";
177 case GL_DOUBLE_MAT3x4:
return "dmat3x4";
178 case GL_DOUBLE_MAT4x2:
return "dmat4x2";
179 case GL_DOUBLE_MAT4x3:
return "dmat4x3";
180 case GL_SAMPLER_1D:
return "sampler1D";
181 case GL_SAMPLER_2D:
return "sampler2D";
182 case GL_SAMPLER_3D:
return "sampler3D";
183 case GL_SAMPLER_CUBE:
return "samplerCube";
184 case GL_SAMPLER_1D_SHADOW:
return "sampler1DShadow";
185 case GL_SAMPLER_2D_SHADOW:
return "sampler2DShadow";
186 case GL_SAMPLER_1D_ARRAY:
return "sampler1DArray";
187 case GL_SAMPLER_2D_ARRAY:
return "sampler2DArray";
188 case GL_SAMPLER_2D_MULTISAMPLE:
return "sampler2DMS";
189 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
return "sampler2DMSArray";
190 case GL_SAMPLER_CUBE_SHADOW:
return "samplerCubeShadow";
191 case GL_SAMPLER_BUFFER:
return "samplerBuffer";
192 case GL_SAMPLER_2D_RECT:
return "sampler2DRect";
193 case GL_SAMPLER_2D_RECT_SHADOW:
return "sampler2DRectShadow";
194 case GL_INT_SAMPLER_1D:
return "isampler1D";
195 case GL_INT_SAMPLER_2D:
return "isampler2D";
196 case GL_INT_SAMPLER_3D:
return "isampler3D";
197 case GL_INT_SAMPLER_CUBE:
return "isamplerCube";
198 case GL_INT_SAMPLER_1D_ARRAY:
return "isampler1DArray";
199 case GL_INT_SAMPLER_2D_ARRAY:
return "isampler2DArray";
200 case GL_INT_SAMPLER_2D_MULTISAMPLE:
return "isampler2DMS";
201 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
return "isampler2DMSArray";
202 case GL_INT_SAMPLER_BUFFER:
return "isamplerBuffer";
203 case GL_INT_SAMPLER_2D_RECT:
return "isampler2DRect";
204 case GL_UNSIGNED_INT_SAMPLER_1D:
return "usampler1D";
205 case GL_UNSIGNED_INT_SAMPLER_2D:
return "usampler2D";
206 case GL_UNSIGNED_INT_SAMPLER_3D:
return "usampler3D";
207 case GL_UNSIGNED_INT_SAMPLER_CUBE:
return "usamplerCube";
208 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY:
return "usampler1DArray";
209 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
return "usampler2DArray";
210 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE:
return "usampler2DMS";
211 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
return "usampler2DMSArray";
212 case GL_UNSIGNED_INT_SAMPLER_BUFFER:
return "usamplerBuffer";
213 case GL_UNSIGNED_INT_SAMPLER_2D_RECT:
return "usampler2DRect";
214 case GL_IMAGE_1D:
return "image1D";
215 case GL_IMAGE_2D:
return "image2D";
216 case GL_IMAGE_3D:
return "image3D";
217 case GL_IMAGE_2D_RECT:
return "image2DRect";
218 case GL_IMAGE_CUBE:
return "imageCube";
219 case GL_IMAGE_BUFFER:
return "imageBuffer";
220 case GL_IMAGE_1D_ARRAY:
return "image1DArray";
221 case GL_IMAGE_2D_ARRAY:
return "image2DArray";
222 case GL_IMAGE_2D_MULTISAMPLE:
return "image2DMS";
223 case GL_IMAGE_2D_MULTISAMPLE_ARRAY:
return "image2DMSArray";
224 case GL_INT_IMAGE_1D:
return "iimage1D";
225 case GL_INT_IMAGE_2D:
return "iimage2D";
226 case GL_INT_IMAGE_3D:
return "iimage3D";
227 case GL_INT_IMAGE_2D_RECT:
return "iimage2DRect";
228 case GL_INT_IMAGE_CUBE:
return "iimageCube";
229 case GL_INT_IMAGE_BUFFER:
return "iimageBuffer";
230 case GL_INT_IMAGE_1D_ARRAY:
return "iimage1DArray";
231 case GL_INT_IMAGE_2D_ARRAY:
return "iimage2DArray";
232 case GL_INT_IMAGE_2D_MULTISAMPLE:
return "iimage2DMS";
233 case GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
return "iimage2DMSArray";
234 case GL_UNSIGNED_INT_IMAGE_1D:
return "uimage1D";
235 case GL_UNSIGNED_INT_IMAGE_2D:
return "uimage2D";
236 case GL_UNSIGNED_INT_IMAGE_3D:
return "uimage3D";
237 case GL_UNSIGNED_INT_IMAGE_2D_RECT:
return "uimage2DRect";
238 case GL_UNSIGNED_INT_IMAGE_CUBE:
return "uimageCube";
239 case GL_UNSIGNED_INT_IMAGE_BUFFER:
return "uimageBuffer";
240 case GL_UNSIGNED_INT_IMAGE_1D_ARRAY:
return "uimage1DArray";
241 case GL_UNSIGNED_INT_IMAGE_2D_ARRAY:
return "uimage2DArray";
242 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE:
return "uimage2DMS";
243 case GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY:
return "uimage2DMSArray";
244 case GL_UNSIGNED_INT_ATOMIC_COUNTER:
return "atomic_uint";
247 return "other data type";
250inline const char* CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(
254 case GL_VERTEX_SHADER:
return "Vertex Shader";
255 case GL_TESS_CONTROL_SHADER:
return "Tess Ctrl Shader";
256 case GL_TESS_EVALUATION_SHADER:
return "Tess Eval Shader";
257 case GL_GEOMETRY_SHADER:
return "Geometry Shader";
258 case GL_FRAGMENT_SHADER:
return "Fragment Shader";
259 case GL_COMPUTE_SHADER:
return "Compute Shader";
262 return "other shader type";
265inline const char* CSCI441_INTERNAL::ShaderUtils::GL_primitive_type_to_string(
269 case GL_POINTS:
return "Points";
270 case GL_LINES:
return "Lines";
271 case GL_LINE_STRIP:
return "Line Strip";
272 case GL_LINE_LOOP:
return "Line Loop";
273 case GL_LINES_ADJACENCY:
return "Line Adjacency";
274 case GL_TRIANGLES:
return "Triangles";
275 case GL_TRIANGLE_STRIP:
return "Triangle Strip";
276 case GL_TRIANGLES_ADJACENCY:
return "Triangle Adjacency";
277 case GL_PATCHES:
return "Patches";
280 return "other primitive type";
283inline void CSCI441_INTERNAL::ShaderUtils::printShaderLog(
284 const GLuint shaderHandle
287 int infoLogLength = 0;
291 if( glIsShader( shaderHandle ) ) {
292 glGetShaderiv( shaderHandle, GL_INFO_LOG_LENGTH, &maxLength );
295 char* infoLog =
new char[maxLength];
297 glGetShaderiv( shaderHandle, GL_COMPILE_STATUS, &status );
298 if( sDEBUG ) printf(
"[INFO]: | Shader Handle %2d: Compile%-26s |\n", shaderHandle, (status == 1 ?
"d Successfully" :
"r Error") );
301 glGetShaderInfoLog(shaderHandle, maxLength, &infoLogLength, infoLog );
303 if(infoLogLength > 0 ) {
305 if( sDEBUG ) printf(
"[INFO]: | Shader Handle %d: %s\n", shaderHandle, infoLog );
310 if( sDEBUG ) fprintf( stderr,
"[WARN]: | Handle %-3d is not for a Shader |\n", shaderHandle );
314inline void CSCI441_INTERNAL::ShaderUtils::printProgramLog(
315 const GLuint programHandle
318 int infoLogLength = 0;
322 if( glIsProgram( programHandle ) ) {
323 glGetProgramiv( programHandle, GL_INFO_LOG_LENGTH, &maxLength );
326 char* infoLog =
new char[maxLength];
328 glGetProgramiv( programHandle, GL_LINK_STATUS, &status );
329 if( sDEBUG ) printf(
"[INFO]: | Program Handle %2d: Linke%-28s |\n", programHandle, (status == 1 ?
"d Successfully" :
"r Error") );
332 glGetProgramInfoLog(programHandle, maxLength, &infoLogLength, infoLog );
334 if(infoLogLength > 0 ) {
336 if( sDEBUG ) printf(
"[INFO]: | Program Handle %d: %s\n", programHandle, infoLog );
341 if( sDEBUG ) fprintf( stderr,
"[WARN]: | Handle %-3d is not for a Shader Program |\n", programHandle );
345inline void CSCI441_INTERNAL::ShaderUtils::printProgramPipelineLog(
346 const GLuint pipelineHandle
349 if( glIsProgramPipeline( pipelineHandle ) ) {
353 glGetProgramPipelineiv( pipelineHandle, GL_INFO_LOG_LENGTH, &maxLength );
356 char* infoLog =
new char[maxLength];
359 glGetProgramPipelineInfoLog(pipelineHandle, maxLength, &infoLogLength, infoLog );
361 if( infoLogLength > 0 ) {
363 if( sDEBUG ) printf(
"[INFO]: | Pipeline Handle %d: %s\n", pipelineHandle, infoLog );
368 if( sDEBUG ) fprintf( stderr,
"[WARN]: | Handle %-3d is not for a Shader Program Pipeline |\n", pipelineHandle );
372inline GLboolean CSCI441_INTERNAL::ShaderUtils::printSubroutineInfo(
373 const GLuint programHandle,
374 const GLenum shaderStage,
375 const GLboolean printHeader
380 glGetProgramStageiv(programHandle, shaderStage, GL_ACTIVE_SUBROUTINE_UNIFORMS, ¶ms);
381 bool headerPrinted =
false;
384 printf(
"[INFO]: >--------------------------------------------------------<\n");
385 headerPrinted =
true;
387 printf(
"[INFO]: | GL_ACTIVE_SUBROUTINE_UNIFORMS (%-15s): %5i |\n", CSCI441_INTERNAL::ShaderUtils::GL_shader_type_to_string(shaderStage), params);
388 for(
int i = 0; i < params; i++ ) {
390 int max_length = 256;
391 int actual_length = 0;
393 glGetActiveSubroutineUniformName(programHandle, shaderStage, i, max_length, &actual_length, name );
394 glGetActiveSubroutineUniformiv(programHandle, shaderStage, i, GL_NUM_COMPATIBLE_SUBROUTINES, ¶ms2 );
395 params3 = (
int*)malloc(
sizeof(
int) * params2);
396 glGetActiveSubroutineUniformiv(programHandle, shaderStage, i, GL_COMPATIBLE_SUBROUTINES, params3 );
397 GLint loc = glGetSubroutineUniformLocation(programHandle, shaderStage, name );
399 printf(
"[INFO]: | %i) name: %-15s #subRoutines: %-5i loc: %2i |\n", i, name, params2, loc );
401 for(
int j = 0; j < params2; j++ ) {
402 GLint idx = params3[j];
405 int max_length2 = 64;
406 int actual_length2 = 0;
407 glGetActiveSubroutineName(programHandle, shaderStage, idx, max_length2, &actual_length2, name2 );
409 printf(
"[INFO]: | %i) subroutine: %-25s index: %2i |\n", j, name2, idx );
415 return !headerPrinted;
418inline void CSCI441_INTERNAL::ShaderUtils::printShaderProgramInfo(
419 const GLuint programHandle,
420 const GLboolean hasVertexShader,
421 const GLboolean hasTessControlShader,
422 const GLboolean hasTessEvalShader,
423 const GLboolean hasGeometryShader,
424 const GLboolean hasFragmentShader,
425 const GLboolean hasComputeShader,
426 const GLboolean useLastNewLine =
true
429 glGetIntegerv(GL_MAJOR_VERSION, &major);
430 glGetIntegerv(GL_MINOR_VERSION, &minor);
438 GLint max_attr_name_size;
439 GLint max_uniform_name_size;
443 glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_attr_name_size);
444 glGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_uniform_name_size);
446 glGetAttachedShaders(programHandle, max_count, &actual_count, shaders );
447 if(actual_count > 0) {
448 if( sDEBUG ) printf(
"[INFO]: >--------------------------------------------------------<\n");
449 if( sDEBUG ) printf(
"[INFO]: | GL_ATTACHED_SHADERS: %33i |\n", actual_count);
450 for(
int i = 0; i < actual_count; i++ ) {
452 glGetShaderiv( shaders[i], GL_SHADER_TYPE, &shaderType );
453 if( sDEBUG ) printf(
"[INFO]: | %i) %-38s Handle: %2i |\n", i, GL_shader_type_to_string(shaderType), shaders[i]);
458 if(hasGeometryShader) {
459 if( major > 3 || (major >= 3 && minor >= 2) ) {
460 GLint verticesOut, inputType, outputType;
461 glGetProgramiv(programHandle, GL_GEOMETRY_VERTICES_OUT, &verticesOut);
462 glGetProgramiv(programHandle, GL_GEOMETRY_INPUT_TYPE, &inputType);
463 glGetProgramiv(programHandle, GL_GEOMETRY_OUTPUT_TYPE, &outputType);
465 printf(
"[INFO]: >--------------------------------------------------------<\n");
466 printf(
"[INFO]: | GEOMETRY SHADER PRIMITIVE I/O |\n");
467 printf(
"[INFO]: | Input Type: %40s |\n", GL_primitive_type_to_string(inputType) );
468 printf(
"[INFO]: | Output Type: %39s |\n", GL_primitive_type_to_string(outputType) );
469 printf(
"[INFO]: | Max Vertices Out: %34d |\n", verticesOut );
474 if(hasVertexShader) {
475 glGetProgramiv(programHandle, GL_ACTIVE_ATTRIBUTES, ¶ms );
477 if( sDEBUG ) printf(
"[INFO]: >--------------------------------------------------------<\n");
478 if( sDEBUG ) printf(
"[INFO]: | GL_ACTIVE_ATTRIBUTES: %32i |\n", params );
479 for(
int i = 0; i < params; i++ ) {
480 char* name = (
char*) malloc(max_attr_name_size *
sizeof(
char));
481 int actual_length = 0;
484 glGetActiveAttrib(programHandle, i, max_attr_name_size, &actual_length, &size, &type, name );
486 for(
int j = 0; j < size; j++ ) {
489 int max_array_size = actual_length + 4 + 2 + 1;
490 char* array_name = (
char*) malloc(max_array_size *
sizeof(
char));
492 snprintf( array_name, max_array_size,
"%s[%i]", name, j );
493 int location = glGetAttribLocation(programHandle, array_name);
494 if( sDEBUG ) printf(
"[INFO]: | %i) type: %-15s name: %-13s loc: %2i |\n", i, GLSL_type_to_string( type ), array_name, location );
498 int location = glGetAttribLocation(programHandle, name );
499 if( sDEBUG ) printf(
"[INFO]: | %i) type: %-15s name: %-13s loc: %2i |\n",i, GLSL_type_to_string( type ), name, location );
507 glGetProgramiv(programHandle, GL_ACTIVE_UNIFORMS, ¶ms);
509 if( sDEBUG ) printf(
"[INFO]: >--------------------------------------------------------<\n" );
510 if( sDEBUG ) printf(
"[INFO]: | GL_ACTIVE_UNIFORMS: %34i |\n", params);
511 for(
int i = 0; i < params; i++) {
512 char* name = (
char*) malloc(max_uniform_name_size *
sizeof(
char));
513 int actual_length = 0;
516 glGetActiveUniform(programHandle, i, max_uniform_name_size, &actual_length, &size, &type, name );
518 for(
int j = 0; j < size; j++) {
519 int max_array_size = actual_length + 4 + 2 + 1;
520 char* array_name = (
char*) malloc(max_array_size *
sizeof(
char));
521 snprintf(array_name, max_array_size,
"%s[%i]", name, j);
522 int location = glGetUniformLocation(programHandle, array_name);
524 if (sDEBUG) printf(
"[INFO]: | %2i) type: %-15s name: %-13s loc: %2i |\n", i, GLSL_type_to_string(type), array_name, location);
529 int location = glGetUniformLocation(programHandle, name);
531 if (sDEBUG) printf(
"[INFO]: | %2i) type: %-15s name: %-13s loc: %2i |\n",i, GLSL_type_to_string(type), name, location);
538 int vsCount, tcsCount, tesCount, gsCount, fsCount, csCount;
539 vsCount = tcsCount = tesCount = gsCount = fsCount = csCount = 0;
541 glGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_BLOCKS, ¶ms);
543 if( sDEBUG ) printf(
"[INFO]: >--------------------------------------------------------<\n");
544 if( sDEBUG ) printf(
"[INFO]: | GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: %20d |\n", params);
545 for(
int i = 0; i < params; i++ ) {
547 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ¶ms2 );
550 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &actualLen);
551 char *name = (
char *)malloc(
sizeof(
char) * actualLen);
552 glGetActiveUniformBlockName(programHandle, i, actualLen,
nullptr, name);
554 auto indices = (GLuint*)malloc(params2*
sizeof(GLuint));
555 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, (GLint*)indices);
557 auto offsets = (GLint*)malloc(params2*
sizeof(GLint));
558 glGetActiveUniformsiv(programHandle, params2, indices, GL_UNIFORM_OFFSET, offsets);
560 if( sDEBUG ) printf(
"[INFO]: | %d) %-34s # Uniforms: %2d |\n", i, name, params2);
562 GLint vs, tcs, tes, gs, fs, cs;
563 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, &vs);
if( vs ) vsCount++;
564 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER, &tcs);
if( tcs) tcsCount++;
565 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER, &tes);
if( tes) tesCount++;
566 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, &gs);
if( gs ) gsCount++;
567 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, &fs);
if( fs ) fsCount++;
568 glGetActiveUniformBlockiv(programHandle, i, GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER, &cs);
if( cs ) csCount++;
569 if( sDEBUG ) printf(
"[INFO]: | Used in: %-4s %-4s %-4s %-3s %-4s %-4s Shader(s) |\n", (vs ?
"Vert" :
""), (tcs ?
"Ctrl" :
""), (tes ?
"Eval" :
""), (gs ?
"Geo" :
""), (fs ?
"Frag" :
""), (cs ?
"Comp" :
""));
572 glGetProgramiv(programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniLength);
573 char *name2 = (
char *)malloc(
sizeof(
char) * maxUniLength);
574 for(
int j = 0; j < params2; j++) {
577 glGetActiveUniform(programHandle, indices[j], maxUniLength, &actualLen, &uniSize, &type, name2);
580 printf(
"[INFO]: | %2d) type: %-15s name: %-21s |\n", j, GLSL_type_to_string(type), name2);
581 printf(
"[INFO]: | uniform index: %3d offset: %4d |\n", indices[j], offsets[j]);
586 if( vsCount + tcsCount + tesCount + gsCount + fsCount + csCount > 0 ) {
587 GLint maxUniBlocks = 0;
588 glGetIntegerv( GL_MAX_COMBINED_UNIFORM_BLOCKS, &maxUniBlocks );
589 if( sDEBUG ) printf(
"[INFO]: | Shader Uniform Block Counts %2d/%2d |\n", params, maxUniBlocks);
590 if( hasVertexShader ) {
591 GLint maxVertexUniformBlocks = 0;
592 glGetIntegerv( GL_MAX_VERTEX_UNIFORM_BLOCKS, &maxVertexUniformBlocks );
594 if( sDEBUG ) printf(
"[INFO]: | Vertex Shader Uniform Blocks: %18d/%2d |\n", vsCount, maxVertexUniformBlocks );
596 if( hasTessControlShader ) {
597 GLint maxTessControlUniformBlocks = 0;
598 glGetIntegerv( GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &maxTessControlUniformBlocks );
600 if( sDEBUG ) printf(
"[INFO]: | Tess Ctrl Shader Uniform Blocks: %15d/%2d |\n", tcsCount, maxTessControlUniformBlocks );
602 if( hasTessEvalShader ) {
603 GLint maxTessEvalUniformBlocks = 0;
604 glGetIntegerv( GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &maxTessEvalUniformBlocks );
606 if( sDEBUG ) printf(
"[INFO]: | Tess Eval Shader Uniform Blocks: %15d/%2d |\n", tesCount, maxTessEvalUniformBlocks );
608 if( hasGeometryShader ) {
609 GLint maxGeometryUniformBlocks = 0;
610 glGetIntegerv( GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &maxGeometryUniformBlocks );
612 if( sDEBUG ) printf(
"[INFO]: | Geometry Shader Uniform Blocks: %16d/%2d |\n", gsCount, maxGeometryUniformBlocks );
614 if( hasFragmentShader ) {
615 GLint maxFragmentUniformBlocks = 0;
616 glGetIntegerv( GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &maxFragmentUniformBlocks );
618 if( sDEBUG ) printf(
"[INFO]: | Fragment Shader Uniform Blocks: %16d/%2d |\n", fsCount, maxFragmentUniformBlocks );
620 if( hasComputeShader ) {
621 GLint maxComputeUniformBlocks = 0;
622 glGetIntegerv( GL_MAX_COMPUTE_UNIFORM_BLOCKS, &maxComputeUniformBlocks );
624 if( sDEBUG ) printf(
"[INFO]: | Compute Shader Uniform Blocks: %17d/%2d |\n", csCount, maxComputeUniformBlocks );
630 if((major == 4 && minor >= 3) || major > 4) {
632 glGetProgramInterfaceiv(programHandle, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, paramsSSBO);
633 if(paramsSSBO[0] > 0) {
635 glGetProgramInterfaceiv(programHandle, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &maxLen);
636 auto ssboName = (GLchar*)malloc(
sizeof(GLchar)*maxLen);
639 const int NUM_PROPS = 7;
640 GLenum props[NUM_PROPS] = {GL_BUFFER_BINDING,
641 GL_REFERENCED_BY_VERTEX_SHADER,
642 GL_REFERENCED_BY_TESS_CONTROL_SHADER, GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
643 GL_REFERENCED_BY_GEOMETRY_SHADER,
644 GL_REFERENCED_BY_FRAGMENT_SHADER,
645 GL_REFERENCED_BY_COMPUTE_SHADER};
647 GLint results[NUM_PROPS];
649 int vSSB, teSSB, tcSSB, gSSB, fSSB, cSSB;
650 vSSB = teSSB = tcSSB = gSSB = fSSB = cSSB = 0;
652 printf(
"[INFO]: >--------------------------------------------------------<\n");
653 printf(
"[INFO]: | GL_SHADER_STORAGE_BLOCK: %29d |\n", paramsSSBO[0] );
654 for(
int i = 0; i < paramsSSBO[0]; i++) {
655 glGetProgramResourceName(programHandle, GL_SHADER_STORAGE_BLOCK, i, maxLen, &ssboNameLen, ssboName);
656 GLuint ssboIndex = glGetProgramResourceIndex(programHandle, GL_SHADER_STORAGE_BLOCK, ssboName);
657 glGetProgramResourceiv(programHandle, GL_SHADER_STORAGE_BLOCK, i, NUM_PROPS, props, NUM_PROPS, &numWritten, results);
659 printf(
"[INFO]: | %3d) name: %-19s index: %3d binding: %3d |\n", i, ssboName, ssboIndex, results[0] );
660 printf(
"[INFO]: | Used in: %-4s %-4s %-4s %-3s %-4s %-4s Shader(s) |\n", (results[1] ?
"Vert" :
""), (results[2] ?
"Ctrl" :
""), (results[3] ?
"Eval" :
""), (results[4] ?
"Geo" :
""), (results[5] ?
"Frag" :
""), (results[6] ?
"Comp" :
""));
662 if(results[1]) vSSB++;
663 if(results[2]) teSSB++;
664 if(results[3]) tcSSB++;
665 if(results[4]) gSSB++;
666 if(results[5]) fSSB++;
667 if(results[6]) cSSB++;
670 GLint maxSSBCounters = 0;
671 glGetIntegerv( GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxSSBCounters );
672 printf(
"[INFO]: | Shader Storage Block Counts: %2d/%2d |\n", paramsSSBO[0], maxSSBCounters );
673 if(hasVertexShader) {
674 GLint maxVertSSB = 0;
675 glGetIntegerv( GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertSSB );
676 printf(
"[INFO]: | Vertex Shader Storage Blocks: %2d/%2d |\n", vSSB, maxVertSSB );
678 if(hasTessControlShader) {
680 glGetIntegerv( GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS, &maxTESSB );
681 printf(
"[INFO]: | Tess Ctrl Shader Storage Blocks: %2d/%2d |\n", teSSB, maxTESSB );
683 if(hasTessEvalShader) {
685 glGetIntegerv( GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS, &maxTCSSB );
686 printf(
"[INFO]: | Tess Eval Shader Storage Blocks: %2d/%2d |\n", tcSSB, maxTCSSB );
688 if(hasGeometryShader) {
690 glGetIntegerv( GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &maxGeoSSB );
691 printf(
"[INFO]: | Geometry Shader Storage Blocks: %2d/%2d |\n", gSSB, maxGeoSSB );
693 if(hasFragmentShader) {
694 GLint maxFragSSB = 0;
695 glGetIntegerv( GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragSSB );
696 printf(
"[INFO]: | Fragment Shader Storage Blocks: %2d/%2d |\n", fSSB, maxFragSSB );
698 if(hasComputeShader) {
699 GLint maxComputeSSB = 0;
700 glGetIntegerv( GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &maxComputeSSB );
701 printf(
"[INFO]: | Compute Shader Storage Blocks: %2d/%2d |\n", cSSB, maxComputeSSB );
706 if((major == 4 && minor >= 2) || major > 4) {
707 GLint paramsAtomic[1];
708 glGetProgramInterfaceiv(programHandle, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, paramsAtomic);
709 if(paramsAtomic[0] > 0) {
711 glGetProgramInterfaceiv(programHandle, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NAME_LENGTH, &maxLen);
712 auto atomicName = (GLchar*)malloc(
sizeof(GLchar)*maxLen);
713 GLsizei atomicNameLen;
715 const int NUM_PROPS = 8;
716 GLenum props[NUM_PROPS] = {GL_BUFFER_BINDING,
717 GL_REFERENCED_BY_VERTEX_SHADER,
718 GL_REFERENCED_BY_TESS_CONTROL_SHADER,
719 GL_REFERENCED_BY_TESS_EVALUATION_SHADER,
720 GL_REFERENCED_BY_GEOMETRY_SHADER,
721 GL_REFERENCED_BY_FRAGMENT_SHADER,
722 GL_REFERENCED_BY_COMPUTE_SHADER,
723 GL_BUFFER_DATA_SIZE};
725 GLint results[NUM_PROPS];
727 printf(
"[INFO]: >--------------------------------------------------------<\n");
728 printf(
"[INFO]: | GL_ATOMIC_COUNTER_BUFFER: %28d |\n", paramsAtomic[0] );
730 int vAC, teAC, tcAC, gAC, fAC, cAC;
731 vAC = teAC = tcAC = gAC = fAC = cAC = 0;
734 glGetProgramiv(programHandle, GL_ACTIVE_UNIFORMS, &numUniforms);
735 for(
int j = 0; j < numUniforms; j++) {
738 glGetActiveUniform(programHandle, j, maxLen, &atomicNameLen, &size, &type, atomicName );
740 GLuint atomicIndex = glGetProgramResourceIndex(programHandle, GL_UNIFORM, atomicName);
742 GLenum atomicProps[1] = {GL_ATOMIC_COUNTER_BUFFER_INDEX};
743 GLint atomicResults[1];
744 glGetProgramResourceiv(programHandle, GL_UNIFORM, atomicIndex, 1, atomicProps, 1,
nullptr, atomicResults);
746 if(atomicResults[0] != -1) {
747 glGetProgramResourceiv(programHandle, GL_ATOMIC_COUNTER_BUFFER, atomicResults[0], NUM_PROPS, props, NUM_PROPS, &numWritten, results);
750 glGetActiveUniformsiv(programHandle, 1, &atomicIndex, GL_UNIFORM_OFFSET, &offset);
752 printf(
"[INFO]: | %3d) type: %-15s name: %-21s |\n", atomicResults[0], GLSL_type_to_string(type), atomicName );
753 printf(
"[INFO]: | uniform index: %3d atomic index: %3d |\n", atomicIndex, atomicResults[0] );
754 printf(
"[INFO]: | binding: %3d offset: %3d buffer size: %4d |\n", results[0], offset, results[7] );
755 printf(
"[INFO]: | Used in: %-4s %-4s %-4s %-3s %-4s %-4s Shader(s) |\n", (results[1] ?
"Vert" :
""), (results[2] ?
"Ctrl" :
""), (results[3] ?
"Eval" :
""), (results[4] ?
"Geo" :
""), (results[5] ?
"Frag" :
""), (results[6] ?
"Comp" :
""));
757 if(results[1]) vAC++;
758 if(results[2]) teAC++;
759 if(results[3]) tcAC++;
760 if(results[4]) gAC++;
761 if(results[5]) fAC++;
762 if(results[6]) cAC++;
766 GLint maxAtomicCounters = 0;
767 glGetIntegerv( GL_MAX_COMBINED_ATOMIC_COUNTERS, &maxAtomicCounters );
768 printf(
"[INFO]: | Atomic Counter Counts: %4d/%4d |\n", paramsAtomic[0], maxAtomicCounters );
769 if(hasVertexShader) {
770 GLint maxVertAtomicCounters = 0;
771 glGetIntegerv( GL_MAX_VERTEX_ATOMIC_COUNTERS, &maxVertAtomicCounters );
772 printf(
"[INFO]: | Vertex Atomic Counters: %4d/%4d |\n", vAC, maxVertAtomicCounters );
774 if(hasTessControlShader) {
775 GLint maxTCAtomicCounters = 0;
776 glGetIntegerv( GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &maxTCAtomicCounters );
777 printf(
"[INFO]: | Tess Ctrl Atomic Counters: %4d/%4d |\n", teAC, maxTCAtomicCounters );
779 if(hasTessEvalShader) {
780 GLint maxTEAtomicCounters = 0;
781 glGetIntegerv( GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, &maxTEAtomicCounters );
782 printf(
"[INFO]: | Tess Eval Atomic Counters: %4d/%4d |\n", tcAC, maxTEAtomicCounters );
784 if(hasGeometryShader) {
785 GLint maxGeoAtomicCounters = 0;
786 glGetIntegerv( GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &maxGeoAtomicCounters );
787 printf(
"[INFO]: | Geometry Atomic Counters: %4d/%4d |\n", gAC, maxGeoAtomicCounters );
789 if(hasFragmentShader) {
790 GLint maxFragAtomicCounters = 0;
791 glGetIntegerv( GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &maxFragAtomicCounters );
792 printf(
"[INFO]: | Fragment Atomic Counters: %4d/%4d |\n", fAC, maxFragAtomicCounters );
794 if(hasComputeShader) {
795 GLint maxComputeAtomicCounters = 0;
796 glGetIntegerv( GL_MAX_COMPUTE_ATOMIC_COUNTERS, &maxComputeAtomicCounters );
797 printf(
"[INFO]: | Compute Atomic Counters: %4d/%4d |\n", cAC, maxComputeAtomicCounters );
803 GLboolean printHeader = GL_TRUE;
804 if( hasVertexShader ) printHeader = printSubroutineInfo(programHandle, GL_VERTEX_SHADER, printHeader );
805 if( hasTessControlShader) printHeader = printSubroutineInfo(programHandle, GL_TESS_CONTROL_SHADER, printHeader );
806 if( hasTessEvalShader) printHeader = printSubroutineInfo(programHandle, GL_TESS_EVALUATION_SHADER, printHeader );
807 if( hasGeometryShader ) printHeader = printSubroutineInfo(programHandle, GL_GEOMETRY_SHADER, printHeader );
808 if( hasFragmentShader ) printHeader = printSubroutineInfo(programHandle, GL_FRAGMENT_SHADER, printHeader );
809 if( hasComputeShader ) printSubroutineInfo(programHandle, GL_COMPUTE_SHADER, printHeader );
813 if(useLastNewLine) printf(
"[INFO]: \\--------------------------------------------------------/\n\n");
816inline GLuint CSCI441_INTERNAL::ShaderUtils::compileShader(
817 const char *filename,
818 const GLenum shaderType
820 GLuint shaderHandle = glCreateShader( shaderType );
char *shaderString;
823 if( readTextFromFile( filename, shaderString ) ) {
826 glShaderSource( shaderHandle, 1, (
const char**)&shaderString,
nullptr );
829 delete [] shaderString;
832 glCompileShader( shaderHandle );
835 printShaderLog( shaderHandle );