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