12#ifndef CSCI441_OPENGL_ENGINE_HPP
13#define CSCI441_OPENGL_ENGINE_HPP
16#include "FontUtils.hpp"
19#ifdef CSCI441_USE_GLEW
25#include <GLFW/glfw3.h>
27#ifdef CSCI441_OPENGL_ENGINE_IMPLEMENTATION
28#define STB_IMAGE_WRITE_IMPLEMENTATION
30#include <stb_image_write.h>
90 virtual
void run() = 0;
103 [[maybe_unused]] virtual
bool saveScreenshot(const
char* FILENAME) noexcept final;
125 [[maybe_unused]] [[nodiscard]]
virtual bool isExtensionEnabled(
const std::string EXT)
const noexcept final {
return _extensions.find(EXT) != _extensions.end(); }
156 [[maybe_unused]] [[nodiscard]]
virtual GLFWwindow*
getWindow() const noexcept final {
return mpWindow; }
166 [[nodiscard]]
virtual unsigned short getError() noexcept final {
167 const unsigned short storedErrorCode =
mErrorCode;
172 return storedErrorCode;
236 OpenGLEngine(
int OPENGL_MAJOR_VERSION,
int OPENGL_MINOR_VERSION,
int WINDOW_WIDTH,
int WINDOW_HEIGHT,
const char* WINDOW_TITLE,
bool WINDOW_RESIZABLE = GLFW_FALSE, GLushort NUM_SAMPLES = 0);
325 static void mErrorCallback(
const int error,
const char* DESCRIPTION) { fprintf(stderr,
"[ERROR]: %d\n\t%s\n", error, DESCRIPTION ); }
330 static void APIENTRY
mDebugMessageCallback(
const GLenum source,
const GLenum type,
const GLuint
id,
const GLenum severity,
const GLsizei length,
const GLchar* message,
const void* userParam) {
331 fprintf( stdout,
"[VERBOSE]: Debug Message (%d): source = %s, type = %s, severity = %s, message = %s\n",
333 CSCI441::OpenGLUtils::debugSourceToString(source),
334 CSCI441::OpenGLUtils::debugTypeToString(type),
335 CSCI441::OpenGLUtils::debugSeverityToString(severity),
470 void _setupGLFunctions();
471 void _cleanupGLFunctions() {}
474 void _moveFromSource(OpenGLEngine&);
479 std::set< std::string > _extensions;
481 GLdouble _lastFrameTime;
482 std::deque<GLdouble> _frameTimes;
489 const int OPENGL_MAJOR_VERSION,
490 const int OPENGL_MINOR_VERSION,
491 const int WINDOW_WIDTH,
492 const int WINDOW_HEIGHT,
493 const char* WINDOW_TITLE,
494 const bool WINDOW_RESIZABLE,
495 const GLushort NUM_SAMPLES
497 mErrorCode(OPENGL_ENGINE_ERROR_NO_ERROR),
498 mOpenGLMajorVersion(OPENGL_MAJOR_VERSION),
499 mOpenGLMinorVersion(OPENGL_MINOR_VERSION),
500 mOpenGLMajorVersionRequested(OPENGL_MAJOR_VERSION),
501 mOpenGLMinorVersionRequested(OPENGL_MINOR_VERSION),
502 mOpenGLMajorVersionCreated(0),
503 mOpenGLMinorVersionCreated(0),
504 mWindowWidth(WINDOW_WIDTH),
505 mWindowHeight(WINDOW_HEIGHT),
506 mFramebufferWidth(WINDOW_WIDTH),
507 mFramebufferHeight(WINDOW_HEIGHT),
508 mWindowResizable(WINDOW_RESIZABLE),
509 mNumSamplesPerFragment(NUM_SAMPLES),
510 mWindowTitle(nullptr),
512 _isInitialized(false),
518 strncpy(
mWindowTitle, WINDOW_TITLE, strlen(WINDOW_TITLE) + 1);
530 mErrorCode(OPENGL_ENGINE_ERROR_NO_ERROR),
531 mOpenGLMajorVersion(0),
532 mOpenGLMinorVersion(0),
533 mOpenGLMajorVersionRequested(0),
534 mOpenGLMinorVersionRequested(0),
535 mOpenGLMajorVersionCreated(0),
536 mOpenGLMinorVersionCreated(0),
539 mFramebufferWidth(0),
540 mFramebufferHeight(0),
541 mWindowResizable(
false),
542 mNumSamplesPerFragment(0),
543 mWindowTitle(
nullptr),
545 _isInitialized(
false),
550 _moveFromSource(src);
560 _moveFromSource(src);
573void CSCI441::OpenGLEngine::_cleanupSelf()
575 delete[] mWindowTitle;
576 mWindowTitle =
nullptr;
580void CSCI441::OpenGLEngine::_moveFromSource(
586 mErrorCode = src.mErrorCode;
587 src.mErrorCode = OPENGL_ENGINE_ERROR_NO_ERROR;
589 mOpenGLMajorVersion = src.mOpenGLMajorVersion;
590 src.mOpenGLMajorVersion = 0;
592 mOpenGLMinorVersion = src.mOpenGLMinorVersion;
593 src.mOpenGLMinorVersion = 0;
595 mOpenGLMajorVersionRequested = src.mOpenGLMajorVersionRequested;
596 src.mOpenGLMajorVersionRequested = 0;
598 mOpenGLMinorVersionRequested = src.mOpenGLMinorVersionRequested;
599 src.mOpenGLMinorVersionRequested = 0;
601 mOpenGLMajorVersionCreated = src.mOpenGLMajorVersionCreated;
602 src.mOpenGLMajorVersionCreated = 0;
604 mOpenGLMinorVersionCreated = src.mOpenGLMinorVersionCreated;
605 src.mOpenGLMinorVersionCreated = 0;
607 mWindowWidth = src.mWindowWidth;
608 src.mWindowWidth = 0;
610 mWindowHeight = src.mWindowHeight;
611 src.mWindowHeight = 0;
613 mWindowResizable = src.mWindowResizable;
614 src.mWindowResizable =
false;
616 mNumSamplesPerFragment = src.mNumSamplesPerFragment;
617 src.mNumSamplesPerFragment = 0;
619 mWindowTitle = src.mWindowTitle;
620 src.mWindowTitle =
nullptr;
622 mpWindow = src.mpWindow;
623 src.mpWindow =
nullptr;
625 _isInitialized = src._isInitialized;
626 src._isInitialized =
false;
628 _isCleanedUp = src._isCleanedUp;
629 src._isCleanedUp =
false;
631 _extensions = std::move(src._extensions);
637 if( !_isInitialized ) {
638 const std::chrono::steady_clock::time_point initBegin = std::chrono::steady_clock::now();
641 fprintf(stdout,
"[INFO]: Using CSCI441 Library v%d.%d.%d.%d\n", CSCI441::VERSION_MAJOR, CSCI441::VERSION_MINOR, CSCI441::VERSION_REVISION, CSCI441::VERSION_PATCH);
644 const std::chrono::steady_clock::time_point glfwBegin = std::chrono::steady_clock::now();
646 glfwGetFramebufferSize( mpWindow, &mFramebufferWidth, &mFramebufferHeight );
647 const std::chrono::steady_clock::time_point glfwEnd = std::chrono::steady_clock::now();
649 const std::chrono::steady_clock::time_point openGLBegin = std::chrono::steady_clock::now();
654 if (mNumSamplesPerFragment > 0) {
655 glEnable(GL_MULTISAMPLE);
657 glDisable(GL_MULTISAMPLE);
663 if( mOpenGLMajorVersion > 4 || (mOpenGLMajorVersion == 4 && mOpenGLMinorVersion >= 3) ) {
665 int flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
666 if (flags & GL_CONTEXT_FLAG_DEBUG_BIT) {
668 glEnable(GL_DEBUG_OUTPUT);
669 glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
670 glDebugMessageCallback(mDebugMessageCallback,
nullptr);
671 glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0,
nullptr, GL_TRUE );
675 CSCI441::OpenGLUtils::printOpenGLInfo();
677 const std::chrono::steady_clock::time_point openGLEnd = std::chrono::steady_clock::now();
678 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupOpenGL()");
680 const std::chrono::steady_clock::time_point shadersBegin = std::chrono::steady_clock::now();
682 const std::chrono::steady_clock::time_point shadersEnd = std::chrono::steady_clock::now();
683 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupShaders()");
685 const std::chrono::steady_clock::time_point buffersBegin = std::chrono::steady_clock::now();
687 const std::chrono::steady_clock::time_point buffersEnd = std::chrono::steady_clock::now();
688 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupBuffers()");
690 const std::chrono::steady_clock::time_point texturesBegin = std::chrono::steady_clock::now();
692 const std::chrono::steady_clock::time_point texturesEnd = std::chrono::steady_clock::now();
693 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupTextures()");
695 const std::chrono::steady_clock::time_point fontsBegin = std::chrono::steady_clock::now();
697 const std::chrono::steady_clock::time_point fontsEnd = std::chrono::steady_clock::now();
698 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupFonts()");
700 const std::chrono::steady_clock::time_point sceneBegin = std::chrono::steady_clock::now();
702 const std::chrono::steady_clock::time_point sceneEnd = std::chrono::steady_clock::now();
703 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mSetupScene()");
705 _isInitialized =
true;
706 _isCleanedUp =
false;
708 const std::chrono::steady_clock::time_point initEnd = std::chrono::steady_clock::now();
710 fprintf(stdout,
"\n[INFO]: Setup complete\n");
711 fprintf(stdout,
"[INFO]: Init Time: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(initEnd - initBegin ).count() ) / 1000000.0);
712 fprintf(stdout,
"[INFO]: \tGLFW: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(glfwEnd - glfwBegin ).count() ) / 1000000.0);
713 fprintf(stdout,
"[INFO]: \tOpenGL: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(openGLEnd - openGLBegin ).count() ) / 1000000.0);
714 fprintf(stdout,
"[INFO]: \tShaders: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(shadersEnd - shadersBegin ).count() ) / 1000000.0);
715 fprintf(stdout,
"[INFO]: \tBuffers: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(buffersEnd - buffersBegin ).count() ) / 1000000.0);
716 fprintf(stdout,
"[INFO]: \tTextures: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(texturesEnd - texturesBegin).count() ) / 1000000.0);
717 fprintf(stdout,
"[INFO]: \tFonts: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(fontsEnd - fontsBegin ).count() ) / 1000000.0);
718 fprintf(stdout,
"[INFO]: \tScene: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(sceneEnd - sceneBegin ).count() ) / 1000000.0);
726 const unsigned short ERROR_CODE
728 switch (ERROR_CODE) {
729 case OPENGL_ENGINE_ERROR_NO_ERROR:
return "No error";
730 case OPENGL_ENGINE_ERROR_GLFW_INIT:
return "Error initializing GLFW";
731 case OPENGL_ENGINE_ERROR_GLFW_WINDOW:
return "Error initializing GLFW window";
732 case OPENGL_ENGINE_ERROR_GLEW_INIT:
return "Error initializing GLEW";
733 case OPENGL_ENGINE_ERROR_GLAD_INIT:
return "Error initializing GLAD";
734 case OPENGL_ENGINE_ERROR_TAKE_SCREENSHOT:
return "Error saving screenshot";
735 default:
return "Unknown error code";
744 const std::string filename =
747 ?
"Screenshot_" + std::to_string(time(
nullptr)) +
".png"
753 glGetIntegerv(GL_VIEWPORT, viewport);
754 const GLsizei x = viewport[0], y = viewport[1], width = viewport[2], height = viewport[3];
757 constexpr int CHANNELS = 4;
758 const auto bytes =
new GLubyte[width*height*CHANNELS];
759 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bytes);
761 stbi_flip_vertically_on_write(
true);
763 if( !stbi_write_png(filename.c_str(), width, height, CHANNELS, bytes, width*CHANNELS) ) {
764 fprintf(stderr,
"[ERROR]: Could not save screenshot\n");
765 mErrorCode = OPENGL_ENGINE_ERROR_TAKE_SCREENSHOT;
767 fprintf(stdout,
"[INFO]: Screenshot saved to %s\n", filename.c_str());
772 return (mErrorCode == OPENGL_ENGINE_ERROR_NO_ERROR);
781 glfwSetErrorCallback(mErrorCallback);
785 fprintf( stderr,
"[ERROR]: Could not initialize GLFW\n" );
786 mErrorCode = OPENGL_ENGINE_ERROR_GLFW_INIT;
788 if(DEBUG) fprintf( stdout,
"[INFO]: GLFW v%d.%d.%d initialized\n", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION );
790 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, mOpenGLMajorVersion );
791 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, mOpenGLMinorVersion );
792 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
793 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
794 glfwWindowHint(GLFW_DOUBLEBUFFER, GLFW_TRUE );
795 glfwWindowHint(GLFW_RESIZABLE, mWindowResizable );
796 glfwWindowHint(GLFW_SAMPLES, mNumSamplesPerFragment);
800 && (mOpenGLMajorVersion > 4 || (mOpenGLMajorVersion == 4 && mOpenGLMinorVersion >= 3)) ) {
801 glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT,
true);
805 mpWindow = glfwCreateWindow(mWindowWidth, mWindowHeight, mWindowTitle,
nullptr,
nullptr );
807 fprintf( stderr,
"[ERROR]: GLFW Window could not be created\n" );
809 mErrorCode = OPENGL_ENGINE_ERROR_GLFW_WINDOW;
811 if(DEBUG) fprintf( stdout,
"[INFO]: GLFW Window created\n" );
812 glfwMakeContextCurrent(mpWindow);
814 glfwSetInputMode(mpWindow, GLFW_LOCK_KEY_MODS, GLFW_TRUE);
815 glfwSetWindowUserPointer(mpWindow, (
void*)
this);
816 glfwSetWindowSizeCallback(mpWindow, mWindowResizeCallback);
822void CSCI441::OpenGLEngine::_setupGLFunctions()
825#ifdef CSCI441_USE_GLEW
826 glewExperimental = GL_TRUE;
827 const GLenum glewResult = glewInit();
830 if( glewResult != GLEW_OK ) {
831 fprintf( stderr,
"[ERROR]: Error initializing GLEW\n");
832 fprintf( stderr,
"[ERROR]: %s\n",
reinterpret_cast<const char *
>(glewGetErrorString(glewResult)) );
833 mErrorCode = OPENGL_ENGINE_ERROR_GLEW_INIT;
836 fprintf(stdout,
"[INFO]: GLEW initialized\n");
837 fprintf(stdout,
"[INFO]: Using GLEW %s\n",
reinterpret_cast<const char *
>(glewGetString(GLEW_VERSION)));
841 int version = gladLoadGL(glfwGetProcAddress);
843 fprintf(stderr,
"[ERROR]: Failed to initialize GLAD\n" );
844 mErrorCode = OPENGL_ENGINE_ERROR_GLAD_INIT;
848 fprintf(stdout,
"[INFO]: GLAD initialized v%d.%d\n", GLAD_VERSION_MAJOR(version), GLAD_VERSION_MINOR(version));
853 if(mErrorCode == OPENGL_ENGINE_ERROR_NO_ERROR) {
854 glGetIntegerv(GL_MAJOR_VERSION, &mOpenGLMajorVersionCreated);
855 glGetIntegerv(GL_MINOR_VERSION, &mOpenGLMinorVersionCreated);
857 fprintf(stdout,
"[INFO]: OpenGL v%d.%d requested\n", mOpenGLMajorVersionRequested, mOpenGLMinorVersionRequested);
858 fprintf(stdout,
"[INFO]: OpenGL v%d.%d created\n", mOpenGLMajorVersionCreated, mOpenGLMinorVersionCreated);
861 GLint numExtensions = 0;
862 glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
863 for (
int i = 0; i < numExtensions; i++) {
864 _extensions.insert(
reinterpret_cast<const char *
>(glGetStringi(GL_EXTENSIONS, i)) );
872 if(DEBUG) fprintf( stdout,
"[INFO]: ...closing window...\n" );
873 glfwDestroyWindow(mpWindow );
875 if(DEBUG) fprintf( stdout,
"[INFO]: ...closing GLFW.....\n" );
882 if( !_isCleanedUp ) {
883 const std::chrono::steady_clock::time_point shutdownBegin = std::chrono::steady_clock::now();
884 if (DEBUG) fprintf(stdout,
"\n[INFO]: Shutting down.......\n");
886 const std::chrono::steady_clock::time_point sceneBegin = std::chrono::steady_clock::now();
888 const std::chrono::steady_clock::time_point sceneEnd = std::chrono::steady_clock::now();
889 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupScene()");
891 const std::chrono::steady_clock::time_point fontsBegin = std::chrono::steady_clock::now();
893 const std::chrono::steady_clock::time_point fontsEnd = std::chrono::steady_clock::now();
894 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupFonts()");
896 const std::chrono::steady_clock::time_point texturesBegin = std::chrono::steady_clock::now();
898 const std::chrono::steady_clock::time_point texturesEnd = std::chrono::steady_clock::now();
899 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupTextures()");
901 const std::chrono::steady_clock::time_point buffersBegin = std::chrono::steady_clock::now();
903 const std::chrono::steady_clock::time_point buffersEnd = std::chrono::steady_clock::now();
904 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupBuffers()");
906 const std::chrono::steady_clock::time_point shadersBegin = std::chrono::steady_clock::now();
908 const std::chrono::steady_clock::time_point shadersEnd = std::chrono::steady_clock::now();
909 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupShaders()");
911 const std::chrono::steady_clock::time_point openGLBegin = std::chrono::steady_clock::now();
913 _cleanupGLFunctions();
914 const std::chrono::steady_clock::time_point openGLEnd = std::chrono::steady_clock::now();
915 CSCI441::OpenGLUtils::checkOpenGLErrors(
"post mCleanupOpenGL()");
917 const std::chrono::steady_clock::time_point glfwBegin = std::chrono::steady_clock::now();
919 const std::chrono::steady_clock::time_point glfwEnd = std::chrono::steady_clock::now();
921 const std::chrono::steady_clock::time_point shutdownEnd = std::chrono::steady_clock::now();
923 fprintf(stdout,
"[INFO]: ..shut down complete!\n");
924 fprintf(stdout,
"[INFO]: Shutdown: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(shutdownEnd - shutdownBegin).count() ) / 1000000.0);
925 fprintf(stdout,
"[INFO]: \tScene: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(sceneEnd - sceneBegin ).count() ) / 1000000.0);
926 fprintf(stdout,
"[INFO]: \tFonts: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(fontsEnd - fontsBegin ).count() ) / 1000000.0);
927 fprintf(stdout,
"[INFO]: \tTextures: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(texturesEnd - texturesBegin).count() ) / 1000000.0);
928 fprintf(stdout,
"[INFO]: \tBuffers: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(buffersEnd - buffersBegin ).count() ) / 1000000.0);
929 fprintf(stdout,
"[INFO]: \tShaders: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(shadersEnd - shadersBegin ).count() ) / 1000000.0);
930 fprintf(stdout,
"[INFO]: \tOpenGL: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(openGLEnd - openGLBegin ).count() ) / 1000000.0);
931 fprintf(stdout,
"[INFO]: \tGLFW: %2.3fs\n",
static_cast<double>( std::chrono::duration_cast<std::chrono::microseconds>(glfwEnd - glfwBegin ).count() ) / 1000000.0);
934 _isInitialized =
false;
944 const auto pEngine =
static_cast<OpenGLEngine *
>(glfwGetWindowUserPointer(pWindow));
949 GLint framebufferWidth, framebufferHeight;
950 glfwGetFramebufferSize( pEngine->getWindow(), &framebufferWidth, &framebufferHeight );
951 pEngine->setCurrentFramebufferSize(framebufferWidth, framebufferHeight);
957 if (DEBUG) fprintf(stdout,
"\n[INFO]: Removing old shaders...\n");
959 if (DEBUG) fprintf(stdout,
"\n[INFO]: Reloading shaders...\n");
961 if (DEBUG) fprintf(stdout,
"\n[INFO]: Shaders reloaded\n");
966 const GLdouble currentTime = glfwGetTime();
968 GLdouble fps = ( !_frameTimes.empty() ? _frameTimes.back() : 0.0 );
969 if (currentTime - _lastFrameTime > 0.1667) {
970 fps =
static_cast<GLdouble
>(_numFrames)/(currentTime - _lastFrameTime);
972 _lastFrameTime = currentTime;
974 if (_frameTimes.size() >= 10) _frameTimes.pop_front();
975 _frameTimes.push_back( fps );
982 GLdouble totalFPS = 0;
983 for(
const auto& fpsUnit : _frameTimes ) {
986 return totalFPS /
static_cast<GLdouble
>(_frameTimes.size());
Helper functions to work with OpenGL 3.0+.
Abstract Class to run an OpenGL application. The following methods must be overridden:
Definition: OpenGLEngine.hpp:52
virtual void mSetupOpenGL()=0
override to enable specific OpenGL features
virtual bool isExtensionEnabled(const std::string EXT) const noexcept final
Returns if OpenGL extension exists.
Definition: OpenGLEngine.hpp:125
bool DEBUG
if information should be printed to console while running
Definition: OpenGLEngine.hpp:242
OpenGLEngine & operator=(const OpenGLEngine &)=delete
do not allow engines to be copied
int mFramebufferWidth
the framebuffer height of the requested GLFW window
Definition: OpenGLEngine.hpp:294
int mOpenGLMinorVersion
the minor version of the requested OpenGL context
Definition: OpenGLEngine.hpp:258
int mOpenGLMajorVersion
the major version of the requested OpenGL context
Definition: OpenGLEngine.hpp:253
static constexpr unsigned short OPENGL_ENGINE_ERROR_NO_ERROR
no error is present, everything is currently working
Definition: OpenGLEngine.hpp:178
virtual bool saveScreenshot(const char *FILENAME) noexcept final
Save a PNG screenshot of the viewport.
Definition: OpenGLEngine.hpp:740
virtual void setCurrentWindowSize(const int WINDOW_WIDTH, const int WINDOW_HEIGHT) final
Stores the new window size.
Definition: OpenGLEngine.hpp:135
virtual void initialize()
Initialize everything needed for OpenGL Rendering. This includes in order: GLFW, function pointers,...
Definition: OpenGLEngine.hpp:635
virtual void shutdown()
Cleanup everything needed for OpenGL Rendering. This includes freeing memory for data used in: any Sc...
Definition: OpenGLEngine.hpp:880
virtual unsigned short getError() noexcept final
Return current value of error code and clear the error code back to no error.
Definition: OpenGLEngine.hpp:166
virtual void mSetupTextures()
override to register any textures with the GPU
Definition: OpenGLEngine.hpp:394
virtual int getWindowHeight() const noexcept final
Return the height of the window.
Definition: OpenGLEngine.hpp:148
virtual bool isDebuggingEnabled() const noexcept final
Returns if logging is enabled.
Definition: OpenGLEngine.hpp:118
static void mWindowResizeCallback(GLFWwindow *pWindow, int width, int height)
Definition: OpenGLEngine.hpp:939
static constexpr unsigned short OPENGL_ENGINE_ERROR_GLAD_INIT
an error occurred while initializing GLAD
Definition: OpenGLEngine.hpp:194
virtual void mCleanupBuffers()
override to cleanup any buffer objects from the GPU
Definition: OpenGLEngine.hpp:427
virtual void mCleanupScene()
override to cleanup any scene specific information
Definition: OpenGLEngine.hpp:412
virtual void mSetupFonts()
override to register any fonts with the GPU
Definition: OpenGLEngine.hpp:400
virtual void setCurrentFramebufferSize(const int FRAMEBUFFER_WIDTH, const int FRAMEBUFFER_HEIGHT) final
Stores the framebuffer size.
Definition: OpenGLEngine.hpp:144
virtual void mCleanupShaders()
override to cleanup any shaders from the GPU
Definition: OpenGLEngine.hpp:432
virtual void mCleanupTextures()
override to cleanup any textures from the GPU
Definition: OpenGLEngine.hpp:422
virtual GLdouble clockFrame() final
measures the amount of time elapsed since the last time this method was called
Definition: OpenGLEngine.hpp:965
bool mWindowResizable
if the GLFW window can be resized while open
Definition: OpenGLEngine.hpp:303
int mOpenGLMinorVersionRequested
the minor version of the requested OpenGL context
Definition: OpenGLEngine.hpp:270
GLushort mNumSamplesPerFragment
how many samples to fire per fragment
Definition: OpenGLEngine.hpp:309
OpenGLEngine(const OpenGLEngine &)=delete
do not allow engines to be copied
static constexpr unsigned short OPENGL_ENGINE_ERROR_TAKE_SCREENSHOT
an error occurred while taking a screenshot
Definition: OpenGLEngine.hpp:198
int mFramebufferHeight
the framebuffer width of the requested GLFW window
Definition: OpenGLEngine.hpp:298
virtual void turnDebuggingOn() noexcept final
Enable logging to command line.
Definition: OpenGLEngine.hpp:109
static constexpr unsigned short OPENGL_ENGINE_ERROR_GLEW_INIT
an error occurred while initializing GLEW
Definition: OpenGLEngine.hpp:190
static constexpr unsigned short OPENGL_ENGINE_ERROR_GLFW_WINDOW
an error occurred while creating the GLFW window
Definition: OpenGLEngine.hpp:186
virtual void mCleanupFonts()
override to cleanup any fonts from the GPU
Definition: OpenGLEngine.hpp:417
int mOpenGLMajorVersionRequested
the major version of the requested OpenGL context
Definition: OpenGLEngine.hpp:264
static void mErrorCallback(const int error, const char *DESCRIPTION)
We will register this function as GLFW's error callback. When an error within OpenGL occurs,...
Definition: OpenGLEngine.hpp:325
static constexpr unsigned short OPENGL_ENGINE_ERROR_LAST
stores the error code number of the last possible error, this corresponds to the max error code value...
Definition: OpenGLEngine.hpp:210
unsigned int mErrorCode
tracks the current status of the OpenGL engine via error codes
Definition: OpenGLEngine.hpp:247
virtual void run()=0
Initiate the draw loop.
static void APIENTRY mDebugMessageCallback(const GLenum source, const GLenum type, const GLuint id, const GLenum severity, const GLsizei length, const GLchar *message, const void *userParam)
callback called whenever a debug message is signaled
Definition: OpenGLEngine.hpp:330
char * mWindowTitle
the title of the GLFW window
Definition: OpenGLEngine.hpp:313
int mWindowHeight
the window height of the requested GLFW window
Definition: OpenGLEngine.hpp:290
virtual GLdouble fpsAverage() final
Definition: OpenGLEngine.hpp:981
virtual void setWindowShouldClose() final
Tell our engine's window to close.
Definition: OpenGLEngine.hpp:161
int mOpenGLMajorVersionCreated
the major version of the created OpenGL context
Definition: OpenGLEngine.hpp:275
static constexpr unsigned short OPENGL_ENGINE_ERROR_SIZE
stores the number of unique error codes that can be generated
Definition: OpenGLEngine.hpp:214
virtual void mReloadShaders() final
calls mCleanupShaders() followed by mSetupShaders() to reload shader source code from file
Definition: OpenGLEngine.hpp:955
virtual void mSetupShaders()
override to register any shaders with the GPU
Definition: OpenGLEngine.hpp:382
GLFWwindow * mpWindow
pointer to the GLFW window object
Definition: OpenGLEngine.hpp:317
virtual void turnDebuggingOff() noexcept final
Disable logging to command line.
Definition: OpenGLEngine.hpp:114
static const char * getErrorStringDescription(unsigned short ERROR_CODE) noexcept
Returns a string describing what the error code corresponds to.
Definition: OpenGLEngine.hpp:725
virtual int getWindowWidth() const noexcept final
Return the width of the window.
Definition: OpenGLEngine.hpp:152
virtual void mSetupBuffers()
override to register any buffer objects with the GPU
Definition: OpenGLEngine.hpp:388
virtual ~OpenGLEngine()
cleans up our OpenGL Engine by destroying the OpenGL context, GLFW window, and cleaning up all GPU re...
Definition: OpenGLEngine.hpp:567
virtual void mCleanupGLFW()
Destroys the associated GLFW window and terminates the GLFW instance.
Definition: OpenGLEngine.hpp:870
int mOpenGLMinorVersionCreated
the minor version of the created OpenGL context
Definition: OpenGLEngine.hpp:280
int mWindowWidth
the window width of the requested GLFW window
Definition: OpenGLEngine.hpp:285
virtual void mCleanupOpenGL()
override to cleanup any specific OpenGL features
Definition: OpenGLEngine.hpp:437
static constexpr unsigned short OPENGL_ENGINE_ERROR_GLFW_INIT
an error occurred while initializing GLFW
Definition: OpenGLEngine.hpp:182
virtual void mSetupGLFW()
Used to setup everything GLFW related. This includes the OpenGL context and our window....
Definition: OpenGLEngine.hpp:776
virtual void mSetupScene()
override to setup any scene specific information
Definition: OpenGLEngine.hpp:406
static constexpr unsigned short OPENGL_ENGINE_ERROR_UNKNOWN
a new error that does not correspond to a predefined scenario has occurred
Definition: OpenGLEngine.hpp:202
virtual GLFWwindow * getWindow() const noexcept final
Return the window object.
Definition: OpenGLEngine.hpp:156
void setFontSize(GLfloat scaleX, GLfloat scaleY)
set the amount to scale font when drawing
Definition: FontUtils.hpp:180
void setWindowSize(GLint width, GLint height)
store the size of the window
Definition: FontUtils.hpp:172
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17