CSCI441 OpenGL Library 5.13.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 "ShaderUtils.hpp"
19#include "objects.hpp"
20
21#ifdef CSCI441_USE_GLEW
22 #include <GL/glew.h>
23#else
24 #include <glad/gl.h>
25#endif
26
27#include <glm/glm.hpp>
28#include <glm/gtc/type_ptr.hpp>
29
30#include <map>
31#include <string>
32#include <vector>
33
34//**********************************************************************************
35
36namespace CSCI441 {
37
42 namespace SimpleShader2 {
47 [[maybe_unused]] void enableFlatShading();
52 [[maybe_unused]] void enableSmoothShading();
53
57 [[maybe_unused]] void setupSimpleShader();
58
65 [[maybe_unused]] GLuint registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS);
76 [[maybe_unused]] void updateVertexArray(GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS);
77
85 [[maybe_unused]] GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
97 [[maybe_unused]] void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
98
103 [[maybe_unused]] void deleteVertexArray(GLuint VAOD);
104
109 [[maybe_unused]] void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
110
115 [[maybe_unused]] void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
116
121 [[maybe_unused]] void popTransformation();
122
127 [[maybe_unused]] void resetTransformationMatrix();
128
135 [[maybe_unused]] void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
136 }
137
142 namespace SimpleShader3 {
147 [[maybe_unused]] void enableFlatShading();
152 [[maybe_unused]] void enableSmoothShading();
153
157 [[maybe_unused]] void setupSimpleShader();
158
165 [[maybe_unused]] GLuint registerVertexArray(const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS);
166
177 [[maybe_unused]] void updateVertexArray(GLuint VAOD, const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS);
178
186 [[maybe_unused]] GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
198 [[maybe_unused]] void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
199
204 [[maybe_unused]] void deleteVertexArray(GLuint VAOD);
205
210 [[maybe_unused]] void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
215 [[maybe_unused]] void setViewMatrix(const glm::mat4& VIEW_MATRIX);
216
221 [[maybe_unused]] void setLightPosition(const glm::vec3& LIGHT_POSITION);
226 [[maybe_unused]] void setLightColor(const glm::vec3& LIGHT_COLOR);
231 [[maybe_unused]] void setMaterialColor(const glm::vec3& MATERIAL_COLOR);
232
237 [[maybe_unused]] void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
238
243 [[maybe_unused]] void popTransformation();
244
249 [[maybe_unused]] void resetTransformationMatrix();
250
255 [[maybe_unused]] void enableLighting();
260 [[maybe_unused]] void disableLighting();
261
268 [[maybe_unused]] void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
269 }
270}
271
274// Internal implementations
275
276namespace CSCI441_INTERNAL {
277 namespace SimpleShader2 {
278 void enableFlatShading();
279 void enableSmoothShading();
280 void setupSimpleShader();
281 GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
282 void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]);
283 void deleteVertexArray(GLuint VAOD);
284 void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
285 void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
286 void popTransformation();
288 void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
289
290 inline GLboolean smoothShading = true;
291 inline GLint shaderProgramHandle = -1;
292 inline GLint modelLocation = -1;
293 inline GLint viewLocation = -1;
294 inline GLint projectionLocation = -1;
295 inline GLint vertexLocation = -1;
296 inline GLint colorLocation = -1;
297
298 inline std::map<GLuint, GLuint> descriptorMap;
299 inline std::vector<glm::mat4> transformationStack;
300 inline glm::mat4 modelMatrix(1.0f);
301 }
302
303 namespace SimpleShader3 {
304 void enableFlatShading();
305 void enableSmoothShading();
306 void setupSimpleShader();
307 GLuint registerVertexArray(GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
308 void updateVertexArray(GLuint VAOD, GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]);
309 void deleteVertexArray(GLuint VAOD);
310 void setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX);
311 void setViewMatrix(const glm::mat4& VIEW_MATRIX);
312 void setLightPosition(const glm::vec3& LIGHT_POSITION);
313 void setLightColor(const glm::vec3& LIGHT_COLOR);
314 void setMaterialColor(const glm::vec3& MATERIAL_COLOR);
315 void pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX);
316 void popTransformation();
318 void setNormalMatrix();
319 void enableLighting();
320 void disableLighting();
321 void draw(GLint PRIMITIVE_TYPE, GLuint VAOD, GLuint VERTEX_COUNT);
322
323 inline GLboolean smoothShading = true;
324 inline GLint shaderProgramHandle = -1;
325 inline GLint modelLocation = -1;
326 inline GLint viewLocation = -1;
327 inline GLint projectionLocation = -1;
328 inline GLint normalMtxLocation = -1;
329 inline GLint lightPositionLocation = -1;
330 inline GLint lightColorLocation = -1;
331 inline GLint materialLocation = -1;
332 inline GLint vertexLocation = -1;
333 inline GLint normalLocation = -1;
334 inline GLint useLightingLocation = -1;
335
336 inline std::map<GLuint, GLuint> descriptorMap;
337 inline std::vector<glm::mat4> transformationStack;
338 inline glm::mat4 modelMatrix(1.0f);
339 inline glm::mat4 viewMatrix(1.0f);
340 }
341}
342
345// Outward facing function implementations
346
347[[maybe_unused]]
349 CSCI441_INTERNAL::SimpleShader2::enableFlatShading();
350}
351
352[[maybe_unused]]
354 CSCI441_INTERNAL::SimpleShader2::enableSmoothShading();
355}
356
357[[maybe_unused]]
359 CSCI441_INTERNAL::SimpleShader2::setupSimpleShader();
360}
361
362[[maybe_unused]]
363inline GLuint CSCI441::SimpleShader2::registerVertexArray(const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS) {
364 return CSCI441_INTERNAL::SimpleShader2::registerVertexArray(VERTEX_POINTS.size(), &VERTEX_POINTS[0], &VERTEX_COLORS[0]);
365}
366
367[[maybe_unused]]
368inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const std::vector<glm::vec2>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_COLORS) {
369 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, VERTEX_POINTS.size(), &VERTEX_POINTS[0], &VERTEX_COLORS[0]);
370}
371
372[[maybe_unused]]
373inline GLuint CSCI441::SimpleShader2::registerVertexArray(const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
374 return CSCI441_INTERNAL::SimpleShader2::registerVertexArray(NUM_POINTS, VERTEX_POINTS, VERTEX_COLORS);
375}
376
377[[maybe_unused]]
378inline void CSCI441::SimpleShader2::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
379 CSCI441_INTERNAL::SimpleShader2::updateVertexArray(VAOD, NUM_POINTS, VERTEX_POINTS, VERTEX_COLORS);
380}
381
382[[maybe_unused]]
383inline void CSCI441::SimpleShader2::deleteVertexArray(const GLuint VAOD) {
384 CSCI441_INTERNAL::SimpleShader2::deleteVertexArray(VAOD);
385}
386
387[[maybe_unused]]
388inline void CSCI441::SimpleShader2::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
389 CSCI441_INTERNAL::SimpleShader2::setProjectionMatrix(PROJECTION_MATRIX);
390}
391
392[[maybe_unused]]
393inline void CSCI441::SimpleShader2::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
394 CSCI441_INTERNAL::SimpleShader2::pushTransformation(TRANSFORMATION_MATRIX);
395}
396
397[[maybe_unused]]
399 CSCI441_INTERNAL::SimpleShader2::popTransformation();
400}
401
402[[maybe_unused]]
404 CSCI441_INTERNAL::SimpleShader2::resetTransformationMatrix();
405}
406
407[[maybe_unused]]
408inline void CSCI441::SimpleShader2::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
409 CSCI441_INTERNAL::SimpleShader2::draw(PRIMITIVE_TYPE, VAOD, VERTEX_COUNT);
410}
411
412//---------------------------------------------------------------------------------------------------------------------
413
414[[maybe_unused]]
416 CSCI441_INTERNAL::SimpleShader3::enableFlatShading();
417}
418
419[[maybe_unused]]
421 CSCI441_INTERNAL::SimpleShader3::enableSmoothShading();
422}
423
424[[maybe_unused]]
426 CSCI441_INTERNAL::SimpleShader3::setupSimpleShader();
427}
428
429[[maybe_unused]]
430inline GLuint CSCI441::SimpleShader3::registerVertexArray(const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS) {
431 return CSCI441_INTERNAL::SimpleShader3::registerVertexArray(VERTEX_POINTS.size(), &VERTEX_POINTS[0], &VERTEX_NORMALS[0]);
432}
433
434[[maybe_unused]]
435inline void CSCI441::SimpleShader3::updateVertexArray(const GLuint VAOD, const std::vector<glm::vec3>& VERTEX_POINTS, const std::vector<glm::vec3>& VERTEX_NORMALS) {
436 CSCI441_INTERNAL::SimpleShader3::updateVertexArray(VAOD, VERTEX_POINTS.size(), &VERTEX_POINTS[0], &VERTEX_NORMALS[0]);
437}
438
439[[maybe_unused]]
440inline GLuint CSCI441::SimpleShader3::registerVertexArray(const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
441 return CSCI441_INTERNAL::SimpleShader3::registerVertexArray(NUM_POINTS, VERTEX_POINTS, VERTEX_NORMALS);
442}
443
444[[maybe_unused]]
445inline void CSCI441::SimpleShader3::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
446 CSCI441_INTERNAL::SimpleShader3::updateVertexArray(VAOD, NUM_POINTS, VERTEX_POINTS, VERTEX_NORMALS);
447}
448
449[[maybe_unused]]
450inline void CSCI441::SimpleShader3::deleteVertexArray(const GLuint VAOD) {
451 CSCI441_INTERNAL::SimpleShader3::deleteVertexArray(VAOD);
452}
453
454[[maybe_unused]]
455inline void CSCI441::SimpleShader3::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
456 CSCI441_INTERNAL::SimpleShader3::setProjectionMatrix(PROJECTION_MATRIX);
457}
458
459[[maybe_unused]]
460inline void CSCI441::SimpleShader3::setViewMatrix(const glm::mat4& VIEW_MATRIX) {
461 CSCI441_INTERNAL::SimpleShader3::setViewMatrix(VIEW_MATRIX);
462}
463
464[[maybe_unused]]
465inline void CSCI441::SimpleShader3::setLightPosition(const glm::vec3& LIGHT_POSITION) {
466 CSCI441_INTERNAL::SimpleShader3::setLightPosition(LIGHT_POSITION);
467}
468
469[[maybe_unused]]
470inline void CSCI441::SimpleShader3::setLightColor(const glm::vec3& LIGHT_COLOR) {
471 CSCI441_INTERNAL::SimpleShader3::setLightColor(LIGHT_COLOR);
472}
473
474[[maybe_unused]]
475inline void CSCI441::SimpleShader3::setMaterialColor(const glm::vec3& MATERIAL_COLOR) {
476 CSCI441_INTERNAL::SimpleShader3::setMaterialColor(MATERIAL_COLOR);
477}
478
479[[maybe_unused]]
480inline void CSCI441::SimpleShader3::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
481 CSCI441_INTERNAL::SimpleShader3::pushTransformation(TRANSFORMATION_MATRIX);
482}
483
484[[maybe_unused]]
486 CSCI441_INTERNAL::SimpleShader3::popTransformation();
487}
488
489[[maybe_unused]]
491 CSCI441_INTERNAL::SimpleShader3::resetTransformationMatrix();
492}
493
494[[maybe_unused]]
496 CSCI441_INTERNAL::SimpleShader3::enableLighting();
497}
498
499[[maybe_unused]]
501 CSCI441_INTERNAL::SimpleShader3::disableLighting();
502}
503
504[[maybe_unused]]
505inline void CSCI441::SimpleShader3::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
506 CSCI441_INTERNAL::SimpleShader3::draw(PRIMITIVE_TYPE, VAOD, VERTEX_COUNT);
507}
508
511// Inward facing function implementations
512
513inline void CSCI441_INTERNAL::SimpleShader2::enableFlatShading() {
514 smoothShading = false;
515}
516inline void CSCI441_INTERNAL::SimpleShader2::enableSmoothShading() {
517 smoothShading = true;
518}
519
520inline void CSCI441_INTERNAL::SimpleShader2::setupSimpleShader() {
521 std::string vertex_shader_src =
522R"_(
523#version 410 core
524
525uniform mat4 model;
526uniform mat4 view;
527uniform mat4 projection;
528
529layout(location=0) in vec2 vPos;
530layout(location=1) in vec3 vColor;
531
532layout(location=0) )_";
533 vertex_shader_src += (smoothShading ? "" : "flat ");
534 vertex_shader_src += R"_(out vec4 fragColor;
535
536void main() {
537 gl_Position = projection * view * model * vec4(vPos, 0.0, 1.0);
538 fragColor = vec4(vColor, 1.0);
539})_";
540 const char* vertexShaders[1] = { vertex_shader_src.c_str() };
541
542 std::string fragment_shader_src =
543R"_(
544#version 410 core
545
546layout(location=0) )_";
547 fragment_shader_src += (smoothShading ? "" : "flat ");
548 fragment_shader_src += R"_( in vec4 fragColor;
549
550layout(location=0) out vec4 fragColorOut;
551
552void main() {
553 fragColorOut = fragColor;
554})_";
555 const char* fragmentShaders[1] = { fragment_shader_src.c_str() };
556
557 printf( "[INFO]: /--------------------------------------------------------\\\n" );
558
559 GLuint vertexShaderHandle = glCreateShader( GL_VERTEX_SHADER );
560 glShaderSource(vertexShaderHandle, 1, vertexShaders, nullptr);
561 glCompileShader(vertexShaderHandle);
562 ShaderUtils::printShaderLog(vertexShaderHandle);
563
564 GLuint fragmentShaderHandle = glCreateShader( GL_FRAGMENT_SHADER );
565 glShaderSource(fragmentShaderHandle, 1, fragmentShaders, nullptr);
566 glCompileShader(fragmentShaderHandle);
567 ShaderUtils::printShaderLog(fragmentShaderHandle);
568
569 shaderProgramHandle = glCreateProgram();
570 glAttachShader(shaderProgramHandle, vertexShaderHandle);
571 glAttachShader(shaderProgramHandle, fragmentShaderHandle);
572 glLinkProgram(shaderProgramHandle);
573 ShaderUtils::printProgramLog(shaderProgramHandle);
574
575 glDetachShader(shaderProgramHandle, vertexShaderHandle);
576 glDeleteShader(vertexShaderHandle);
577
578 glDetachShader(shaderProgramHandle, fragmentShaderHandle);
579 glDeleteShader(fragmentShaderHandle);
580
581 ShaderUtils::printShaderProgramInfo(shaderProgramHandle, true, false, false, false, true, false, true);
582
583 modelLocation = glGetUniformLocation(shaderProgramHandle, "model");
584 viewLocation = glGetUniformLocation(shaderProgramHandle, "view");
585 projectionLocation = glGetUniformLocation(shaderProgramHandle, "projection");
586
587 vertexLocation = glGetAttribLocation(shaderProgramHandle, "vPos");
588 colorLocation = glGetAttribLocation(shaderProgramHandle, "vColor");
589
590
591 glm::mat4 identity(1.0f);
592 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(identity));
593 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(identity));
594 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(identity));
595
596 transformationStack.emplace_back(identity);
597
598 glUseProgram(shaderProgramHandle);
599}
600
601inline GLuint CSCI441_INTERNAL::SimpleShader2::registerVertexArray(const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
602 GLuint vaod;
603 glGenVertexArrays(1, &vaod);
604 glBindVertexArray(vaod);
605
606 GLuint vbod;
607 glGenBuffers(1, &vbod);
608 glBindBuffer(GL_ARRAY_BUFFER, vbod);
609 glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2 + sizeof(GLfloat)*NUM_POINTS*3), nullptr, GL_STATIC_DRAW);
610 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2), VERTEX_POINTS);
611 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*2), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_COLORS);
612
613 glEnableVertexAttribArray(vertexLocation);
614 glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)nullptr);
615
616 glEnableVertexAttribArray(colorLocation);
617 glVertexAttribPointer(colorLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(GLfloat)*NUM_POINTS*2));
618
619 descriptorMap.insert( std::pair<GLuint, GLuint>( vaod, vbod ) );
620
621 return vaod;
622}
623
624inline void CSCI441_INTERNAL::SimpleShader2::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec2 VERTEX_POINTS[], const glm::vec3 VERTEX_COLORS[]) {
625 const auto descriptorIter = descriptorMap.find(VAOD);
626 if( descriptorIter != descriptorMap.end() ) {
627 glBindVertexArray(descriptorIter->first);
628 glBindBuffer(GL_ARRAY_BUFFER, descriptorIter->second);
629 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*2), VERTEX_POINTS);
630 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*2), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_COLORS);
631 }
632}
633
634inline void CSCI441_INTERNAL::SimpleShader2::deleteVertexArray(const GLuint VAOD) {
635 const auto descriptorIter = descriptorMap.find(VAOD);
636 if( descriptorIter != descriptorMap.end() ) {
637 glDeleteVertexArrays(1, &(descriptorIter->first));
638 glDeleteBuffers(1, &(descriptorIter->second));
639 }
640}
641
642inline void CSCI441_INTERNAL::SimpleShader2::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
643 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(PROJECTION_MATRIX));
644}
645
646inline void CSCI441_INTERNAL::SimpleShader2::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
647 transformationStack.emplace_back(TRANSFORMATION_MATRIX);
648
649 modelMatrix *= TRANSFORMATION_MATRIX;
650 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
651}
652
653inline void CSCI441_INTERNAL::SimpleShader2::popTransformation() {
654 // ensure there is a transformation stack to pop off
655 // never let the original identity matrix pop off
656 if( transformationStack.size() > 1 ) {
657 transformationStack.pop_back();
658
659 modelMatrix = glm::mat4(1.0f);
660 for( auto tMtx : transformationStack ) {
661 modelMatrix *= tMtx;
662 }
663 glProgramUniformMatrix4fv( shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix) );
664 }
665}
666
667inline void CSCI441_INTERNAL::SimpleShader2::resetTransformationMatrix() {
668 modelMatrix = glm::mat4(1.0f);
669 transformationStack.clear();
670 transformationStack.emplace_back(modelMatrix);
671 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
672}
673
674inline void CSCI441_INTERNAL::SimpleShader2::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
675 glUseProgram(shaderProgramHandle);
676 glBindVertexArray(VAOD);
677 glDrawArrays(PRIMITIVE_TYPE, 0, static_cast<GLsizei>(VERTEX_COUNT));
678}
679
680//---------------------------------------------------------------------------------------------------------------------
681
682inline void CSCI441_INTERNAL::SimpleShader3::enableFlatShading() {
683 smoothShading = false;
684}
685inline void CSCI441_INTERNAL::SimpleShader3::enableSmoothShading() {
686 smoothShading = true;
687}
688
689inline void CSCI441_INTERNAL::SimpleShader3::setupSimpleShader() {
690 std::string vertex_shader_src =
691R"_(
692#version 410 core
693
694uniform mat4 model;
695uniform mat4 view;
696uniform mat4 projection;
697uniform mat3 normalMtx;
698uniform vec3 lightColor;
699uniform vec3 lightPosition;
700uniform vec3 materialColor;
701
702layout(location=0) in vec3 vPos;
703layout(location=2) in vec3 vNormal;
704
705layout(location=0) )_";
706 vertex_shader_src += (smoothShading ? "" : "flat ");
707 vertex_shader_src += R"_(out vec4 fragColor;
708
709void main() {
710 gl_Position = projection * view * model * vec4(vPos, 1.0);
711
712 vec3 vertexEye = (view * model * vec4(vPos, 1.0)).xyz;
713 vec3 lightEye = (view * vec4(lightPosition, 1.0)).xyz;
714 vec3 lightVec = normalize( lightEye - vertexEye );
715 vec3 normalVec = normalize( normalMtx * vNormal );
716 float sDotN = max(dot(lightVec, normalVec), 0.0);
717 vec3 diffColor = lightColor * materialColor * sDotN;
718 vec3 ambColor = materialColor * 0.3;
719 vec3 color = diffColor + ambColor;
720 fragColor = vec4(color, 1.0);
721})_";
722 const char* vertexShaders[1] = { vertex_shader_src.c_str() };
723
724 std::string fragment_shader_src =
725R"_(#version 410 core
726
727uniform vec3 materialColor;
728uniform int useLighting;
729
730layout(location=0) )_";
731 fragment_shader_src += (smoothShading ? "" : "flat ");
732 fragment_shader_src += R"_( in vec4 fragColor;
733
734layout(location=0) out vec4 fragColorOut;
735
736void main() {
737 if(useLighting == 1) {
738 fragColorOut = fragColor;
739 } else {
740 fragColorOut = vec4(materialColor, 1.0f);
741 }
742})_";
743 const char* fragmentShaders[1] = { fragment_shader_src.c_str() };
744
745 printf( "[INFO]: /--------------------------------------------------------\\\n" );
746
747 GLuint vertexShaderHandle = glCreateShader( GL_VERTEX_SHADER );
748 glShaderSource(vertexShaderHandle, 1, vertexShaders, nullptr);
749 glCompileShader(vertexShaderHandle);
750 ShaderUtils::printShaderLog(vertexShaderHandle);
751
752 GLuint fragmentShaderHandle = glCreateShader( GL_FRAGMENT_SHADER );
753 glShaderSource(fragmentShaderHandle, 1, fragmentShaders, nullptr);
754 glCompileShader(fragmentShaderHandle);
755 ShaderUtils::printShaderLog(fragmentShaderHandle);
756
757 shaderProgramHandle = glCreateProgram();
758 glAttachShader(shaderProgramHandle, vertexShaderHandle);
759 glAttachShader(shaderProgramHandle, fragmentShaderHandle);
760 glLinkProgram(shaderProgramHandle);
761 ShaderUtils::printProgramLog(shaderProgramHandle);
762
763 glDetachShader(shaderProgramHandle, vertexShaderHandle);
764 glDeleteShader(vertexShaderHandle);
765
766 glDetachShader(shaderProgramHandle, fragmentShaderHandle);
767 glDeleteShader(fragmentShaderHandle);
768
769 ShaderUtils::printShaderProgramInfo(shaderProgramHandle, true, false, false, false, true, false, true);
770
771 modelLocation = glGetUniformLocation(shaderProgramHandle, "model");
772 viewLocation = glGetUniformLocation(shaderProgramHandle, "view");
773 projectionLocation = glGetUniformLocation(shaderProgramHandle, "projection");
774 normalMtxLocation = glGetUniformLocation(shaderProgramHandle, "normalMtx");
775 lightPositionLocation=glGetUniformLocation(shaderProgramHandle, "lightPosition");
776 lightColorLocation = glGetUniformLocation(shaderProgramHandle, "lightColor");
777 materialLocation = glGetUniformLocation(shaderProgramHandle, "materialColor");
778 useLightingLocation = glGetUniformLocation(shaderProgramHandle, "useLighting");
779
780 vertexLocation = glGetAttribLocation(shaderProgramHandle, "vPos");
781 normalLocation = glGetAttribLocation(shaderProgramHandle, "vNormal");
782
783 glm::mat4 identity(1.0f);
784 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(identity));
785 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(identity));
786 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(identity));
787
788 transformationStack.emplace_back(identity);
789
790 glm::vec3 white(1.0f, 1.0f, 1.0f);
791 glProgramUniform3fv(shaderProgramHandle, lightColorLocation, 1, glm::value_ptr(white));
792 glProgramUniform3fv(shaderProgramHandle, materialLocation, 1, glm::value_ptr(white));
793
794 glm::vec3 origin(0.0f, 0.0f, 0.0f);
795 glProgramUniform3fv(shaderProgramHandle, lightPositionLocation, 1, glm::value_ptr(origin));
796
797 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 1);
798
799 glUseProgram(shaderProgramHandle);
800 CSCI441::setVertexAttributeLocations(vertexLocation, normalLocation);
801}
802
803inline GLuint CSCI441_INTERNAL::SimpleShader3::registerVertexArray(const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
804 GLuint vaod;
805 glGenVertexArrays(1, &vaod);
806 glBindVertexArray(vaod);
807
808 GLuint vbod;
809 glGenBuffers(1, &vbod);
810 glBindBuffer(GL_ARRAY_BUFFER, vbod);
811 glBufferData(GL_ARRAY_BUFFER, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3 + sizeof(GLfloat)*NUM_POINTS*3), nullptr, GL_STATIC_DRAW);
812 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_POINTS);
813 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*3), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_NORMALS);
814
815 glEnableVertexAttribArray(vertexLocation);
816 glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr);
817
818 glEnableVertexAttribArray(normalLocation);
819 glVertexAttribPointer(normalLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(GLfloat)*NUM_POINTS*2));
820
821 descriptorMap.insert( std::pair<GLuint, GLuint>( vaod, vbod ) );
822
823 return vaod;
824}
825
826inline void CSCI441_INTERNAL::SimpleShader3::updateVertexArray(const GLuint VAOD, const GLuint NUM_POINTS, const glm::vec3 VERTEX_POINTS[], const glm::vec3 VERTEX_NORMALS[]) {
827 const auto descriptorIter = descriptorMap.find(VAOD);
828 if( descriptorIter != descriptorMap.end() ) {
829 glBindVertexArray(descriptorIter->first);
830 glBindBuffer(GL_ARRAY_BUFFER, descriptorIter->second);
831 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_POINTS);
832 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(GLfloat)*NUM_POINTS*3), static_cast<GLsizeiptr>(sizeof(GLfloat)*NUM_POINTS*3), VERTEX_NORMALS);
833 }
834}
835
836inline void CSCI441_INTERNAL::SimpleShader3::deleteVertexArray(const GLuint VAOD) {
837 const auto descriptorIter = descriptorMap.find(VAOD);
838 if( descriptorIter != descriptorMap.end() ) {
839 glDeleteVertexArrays(1, &(descriptorIter->first));
840 glDeleteBuffers(1, &(descriptorIter->second));
841 }
842}
843
844inline void CSCI441_INTERNAL::SimpleShader3::setProjectionMatrix(const glm::mat4& PROJECTION_MATRIX) {
845 glProgramUniformMatrix4fv(shaderProgramHandle, projectionLocation, 1, GL_FALSE, glm::value_ptr(PROJECTION_MATRIX));
846}
847
848inline void CSCI441_INTERNAL::SimpleShader3::setViewMatrix(const glm::mat4& VIEW_MATRIX) {
849 glProgramUniformMatrix4fv(shaderProgramHandle, viewLocation, 1, GL_FALSE, glm::value_ptr(VIEW_MATRIX));
850
851 viewMatrix = VIEW_MATRIX;
852 setNormalMatrix();
853}
854
855inline void CSCI441_INTERNAL::SimpleShader3::setLightPosition(const glm::vec3& LIGHT_POSITION) {
856 glProgramUniform3fv(shaderProgramHandle, lightPositionLocation, 1, glm::value_ptr(LIGHT_POSITION));
857}
858
859inline void CSCI441_INTERNAL::SimpleShader3::setLightColor(const glm::vec3& LIGHT_COLOR) {
860 glProgramUniform3fv(shaderProgramHandle, lightColorLocation, 1, glm::value_ptr(LIGHT_COLOR));
861}
862
863inline void CSCI441_INTERNAL::SimpleShader3::setMaterialColor(const glm::vec3& MATERIAL_COLOR) {
864 glProgramUniform3fv(shaderProgramHandle, materialLocation, 1, glm::value_ptr(MATERIAL_COLOR));
865}
866
867inline void CSCI441_INTERNAL::SimpleShader3::pushTransformation(const glm::mat4& TRANSFORMATION_MATRIX) {
868 transformationStack.emplace_back(TRANSFORMATION_MATRIX);
869
870 modelMatrix *= TRANSFORMATION_MATRIX;
871 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
872
873 setNormalMatrix();
874}
875
876inline void CSCI441_INTERNAL::SimpleShader3::popTransformation() {
877 // ensure there is a transformation stack to pop off
878 // never let the original identity matrix pop off
879 if( transformationStack.size() > 1 ) {
880 transformationStack.pop_back();
881
882 modelMatrix = glm::mat4(1.0f);
883 for( auto tMtx : transformationStack ) {
884 modelMatrix *= tMtx;
885 }
886 glProgramUniformMatrix4fv( shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix) );
887
888 setNormalMatrix();
889 }
890}
891
892inline void CSCI441_INTERNAL::SimpleShader3::resetTransformationMatrix() {
893 modelMatrix = glm::mat4(1.0f);
894 transformationStack.clear();
895 transformationStack.emplace_back(modelMatrix);
896 glProgramUniformMatrix4fv(shaderProgramHandle, modelLocation, 1, GL_FALSE, glm::value_ptr(modelMatrix));
897 setNormalMatrix();
898}
899
900inline void CSCI441_INTERNAL::SimpleShader3::setNormalMatrix() {
901 glm::mat4 modelView = viewMatrix * modelMatrix;
902 glm::mat3 normalMatrix = glm::mat3( glm::transpose( glm::inverse( modelView ) ) );
903 glProgramUniformMatrix3fv(shaderProgramHandle, normalMtxLocation, 1, GL_FALSE, glm::value_ptr(normalMatrix));
904}
905
906inline void CSCI441_INTERNAL::SimpleShader3::enableLighting() {
907 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 1);
908}
909
910inline void CSCI441_INTERNAL::SimpleShader3::disableLighting() {
911 glProgramUniform1i(shaderProgramHandle, useLightingLocation, 0);
912}
913
914inline void CSCI441_INTERNAL::SimpleShader3::draw(const GLint PRIMITIVE_TYPE, const GLuint VAOD, const GLuint VERTEX_COUNT) {
915 glUseProgram(shaderProgramHandle);
916 glBindVertexArray(VAOD);
917 glDrawArrays(PRIMITIVE_TYPE, 0, static_cast<GLsizei>(VERTEX_COUNT));
918}
919
920#endif //__CSCI441_SIMPLE_SHADER_HPP__
Helper functions to work with OpenGL Shaders.
void enableFlatShading()
turns on Flat Shading
Definition: SimpleShader.hpp:415
void deleteVertexArray(GLuint VAOD)
Deletes the Vertex Array Object and corresponding Vertex Buffer Object.
Definition: SimpleShader.hpp:383
void setupSimpleShader()
Registers a simple Gouraud shader for 2-Dimensional drawing.
Definition: SimpleShader.hpp:358
void setProjectionMatrix(const glm::mat4 &PROJECTION_MATRIX)
Sets the Projection Matrix.
Definition: SimpleShader.hpp:388
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:505
void setMaterialColor(const glm::vec3 &MATERIAL_COLOR)
sets current diffuse material color to apply to object
Definition: SimpleShader.hpp:475
void setupSimpleShader()
Registers a simple Gouraud Shader with Lambertian Illumination for 3-Dimensional drawing.
Definition: SimpleShader.hpp:425
void pushTransformation(const glm::mat4 &TRANSFORMATION_MATRIX)
Pushes a transformation to the stack and updates our model matrix.
Definition: SimpleShader.hpp:480
void enableFlatShading()
turns on Flat Shading
Definition: SimpleShader.hpp:348
void setLightPosition(const glm::vec3 &LIGHT_POSITION)
sets position of single global light in world space
Definition: SimpleShader.hpp:465
void popTransformation()
Pops the last transformation off the stack and updates our model matrix by the inverse of the last tr...
Definition: SimpleShader.hpp:485
void resetTransformationMatrix()
Sets the model matrix back to the identity matrix and clears the transformation stack.
Definition: SimpleShader.hpp:403
void setLightColor(const glm::vec3 &LIGHT_COLOR)
sets color of single global light
Definition: SimpleShader.hpp:470
void enableSmoothShading()
turns on Smooth Shading
Definition: SimpleShader.hpp:353
void disableLighting()
turns off lighting and applies material color to fragment
Definition: SimpleShader.hpp:500
void resetTransformationMatrix()
Sets the model matrix back to the identity matrix and clears the transformation stack.
Definition: SimpleShader.hpp:490
void enableSmoothShading()
turns on Smooth Shading
Definition: SimpleShader.hpp:420
void enableLighting()
turns on lighting and applies Phong Illumination to fragment
Definition: SimpleShader.hpp:495
void setViewMatrix(const glm::mat4 &VIEW_MATRIX)
Sets the View Matrix.
Definition: SimpleShader.hpp:460
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:408
void deleteVertexArray(GLuint VAOD)
Deletes the Vertex Array Object and corresponding Vertex Buffer Object.
Definition: SimpleShader.hpp:450
void pushTransformation(const glm::mat4 &TRANSFORMATION_MATRIX)
Pushes a transformation to the stack and updates our model matrix.
Definition: SimpleShader.hpp:393
void setProjectionMatrix(const glm::mat4 &PROJECTION_MATRIX)
Sets the Projection Matrix.
Definition: SimpleShader.hpp:455
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:435
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:430
void popTransformation()
Pops the last transformation off the stack and updates our model matrix by the inverse of the last tr...
Definition: SimpleShader.hpp:398
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:368
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:363
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:552
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.