diff --git a/src/aquarium-direct-map/Main.cpp b/src/aquarium-direct-map/Main.cpp index c6851bb..f652778 100644 --- a/src/aquarium-direct-map/Main.cpp +++ b/src/aquarium-direct-map/Main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #define GLFW_INCLUDE_NONE @@ -47,6 +48,29 @@ #define min(a, b) ((a) < (b) ? (a) : (b)) +namespace { + +class GLFWInitializer { +public: + GLFWInitializer() { + ++sCounter; + glfwInit(); // Initialization failure can be detected with glfwGetError(). + // On success, the next glfwInit() invocation will be a no-op. + } + ~GLFWInitializer() { + if (--sCounter == 0) { + glfwTerminate(); // no effect if GLFW is not initialized + } + } + +private: + static int sCounter; +}; + +int GLFWInitializer::sCounter = 0; + +} // namespace + std::chrono::steady_clock::time_point getCurrentTimePoint(); void render(); @@ -215,6 +239,26 @@ std::chrono::steady_clock::time_point getCurrentTimePoint() { #endif } +std::pair getMonitorResolution() { + GLFWInitializer initializer; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; + return {}; + } + + GLFWmonitor *monitor = glfwGetPrimaryMonitor(); + if (!monitor) { + return {}; + } + + const GLFWvidmode *mode = glfwGetVideoMode(monitor); + if (!mode) { + return {}; + } + + return {mode->width, mode->height}; +} + void setGenericConstMatrix(GenericConst *genericConst) { genericConst->viewProjection = &viewProjection; genericConst->viewInverse = &viewInverse; @@ -436,10 +480,9 @@ bool initialize(int argc, char **argv) { } int main(int argc, char **argv) { - - // initialize GLFW - if (!glfwInit()) { - std::cout << stderr << "Failed to initialize GLFW" << std::endl; + GLFWInitializer initializer; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; return -1; } @@ -460,15 +503,12 @@ int main(int argc, char **argv) { glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - clientWidth = mode->width; - clientHeight = mode->height; + clientWidth = getMonitorResolution().first; + clientHeight = getMonitorResolution().second; window = glfwCreateWindow(clientWidth, clientHeight, "Aquarium", NULL, NULL); if (window == NULL) { std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); return -1; } glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); @@ -505,8 +545,6 @@ int main(int argc, char **argv) { onDestroy(); - glfwTerminate(); - return 0; } diff --git a/src/aquarium-optimized/Context.cpp b/src/aquarium-optimized/Context.cpp index f75b4ca..8694a72 100644 --- a/src/aquarium-optimized/Context.cpp +++ b/src/aquarium-optimized/Context.cpp @@ -6,14 +6,52 @@ #include "Context.h" +#include #include +#define GLFW_INCLUDE_NONE +#include "GLFW/glfw3.h" + #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_internal.h" #include "Aquarium.h" +int Context::GLFWInitializer::sCounter = 0; + +Context::GLFWInitializer::GLFWInitializer() { + ++sCounter; + glfwInit(); // Initialization failure can be detected with glfwGetError(). On + // success, the next glfwInit() invocation will be a no-op. +} + +Context::GLFWInitializer::~GLFWInitializer() { + if (--sCounter == 0) { + glfwTerminate(); // no effect if GLFW is not initialized + } +} + +std::pair Context::getMonitorResolution() { + GLFWInitializer initializer; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; + return {}; + } + + GLFWmonitor *monitor = glfwGetPrimaryMonitor(); + if (!monitor) { + return {}; + } + + const GLFWvidmode *mode = glfwGetVideoMode(monitor); + if (!mode) { + return {}; + } + + return {mode->width, mode->height}; +} + void Context::renderImgui( const FPSTimer &fpsTimer, int *fishCount, diff --git a/src/aquarium-optimized/Context.h b/src/aquarium-optimized/Context.h index 00fe635..d1a1386 100644 --- a/src/aquarium-optimized/Context.h +++ b/src/aquarium-optimized/Context.h @@ -10,6 +10,7 @@ #include #include +#include #include #include "Aquarium.h" @@ -25,7 +26,18 @@ class Texture; static char fishCountInputBuffer[64]; class Context { + class GLFWInitializer { + public: + GLFWInitializer(); + ~GLFWInitializer(); + + private: + static int sCounter; + }; + public: + static std::pair getMonitorResolution(); + Context() : mDisableControlPanel(false), mMSAASampleCount(1), @@ -111,6 +123,7 @@ class Context { int mMSAASampleCount; private: + GLFWInitializer mGLFWInitializer; bool show_option_window; }; diff --git a/src/aquarium-optimized/d3d12/ContextD3D12.cpp b/src/aquarium-optimized/d3d12/ContextD3D12.cpp index f2e57dd..4e02018 100644 --- a/src/aquarium-optimized/d3d12/ContextD3D12.cpp +++ b/src/aquarium-optimized/d3d12/ContextD3D12.cpp @@ -74,8 +74,6 @@ ContextD3D12::~ContextD3D12() { destoryImgUI(); } destoryFishResource(); - - glfwTerminate(); } ContextD3D12 *ContextD3D12::create(BACKENDTYPE backendType) { @@ -91,9 +89,8 @@ bool ContextD3D12::initialize( mDisableControlPanel = toggleBitset.test(static_cast(TOGGLE::DISABLECONTROLPANEL)); - // initialise GLFW - if (!glfwInit()) { - std::cout << "Failed to initialise GLFW" << std::endl; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; return false; } @@ -102,16 +99,14 @@ bool ContextD3D12::initialize( // set full screen // glfwWindowHint(GLFW_DECORATED, GLFW_FALSE); - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; + mClientWidth = getMonitorResolution().first; + mClientHeight = getMonitorResolution().second; setWindowSize(windowWidth, windowHeight); if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", - pMonitor, nullptr); + glfwGetPrimaryMonitor(), nullptr); } else { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); @@ -119,7 +114,6 @@ bool ContextD3D12::initialize( if (mWindow == nullptr) { std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); return false; } diff --git a/src/aquarium-optimized/dawn/ContextDawn.cpp b/src/aquarium-optimized/dawn/ContextDawn.cpp index 870bfa7..6c54839 100644 --- a/src/aquarium-optimized/dawn/ContextDawn.cpp +++ b/src/aquarium-optimized/dawn/ContextDawn.cpp @@ -107,8 +107,6 @@ ContextDawn::~ContextDawn() { mSwapchain = nullptr; queue = nullptr; mDevice = nullptr; - - glfwTerminate(); } ContextDawn *ContextDawn::create(BACKENDTYPE backendType) { @@ -151,9 +149,8 @@ bool ContextDawn::initialize( mDisableControlPanel = toggleBitset.test(static_cast(TOGGLE::DISABLECONTROLPANEL)); - // initialise GLFW - if (!glfwInit()) { - std::cout << "Failed to initialise GLFW" << std::endl; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; return false; } @@ -163,16 +160,14 @@ bool ContextDawn::initialize( // set full screen glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; + mClientWidth = getMonitorResolution().first; + mClientHeight = getMonitorResolution().second; setWindowSize(windowWidth, windowHeight); if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", - pMonitor, nullptr); + glfwGetPrimaryMonitor(), nullptr); } else { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); @@ -180,7 +175,6 @@ bool ContextDawn::initialize( if (mWindow == nullptr) { std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); return false; } diff --git a/src/aquarium-optimized/opengl/ContextGL.cpp b/src/aquarium-optimized/opengl/ContextGL.cpp index 8e220f7..acd3ae8 100644 --- a/src/aquarium-optimized/opengl/ContextGL.cpp +++ b/src/aquarium-optimized/opengl/ContextGL.cpp @@ -39,8 +39,6 @@ ContextGL::~ContextGL() { if (!mDisableControlPanel) { destoryImgUI(); } - - glfwTerminate(); } ContextGL *ContextGL::create(BACKENDTYPE backendType) { @@ -52,9 +50,8 @@ bool ContextGL::initialize( const std::bitset(TOGGLE::TOGGLEMAX)> &toggleBitset, int windowWidth, int windowHeight) { - // initialise GLFW - if (!glfwInit()) { - std::cout << "Failed to initialise GLFW" << std::endl; + if (glfwGetError(nullptr) != GLFW_NO_ERROR) { + std::cout << "Failed to initialize GLFW" << std::endl; return false; } @@ -87,17 +84,15 @@ bool ContextGL::initialize( glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); #endif - GLFWmonitor *pMonitor = glfwGetPrimaryMonitor(); - const GLFWvidmode *mode = glfwGetVideoMode(pMonitor); - mClientWidth = mode->width; - mClientHeight = mode->height; + mClientWidth = getMonitorResolution().first; + mClientHeight = getMonitorResolution().second; setWindowSize(windowWidth, windowHeight); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); if (toggleBitset.test(static_cast(TOGGLE::ENABLEFULLSCREENMODE))) { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", - pMonitor, nullptr); + glfwGetPrimaryMonitor(), nullptr); } else { mWindow = glfwCreateWindow(mClientWidth, mClientHeight, "Aquarium", nullptr, nullptr); @@ -105,7 +100,6 @@ bool ContextGL::initialize( if (mWindow == nullptr) { std::cout << "Failed to open GLFW window." << std::endl; - glfwTerminate(); return false; }