CSCI441 OpenGL Library 5.19.1
CS@Mines CSCI441 Computer Graphics Course Library
Loading...
Searching...
No Matches
SimpleShader.hpp
Go to the documentation of this file.
1
15#ifndef CSCI441_SIMPLE_SHADER_HPP
16#define CSCI441_SIMPLE_SHADER_HPP
17
18#include "constants.h"
19#include "objects.hpp"
20#include "ShaderUtils.hpp"
21
22#ifdef CSCI441_USE_GLEW
23 #include <GL/glew.h>
24#else
25 #include <glad/gl.h>
26#endif
27
28#include <glm/glm.hpp>
29#include <glm/gtc/type_ptr.hpp>
30
31#include <map>
32#include <string>
33#include <vector>
34
35//**********************************************************************************
36
37namespace CSCI441 {
38
43 namespace SimpleShader2 {
48 [[maybe_unused]] void enableFlatShading();
53 [[maybe_unused]] void enableSmoothShading();
54
58 [[maybe_unused]] void setupSimpleShader();
59
63 [[maybe_unused]] void cleanupSimpleShader();
64
72 [[maybe_unused]] GLuint registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS);
73
80 [[maybe_unused]] GLuint registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec4>& VERTEX_COLORS);
92 [[maybe_unused]] void updateVertexArray(GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS);
103 [[maybe_unused]] void updateVertexArray(GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec4>& VERTEX_COLORS);
104
113 [[maybe_unused]] GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
121 [[maybe_unused]] GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]);
134 [[maybe_unused]] void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
146 [[maybe_unused]] void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]);
147
152 [[maybe_unused]] void deleteVertexArray(GLuint VAOD);
153
158 [[maybe_unused]] void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
159
164 [[maybe_unused]] void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
165
170 [[maybe_unused]] void popTransformation();
171
176 [[maybe_unused]] void resetTransformationMatrix();
177
184 [[maybe_unused]] void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
185 }
186
191 namespace SimpleShader3 {
196 [[maybe_unused]] void enableFlatShading();
201 [[maybe_unused]] void enableSmoothShading();
202
206 [[maybe_unused]] void setupSimpleShader();
207
211 [[maybe_unused]] void cleanupSimpleShader();
212
219 [[maybe_unused]] GLuint registerVertexArray(const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS);
220
231 [[maybe_unused]] void updateVertexArray(GLuint VAOD, const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS);
232
240 [[maybe_unused]] GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
252 [[maybe_unused]] void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
253
258 [[maybe_unused]] void deleteVertexArray(GLuint VAOD);
259
264 [[maybe_unused]] void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
269 [[maybe_unused]] void setViewMatrix(const glm::mat4& VIEW_MATRIX);
270
275 [[maybe_unused]] void setLightPosition(const glm::vec3& LIGHT_POSITION);
280 [[maybe_unused]] void setLightColor(const glm::vec3& LIGHT_COLOR);
286 [[maybe_unused]] void setMaterialColor(const glm::vec3& MATERIAL_COLOR);
291 [[maybe_unused]] void setMaterialColor(const glm::vec4& MATERIAL_COLOR);
292
297 [[maybe_unused]] void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
298
303 [[maybe_unused]] void popTransformation();
304
309 [[maybe_unused]] void resetTransformationMatrix();
310
315 [[maybe_unused]] void enableLighting();
320 [[maybe_unused]] void disableLighting();
321
328 [[maybe_unused]] void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
329 }
330}
331
334// Internal implementations
335
336namespace CSCI441_INTERNAL {
337 namespace SimpleShader2 {
338 void enableFlatShading();
339 void enableSmoothShading();
340 void setupSimpleShader();
341 void cleanupSimpleShader();
342 GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]);
343 void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]);
344 void deleteVertexArray(GLuint VAOD);
345 void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
346 void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
347 void popTransformation();
349 void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
350
351 inline GLboolean smoothShading = true;
352 inline GLint shaderProgramHandle = -1;
353 inline GLint modelLocation = -1;
354 inline GLint viewLocation = -1;
355 inline GLint projectionLocation = -1;
356 inline GLint positionLocation = -1;
357 inline GLint colorLocation = -1;
358
359 inline std::map<GLuint, GLuint> descriptorMap;
360 inline std::vector<glm::mat4> transformationStack;
361 inline glm::mat4 modelMatrix(1.0f);
362 }
363
364 namespace SimpleShader3 {
365 void enableFlatShading();
366 void enableSmoothShading();
367 void setupSimpleShader();
368 void cleanupSimpleShader();
369 GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
370 void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
371 void deleteVertexArray(GLuint VAOD);
372 void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
373 void setViewMatrix(const glm::mat4& VIEW_MATRIX);
374 void setLightPosition(const glm::vec3& LIGHT_POSITION);
375 void setLightColor(const glm::vec3& LIGHT_COLOR);
376 void setMaterialColor(const glm::vec4& MATERIAL_COLOR);
377 void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
378 void popTransformation();
380 void setNormalMatrix();
381 void enableLighting();
382 void disableLighting();
383 void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
384
385 inline GLboolean smoothShading = true;
386 inline GLint shaderProgramHandle = -1;
387 inline GLint modelLocation = -1;
388 inline GLint viewLocation = -1;
389 inline GLint projectionLocation = -1;
390 inline GLint normalMtxLocation = -1;
391 inline GLint lightPositionLocation = -1;
392 inline GLint lightColorLocation = -1;
393 inline GLint materialLocation = -1;
394 inline GLint positionLocation = -1;
395 inline GLint normalLocation = -1;
396 inline GLint useLightingLocation = -1;
397
398 inline std::map<GLuint, GLuint> descriptorMap;
399 inline std::vector<glm::mat4> transformationStack;
400 inline glm::mat4 modelMatrix(1.0f);
401 inline glm::mat4 viewMatrix(1.0f);
402 }
403}
404
407// Outward facing function implementations
408
409[[maybe_unused]]
411 CSCI441_INTERNAL::SimpleShader2::enableFlatShading();
412}
413
414[[maybe_unused]]
416 CSCI441_INTERNAL::SimpleShader2::enableSmoothShading();
417}
418
419[[maybe_unused]]
421 CSCI441_INTERNAL::SimpleShader2::setupSimpleShader();
422}
423
424[[maybe_unused]]
426 CSCI441_INTERNAL::SimpleShader2::cleanupSimpleShader();
427}
428
429[[maybe_unused]]
430inline GLuint CSCI441::SimpleShader2::registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS) {
431 std::vector<glm::vec4> alphaColors( VERTEX_COLORS.size() );
432 for (size_t i = 0; i < VERTEX_COLORS.size(); i++) {
433 alphaColors.at(i) = glm::vec4( VERTEX_COLORS[i], 1.0f );
434 }
435 return CSCI441_INTERNAL::SimpleShader2::registerVertexArray(VERTEX_POINTS.size(), VERTEX_POINTS.data(), alphaColors.data());
436}
437
438[[maybe_unused]]
439inline GLuint CSCI441::SimpleShader2::registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec4>& VERTEX_COLORS) {
440 return CSCI441_INTERNAL::SimpleShader2::registerVertexArray(VERTEX_POINTS.size(), VERTEX_POINTS.data(), VERTEX_COLORS.data());
441}
442
443[[maybe_unused]]
444inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS) {
445 std::vector<glm::vec4> alphaColors( VERTEX_COLORS.size() );
446 for (size_t i = 0; i < VERTEX_COLORS.size(); i++) {
447 alphaColors.at(i) = glm::vec4( VERTEX_COLORS[i], 1.0f );
448 }
449 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, VERTEX_POINTS.size(), VERTEX_POINTS.data(), alphaColors.data());
450}
451
452[[maybe_unused]]
453inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec4>& VERTEX_COLORS) {
454 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, VERTEX_POINTS.size(), VERTEX_POINTS.data(), VERTEX_COLORS.data());
455}
456
457[[maybe_unused]]
458inline GLuint CSCI441::SimpleShader2::registerVertexArray(const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
459 std::vector<glm::vec4> alphaColors(NUM_POINTS);
460 for (GLuint i = 0; i < NUM_POINTS; i++) {
461 alphaColors.at(i) = glm::vec4( VERTEX_COLORS[i], 1.0f );
462 }
463 return CSCI441_INTERNAL::SimpleShader2::registerVertexArray(NUM_POINTS, VERTEX_POINTS, alphaColors.data());
464}
465
466[[maybe_unused]]
467inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
468 std::vector<glm::vec4> alphaColors(NUM_POINTS);
469 for (GLuint i = 0; i < NUM_POINTS; i++) {
470 alphaColors.at(i) = glm::vec4( VERTEX_COLORS[i], 1.0f );
471 }
472 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, NUM_POINTS, VERTEX_POINTS, alphaColors.data());
473}
474
475[[maybe_unused]]
476inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]) {
477 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, NUM_POINTS, VERTEX_POINTS, VERTEX_COLORS);
478}
479
480[[maybe_unused]]
481inline void CSCI441::SimpleShader2::deleteVertexArray(const GLuint VAOD) {
482 CSCI441_INTERNAL::SimpleShader2::deleteVertexArray(VAOD);
483}
484
485[[maybe_unused]]
486inline void CSCI441::SimpleShader2::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
487 CSCI441_INTERNAL::SimpleShader2::setProjectionMatrix(PROJECTION_MATRIX);
488}
489
490[[maybe_unused]]
491inline void CSCI441::SimpleShader2::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
492 CSCI441_INTERNAL::SimpleShader2::pushTransformation(TRANSFORMATION_MATRIX);
493}
494
495[[maybe_unused]]
497 CSCI441_INTERNAL::SimpleShader2::popTransformation();
498}
499
500[[maybe_unused]]
502 CSCI441_INTERNAL::SimpleShader2::resetTransformationMatrix();
503}
504
505[[maybe_unused]]
506inline void CSCI441::SimpleShader2::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
507 CSCI441_INTERNAL::SimpleShader2::draw(PRIMITIVE_TYPE, VAOD, VERTEX_COUNT);
508}
509
510//---------------------------------------------------------------------------------------------------------------------
511
512[[maybe_unused]]
514 CSCI441_INTERNAL::SimpleShader3::enableFlatShading();
515}
516
517[[maybe_unused]]
519 CSCI441_INTERNAL::SimpleShader3::enableSmoothShading();
520}
521
522[[maybe_unused]]
524 CSCI441_INTERNAL::SimpleShader3::setupSimpleShader();
525}
526
527[[maybe_unused]]
529 CSCI441_INTERNAL::SimpleShader3::cleanupSimpleShader();
530}
531
532[[maybe_unused]]
533inline GLuint CSCI441::SimpleShader3::registerVertexArray(const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS) {
534 return CSCI441_INTERNAL::SimpleShader3::registerVertexArray(VERTEX_POINTS.size(), VERTEX_POINTS.data(), VERTEX_NORMALS.data());
535}
536
537[[maybe_unused]]
538inline void CSCI441::SimpleShader3::updateVertexArray(const GLuint VAOD, const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS) {
539 CSCI441_INTERNAL::SimpleShader3::updateVertexArray(VAOD, VERTEX_POINTS.size(), VERTEX_POINTS.data(), VERTEX_NORMALS.data());
540}
541
542[[maybe_unused]]
543inline GLuint CSCI441::SimpleShader3::registerVertexArray(const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
544 return CSCI441_INTERNAL::SimpleShader3::registerVertexArray(NUM_POINTS, VERTEX_POINTS, VERTEX_NORMALS);
545}
546
547[[maybe_unused]]
548inline void CSCI441::SimpleShader3::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
549 CSCI441_INTERNAL::SimpleShader3::updateVertexArray(VAOD, NUM_POINTS, VERTEX_POINTS, VERTEX_NORMALS);
550}
551
552[[maybe_unused]]
553inline void CSCI441::SimpleShader3::deleteVertexArray(const GLuint VAOD) {
554 CSCI441_INTERNAL::SimpleShader3::deleteVertexArray(VAOD);
555}
556
557[[maybe_unused]]
558inline void CSCI441::SimpleShader3::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
559 CSCI441_INTERNAL::SimpleShader3::setProjectionMatrix(PROJECTION_MATRIX);
560}
561
562[[maybe_unused]]
563inline void CSCI441::SimpleShader3::setViewMatrix(const glm::mat4& VIEW_MATRIX) {
564 CSCI441_INTERNAL::SimpleShader3::setViewMatrix(VIEW_MATRIX);
565}
566
567[[maybe_unused]]
568inline void CSCI441::SimpleShader3::setLightPosition(const glm::vec3& LIGHT_POSITION) {
569 CSCI441_INTERNAL::SimpleShader3::setLightPosition(LIGHT_POSITION);
570}
571
572[[maybe_unused]]
573inline void CSCI441::SimpleShader3::setLightColor(const glm::vec3& LIGHT_COLOR) {
574 CSCI441_INTERNAL::SimpleShader3::setLightColor( LIGHT_COLOR );
575}
576
577[[maybe_unused]]
578inline void CSCI441::SimpleShader3::setMaterialColor(const glm::vec3& MATERIAL_COLOR) {
579 CSCI441_INTERNAL::SimpleShader3::setMaterialColor( glm::vec4(MATERIAL_COLOR, 1.0f) );
580}
581
582[[maybe_unused]]
583inline void CSCI441::SimpleShader3::setMaterialColor(const glm::vec4& MATERIAL_COLOR) {
584 CSCI441_INTERNAL::SimpleShader3::setMaterialColor(MATERIAL_COLOR);
585}
586
587[[maybe_unused]]
588inline void CSCI441::SimpleShader3::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
589 CSCI441_INTERNAL::SimpleShader3::pushTransformation(TRANSFORMATION_MATRIX);
590}
591
592[[maybe_unused]]
594 CSCI441_INTERNAL::SimpleShader3::popTransformation();
595}
596
597[[maybe_unused]]
599 CSCI441_INTERNAL::SimpleShader3::resetTransformationMatrix();
600}
601
602[[maybe_unused]]
604 CSCI441_INTERNAL::SimpleShader3::enableLighting();
605}
606
607[[maybe_unused]]
609 CSCI441_INTERNAL::SimpleShader3::disableLighting();
610}
611
612[[maybe_unused]]
613inline void CSCI441::SimpleShader3::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
614 CSCI441_INTERNAL::SimpleShader3::draw(PRIMITIVE_TYPE, VAOD, VERTEX_COUNT);
615}
616
619// Inward facing function implementations
620
621inline void CSCI441_INTERNAL::SimpleShader2::enableFlatShading() {
622 smoothShading = false;
623}
624inline void CSCI441_INTERNAL::SimpleShader2::enableSmoothShading() {
625 smoothShading = true;
626}
627
628inline void CSCI441_INTERNAL::SimpleShader2::setupSimpleShader() {
629 std::string vertex_shader_src =
630R"_(
631#version 410 core
632
633uniform mat4 model;
634uniform mat4 view;
635uniform mat4 projection;
636
637layout(location=0) in vec2 vPos;
638layout(location=1) in vec4 vColor;
639
640layout(location=0) )_";
641 vertex_shader_src += (smoothShading ? "" : "flat ");
642 vertex_shader_src += R"_(out vec4 fragColor;
643
644void main() {
645 gl_Position = projection * view * model * vec4(vPos, 0.0, 1.0);
646 fragColor = vColor;
647})_";
648 const char* vertexShaders[1] = { vertex_shader_src.c_str() };
649
650 std::string fragment_shader_src =
651R"_(
652#version 410 core
653
654layout(location=0) )_";
655 fragment_shader_src += (smoothShading ? "" : "flat ");
656 fragment_shader_src += R"_( in vec4 fragColor;
657
658layout(location=0) out vec4 fragColorOut;
659
660void main() {
661 fragColorOut = fragColor;
662})_";
663 const char* fragmentShaders[1] = { fragment_shader_src.c_str() };
664
665 printf( "[INFO]: /--------------------------------------------------------\\\n" );
666
667 const GLuint vertexShaderHandle = glCreateShader( GL_VERTEX_SHADER );
668 glShaderSource(vertexShaderHandle, 1, vertexShaders, nullptr);
669 glCompileShader(vertexShaderHandle);
670 ShaderUtils::printShaderLog(vertexShaderHandle);
671
672 const GLuint fragmentShaderHandle = glCreateShader( GL_FRAGMENT_SHADER );
673 glShaderSource(fragmentShaderHandle, 1, fragmentShaders, nullptr);
674 glCompileShader(fragmentShaderHandle);
675 ShaderUtils::printShaderLog(fragmentShaderHandle);
676
677 shaderProgramHandle = glCreateProgram();
678 glAttachShader(shaderProgramHandle, vertexShaderHandle);
679 glAttachShader(shaderProgramHandle, fragmentShaderHandle);
680 glLinkProgram(shaderProgramHandle);
681 ShaderUtils::printProgramLog(shaderProgramHandle);
682
683 glDetachShader(shaderProgramHandle, vertexShaderHandle);
684 glDeleteShader(vertexShaderHandle);
685
686 glDetachShader(shaderProgramHandle, fragmentShaderHandle);
687 glDeleteShader(fragmentShaderHandle);
688
689 ShaderUtils::printShaderProgramInfo(shaderProgramHandle, true, false, false, false, true, false, true);
690
691 modelLocation = glGetUniformLocation(shaderProgramHandle, "model");
692 viewLocation = glGetUniformLocation(shaderProgramHandle, "view");
693 projectionLocation = glGetUniformLocation(shaderProgramHandle, "projection");
694
695 positionLocation = glGetAttribLocation(shaderProgramHandle, "vPos");
696 colorLocation = glGetAttribLocation(shaderProgramHandle, "vColor");
697
698
699 glm::mat4 identity(1.0f);
700 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(identity));
701 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(identity));
702 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(identity));
703
704 transformationStack.emplace_back(identity);
705
706 glUseProgram(shaderProgramHandle);
707}
708
709inline void CSCI441_INTERNAL::SimpleShader2::cleanupSimpleShader() {
710 glDeleteProgram(shaderProgramHandle);
711 shaderProgramHandle = 0;
712
713 transformationStack.clear();
714}
715
716inline GLuint CSCI441_INTERNAL::SimpleShader2::registerVertexArray(const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]) {
717 GLuint vaod;
718 glGenVertexArrays(1, &vaod);
719 glBindVertexArray(vaod);
720
721 GLuint vbod;
722 glGenBuffers(1, &vbod);
723 glBindBuffer(GL_ARRAY_BUFFER, vbod);
724 glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2 + sizeof(GLfloat)*NUM_POINTS*4), nullptr, GL_STATIC_DRAW);
725 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2), VERTEX_POINTS);
726 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*2), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*4), VERTEX_COLORS);
727
728 glEnableVertexAttribArray(positionLocation);
729 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, static_cast<void *>(nullptr));
730
731 glEnableVertexAttribArray(colorLocation);
732 glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void *>(sizeof(GLfloat) * NUM_POINTS * 2));
733
734 descriptorMap.insert( std::pair( vaod, vbod ) );
735
736 return vaod;
737}
738
739inline void CSCI441_INTERNAL::SimpleShader2::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec4 VERTEX_COLORS[]) {
740 const auto descriptorIter = descriptorMap.find(VAOD);
741 if( descriptorIter != descriptorMap.end() ) {
742 glBindVertexArray(descriptorIter->first);
743 glBindBuffer(GL_ARRAY_BUFFER, descriptorIter->second);
744 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2), VERTEX_POINTS);
745 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*2), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*4), VERTEX_COLORS);
746 }
747}
748
749inline void CSCI441_INTERNAL::SimpleShader2::deleteVertexArray(const GLuint VAOD) {
750 const auto descriptorIter = descriptorMap.find(VAOD);
751 if( descriptorIter != descriptorMap.end() ) {
752 glDeleteVertexArrays(1, &(descriptorIter->first));
753 glDeleteBuffers(1, &(descriptorIter->second));
754 descriptorMap.erase(descriptorIter);
755 }
756}
757
758inline void CSCI441_INTERNAL::SimpleShader2::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
759 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(PROJECTION_MATRIX));
760}
761
762inline void CSCI441_INTERNAL::SimpleShader2::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
763 transformationStack.emplace_back(TRANSFORMATION_MATRIX);
764
765 modelMatrix *= TRANSFORMATION_MATRIX;
766 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
767}
768
769inline void CSCI441_INTERNAL::SimpleShader2::popTransformation() {
770 // ensure there is a transformation stack to pop off
771 // never let the original identity matrix pop off
772 if( transformationStack.size() > 1 ) {
773 transformationStack.pop_back();
774
775 modelMatrix = glm::mat4(1.0f);
776 for( auto tMtx : transformationStack ) {
777 modelMatrix *= tMtx;
778 }
779 glProgramUniformMatrix4fv( shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix) );
780 }
781}
782
783inline void CSCI441_INTERNAL::SimpleShader2::resetTransformationMatrix() {
784 modelMatrix = glm::mat4(1.0f);
785 transformationStack.clear();
786 transformationStack.emplace_back(modelMatrix);
787 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
788}
789
790inline void CSCI441_INTERNAL::SimpleShader2::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
791 glUseProgram(shaderProgramHandle);
792 glBindVertexArray(VAOD);
793 glDrawArrays(PRIMITIVE_TYPE, 0, static_cast<GLsizei>(VERTEX_COUNT));
794}
795
796//---------------------------------------------------------------------------------------------------------------------
797
798inline void CSCI441_INTERNAL::SimpleShader3::enableFlatShading() {
799 smoothShading = false;
800}
801inline void CSCI441_INTERNAL::SimpleShader3::enableSmoothShading() {
802 smoothShading = true;
803}
804
805inline void CSCI441_INTERNAL::SimpleShader3::setupSimpleShader() {
806 std::string vertex_shader_src =
807R"_(
808#version 410 core
809
810uniform mat4 model;
811uniform mat4 view;
812uniform mat4 projection;
813uniform mat3 normalMtx;
814uniform vec3 lightColor;
815uniform vec3 lightPosition;
816uniform vec4 materialColor;
817
818layout(location=0) in vec3 vPos;
819layout(location=2) in vec3 vNormal;
820
821layout(location=0) )_";
822 vertex_shader_src += (smoothShading ? "" : "flat ");
823 vertex_shader_src += R"_(out vec4 fragColor;
824
825void main() {
826 gl_Position = projection * view * model * vec4(vPos, 1.0);
827
828 vec3 vertexEye = (view * model * vec4(vPos, 1.0)).xyz;
829 vec3 lightEye = (view * vec4(lightPosition, 1.0)).xyz;
830 vec3 lightVec = normalize( lightEye - vertexEye );
831 vec3 normalVec = normalize( normalMtx * vNormal );
832 float sDotN = max(dot(lightVec, normalVec), 0.0);
833 vec3 diffColor = lightColor * materialColor.rgb * sDotN;
834 vec3 ambColor = materialColor.rgb * 0.3;
835 vec4 color = vec4( diffColor + ambColor, materialColor.a );
836 fragColor = clamp(color, 0.0f, 1.0f);
837})_";
838 const char* vertexShaders[1] = { vertex_shader_src.c_str() };
839
840 std::string fragment_shader_src =
841R"_(#version 410 core
842
843uniform vec4 materialColor;
844uniform int useLighting;
845
846layout(location=0) )_";
847 fragment_shader_src += (smoothShading ? "" : "flat ");
848 fragment_shader_src += R"_( in vec4 fragColor;
849
850layout(location=0) out vec4 fragColorOut;
851
852void main() {
853 if(useLighting == 1) {
854 fragColorOut = fragColor;
855 } else {
856 fragColorOut = materialColor;
857 }
858})_";
859 const char* fragmentShaders[1] = { fragment_shader_src.c_str() };
860
861 printf( "[INFO]: /--------------------------------------------------------\\\n" );
862
863 const GLuint vertexShaderHandle = glCreateShader( GL_VERTEX_SHADER );
864 glShaderSource(vertexShaderHandle, 1, vertexShaders, nullptr);
865 glCompileShader(vertexShaderHandle);
866 ShaderUtils::printShaderLog(vertexShaderHandle);
867
868 const GLuint fragmentShaderHandle = glCreateShader( GL_FRAGMENT_SHADER );
869 glShaderSource(fragmentShaderHandle, 1, fragmentShaders, nullptr);
870 glCompileShader(fragmentShaderHandle);
871 ShaderUtils::printShaderLog(fragmentShaderHandle);
872
873 shaderProgramHandle = glCreateProgram();
874 glAttachShader(shaderProgramHandle, vertexShaderHandle);
875 glAttachShader(shaderProgramHandle, fragmentShaderHandle);
876 glLinkProgram(shaderProgramHandle);
877 ShaderUtils::printProgramLog(shaderProgramHandle);
878
879 glDetachShader(shaderProgramHandle, vertexShaderHandle);
880 glDeleteShader(vertexShaderHandle);
881
882 glDetachShader(shaderProgramHandle, fragmentShaderHandle);
883 glDeleteShader(fragmentShaderHandle);
884
885 ShaderUtils::printShaderProgramInfo(shaderProgramHandle, true, false, false, false, true, false, true);
886
887 modelLocation = glGetUniformLocation(shaderProgramHandle, "model");
888 viewLocation = glGetUniformLocation(shaderProgramHandle, "view");
889 projectionLocation = glGetUniformLocation(shaderProgramHandle, "projection");
890 normalMtxLocation = glGetUniformLocation(shaderProgramHandle, "normalMtx");
891 lightPositionLocation=glGetUniformLocation(shaderProgramHandle, "lightPosition");
892 lightColorLocation = glGetUniformLocation(shaderProgramHandle, "lightColor");
893 materialLocation = glGetUniformLocation(shaderProgramHandle, "materialColor");
894 useLightingLocation = glGetUniformLocation(shaderProgramHandle, "useLighting");
895
896 positionLocation = glGetAttribLocation(shaderProgramHandle, "vPos");
897 normalLocation = glGetAttribLocation(shaderProgramHandle, "vNormal");
898
899 constexpr glm::mat4 identity(1.0f);
900 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(identity));
901 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(identity));
902 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(identity));
903
904 transformationStack.emplace_back(identity);
905
906 constexpr glm::vec3 white3 {1.0f, 1.0f, 1.0f};
907 glProgramUniform3fv(shaderProgramHandle, lightColorLocation, 1, glm::value_ptr(white3));
908 constexpr glm::vec4 white4 {1.0f, 1.0f, 1.0f, 1.0f};
909 glProgramUniform4fv(shaderProgramHandle, materialLocation, 1, glm::value_ptr(white4));
910
911 constexpr glm::vec3 origin {0.0f, 0.0f, 0.0f};
912 glProgramUniform3fv(shaderProgramHandle, lightPositionLocation, 1, glm::value_ptr(origin));
913
914 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 1);
915
916 glUseProgram(shaderProgramHandle);
917 CSCI441::setVertexAttributeLocations(positionLocation, normalLocation);
918}
919
920inline void CSCI441_INTERNAL::SimpleShader3::cleanupSimpleShader() {
921 glDeleteProgram(shaderProgramHandle);
922 shaderProgramHandle = 0;
923
924 transformationStack.clear();
925}
926
927inline GLuint CSCI441_INTERNAL::SimpleShader3::registerVertexArray(const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
928 GLuint vaod;
929 glGenVertexArrays(1, &vaod);
930 glBindVertexArray(vaod);
931
932 GLuint vbod;
933 glGenBuffers(1, &vbod);
934 glBindBuffer(GL_ARRAY_BUFFER, vbod);
935 glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3 + sizeof(GLfloat)*NUM_POINTS*3), nullptr, GL_STATIC_DRAW);
936 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_POINTS);
937 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*3), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_NORMALS);
938
939 glEnableVertexAttribArray(positionLocation);
940 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, static_cast<void *>(nullptr));
941
942 glEnableVertexAttribArray(normalLocation);
943 glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<void *>(sizeof(GLfloat) * NUM_POINTS * 2));
944
945 descriptorMap.insert( std::pair( vaod, vbod ) );
946
947 return vaod;
948}
949
950inline void CSCI441_INTERNAL::SimpleShader3::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
951 const auto descriptorIter = descriptorMap.find(VAOD);
952 if( descriptorIter != descriptorMap.end() ) {
953 glBindVertexArray(descriptorIter->first);
954 glBindBuffer(GL_ARRAY_BUFFER, descriptorIter->second);
955 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_POINTS);
956 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*3), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_NORMALS);
957 }
958}
959
960inline void CSCI441_INTERNAL::SimpleShader3::deleteVertexArray(const GLuint VAOD) {
961 const auto descriptorIter = descriptorMap.find(VAOD);
962 if( descriptorIter != descriptorMap.end() ) {
963 glDeleteVertexArrays(1, &(descriptorIter->first));
964 glDeleteBuffers(1, &(descriptorIter->second));
965 descriptorMap.erase(descriptorIter);
966 }
967}
968
969inline void CSCI441_INTERNAL::SimpleShader3::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
970 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(PROJECTION_MATRIX));
971}
972
973inline void CSCI441_INTERNAL::SimpleShader3::setViewMatrix(const glm::mat4& VIEW_MATRIX) {
974 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(VIEW_MATRIX));
975
976 viewMatrix = VIEW_MATRIX;
977 setNormalMatrix();
978}
979
980inline void CSCI441_INTERNAL::SimpleShader3::setLightPosition(const glm::vec3& LIGHT_POSITION) {
981 glProgramUniform3fv(shaderProgramHandle, lightPositionLocation, 1, glm::value_ptr(LIGHT_POSITION));
982}
983
984inline void CSCI441_INTERNAL::SimpleShader3::setLightColor(const glm::vec3& LIGHT_COLOR) {
985 glProgramUniform3fv(shaderProgramHandle, lightColorLocation, 1, glm::value_ptr(LIGHT_COLOR));
986}
987
988inline void CSCI441_INTERNAL::SimpleShader3::setMaterialColor(const glm::vec4& MATERIAL_COLOR) {
989 glProgramUniform4fv(shaderProgramHandle, materialLocation, 1, glm::value_ptr(MATERIAL_COLOR));
990}
991
992inline void CSCI441_INTERNAL::SimpleShader3::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
993 transformationStack.emplace_back(TRANSFORMATION_MATRIX);
994
995 modelMatrix *= TRANSFORMATION_MATRIX;
996 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
997
998 setNormalMatrix();
999}
1000
1001inline void CSCI441_INTERNAL::SimpleShader3::popTransformation() {
1002 // ensure there is a transformation stack to pop off
1003 // never let the original identity matrix pop off
1004 if( transformationStack.size() > 1 ) {
1005 transformationStack.pop_back();
1006
1007 modelMatrix = glm::mat4(1.0f);
1008 for( const auto& tMtx : transformationStack ) {
1009 modelMatrix *= tMtx;
1010 }
1011 glProgramUniformMatrix4fv( shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix) );
1012
1013 setNormalMatrix();
1014 }
1015}
1016
1017inline void CSCI441_INTERNAL::SimpleShader3::resetTransformationMatrix() {
1018 modelMatrix = glm::mat4(1.0f);
1019 transformationStack.clear();
1020 transformationStack.emplace_back(modelMatrix);
1021 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
1022 setNormalMatrix();
1023}
1024
1025inline void CSCI441_INTERNAL::SimpleShader3::setNormalMatrix() {
1026 const glm::mat4 modelView = viewMatrix * modelMatrix;
1027 const glm::mat3 normalMatrix = glm::mat3( glm::transpose( glm::inverse( modelView ) ) );
1028 glProgramUniformMatrix3fv(shaderProgramHandle, normalMtxLocation, 1, GL_FALSE, glm::value_ptr(normalMatrix));
1029}
1030
1031inline void CSCI441_INTERNAL::SimpleShader3::enableLighting() {
1032 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 1);
1033}
1034
1035inline void CSCI441_INTERNAL::SimpleShader3::disableLighting() {
1036 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 0);
1037}
1038
1039inline void CSCI441_INTERNAL::SimpleShader3::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
1040 glUseProgram(shaderProgramHandle);
1041 glBindVertexArray(VAOD);
1042 glDrawArrays(PRIMITIVE_TYPE, 0, static_cast<GLsizei>(VERTEX_COUNT));
1043}
1044
1045#endif //__CSCI441_SIMPLE_SHADER_HPP__
Helper functions to work with OpenGL Shaders.
void enableFlatShading()
turns on Flat Shading
Definition: SimpleShader.hpp:513
void deleteVertexArray(GLuint VAOD)
Deletes the Vertex Array Object and corresponding Vertex Buffer Object.
Definition: SimpleShader.hpp:481
void setupSimpleShader()
Registers a simple Gouraud shader for 2-Dimensional drawing.
Definition: SimpleShader.hpp:420
void setProjectionMatrix(const glm::mat4 &PROJECTION_MATRIX)
Sets the Projection Matrix.
Definition: SimpleShader.hpp:486
void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT)
loads associated VAO, drawing given primitive made up of corresponding number of vertices
Definition: SimpleShader.hpp:613
void setMaterialColor(const glm::vec3 &MATERIAL_COLOR)
sets current diffuse material color to apply to object
Definition: SimpleShader.hpp:578
void cleanupSimpleShader()
Deletes shader from GPU.
Definition: SimpleShader.hpp:425
void setupSimpleShader()
Registers a simple Gouraud Shader with Lambertian Illumination for 3-Dimensional drawing.
Definition: SimpleShader.hpp:523
void pushTransformation(const glm::mat4 &TRANSFORMATION_MATRIX)
Pushes a transformation to the stack and updates our model matrix.
Definition: SimpleShader.hpp:588
void enableFlatShading()
turns on Flat Shading
Definition: SimpleShader.hpp:410
void setLightPosition(const glm::vec3 &LIGHT_POSITION)
sets position of single global light in world space
Definition: SimpleShader.hpp:568
void popTransformation()
Pops the last transformation off the stack and updates our model matrix by the inverse of the last tr...
Definition: SimpleShader.hpp:593
void resetTransformationMatrix()
Sets the model matrix back to the identity matrix and clears the transformation stack.
Definition: SimpleShader.hpp:501
void setLightColor(const glm::vec3 &LIGHT_COLOR)
sets color of single global light
Definition: SimpleShader.hpp:573
void enableSmoothShading()
turns on Smooth Shading
Definition: SimpleShader.hpp:415
void disableLighting()
turns off lighting and applies material color to fragment
Definition: SimpleShader.hpp:608
void resetTransformationMatrix()
Sets the model matrix back to the identity matrix and clears the transformation stack.
Definition: SimpleShader.hpp:598
void enableSmoothShading()
turns on Smooth Shading
Definition: SimpleShader.hpp:518
void enableLighting()
turns on lighting and applies Phong Illumination to fragment
Definition: SimpleShader.hpp:603
void setViewMatrix(const glm::mat4 &VIEW_MATRIX)
Sets the View Matrix.
Definition: SimpleShader.hpp:563
void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT)
loads associated VAO, drawing given primitive made up of corresponding number of vertices
Definition: SimpleShader.hpp:506
void deleteVertexArray(GLuint VAOD)
Deletes the Vertex Array Object and corresponding Vertex Buffer Object.
Definition: SimpleShader.hpp:553
void pushTransformation(const glm::mat4 &TRANSFORMATION_MATRIX)
Pushes a transformation to the stack and updates our model matrix.
Definition: SimpleShader.hpp:491
void setProjectionMatrix(const glm::mat4 &PROJECTION_MATRIX)
Sets the Projection Matrix.
Definition: SimpleShader.hpp:558
void updateVertexArray(GLuint VAOD, const std::vector< glm::vec3 > &VERTEX_POINTS, const std::vector< glm::vec3 > &VERTEX_NORMALS)
Updates GL_ARRAY_BUFFER for the corresponding VAO.
Definition: SimpleShader.hpp:538
GLuint registerVertexArray(const std::vector< glm::vec3 > &VERTEX_POINTS, const std::vector< glm::vec3 > &VERTEX_NORMALS)
registers the associated vertex locations and colors with the GPU
Definition: SimpleShader.hpp:533
void popTransformation()
Pops the last transformation off the stack and updates our model matrix by the inverse of the last tr...
Definition: SimpleShader.hpp:496
void cleanupSimpleShader()
Deletes shader from GPU.
Definition: SimpleShader.hpp:528
void updateVertexArray(GLuint VAOD, const std::vector< glm::vec2 > &VERTEX_POINTS, const std::vector< glm::vec3 > &VERTEX_COLORS)
Updates GL_ARRAY_BUFFER for the corresponding VAO.
Definition: SimpleShader.hpp:444
GLuint registerVertexArray(const std::vector< glm::vec2 > &VERTEX_POINTS, const std::vector< glm::vec3 > &VERTEX_COLORS)
registers the associated vertex locations and colors with the GPU
Definition: SimpleShader.hpp:430
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17
void setVertexAttributeLocations(GLint positionLocation, GLint normalLocation=-1, GLint texCoordLocation=-1)
Sets the attribute locations for vertex positions, normals, and texture coordinates.
Definition: objects.hpp:553
Abstracts the process of working with a 2D shader program.
Abstracts the process of working with a 3D shader program.
Helper functions to draw 3D OpenGL 3.0+ objects.