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