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