#pragma once // GLFW, GLEW, GLM #include #include #include #include // DGL #include "DGL_FundamentalTypes.hpp" #include "DGL_MiscTypes.hpp" #include "DGL_Enum.hpp" #include "DGL_Shader.hpp" #include "DGL_Buffers.hpp" #include "DGL_Space.hpp" // Non-Standard C++ #include "Cpp_Alias.hpp" namespace DGL { // Aliases // C++ STL using std::cout; using std::endl; // GLFW using Monitor = GLFWmonitor; using TimeValInt = uint64_t; using TimeValDec = double; using Window = GLFWwindow; using WindowRefList = std::vector< ptr >; // Object Instances WindowRefList Windows; // Constants sfn constexpr NotShared () -> ptr { return NULL; } sfn constexpr WindowedMode() -> ptr { return NULL; } // Forward Declares sfn SwapBuffers(const ptr _window) -> void; // Functionality sfn CanClose(const ptr _theWindow) { return glfwWindowShouldClose(_theWindow); } sfn CanUseRawMouse() { return glfwRawMouseMotionSupported(); } sfn CreateWindow ( int _width, int _height, RawString _title, ptr _monitorToFullscreen, ptr _windowToShareResourcesWith ) -> ptr { Windows.push_back(glfwCreateWindow(_width, _height, _title, _monitorToFullscreen, _windowToShareResourcesWith)); try { if (Windows.back() == NULL) { throw std::runtime_error("Failed to create a window"); } } catch (std::runtime_error _error) { ErrorRuntime(_error); Exit(ExitCode::Failed); } return Windows.back(); } sfn CursorPositionUpdateBind(ptr _window, FnPtr _functionToCall) { glfwSetCursorPosCallback(_window, GLFWcursorposfun(_functionToCall)); } sfn DestoryWindow(const ptr _window) { using ElementType = decltype(Windows.begin()); for (ElementType element = Windows.begin(); element != Windows.end(); element++) { if (*element == _window) { glfwDestroyWindow(_window); Windows.erase(element); } } return; } sfn DrawArrays(EPrimitives _primitive, gInt _startingIndex, gInt _numToRender) { glDrawArrays(GLenum(_primitive), _startingIndex, _numToRender); // Starting from vertex 0; 3 vertices total -> 1 triangle. } sfn DrawElements(EPrimitives _primitive, gSize _numElements, EDataType _dataType, DataPtr _offfsetAddressFromFirstIndex) { glDrawElements(GLenum(_primitive), _numElements, GLenum(_dataType), _offfsetAddressFromFirstIndex); } sfn GetCursorPosition(ptr _window, ptr _xAxis, ptr _yAxis) { glfwGetCursorPos(_window, _xAxis, _yAxis); } sfn GetMouseInputMode(ptr _contextWindowRef, EMouseMode _mode) { return glfwGetInputMode(_contextWindowRef, GLenum(_mode)); } sfn GetRawTime() -> TimeValInt { return glfwGetTimerValue(); } sfn GetTime() -> TimeValDec { return glfwGetTime(); } sfn InitalizeGLFW() { try { std::cout << "Initializing GLFW Version: " << glfwGetVersionString() << std::endl; /* Initialize the library */ if (!glfwInit()) { throw std::runtime_error("Failed to initialize GLFW"); } } catch (const std::runtime_error _error) { ErrorRuntime(_error); Exit(ExitCode::Failed); } return; } sfn InitalizeGLEW() { try { // If using GLEW version 1.13 or earlier //glewExperimental = true; std::cout << "Initializing Glew Version: " << glewGetString(GLEW_VERSION) << std::endl; GLenum err = glewInit(); if (err != GLEW_OK) { // Problem: glewInit failed, something is seriously wrong. std::cout << "glewInit failed: " << glewGetErrorString(err) << std::endl; throw std::runtime_error("Failed to initialize GLFW"); } cout << "OpenGL Version: " << glGetString(GL_VERSION) << endl; } catch (const std::runtime_error _error) { ErrorRuntime(_error); Exit(ExitCode::Failed); } } sfn KeyPressed(ptr _contextWindowRef, EKeyCodes _keyToCheck) -> bool { return glfwGetKey(_contextWindowRef, int(_keyToCheck)); } template sfn KeysPressed(ptr _contextWindowRef, CodeType... _otherKeys) -> bool { return (KeyPressed(_contextWindowRef, _otherKeys) && ...) == true; } sfn PollEvents() { glfwPollEvents(); return; } sfn ResetCursor(ptr _window, gFloat _screenCenterWidth, gFloat _screenCenterHeight) { glfwSetCursorPos(_window, _screenCenterWidth, _screenCenterHeight); glfwSetCursorPos(_window, 0, 0); } sfn RunBasicWindowLoop(const ptr _window) { /* Loop until the user closes the window */ while (not CanClose(_window)) { ClearBuffer(EFrameBuffer::Color); SwapBuffers(_window); PollEvents(); } return; } sfn RunBasicWindowLoop_Timed(const ptr _window, TimeValDec _interval, Delegate< Func> _renderProcedure) { TimeValDec start, end, deltaSinceClear = 0.0; while (not CanClose(_window)) { start = GetTime(); if (deltaSinceClear > _interval) { ClearBuffer(EFrameBuffer::Color, EFrameBuffer::Depth); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.25f, 0.25f, 0.25f, 1.0f); //glMatrixMode(GL_MODELVIEW); //glLoadIdentity(); _renderProcedure(); SwapBuffers(_window); PollEvents(); } end = GetTime(); deltaSinceClear = deltaSinceClear + end - start; } return; } sfn SetClearColor(LinearColor _colorToSet) { glClearColor(_colorToSet.Red, _colorToSet.Green, _colorToSet.Blue, _colorToSet.Alpha); } sfn SetCurrentContext(const ptr _window) { try { glfwMakeContextCurrent(_window); ptr< RawString > ErrorMsg = NULL; int code = glfwGetError(ErrorMsg); if (code == GLFW_NO_WINDOW_CONTEXT) { throw std::runtime_error( Dref(ErrorMsg) ); } } catch (const std::runtime_error _error) { ErrorRuntime(_error); Exit(ExitCode::Failed); } return; } template sfn SetInputMode(ptr _window, EMouseMode _mouseMode, ModeParam _modeParam) { glfwSetInputMode(_window, GLenum(_mouseMode), GLenum(_modeParam)); } sfn SetPolygonMode(EFace _desiredFaces, ERenderMode _desiredMode) { glPolygonMode(GLenum(_desiredFaces), GLenum(_desiredMode)); } sfn SwapBuffers(const ptr _window) -> void { glfwSwapBuffers(_window); return; } sfn TerminateGLFW() { glfwTerminate(); return; } }