Would it be possible to split Window.Display from event polling (and expose polling in the public interface)? This could be done via an auto-poll flag (which should be true by default, as not to break the api).
Furthermore it would be *really* nice if I could unbind the current rendercontext, to rebind it again in a different thread.
The first point would separate rendering&input more, and it would become possible to pause rendering (including unnecessary buffer clearing & swapping) when the window is minimized, without automatically also stopping input from being polled (basically resulting in a crash/unresponsive window)
The second point (combined with the first) would make it possible to separate Rendering into a different Thread which make far more sense than having those in the same thread in a multi threading environment (which is something we honestly can't ignore anymore), because rendering has nothing to do with input handling and this way the events could be polled directly in the thread that actually uses the events (which otherwise would have to be sent to the other thread first, possibly requiring extra synchronization).
I really hope you make this possible, as I really like this library, but also need these features.
For a small win32 example of what I want to do, see below:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <GL/gl.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HDC hDC, HGLRC hRC);
void DisableOpenGL(HDC hDC, HGLRC hRC);
volatile bool quit = false;
volatile bool paused = false;
struct GlThreadData
{
HDC hDC;
HGLRC hRC;
};
DWORD WINAPI GlThread(LPVOID arg1)
{
GlThreadData d = *reinterpret_cast<GlThreadData*>(arg1);
HDC hDC = d.hDC;
HGLRC hRC = d.hRC;
float theta = 0.0f;
EnableOpenGL( d.hDC, d.hRC );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
while(!quit)
{
glClear( GL_COLOR_BUFFER_BIT );
glPushMatrix();
glScalef(0.9f,0.9f,0.9f);
glRotatef( theta, 0.0f, 0.0f, 1.0f );
glBegin( GL_TRIANGLES );
glColor3f( 1.0f, 0.0f, 0.0f ); glVertex2f( 0.0f, 1.0f );
glColor3f( 0.0f, 1.0f, 0.0f ); glVertex2f( 0.87f, -0.5f );
glColor3f( 0.0f, 0.0f, 1.0f ); glVertex2f( -0.87f, -0.5f );
glEnd();
glPopMatrix();
SwapBuffers( d.hDC );
if(!paused)
theta += 1.0f;
}
DisableOpenGL( d.hDC, d.hRC );
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
MSG msg;
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = L"MsgPumpThread";
RegisterClass(&wc);
hWnd = CreateWindow(
L"MsgPumpThread", L"Threaded OpenGL / Windows Message Pump",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
0, 0, 300, 300,
NULL, NULL, hInstance, NULL );
PIXELFORMATDESCRIPTOR pfd;
int format;
HDC hDC = GetDC( hWnd );
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 8;
pfd.cDepthBits = 24;
pfd.cStencilBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( hDC, &pfd );
SetPixelFormat( hDC, format, &pfd );
HGLRC hRC = wglCreateContext( hDC );
GlThreadData gtd = { hDC, hRC };
HANDLE hGlThread;
hGlThread=CreateThread(0,0,&GlThread,>d,0,0);
while(!quit)
{
if(!GetMessage(&msg, NULL, 0, 0))
{
quit = true;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
WaitForSingleObject(hGlThread,INFINITE);
wglDeleteContext( hRC );
ReleaseDC( hWnd, hDC );
DestroyWindow( hWnd );
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage( 0 );
return 0;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_SPACE:
paused = !paused;
return 0;
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
}
return 0;
default:
return DefWindowProc( hWnd, message, wParam, lParam );
}
}
void EnableOpenGL(HDC hDC, HGLRC hRC)
{
wglMakeCurrent( hDC, hRC );
}
void DisableOpenGL(HDC hDC, HGLRC hRC)
{
wglMakeCurrent( NULL, NULL );
}