CSCI441 OpenGL Library 5.13.0
CS@Mines CSCI441 Computer Graphics Course Library
Loading...
Searching...
No Matches
objects.hpp
Go to the documentation of this file.
1
15#ifndef CSCI441_OBJECTS_HPP
16#define CSCI441_OBJECTS_HPP
17
18#include "teapot.hpp" // for teapot()
19
20#ifdef CSCI441_USE_GLEW
21 #include <GL/glew.h>
22#else
23 #include <glad/gl.h>
24#endif
25
26#include <glm/gtc/constants.hpp>
27
28#include <cassert> // for assert()
29#include <map> // for map
30
32
37namespace CSCI441 {
45 void setVertexAttributeLocations( GLint positionLocation, GLint normalLocation = -1, GLint texCoordLocation = -1 );
46
50 [[maybe_unused]] void deleteObjectVAOs();
51
55 [[maybe_unused]] void deleteObjectVBOs();
56
69 [[maybe_unused]] void drawSolidCone( GLfloat base, GLfloat height, GLint stacks, GLint slices );
82 [[maybe_unused]] void drawWireCone( GLfloat base, GLfloat height, GLint stacks, GLint slices );
83
89 [[maybe_unused]] void drawSolidCube( GLfloat sideLength );
96 void drawSolidCubeFlat( GLfloat sideLength );
103 void drawSolidCubeIndexed( GLfloat sideLength );
110 [[maybe_unused]] void drawSolidCubeTextured( GLfloat sideLength );
117 [[maybe_unused]] void drawWireCube( GLfloat sideLength );
118
125 [[maybe_unused]] void drawCubeMap( GLfloat sideLength );
126
140 [[maybe_unused]] void drawSolidCylinder( GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices );
154 [[maybe_unused]] void drawWireCylinder( GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices );
155
169 [[maybe_unused]] void drawSolidDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings );
183 [[maybe_unused]] void drawWireDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings );
184
202 [[maybe_unused]] void drawSolidPartialDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep );
220 [[maybe_unused]] void drawWirePartialDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep );
221
232 [[maybe_unused]] void drawSolidSphere( GLfloat radius, GLint stacks, GLint slices );
243 [[maybe_unused]] void drawWireSphere( GLfloat radius, GLint stacks, GLint slices );
244
255 [[maybe_unused]] void drawSolidHalfSphere( GLfloat radius, GLint stacks, GLint slices );
266 [[maybe_unused]] void drawWireHalfSphere( GLfloat radius, GLint stacks, GLint slices );
267
278 [[maybe_unused]] void drawSolidDome( GLfloat radius, GLint stacks, GLint slices );
289 [[maybe_unused]] void drawWireDome( GLfloat radius, GLint stacks, GLint slices );
290
297 [[maybe_unused]] void drawSolidTeapot( GLfloat unused = 1.0f );
304 [[maybe_unused]] void drawWireTeapot( GLfloat unused = 1.0f );
305
318 [[maybe_unused]] void drawSolidTorus( GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings );
331 [[maybe_unused]] void drawWireTorus( GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings );
332}
333
336// Internal rendering implementations to stay consistent with solid and wire modes
337//
338// Cone is drawn with a cylinder
339// Disk is drawn with a partial disk
340
345namespace CSCI441_INTERNAL {
349 void deleteObjectVAOs();
353 void deleteObjectVBOs();
354
360 void drawCube( GLfloat sideLength, GLenum renderMode );
366 void drawCubeIndexed( GLfloat sideLength, GLenum renderMode );
372 void drawCubeFlat( GLfloat sideLength, GLenum renderMode );
383 void drawCylinder( GLfloat base, GLfloat top, GLfloat height, GLuint stacks, GLuint slices, GLenum renderMode );
384 void drawPartialDisk(GLfloat innerRadius, GLfloat outerRadius, GLuint slices, GLuint rings, GLfloat startAngle, GLfloat sweepAngle, GLenum renderMode );
385 void drawSphere( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode );
386 void drawHalfSphere( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode );
387 void drawDome( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode );
388 void drawTorus( GLfloat innerRadius, GLfloat outerRadius, GLuint sides, GLuint rings, GLenum renderMode );
393 void drawTeapot( GLenum renderMode );
394
398 inline GLint _positionAttributeLocation = -1;
402 inline GLint _normalAttributeLocation = -1;
406 inline GLint _texCoordAttributeLocation = -1;
407
412 void generateCubeVAOFlat( GLfloat sideLength );
413 void generateCubeVAOIndexed( GLfloat sideLength );
414 inline std::map< GLfloat, GLuint > _cubeVAO;
415 inline std::map< GLfloat, GLuint > _cubeVBO;
416 inline std::map< GLfloat, GLuint > _cubeVAOIndexed;
417 inline std::map< GLfloat, GLuint > _cubeVBOIndexed;
418 inline std::map< GLfloat, GLuint > _cubeIBOIndexed;
419
421 struct CylinderData {
423 GLfloat radiusBase;
425 GLfloat top;
427 GLfloat height;
429 GLuint stacks;
431 GLuint slices;
433 [[nodiscard]] GLuint64 numVertices() const { return stacks * (slices + 1) * 2; }
435 bool operator<( const CylinderData rhs ) const {
436 if( radiusBase < rhs.radiusBase ) {
437 return true;
438 } else if( fabs(radiusBase - rhs.radiusBase) <= 0.000001 ) {
439 if( top < rhs.top ) {
440 return true;
441 } else if( fabs(top - rhs.top) <= 0.000001 ) {
442 if( height < rhs.height ) {
443 return true;
444 } else if( fabs(height - rhs.height) <= 0.000001 ) {
445 if( stacks < rhs.stacks ) {
446 return true;
447 } else if( stacks == rhs.stacks ) {
448 if( slices < rhs.slices ) {
449 return true;
450 }
451 }
452 }
453 }
454 }
455 return false;
456 }
457 };
458 void generateCylinderVAO( CylinderData cylData );
459 inline std::map< CylinderData, GLuint > _cylinderVAO;
460 inline std::map< CylinderData, GLuint > _cylinderVBO;
461
462 struct DiskData {
463 GLfloat innerRadius, outerRadius, startAngle, sweepAngle;
464 GLuint slices, rings;
465 [[nodiscard]] GLuint64 numVertices() const { return rings * (slices + 1) * 2; }
466 bool operator<( const DiskData rhs ) const {
467 if( innerRadius < rhs.innerRadius ) {
468 return true;
469 } else if( fabs(innerRadius - rhs.innerRadius) <= 0.000001 ) {
470 if( outerRadius < rhs.outerRadius ) {
471 return true;
472 } else if( fabs(outerRadius - rhs.outerRadius) <= 0.000001 ) {
473 if( startAngle < rhs.startAngle ) {
474 return true;
475 } else if( fabs(startAngle - rhs.startAngle) <= 0.000001 ) {
476 if( sweepAngle < rhs.sweepAngle ) {
477 return true;
478 } else if( fabs(sweepAngle - rhs.sweepAngle) <= 0.000001 ) {
479 if( slices < rhs.slices ) {
480 return true;
481 } else if( slices == rhs.slices ) {
482 if(rings < rhs.rings ) {
483 return true;
484 }
485 }
486 }
487 }
488 }
489 }
490 return false;
491 }
492 };
493 void generateDiskVAO( DiskData diskData );
494 inline std::map< DiskData, GLuint > _diskVAO;
495 inline std::map< DiskData, GLuint > _diskVBO;
496
497 struct SphereData {
498 GLfloat radius;
499 GLuint stacks, slices;
500 [[nodiscard]] GLuint64 numVertices() const { return ((slices + 2) * 2) + (((stacks - 2) * (slices+1)) * 2); }
501 bool operator<( const SphereData rhs ) const {
502 if( radius < rhs.radius ) {
503 return true;
504 } else if( fabs(radius - rhs.radius) <= 0.000001 ) {
505 if( stacks < rhs.stacks ) {
506 return true;
507 } else if( stacks == rhs.stacks ) {
508 if( slices < rhs.slices ) {
509 return true;
510 }
511 }
512 }
513 return false;
514 }
515 };
516 void generateSphereVAO( SphereData sphereData );
517 inline std::map< SphereData, GLuint > _sphereVAO;
518 inline std::map< SphereData, GLuint > _sphereVBO;
519
520 struct TorusData {
521 GLfloat innerRadius, outerRadius;
522 GLuint sides, rings;
523 [[nodiscard]] GLuint64 numVertices() const { return sides * 4 * rings; }
524 bool operator<( const TorusData rhs ) const {
525 if( innerRadius < rhs.innerRadius ) {
526 return true;
527 } else if( fabs(innerRadius - rhs.innerRadius) <= 0.000001 ) {
528 if( outerRadius < rhs.outerRadius ) {
529 return true;
530 } else if( fabs(outerRadius - rhs.outerRadius) <= 0.000001 ) {
531 if( sides < rhs.sides ) {
532 return true;
533 } else if( sides == rhs.sides ) {
534 if( rings < rhs.rings ) {
535 return true;
536 }
537 }
538 }
539 }
540 return false;
541 }
542 };
543 void generateTorusVAO( TorusData torusData );
544 inline std::map< TorusData, GLuint > _torusVAO;
545 inline std::map< TorusData, GLuint > _torusVBO;
546}
547
550// Outward facing function implementations
551
552inline void CSCI441::setVertexAttributeLocations( GLint positionLocation, GLint normalLocation, GLint texCoordLocation ) {
553 CSCI441_INTERNAL::_positionAttributeLocation = positionLocation;
554 CSCI441_INTERNAL::_normalAttributeLocation = normalLocation;
555 CSCI441_INTERNAL::_texCoordAttributeLocation = texCoordLocation;
556 CSCI441_INTERNAL::setTeapotAttributeLocations(positionLocation, normalLocation, texCoordLocation);
557}
558
559[[maybe_unused]]
561 CSCI441_INTERNAL::deleteObjectVAOs();
562}
563
564[[maybe_unused]]
566 CSCI441_INTERNAL::deleteObjectVBOs();
567}
568
569[[maybe_unused]]
570inline void CSCI441::drawSolidCone( GLfloat base, GLfloat height, GLint stacks, GLint slices ) {
571 assert( base > 0.0f );
572 assert( height > 0.0f );
573 assert( stacks > 0 );
574 assert( slices > 2 );
575
576 CSCI441_INTERNAL::drawCylinder( base, 0.0f, height, stacks, slices, GL_FILL );
577}
578
579[[maybe_unused]]
580inline void CSCI441::drawWireCone( GLfloat base, GLfloat height, GLint stacks, GLint slices ) {
581 assert( base > 0.0f );
582 assert( height > 0.0f );
583 assert( stacks > 0 );
584 assert( slices > 2 );
585
586 CSCI441_INTERNAL::drawCylinder( base, 0.0f, height, stacks, slices, GL_LINE );
587}
588
589[[maybe_unused]]
590inline void CSCI441::drawSolidCube( GLfloat sideLength ) {
591 drawSolidCubeIndexed(sideLength);
592}
593
594[[maybe_unused]]
595inline void CSCI441::drawSolidCubeTextured( GLfloat sideLength ) {
596 drawSolidCubeFlat(sideLength);
597}
598
599inline void CSCI441::drawSolidCubeIndexed(GLfloat sideLength) {
600 assert( sideLength > 0.0f );
601
602 CSCI441_INTERNAL::drawCube( sideLength, GL_FILL );
603}
604
605inline void CSCI441::drawSolidCubeFlat(GLfloat sideLength) {
606 assert( sideLength > 0.0f );
607
608 CSCI441_INTERNAL::drawCubeFlat( sideLength, GL_FILL );
609}
610
611[[maybe_unused]]
612inline void CSCI441::drawWireCube( GLfloat sideLength ) {
613 assert( sideLength > 0.0f );
614
615 CSCI441_INTERNAL::drawCube( sideLength, GL_LINE );
616}
617
618[[maybe_unused]]
619inline void CSCI441::drawCubeMap(GLfloat sideLength) {
620 assert(sideLength > 0.0f);
621
622 CSCI441_INTERNAL::drawCube( sideLength, GL_FILL );
623}
624
625[[maybe_unused]]
626inline void CSCI441::drawSolidCylinder( GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices ) {
627 assert( (base >= 0.0f && top > 0.0f) || (base > 0.0f && top >= 0.0f) );
628 assert( height > 0.0f );
629 assert( stacks > 0 );
630 assert( slices > 2 );
631
632 CSCI441_INTERNAL::drawCylinder( base, top, height, stacks, slices, GL_FILL );
633}
634
635[[maybe_unused]]
636inline void CSCI441::drawWireCylinder( GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices ) {
637 assert( (base >= 0.0f && top > 0.0f) || (base > 0.0f && top >= 0.0f) );
638 assert( height > 0.0f );
639 assert( stacks > 0 );
640 assert( slices > 2 );
641
642 CSCI441_INTERNAL::drawCylinder( base, top, height, stacks, slices, GL_LINE );
643}
644
645[[maybe_unused]]
646inline void CSCI441::drawSolidDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings ) {
647 assert( inner >= 0.0f );
648 assert( outer > 0.0f );
649 assert( outer > inner );
650 assert( slices > 2 );
651 assert( rings > 0 );
652
653 CSCI441_INTERNAL::drawPartialDisk( inner, outer, slices, rings, 0, glm::two_pi<float>(), GL_FILL );
654}
655
656[[maybe_unused]]
657inline void CSCI441::drawWireDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings ) {
658 assert( inner >= 0.0f );
659 assert( outer > 0.0f );
660 assert( outer > inner );
661 assert( slices > 2 );
662 assert( rings > 0 );
663
664 CSCI441_INTERNAL::drawPartialDisk( inner, outer, slices, rings, 0, glm::two_pi<float>(), GL_LINE );
665}
666
667[[maybe_unused]]
668inline void CSCI441::drawSolidPartialDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep ) {
669 assert( inner >= 0.0f );
670 assert( outer > 0.0f );
671 assert( outer > inner );
672 assert( slices > 2 );
673 assert( rings > 0 );
674 assert( start >= 0.0f && start <= 360.0f );
675 assert( sweep >= 0.0f && sweep <= 360.0f );
676
677 CSCI441_INTERNAL::drawPartialDisk( inner, outer, slices, rings, start * glm::pi<float>() / 180.0f, sweep * glm::pi<float>() / 180.0f, GL_FILL );
678}
679
680[[maybe_unused]]
681inline void CSCI441::drawWirePartialDisk( GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep ) {
682 assert( inner >= 0.0f );
683 assert( outer > 0.0f );
684 assert( outer > inner );
685 assert( slices > 2 );
686 assert( rings > 0 );
687 assert( start >= 0.0f && start <= 360.0f );
688 assert( sweep >= 0.0f && sweep <= 360.0f );
689
690 CSCI441_INTERNAL::drawPartialDisk( inner, outer, slices, rings, start * glm::pi<float>() / 180.0f, sweep * glm::pi<float>() / 180.0f, GL_LINE );
691}
692
693[[maybe_unused]]
694inline void CSCI441::drawSolidSphere( GLfloat radius, GLint stacks, GLint slices ) {
695 assert( radius > 0.0f );
696 assert( stacks > 1 );
697 assert( slices > 2 );
698
699 CSCI441_INTERNAL::drawSphere( radius, stacks, slices, GL_FILL );
700}
701
702[[maybe_unused]]
703inline void CSCI441::drawWireSphere( GLfloat radius, GLint stacks, GLint slices ) {
704 assert( radius > 0.0f );
705 assert( stacks > 1);
706 assert( slices > 2 );
707
708 CSCI441_INTERNAL::drawSphere( radius, stacks, slices, GL_LINE );
709}
710
711[[maybe_unused]]
712inline void CSCI441::drawSolidHalfSphere( GLfloat radius, GLint stacks, GLint slices ) {
713 assert( radius > 0.0f );
714 assert( stacks > 1 );
715 assert( slices > 2 );
716
717 CSCI441_INTERNAL::drawHalfSphere( radius, stacks, slices, GL_FILL );
718}
719
720[[maybe_unused]]
721inline void CSCI441::drawWireHalfSphere( GLfloat radius, GLint stacks, GLint slices ) {
722 assert( radius > 0.0f );
723 assert( stacks > 1);
724 assert( slices > 2 );
725
726 CSCI441_INTERNAL::drawHalfSphere( radius, stacks, slices, GL_LINE );
727}
728
729[[maybe_unused]]
730inline void CSCI441::drawSolidDome( GLfloat radius, GLint stacks, GLint slices ) {
731 assert( radius > 0.0f );
732 assert( stacks > 1 );
733 assert( slices > 2 );
734
735 CSCI441_INTERNAL::drawDome( radius, stacks, slices, GL_FILL );
736}
737
738[[maybe_unused]]
739inline void CSCI441::drawWireDome( GLfloat radius, GLint stacks, GLint slices ) {
740 assert( radius > 0.0f );
741 assert( stacks > 1);
742 assert( slices > 2 );
743
744 CSCI441_INTERNAL::drawDome( radius, stacks, slices, GL_LINE );
745}
746
747[[maybe_unused]]
748inline void CSCI441::drawSolidTeapot( [[maybe_unused]] GLfloat unused ) {
749 CSCI441_INTERNAL::drawTeapot(GL_FILL);
750}
751
752[[maybe_unused]]
753inline void CSCI441::drawWireTeapot( [[maybe_unused]] GLfloat unused ) {
754 CSCI441_INTERNAL::drawTeapot(GL_LINE);
755}
756
757[[maybe_unused]]
758inline void CSCI441::drawSolidTorus( GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings ) {
759 assert( innerRadius > 0.0f );
760 assert( outerRadius > 0.0f );
761 assert( sides > 2 );
762 assert( rings > 2 );
763
764 CSCI441_INTERNAL::drawTorus( innerRadius, outerRadius, sides, rings, GL_FILL );
765}
766
767[[maybe_unused]]
768inline void CSCI441::drawWireTorus( GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings ) {
769 assert( innerRadius > 0.0f );
770 assert( outerRadius > 0.0f );
771 assert( sides > 2 );
772 assert( rings > 2 );
773
774 CSCI441_INTERNAL::drawTorus( innerRadius, outerRadius, sides, rings, GL_LINE );
775}
776
779// Internal function rendering implementations
780
781inline void CSCI441_INTERNAL::deleteObjectVAOs() {
782 for(auto &[sideLength, vaod] : _cubeVAO) {
783 glDeleteVertexArrays(1, &vaod);
784 }
785 _cubeVAO.clear();
786
787 for(auto &[sideLength, vaod] : _cubeVAOIndexed) {
788 glDeleteVertexArrays(1, &vaod);
789 }
790 _cubeVAOIndexed.clear();
791
792 for(auto &[cylData, vaod] : _cylinderVAO) {
793 glDeleteVertexArrays(1, &vaod);
794 }
795 _cylinderVAO.clear();
796
797 for(auto &[diskData, vaod] : _diskVAO) {
798 glDeleteVertexArrays(1, &vaod);
799 }
800 _diskVAO.clear();
801
802 for(auto &[sphereData, vaod] : _sphereVAO) {
803 glDeleteVertexArrays(1, &vaod);
804 }
805 _sphereVAO.clear();
806
807 for(auto &[torusData, vaod] : _torusVAO) {
808 glDeleteVertexArrays(1, &vaod);
809 }
810 _torusVAO.clear();
811}
812
813inline void CSCI441_INTERNAL::deleteObjectVBOs() {
814 for(auto &[sideLength, vbod] : _cubeVBO) {
815 glDeleteBuffers(1, &vbod);
816 }
817 _cubeVBO.clear();
818
819 for(auto &[sideLength, vbod] : _cubeVBOIndexed) {
820 glDeleteBuffers(1, &vbod);
821 }
822 _cubeVBOIndexed.clear();
823
824 for(auto &[sideLength, vbod] : _cubeIBOIndexed) {
825 glDeleteBuffers(1, &vbod);
826 }
827 _cubeIBOIndexed.clear();
828
829 for(auto &[cylData, vbod] : _cylinderVBO) {
830 glDeleteBuffers(1, &vbod);
831 }
832 _cylinderVBO.clear();
833
834 for(auto &[diskData, vbod] : _diskVBO) {
835 glDeleteBuffers(1, &vbod);
836 }
837 _diskVBO.clear();
838
839 for(auto &[sphereData, vbod] : _sphereVBO) {
840 glDeleteBuffers(1, &vbod);
841 }
842 _sphereVBO.clear();
843
844 for(auto &[torusData, vbod] : _torusVBO) {
845 glDeleteBuffers(1, &vbod);
846 }
847 _torusVBO.clear();
848}
849
850inline void CSCI441_INTERNAL::drawCube( GLfloat sideLength, GLenum renderMode ) {
851 drawCubeIndexed(sideLength, renderMode);
852}
853
854inline void CSCI441_INTERNAL::drawCubeFlat( GLfloat sideLength, GLenum renderMode ) {
855 if( CSCI441_INTERNAL::_cubeVAO.count( sideLength ) == 0 ) {
856 CSCI441_INTERNAL::generateCubeVAOFlat( sideLength );
857 }
858
859 const GLuint64 NUM_VERTICES = 36;
860
861 GLint currentPolygonMode[2];
862 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
863
864 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
865 glBindVertexArray( CSCI441_INTERNAL::_cubeVAO.find( sideLength )->second );
866 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_cubeVBO.find( sideLength )->second );
867 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
868 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
869 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
870 }
871 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
872 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
873 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
874 }
875 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
876 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
877 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
878 }
879
880 glDrawArrays( GL_TRIANGLES, 0, 36 );
881
882 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
883}
884
885inline void CSCI441_INTERNAL::drawCubeIndexed( GLfloat sideLength, GLenum renderMode ) {
886 if( CSCI441_INTERNAL::_cubeVAOIndexed.count( sideLength ) == 0 ) {
887 CSCI441_INTERNAL::generateCubeVAOIndexed( sideLength );
888 }
889
890 const GLuint64 NUM_VERTICES = 8;
891
892 GLint currentPolygonMode[2];
893 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
894
895 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
896 glBindVertexArray( CSCI441_INTERNAL::_cubeVAOIndexed.find( sideLength )->second );
897 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_cubeVBOIndexed.find( sideLength )->second );
898 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
899 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
900 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
901 }
902 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
903 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
904 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
905 }
906 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
907 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
908 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
909 }
910
911 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, (void*)nullptr);
912
913 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
914}
915
916inline void CSCI441_INTERNAL::drawCylinder( GLfloat base, GLfloat top, GLfloat height, GLuint stacks, GLuint slices, GLenum renderMode ) {
917 CylinderData cylData = { base, top, height, stacks, slices };
918 if( CSCI441_INTERNAL::_cylinderVAO.count( cylData ) == 0 ) {
919 CSCI441_INTERNAL::generateCylinderVAO( cylData );
920 }
921
922 const GLuint64 NUM_VERTICES = cylData.numVertices();
923
924 GLint currentPolygonMode[2];
925 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
926
927 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
928 glBindVertexArray( CSCI441_INTERNAL::_cylinderVAO.find( cylData )->second );
929 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_cylinderVBO.find( cylData )->second );
930 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
931 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
932 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
933 }
934 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
935 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
936 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
937 }
938 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
939 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
940 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
941 }
942
943 for(GLuint stackNum = 0; stackNum < stacks; stackNum++) {
944 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>((slices+1)*2*stackNum), static_cast<GLint>((slices+1)*2) );
945 }
946
947 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
948}
949
950inline void CSCI441_INTERNAL::drawPartialDisk(GLfloat innerRadius, GLfloat outerRadius, GLuint slices, GLuint rings, GLfloat startAngle, GLfloat sweepAngle, GLenum renderMode ) {
951 DiskData diskData = {innerRadius, outerRadius, startAngle, sweepAngle, slices, rings };
952 if( CSCI441_INTERNAL::_diskVAO.count( diskData ) == 0 ) {
953 CSCI441_INTERNAL::generateDiskVAO( diskData );
954 }
955
956 const GLuint64 NUM_VERTICES = diskData.numVertices();
957
958 GLint currentPolygonMode[2];
959 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
960
961 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
962 glBindVertexArray( CSCI441_INTERNAL::_diskVAO.find( diskData )->second );
963 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_diskVBO.find( diskData )->second );
964 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
965 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
966 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
967 }
968 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
969 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
970 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
971 }
972 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
973 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
974 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
975 }
976
977 for(GLuint ringNum = 0; ringNum < rings; ringNum++) {
978 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>((slices+1)*2*ringNum), static_cast<GLint>((slices+1)*2) );
979 }
980
981 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
982}
983
984inline void CSCI441_INTERNAL::drawSphere( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode ) {
985 SphereData sphereData = { radius, stacks, slices };
986 if( CSCI441_INTERNAL::_sphereVAO.count( sphereData ) == 0 ) {
987 CSCI441_INTERNAL::generateSphereVAO( sphereData );
988 }
989
990 const GLuint64 NUM_VERTICES = sphereData.numVertices();
991
992 GLint currentPolygonMode[2];
993 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
994
995 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
996 glBindVertexArray( CSCI441_INTERNAL::_sphereVAO.find( sphereData )->second );
997 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_sphereVBO.find( sphereData )->second );
998 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
999 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
1000 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
1001 }
1002 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
1003 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
1004 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
1005 }
1006 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
1007 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
1008 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
1009 }
1010
1011 glDrawArrays( GL_TRIANGLE_FAN, 0, static_cast<GLint>(slices+2) );
1012
1013 for(GLuint stackNum = 1; stackNum < stacks-1; stackNum++) {
1014 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>((slices+2) + (stackNum-1)*((slices+1)*2)), static_cast<GLint>((slices+1)*2) );
1015 }
1016
1017 glDrawArrays( GL_TRIANGLE_FAN, static_cast<GLint>((slices+2) + (stacks-2)*(slices+1)*2), static_cast<GLint>(slices+2) );
1018
1019 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
1020}
1021
1022inline void CSCI441_INTERNAL::drawHalfSphere( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode ) {
1023 SphereData sphereData = { radius, stacks, slices };
1024 if( CSCI441_INTERNAL::_sphereVAO.count( sphereData ) == 0 ) {
1025 CSCI441_INTERNAL::generateSphereVAO( sphereData );
1026 }
1027
1028 const GLuint64 NUM_VERTICES = sphereData.numVertices();
1029
1030 GLint currentPolygonMode[2];
1031 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
1032
1033 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
1034 glBindVertexArray( CSCI441_INTERNAL::_sphereVAO.find( sphereData )->second );
1035 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_sphereVBO.find( sphereData )->second );
1036 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
1037 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
1038 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
1039 }
1040 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
1041 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
1042 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
1043 }
1044 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
1045 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
1046 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
1047 }
1048
1049 glDrawArrays( GL_TRIANGLE_FAN, static_cast<GLint>((slices+2)/2), static_cast<GLint>((slices+2)/2) );
1050
1051 for(GLuint stackNum = 1; stackNum < stacks-1; stackNum++) {
1052 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>((slices+2) + (stackNum-1)*((slices+1)*2)), static_cast<GLint>(slices+2) );
1053 }
1054
1055 glDrawArrays( GL_TRIANGLE_FAN, static_cast<GLint>((slices+2) + (stacks-2)*(slices+1)*2), static_cast<GLint>((slices+2)/2) );
1056
1057 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
1058
1059 drawPartialDisk(0.0f, radius, slices, stacks, 0.0f, glm::two_pi<float>(), renderMode);
1060}
1061
1062inline void CSCI441_INTERNAL::drawDome( GLfloat radius, GLuint stacks, GLuint slices, GLenum renderMode ) {
1063 SphereData sphereData = { radius, stacks, slices };
1064 if( CSCI441_INTERNAL::_sphereVAO.count( sphereData ) == 0 ) {
1065 CSCI441_INTERNAL::generateSphereVAO( sphereData );
1066 }
1067
1068 const GLuint64 NUM_VERTICES = sphereData.numVertices();
1069
1070 GLint currentPolygonMode[2];
1071 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
1072
1073 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
1074 glBindVertexArray( CSCI441_INTERNAL::_sphereVAO.find( sphereData )->second );
1075 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_sphereVBO.find( sphereData )->second );
1076 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
1077 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
1078 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
1079 }
1080 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
1081 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
1082 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
1083 }
1084 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
1085 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
1086 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
1087 }
1088
1089 glDrawArrays( GL_TRIANGLE_FAN, 0, static_cast<GLint>(slices+2) );
1090
1091 for(GLuint stackNum = (stacks-1)/2; stackNum < stacks-1; stackNum++) {
1092 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>((slices+2) + (stackNum-1)*((slices+1)*2)), static_cast<GLint>((slices+1)*2) );
1093 }
1094
1095 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
1096}
1097
1098inline void CSCI441_INTERNAL::drawTorus( GLfloat innerRadius, GLfloat outerRadius, GLuint sides, GLuint rings, GLenum renderMode ) {
1099 TorusData torusData = { innerRadius, outerRadius, sides, rings };
1100 if( CSCI441_INTERNAL::_torusVAO.count( torusData ) == 0 ) {
1101 CSCI441_INTERNAL::generateTorusVAO( torusData );
1102 }
1103
1104 const GLuint64 NUM_VERTICES = torusData.numVertices();
1105
1106 GLint currentPolygonMode[2];
1107 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
1108
1109 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
1110 glBindVertexArray( CSCI441_INTERNAL::_torusVAO.find( torusData )->second );
1111 glBindBuffer( GL_ARRAY_BUFFER, CSCI441_INTERNAL::_torusVBO.find( torusData )->second );
1112 if(CSCI441_INTERNAL::_positionAttributeLocation != -1) {
1113 glEnableVertexAttribArray( CSCI441_INTERNAL::_positionAttributeLocation );
1114 glVertexAttribPointer( CSCI441_INTERNAL::_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)nullptr );
1115 }
1116 if(CSCI441_INTERNAL::_normalAttributeLocation != -1) {
1117 glEnableVertexAttribArray( CSCI441_INTERNAL::_normalAttributeLocation );
1118 glVertexAttribPointer( CSCI441_INTERNAL::_normalAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES) );
1119 }
1120 if(CSCI441_INTERNAL::_texCoordAttributeLocation != -1) {
1121 glEnableVertexAttribArray( CSCI441_INTERNAL::_texCoordAttributeLocation );
1122 glVertexAttribPointer( CSCI441_INTERNAL::_texCoordAttributeLocation, 2, GL_FLOAT, GL_FALSE, 0, (void*)(sizeof(glm::vec3) * NUM_VERTICES * 2) );
1123 }
1124
1125 for(GLuint ringNum = 0; ringNum < rings; ringNum++) {
1126 glDrawArrays( GL_TRIANGLE_STRIP, static_cast<GLint>(ringNum*sides*4), static_cast<GLint>(sides*4) );
1127 }
1128
1129 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
1130}
1131
1132inline void CSCI441_INTERNAL::drawTeapot( GLenum renderMode ) {
1133 GLint currentPolygonMode[2];
1134 glGetIntegerv(GL_POLYGON_MODE, currentPolygonMode);
1135
1136 glPolygonMode( GL_FRONT_AND_BACK, renderMode );
1137 CSCI441_INTERNAL::teapot();
1138 glPolygonMode( GL_FRONT_AND_BACK, currentPolygonMode[0] );
1139}
1140
1141inline void CSCI441_INTERNAL::generateCubeVAOFlat( GLfloat sideLength ) {
1142 GLuint vaod;
1143 glGenVertexArrays( 1, &vaod );
1144 glBindVertexArray( vaod );
1145
1146 GLuint vbod;
1147 glGenBuffers( 1, &vbod );
1148 glBindBuffer( GL_ARRAY_BUFFER, vbod );
1149
1150 const GLfloat CORNER_POINT = sideLength / 2.0f;
1151
1152 const GLuint64 NUM_VERTICES = 36;
1153
1154 glm::vec3 vertices[NUM_VERTICES] = {
1155 // Left Face
1156 {-CORNER_POINT, -CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, -CORNER_POINT},
1157 {-CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, CORNER_POINT},
1158 // Right Face
1159 {CORNER_POINT, CORNER_POINT, CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {CORNER_POINT, CORNER_POINT, -CORNER_POINT},
1160 {CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, -CORNER_POINT},
1161 // Top Face
1162 {-CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, CORNER_POINT}, {CORNER_POINT, CORNER_POINT, -CORNER_POINT},
1163 {CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, CORNER_POINT}, {CORNER_POINT, CORNER_POINT, CORNER_POINT},
1164 // Bottom Face
1165 {CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, -CORNER_POINT},
1166 {CORNER_POINT, -CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, -CORNER_POINT},
1167 // Back Face
1168 {CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, -CORNER_POINT},
1169 {-CORNER_POINT, CORNER_POINT, -CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, -CORNER_POINT}, {-CORNER_POINT, -CORNER_POINT, -CORNER_POINT},
1170 // Front Face
1171 {-CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {-CORNER_POINT, CORNER_POINT, CORNER_POINT},
1172 {-CORNER_POINT, CORNER_POINT, CORNER_POINT}, {CORNER_POINT, -CORNER_POINT, CORNER_POINT}, {CORNER_POINT, CORNER_POINT, CORNER_POINT}
1173 };
1174 glm::vec3 normals[NUM_VERTICES] = {
1175 // Left Face
1176 {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f},
1177 {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f},
1178 // Right Face
1179 {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
1180 {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
1181 // Top Face
1182 {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f},
1183 {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f},
1184 // Bottom Face
1185 {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
1186 {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {0.0f, -1.0f, 0.0f},
1187 // Back Face
1188 {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f},
1189 {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, -1.0f},
1190 // Front Face
1191 {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f},
1192 {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 1.0f}
1193 };
1194 glm::vec2 texCoords[NUM_VERTICES] = {
1195 // Left Face
1196 {0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f},
1197 {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f},
1198 // Right Face
1199 {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f},
1200 {1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f},
1201 // Top Face
1202 {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f},
1203 {0.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
1204 // Bottom Face
1205 {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 0.0f},
1206 {0.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f},
1207 // Back Face
1208 {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f},
1209 {1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f},
1210 // Front Face
1211 {0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f},
1212 {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}
1213 };
1214
1215 glBufferData(GL_ARRAY_BUFFER, (sizeof(glm::vec3)*2 + sizeof(glm::vec2)) * NUM_VERTICES, nullptr, GL_STATIC_DRAW );
1216 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * NUM_VERTICES, vertices );
1217 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES, sizeof(glm::vec3) * NUM_VERTICES, normals );
1218 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 2, sizeof(glm::vec2) * NUM_VERTICES, texCoords );
1219
1220 CSCI441_INTERNAL::_cubeVAO.insert( std::pair<GLfloat, GLuint>( sideLength, vaod ) );
1221 CSCI441_INTERNAL::_cubeVBO.insert( std::pair<GLfloat, GLuint>( sideLength, vbod ) );
1222}
1223
1224inline void CSCI441_INTERNAL::generateCubeVAOIndexed( GLfloat sideLength ) {
1225 const GLfloat CORNER_POINT = sideLength / 2.0f;
1226
1227 const GLuint64 NUM_VERTICES = 8;
1228
1229 glm::vec3 vertices[NUM_VERTICES] = {
1230 { -CORNER_POINT, -CORNER_POINT, -CORNER_POINT }, // 0 - bln
1231 { CORNER_POINT, -CORNER_POINT, -CORNER_POINT }, // 1 - brn
1232 { CORNER_POINT, CORNER_POINT, -CORNER_POINT }, // 2 - trn
1233 { -CORNER_POINT, CORNER_POINT, -CORNER_POINT }, // 3 - tln
1234 { -CORNER_POINT, -CORNER_POINT, CORNER_POINT }, // 4 - blf
1235 { CORNER_POINT, -CORNER_POINT, CORNER_POINT }, // 5 - brf
1236 { CORNER_POINT, CORNER_POINT, CORNER_POINT }, // 6 - trf
1237 { -CORNER_POINT, CORNER_POINT, CORNER_POINT } // 7 - tlf
1238 };
1239 glm::vec3 normals[NUM_VERTICES] = {
1240 {-1.0f, -1.0f, -1.0f}, // 0 bln
1241 { 1.0f, -1.0f, -1.0f}, // 1 brn
1242 { 1.0f, 1.0f, -1.0f}, // 2 trn
1243 {-1.0f, 1.0f, -1.0f}, // 3 tln
1244 {-1.0f, -1.0f, 1.0f}, // 4 blf
1245 { 1.0f, -1.0f, 1.0f}, // 5 brf
1246 { 1.0f, 1.0f, 1.0f}, // 6 trf
1247 {-1.0f, 1.0f, 1.0f} // 7 tlf
1248 };
1249 glm::vec3 texCoords[NUM_VERTICES] = {
1250 {-1.0f, -1.0f, -1.0f}, // 0 bln
1251 { 1.0f, -1.0f, -1.0f}, // 1.0f brn
1252 { 1.0f, 1.0f, -1.0f}, // 2 trn
1253 {-1.0f, 1.0f, -1.0f}, // 3 tln
1254 {-1.0f, -1.0f, 1.0f}, // 4 blf
1255 { 1.0f, -1.0f, 1.0f}, // 5 brf
1256 { 1.0f, 1.0f, 1.0f}, // 6 trf
1257 {-1.0f, 1.0f, 1.0f} // 7 tlf
1258 };
1259 GLushort indices[36] = {
1260 0, 2, 1, 0, 3, 2, // near
1261 1, 2, 5, 5, 2, 6, // right
1262 2, 7, 6, 3, 7, 2, // top
1263 0, 1, 4, 1, 5, 4, // bottom
1264 4, 5, 6, 4, 6, 7, // back
1265 0, 4, 3, 4, 7, 3 // left
1266 };
1267
1268 GLuint vaod;
1269 glGenVertexArrays( 1, &vaod );
1270 glBindVertexArray( vaod );
1271
1272 GLuint vbods[2];
1273 glGenBuffers( 2, vbods );
1274
1275 glBindBuffer( GL_ARRAY_BUFFER, vbods[0] );
1276 glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 3, nullptr, GL_STATIC_DRAW );
1277 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * NUM_VERTICES, vertices );
1278 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES, sizeof(glm::vec3) * NUM_VERTICES, normals );
1279 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 2, sizeof(glm::vec3) * NUM_VERTICES, texCoords );
1280
1281 glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, vbods[1] );
1282 glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW) ;
1283
1284 CSCI441_INTERNAL::_cubeVAOIndexed.insert( std::pair<GLfloat, GLuint>( sideLength, vaod ) );
1285 CSCI441_INTERNAL::_cubeVBOIndexed.insert( std::pair<GLfloat, GLuint>( sideLength, vbods[0] ) );
1286 CSCI441_INTERNAL::_cubeIBOIndexed.insert( std::pair<GLfloat, GLuint>( sideLength, vbods[1] ) );
1287}
1288
1289inline void CSCI441_INTERNAL::generateCylinderVAO( CylinderData cylData ) {
1290 GLuint vaod;
1291 glGenVertexArrays( 1, &vaod );
1292 glBindVertexArray( vaod );
1293
1294 GLuint vbod;
1295 glGenBuffers( 1, &vbod );
1296 glBindBuffer( GL_ARRAY_BUFFER, vbod );
1297
1298 const GLuint64 NUM_VERTICES = cylData.numVertices();
1299
1300 GLfloat sliceStep = glm::two_pi<float>() / (GLfloat)cylData.slices;
1301 GLfloat stackStep = cylData.height / (GLfloat)cylData.stacks;
1302
1303 auto vertices = new glm::vec3[NUM_VERTICES];
1304 auto normals = new glm::vec3[NUM_VERTICES];
1305 auto texCoords = new glm::vec2[NUM_VERTICES];
1306
1307 GLuint64 idx = 0;
1308
1309 for(GLuint stackNum = 0; stackNum < cylData.stacks; stackNum++ ) {
1310 GLfloat botRadius = cylData.radiusBase * (GLfloat)(cylData.stacks - stackNum) / (GLfloat)cylData.stacks + cylData.top * (GLfloat)stackNum / (GLfloat)cylData.stacks;
1311 GLfloat topRadius = cylData.radiusBase * (GLfloat)(cylData.stacks - stackNum - 1) / (GLfloat)cylData.stacks + cylData.top * (GLfloat)(stackNum + 1) / (GLfloat)cylData.stacks;
1312
1313 for(GLuint sliceNum = 0; sliceNum <= cylData.slices; sliceNum++ ) {
1314 vertices[ idx ].x = glm::cos( sliceNum * sliceStep )*botRadius;
1315 vertices[ idx ].y = (GLfloat)stackNum * stackStep;
1316 vertices[ idx ].z = glm::sin( sliceNum * sliceStep )*botRadius;
1317
1318 normals[ idx ].x = glm::cos( sliceNum * sliceStep );
1319 normals[ idx ].y = 0.0f;
1320 normals[ idx ].z = glm::sin( sliceNum * sliceStep );
1321
1322 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)cylData.slices;
1323 texCoords[ idx ].t = (GLfloat)stackNum / (GLfloat)cylData.stacks;
1324
1325 idx++;
1326
1327 vertices[ idx ].x = glm::cos( sliceNum * sliceStep )*topRadius;
1328 vertices[ idx ].y = (GLfloat)(stackNum+1) * stackStep;
1329 vertices[ idx ].z = glm::sin( sliceNum * sliceStep )*topRadius;
1330
1331 normals[ idx ].x = glm::cos( sliceNum * sliceStep );
1332 normals[ idx ].y = 0.0f;
1333 normals[ idx ].z = glm::sin( sliceNum * sliceStep );
1334
1335 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)cylData.slices;
1336 texCoords[ idx ].t = (GLfloat)(stackNum+1) / (GLfloat)cylData.stacks;
1337
1338 idx++;
1339 }
1340 }
1341
1342 glBufferData(GL_ARRAY_BUFFER, (sizeof(glm::vec3)*2 + sizeof(glm::vec2)) * NUM_VERTICES, nullptr, GL_STATIC_DRAW );
1343 glBufferSubData(GL_ARRAY_BUFFER, 0, static_cast<GLsizeiptr>(sizeof(glm::vec3) * NUM_VERTICES), vertices );
1344 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(glm::vec3) * NUM_VERTICES), static_cast<GLsizeiptr>(sizeof(glm::vec3) * NUM_VERTICES), normals );
1345 glBufferSubData(GL_ARRAY_BUFFER, static_cast<GLintptr>(sizeof(glm::vec3) * NUM_VERTICES * 2), static_cast<GLsizeiptr>(sizeof(glm::vec2) * NUM_VERTICES), texCoords );
1346
1347 CSCI441_INTERNAL::_cylinderVAO.insert( std::pair<CylinderData, GLuint>( cylData, vaod ) );
1348 CSCI441_INTERNAL::_cylinderVBO.insert( std::pair<CylinderData, GLuint>( cylData, vbod ) );
1349
1350 delete[] vertices;
1351 delete[] texCoords;
1352 delete[] normals;
1353}
1354
1355inline void CSCI441_INTERNAL::generateDiskVAO( DiskData diskData ) {
1356 GLuint vaod;
1357 glGenVertexArrays( 1, &vaod );
1358 glBindVertexArray( vaod );
1359
1360 GLuint vbod;
1361 glGenBuffers( 1, &vbod );
1362 glBindBuffer( GL_ARRAY_BUFFER, vbod );
1363
1364 const GLuint64 NUM_VERTICES = diskData.numVertices();
1365
1366 GLfloat sliceStep = diskData.sweepAngle / (GLfloat)diskData.slices;
1367 GLfloat ringStep = (diskData.outerRadius - diskData.innerRadius) / (GLfloat)diskData.rings;
1368
1369 auto vertices = new glm::vec3[NUM_VERTICES];
1370 auto normals = new glm::vec3[NUM_VERTICES];
1371 auto texCoords = new glm::vec2[NUM_VERTICES];
1372
1373 GLuint64 idx = 0;
1374
1375 for(GLuint ringNum = 0; ringNum < diskData.rings; ringNum++ ) {
1376 GLfloat currRadius = diskData.innerRadius + (GLfloat)ringNum * ringStep;
1377 GLfloat nextRadius = diskData.innerRadius + (GLfloat)(ringNum + 1) * ringStep;
1378
1379 GLfloat theta = diskData.startAngle;
1380 for(GLuint i = 0; i <= diskData.slices; i++ ) {
1381 vertices[ idx ].x = glm::cos(theta)*currRadius;
1382 vertices[ idx ].y = glm::sin(theta)*currRadius;
1383 vertices[ idx ].z = 0.0f;
1384
1385 normals[ idx ].x = 0.0f;
1386 normals[ idx ].y = 0.0f;
1387 normals[ idx ].z = 1.0f;
1388
1389 texCoords[ idx ].s = glm::cos(theta)*(currRadius/diskData.outerRadius);
1390 texCoords[ idx ].t = glm::sin(theta)*(currRadius/diskData.outerRadius);
1391
1392 idx++;
1393
1394 vertices[ idx ].x = glm::cos(theta)*nextRadius;
1395 vertices[ idx ].y = glm::sin(theta)*nextRadius;
1396 vertices[ idx ].z = 0.0f;
1397
1398 normals[ idx ].x = 0.0f;
1399 normals[ idx ].y = 0.0f;
1400 normals[ idx ].z = 1.0f;
1401
1402 texCoords[ idx ].s = glm::cos(theta)*(nextRadius/diskData.outerRadius);
1403 texCoords[ idx ].t = glm::sin(theta)*(nextRadius/diskData.outerRadius);
1404
1405 idx++;
1406 theta += sliceStep;
1407 }
1408 }
1409
1410 glBufferData(GL_ARRAY_BUFFER, (sizeof(glm::vec3)*2 + sizeof(glm::vec2)) * NUM_VERTICES, nullptr, GL_STATIC_DRAW );
1411 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * NUM_VERTICES, vertices );
1412 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES, sizeof(glm::vec3) * NUM_VERTICES, normals );
1413 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 2, sizeof(glm::vec2) * NUM_VERTICES, texCoords );
1414
1415 CSCI441_INTERNAL::_diskVAO.insert( std::pair<DiskData, GLuint>( diskData, vaod ) );
1416 CSCI441_INTERNAL::_diskVBO.insert( std::pair<DiskData, GLuint>( diskData, vbod ) );
1417
1418 delete[] vertices;
1419 delete[] texCoords;
1420 delete[] normals;
1421}
1422
1423inline void CSCI441_INTERNAL::generateSphereVAO( SphereData sphereData ) {
1424 GLuint vaod;
1425 glGenVertexArrays( 1, &vaod );
1426 glBindVertexArray( vaod );
1427
1428 GLuint vbod;
1429 glGenBuffers( 1, &vbod );
1430 glBindBuffer( GL_ARRAY_BUFFER, vbod );
1431
1432 const GLuint64 NUM_VERTICES = sphereData.numVertices();
1433
1434 GLfloat sliceStep = glm::two_pi<float>() / (GLfloat)sphereData.slices;
1435 GLfloat stackStep = glm::pi<float>() / (GLfloat)sphereData.stacks;
1436
1437 auto vertices = new glm::vec3[NUM_VERTICES];
1438 auto normals = new glm::vec3[NUM_VERTICES];
1439 auto texCoords = new glm::vec2[NUM_VERTICES];
1440
1441 GLuint64 idx = 0;
1442
1443 // sphere top
1444 GLfloat phi = stackStep * (GLfloat)sphereData.stacks;
1445 GLfloat phiNext = stackStep * (GLfloat)(sphereData.stacks - 1);
1446
1447 vertices[ idx ].x = 0.0f;
1448 vertices[ idx ].y = -glm::cos( phi )*sphereData.radius;
1449 vertices[ idx ].z = 0.0f;
1450
1451 normals[ idx ].x = 0.0f;
1452 normals[ idx ].y = 1.0f;
1453 normals[ idx ].z = 0.0f;
1454
1455 texCoords[ idx ].s = 0.5f;
1456 texCoords[ idx ].t = 1.0f;
1457
1458 idx++;
1459
1460 for(GLuint sliceNum = 0; sliceNum <= sphereData.slices; sliceNum++ ) {
1461 GLfloat theta = sliceStep * (GLfloat)sliceNum;
1462
1463 vertices[ idx ].x = -glm::cos( theta )*glm::sin( phiNext )*sphereData.radius;
1464 vertices[ idx ].y = -glm::cos( phiNext )*sphereData.radius;
1465 vertices[ idx ].z = glm::sin( theta )*glm::sin( phiNext )*sphereData.radius;
1466
1467 normals[ idx ].x = -glm::cos( theta )*glm::sin( phiNext );
1468 normals[ idx ].y = -glm::cos( phiNext );
1469 normals[ idx ].z = glm::sin( theta )*glm::sin( phiNext );
1470
1471 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)sphereData.slices;
1472 texCoords[ idx ].t = 1.0f;
1473
1474 idx++;
1475 }
1476
1477 // sphere stacks
1478 for(GLuint stackNum = 1; stackNum < sphereData.stacks - 1; stackNum++ ) {
1479 phi = stackStep * (GLfloat)stackNum;
1480 phiNext = stackStep * (GLfloat)(stackNum + 1);
1481
1482 for(GLuint sliceNum = sphereData.slices; sliceNum > 0; sliceNum-- ) {
1483 GLfloat theta = sliceStep * (GLfloat)sliceNum;
1484
1485 vertices[ idx ].x = -glm::cos( theta )*glm::sin( phi )*sphereData.radius;
1486 vertices[ idx ].y = -glm::cos( phi )*sphereData.radius;
1487 vertices[ idx ].z = glm::sin( theta )*glm::sin( phi )*sphereData.radius;
1488
1489 normals[ idx ].x = -glm::cos( theta )*glm::sin( phi );
1490 normals[ idx ].y = -glm::cos( phi );
1491 normals[ idx ].z = glm::sin( theta )*glm::sin( phi );
1492
1493 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)sphereData.slices;
1494 texCoords[ idx ].t = (GLfloat)(stackNum-1) / (GLfloat)(sphereData.stacks - 2);
1495
1496 idx++;
1497
1498 vertices[ idx ].x = -glm::cos( theta )*glm::sin( phiNext )*sphereData.radius;
1499 vertices[ idx ].y = -glm::cos( phiNext )*sphereData.radius;
1500 vertices[ idx ].z = glm::sin( theta )*glm::sin( phiNext )*sphereData.radius;
1501
1502 normals[ idx ].x = -glm::cos( theta )*glm::sin( phiNext );
1503 normals[ idx ].y = -glm::cos( phiNext );
1504 normals[ idx ].z = glm::sin( theta )*glm::sin( phiNext );
1505
1506 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)sphereData.slices;
1507 texCoords[ idx ].t = (GLfloat)(stackNum) / (GLfloat)(sphereData.stacks - 2);
1508
1509 idx++;
1510 }
1511
1512 vertices[ idx ].x = -glm::sin( phi )*sphereData.radius;
1513 vertices[ idx ].y = -glm::cos( phi )*sphereData.radius;
1514 vertices[ idx ].z = 0.0f;
1515
1516 normals[ idx ].x = -glm::sin( phi );
1517 normals[ idx ].y = -glm::cos( phi );
1518 normals[ idx ].z = 0.0f;
1519
1520 texCoords[ idx ].s = 0.0f;
1521 texCoords[ idx ].t = (GLfloat)(stackNum-1) / (GLfloat)(sphereData.stacks - 2);
1522
1523 idx++;
1524
1525 vertices[ idx ].x = -glm::sin( phiNext )*sphereData.radius;
1526 vertices[ idx ].y = -glm::cos( phiNext )*sphereData.radius;
1527 vertices[ idx ].z = 0.0f;
1528
1529 normals[ idx ].x = -glm::sin( phiNext );
1530 normals[ idx ].y = -glm::cos( phiNext );
1531 normals[ idx ].z = 0.0f;
1532
1533 texCoords[ idx ].s = 0.0f;
1534 texCoords[ idx ].t = (GLfloat)(stackNum) / (GLfloat)(sphereData.stacks - 2);
1535
1536 idx++;
1537 }
1538
1539 // sphere bottom
1540 phi = 0;
1541 phiNext = stackStep;
1542
1543 vertices[ idx ].x = 0.0f;
1544 vertices[ idx ].y = -glm::cos( phi )*sphereData.radius;
1545 vertices[ idx ].z = 0.0f;
1546
1547 normals[ idx ].x = 0.0f;
1548 normals[ idx ].y = -1.0f;
1549 normals[ idx ].z = 0.0f;
1550
1551 texCoords[ idx ].s = 0.5f;
1552 texCoords[ idx ].t = 0.0f;
1553
1554 idx++;
1555
1556 for(GLuint sliceNum = sphereData.slices; sliceNum > 0; sliceNum--) {
1557 GLfloat theta = sliceStep * (GLfloat)sliceNum;
1558
1559 vertices[ idx ].x = -glm::cos( theta )*glm::sin( phiNext )*sphereData.radius;
1560 vertices[ idx ].y = -glm::cos( phiNext )*sphereData.radius;
1561 vertices[ idx ].z = glm::sin( theta )*glm::sin( phiNext )*sphereData.radius;
1562
1563 normals[ idx ].x = -glm::cos( theta )*glm::sin( phiNext );
1564 normals[ idx ].y = -glm::cos( phiNext );
1565 normals[ idx ].z = glm::sin( theta )*glm::sin( phiNext );
1566
1567 texCoords[ idx ].s = (GLfloat)sliceNum / (GLfloat)sphereData.slices;
1568 texCoords[ idx ].t = 0.0f;
1569
1570 idx++;
1571 }
1572
1573 vertices[ idx ].x = -glm::sin( phiNext )*sphereData.radius;
1574 vertices[ idx ].y = -glm::cos( phiNext )*sphereData.radius;
1575 vertices[ idx ].z = 0.0f;
1576
1577 normals[ idx ].x = -glm::sin( phiNext );
1578 normals[ idx ].y = -glm::cos( phiNext );
1579 normals[ idx ].z = 0.0f;
1580
1581 texCoords[ idx ].s = 0.0f;
1582 texCoords[ idx ].t = 0.0f;
1583
1584 glBufferData(GL_ARRAY_BUFFER, (sizeof(glm::vec3)*2 + sizeof(glm::vec2)) * NUM_VERTICES, nullptr, GL_STATIC_DRAW );
1585 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * NUM_VERTICES, vertices );
1586 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES, sizeof(glm::vec3) * NUM_VERTICES, normals );
1587 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 2, sizeof(glm::vec2) * NUM_VERTICES, texCoords );
1588
1589 CSCI441_INTERNAL::_sphereVAO.insert( std::pair<SphereData, GLuint>( sphereData, vaod ) );
1590 CSCI441_INTERNAL::_sphereVBO.insert( std::pair<SphereData, GLuint>( sphereData, vbod ) );
1591
1592 delete[] vertices;
1593 delete[] texCoords;
1594 delete[] normals;
1595}
1596
1597inline void CSCI441_INTERNAL::generateTorusVAO( TorusData torusData ) {
1598 GLuint vaod;
1599 glGenVertexArrays( 1, &vaod );
1600 glBindVertexArray( vaod );
1601
1602 GLuint vbod;
1603 glGenBuffers( 1, &vbod );
1604 glBindBuffer( GL_ARRAY_BUFFER, vbod );
1605
1606 const GLuint64 NUM_VERTICES = torusData.numVertices();
1607
1608 auto vertices = new glm::vec3[NUM_VERTICES];
1609 auto normals = new glm::vec3[NUM_VERTICES];
1610 auto texCoords = new glm::vec2[NUM_VERTICES];
1611
1612 GLuint64 idx = 0;
1613
1614 GLfloat sideStep = glm::two_pi<float>() / (GLfloat)torusData.sides;
1615 GLfloat ringStep = glm::two_pi<float>() / (GLfloat)torusData.rings;
1616
1617 for(GLuint ringNum = 0; ringNum < torusData.rings; ringNum++ ) {
1618 GLfloat currTheta = ringStep * (GLfloat)ringNum;
1619 GLfloat nextTheta = ringStep * (GLfloat)(ringNum+1);
1620
1621 for(GLuint sideNum = 0; sideNum < torusData.sides; sideNum++ ) {
1622 GLfloat currPhi = sideStep * (GLfloat)sideNum;
1623 GLfloat nextPhi = sideStep * (GLfloat)(sideNum+1);
1624
1625 vertices[ idx ].x = (torusData.outerRadius + torusData.innerRadius * glm::cos(currPhi ) ) * glm::cos(currTheta );
1626 vertices[ idx ].y = (torusData.outerRadius + torusData.innerRadius * glm::cos(currPhi ) ) * glm::sin(currTheta );
1627 vertices[ idx ].z = torusData.innerRadius * glm::sin(currPhi );
1628
1629 normals[ idx ].x = glm::cos( currPhi ) * glm::cos( currTheta );
1630 normals[ idx ].y = glm::cos( currPhi ) * glm::sin( currTheta );
1631 normals[ idx ].z = glm::sin( currPhi );
1632
1633 texCoords[ idx ].s = (GLfloat)sideNum / (GLfloat)torusData.sides;
1634 texCoords[ idx ].t = (GLfloat)ringNum / (GLfloat)torusData.rings;
1635
1636 idx++;
1637
1638 vertices[ idx ].x = (torusData.outerRadius + torusData.innerRadius * glm::cos(currPhi ) ) * glm::cos(nextTheta );
1639 vertices[ idx ].y = (torusData.outerRadius + torusData.innerRadius * glm::cos(currPhi ) ) * glm::sin(nextTheta );
1640 vertices[ idx ].z = torusData.innerRadius * glm::sin(currPhi );
1641
1642 normals[ idx ].x = glm::cos( currPhi ) * glm::cos( nextTheta );
1643 normals[ idx ].y = glm::cos( currPhi ) * glm::sin( nextTheta );
1644 normals[ idx ].z = glm::sin( currPhi );
1645
1646 texCoords[ idx ].s = (GLfloat)sideNum / (GLfloat)torusData.sides;
1647 texCoords[ idx ].t = (GLfloat)(ringNum+1) / (GLfloat)torusData.rings;
1648
1649 idx++;
1650
1651 vertices[ idx ].x = (torusData.outerRadius + torusData.innerRadius * glm::cos(nextPhi ) ) * glm::cos(currTheta );
1652 vertices[ idx ].y = (torusData.outerRadius + torusData.innerRadius * glm::cos(nextPhi ) ) * glm::sin(currTheta );
1653 vertices[ idx ].z = torusData.innerRadius * glm::sin(nextPhi );
1654
1655 normals[ idx ].x = glm::cos( nextPhi ) * glm::cos( currTheta );
1656 normals[ idx ].y = glm::cos( nextPhi ) * glm::sin( currTheta );
1657 normals[ idx ].z = glm::sin( nextPhi );
1658
1659 texCoords[ idx ].s = (GLfloat)(sideNum+1) / (GLfloat)torusData.sides;
1660 texCoords[ idx ].t = (GLfloat)ringNum / (GLfloat)torusData.rings;
1661
1662 idx++;
1663
1664 vertices[ idx ].x = (torusData.outerRadius + torusData.innerRadius * glm::cos(nextPhi ) ) * glm::cos(nextTheta );
1665 vertices[ idx ].y = (torusData.outerRadius + torusData.innerRadius * glm::cos(nextPhi ) ) * glm::sin(nextTheta );
1666 vertices[ idx ].z = torusData.innerRadius * glm::sin(nextPhi );
1667
1668 normals[ idx ].x = glm::cos( nextPhi ) * glm::cos( nextTheta );
1669 normals[ idx ].y = glm::cos( nextPhi ) * glm::sin( nextTheta );
1670 normals[ idx ].z = glm::sin( nextPhi );
1671
1672 texCoords[ idx ].s = (GLfloat)(sideNum+1) / (GLfloat)torusData.sides;
1673 texCoords[ idx ].t = (GLfloat)(ringNum+1) / (GLfloat)torusData.rings;
1674
1675 idx++;
1676 }
1677 }
1678
1679 glBufferData(GL_ARRAY_BUFFER, (sizeof(glm::vec3)*2 + sizeof(glm::vec2)) * NUM_VERTICES, nullptr, GL_STATIC_DRAW );
1680 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * NUM_VERTICES, vertices );
1681 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES, sizeof(glm::vec3) * NUM_VERTICES, normals );
1682 glBufferSubData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * NUM_VERTICES * 2, sizeof(glm::vec2) * NUM_VERTICES, texCoords );
1683
1684 CSCI441_INTERNAL::_torusVAO.insert( std::pair<TorusData, GLuint>( torusData, vaod ) );
1685 CSCI441_INTERNAL::_torusVBO.insert( std::pair<TorusData, GLuint>( torusData, vbod ) );
1686
1687 delete[] vertices;
1688 delete[] texCoords;
1689 delete[] normals;
1690}
1691
1692#endif // __CSCI441_OBJECTS_HPP__
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17
void drawSolidTeapot(GLfloat unused=1.0f)
Draws a solid teapot.
Definition: objects.hpp:748
void drawWireTeapot(GLfloat unused=1.0f)
Draws a wireframe teapot.
Definition: objects.hpp:753
void drawSolidCube(GLfloat sideLength)
Calls through to drawSolidCubeIndexed()
Definition: objects.hpp:590
void drawSolidCylinder(GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices)
Draws a solid open ended cylinder.
Definition: objects.hpp:626
void drawWireCube(GLfloat sideLength)
Draws a wireframe cube.
Definition: objects.hpp:612
void drawSolidPartialDisk(GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep)
Draws part of a solid disk.
Definition: objects.hpp:668
void drawSolidDome(GLfloat radius, GLint stacks, GLint slices)
Draws a solid dome.
Definition: objects.hpp:730
void deleteObjectVBOs()
deletes the VBOs stored for all object types
Definition: objects.hpp:565
void deleteObjectVAOs()
deletes the VAOs stored for all object types
Definition: objects.hpp:560
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
void drawWireTorus(GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings)
Draws a wireframe torus.
Definition: objects.hpp:768
void drawWireDome(GLfloat radius, GLint stacks, GLint slices)
Draws a wireframe dome.
Definition: objects.hpp:739
void drawSolidCone(GLfloat base, GLfloat height, GLint stacks, GLint slices)
Draws a solid cone.
Definition: objects.hpp:570
void drawWireHalfSphere(GLfloat radius, GLint stacks, GLint slices)
Draws a wireframe half sphere with a bottom.
Definition: objects.hpp:721
void drawSolidCubeTextured(GLfloat sideLength)
Draws a solid textured cube. Calls through to drawSolidCubeFlat()
Definition: objects.hpp:595
void drawSolidTorus(GLfloat innerRadius, GLfloat outerRadius, GLint sides, GLint rings)
Draws a solid torus.
Definition: objects.hpp:758
void drawSolidHalfSphere(GLfloat radius, GLint stacks, GLint slices)
Draws a solid half sphere with a bottom.
Definition: objects.hpp:712
void drawSolidCubeFlat(GLfloat sideLength)
Draws a solid cube with normals aligned with cube face.
Definition: objects.hpp:605
void drawWireSphere(GLfloat radius, GLint stacks, GLint slices)
Draws a wireframe sphere.
Definition: objects.hpp:703
void drawSolidSphere(GLfloat radius, GLint stacks, GLint slices)
Draws a solid sphere.
Definition: objects.hpp:694
void drawWireCone(GLfloat base, GLfloat height, GLint stacks, GLint slices)
Draws a wireframe cone.
Definition: objects.hpp:580
void drawSolidDisk(GLfloat inner, GLfloat outer, GLint slices, GLint rings)
Draws a solid disk.
Definition: objects.hpp:646
void drawSolidCubeIndexed(GLfloat sideLength)
Draws a solid cube.
Definition: objects.hpp:599
void drawCubeMap(GLfloat sideLength)
Draws a cube with 3D Texture Coordinates to map a cube map texture to it.
Definition: objects.hpp:619
void drawWireDisk(GLfloat inner, GLfloat outer, GLint slices, GLint rings)
Draws a wireframe disk.
Definition: objects.hpp:657
void drawWirePartialDisk(GLfloat inner, GLfloat outer, GLint slices, GLint rings, GLfloat start, GLfloat sweep)
Draws part of a wireframe disk.
Definition: objects.hpp:681
void drawWireCylinder(GLfloat base, GLfloat top, GLfloat height, GLint stacks, GLint slices)
Draws a wireframe open ended cylinder.
Definition: objects.hpp:636
Helper functions to draw teapot with OpenGL 3.0+.