Created
August 7, 2016 11:58
-
-
Save TheVice/ea39ac0c21c527efe09c5e2399a01092 to your computer and use it in GitHub Desktop.
Several GLFW windows in own threads
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The MIT License (MIT) | |
* | |
* Copyright (c) 2016 https://github.com/TheVice/ | |
* | |
*/ | |
#include <GL/glew.h> | |
#include <GLFW/glfw3.h> | |
#include <glm/glm.hpp> | |
#ifdef WIN32 | |
#include <tchar.h> | |
#include <windows.h> | |
#endif | |
#ifndef _MSC_VER | |
#include <iostream> | |
#endif | |
#include <map> | |
#include <thread> | |
#include <sstream> | |
static std::ostringstream gErrors; | |
static const glm::vec4 gCornflowerBlue = { 0.392f, 0.584f, 0.929f, 1.0f }; | |
static const GLuint gScreenWidth = 800; | |
static const GLuint gScreenHeight = 600; | |
#ifndef NDEBUG | |
void errorCallback(int aError, const char* aDescription) | |
{ | |
gErrors << aDescription << " (Error #" << aError << ")" << std::endl; | |
} | |
#endif | |
void InitGlfw() | |
{ | |
#ifndef NDEBUG | |
glfwSetErrorCallback(errorCallback); | |
#endif | |
if (!glfwInit()) | |
{ | |
gErrors << "glfwInit() failed" << std::endl; | |
throw std::runtime_error(gErrors.str()); | |
} | |
} | |
void InitGlew() | |
{ | |
const GLenum ret = glewInit(); | |
if (GLEW_OK != ret) | |
{ | |
gErrors << glewGetErrorString(ret) << std::endl; | |
gErrors << "glewInit() failed" << std::endl; | |
throw std::runtime_error(gErrors.str()); | |
} | |
} | |
GLFWwindow* CreateWindowGLFW(const char* aTitle, GLFWmonitor* aMonitor, GLFWwindow* aShare) | |
{ | |
GLFWwindow* window = glfwCreateWindow(gScreenWidth, gScreenHeight, aTitle, aMonitor, aShare); | |
if (!window) | |
{ | |
gErrors << "glfwCreateWindow() failed" << std::endl; | |
throw std::runtime_error(gErrors.str()); | |
} | |
return window; | |
} | |
void ProcessWindow(GLFWwindow* aWindow) | |
{ | |
glfwMakeContextCurrent(aWindow); | |
InitGlew(); | |
glViewport(0, 0, gScreenWidth, gScreenHeight); | |
while (!glfwWindowShouldClose(aWindow)) | |
{ | |
glClearBufferfv(GL_COLOR, 0, &gCornflowerBlue[0]); | |
// | |
glfwSwapBuffers(aWindow); | |
} | |
} | |
#ifndef WIN32 | |
int main(int argc, char** argv) | |
{ | |
(void)argc; | |
(void)argv; | |
#else | |
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) | |
{ | |
(void)hInstance; | |
(void)hPrevInstance; | |
(void)lpCmdLine; | |
(void)nCmdShow; | |
#endif | |
InitGlfw(); | |
std::map<GLFWwindow*, std::thread> windowsAndThreads; | |
// | |
{ | |
GLFWwindow* window1 = CreateWindowGLFW("First Window", nullptr, nullptr); | |
GLFWwindow* window2 = CreateWindowGLFW("Second Window", nullptr, window1); | |
// | |
std::thread windowThread1(ProcessWindow, window1); | |
std::thread windowThread2(ProcessWindow, window2); | |
// | |
auto windowAndThread = std::make_pair<GLFWwindow*, std::thread>(std::move(window1), std::move(windowThread1)); | |
windowsAndThreads.insert(std::move(windowAndThread)); | |
// | |
windowAndThread = std::make_pair<GLFWwindow*, std::thread>(std::move(window2), std::move(windowThread2)); | |
windowsAndThreads.insert(std::move(windowAndThread)); | |
} | |
// | |
bool shouldClose = false; | |
while (!shouldClose) | |
{ | |
for (auto windowAndThread = windowsAndThreads.begin(); windowAndThread != windowsAndThreads.end();) | |
{ | |
glfwPollEvents(); | |
if (glfwWindowShouldClose(windowAndThread->first)) | |
{ | |
windowAndThread->second.join(); | |
glfwDestroyWindow(windowAndThread->first); | |
//#if __cplusplus >= 2011103L | |
windowAndThread = windowsAndThreads.erase(windowAndThread); | |
//#else | |
// windowsAndThreads.erase(windowAndThread++); | |
//#endif | |
} | |
else | |
{ | |
++windowAndThread; | |
} | |
} | |
if (windowsAndThreads.empty()) | |
{ | |
shouldClose = true; | |
} | |
} | |
glfwTerminate(); | |
#ifndef NDEBUG | |
std::string errors = gErrors.str(); | |
if (!errors.empty()) | |
{ | |
#ifdef _MSC_VER | |
OutputDebugStringA(errors.c_str()); | |
#else | |
std::cerr << errors.c_str() << std::endl; | |
#endif | |
} | |
#endif | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment