Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

283 lines (230 sloc) 7.394 kB
/**************************************************************************
*
* Copyright 2011 Jose Fonseca
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**************************************************************************/
#include <iostream>
#include "glproc.hpp"
#include "glws.hpp"
namespace glws {
static LRESULT CALLBACK
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
MINMAXINFO *pMMI;
switch (uMsg) {
case WM_GETMINMAXINFO:
// Allow to create a window bigger than the desktop
pMMI = (MINMAXINFO *)lParam;
pMMI->ptMaxSize.x = 60000;
pMMI->ptMaxSize.y = 60000;
pMMI->ptMaxTrackSize.x = 60000;
pMMI->ptMaxTrackSize.y = 60000;
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
class WglDrawable : public Drawable
{
public:
DWORD dwExStyle;
DWORD dwStyle;
HWND hWnd;
HDC hDC;
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
WglDrawable(const Visual *vis, int width, int height) :
Drawable(vis, width, height)
{
static bool first = TRUE;
RECT rect;
if (first) {
WNDCLASS wc;
memset(&wc, 0, sizeof wc);
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "glretrace";
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
first = FALSE;
}
dwExStyle = 0;
dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
int x = 0, y = 0;
rect.left = x;
rect.top = y;
rect.right = rect.left + width;
rect.bottom = rect.top + height;
AdjustWindowRectEx(&rect, dwStyle, FALSE, dwExStyle);
hWnd = CreateWindowEx(dwExStyle,
"glretrace", /* wc.lpszClassName */
NULL,
dwStyle,
0, /* x */
0, /* y */
rect.right - rect.left, /* width */
rect.bottom - rect.top, /* height */
NULL,
NULL,
NULL,
NULL);
hDC = GetDC(hWnd);
memset(&pfd, 0, sizeof pfd);
pfd.cColorBits = 4;
pfd.cRedBits = 1;
pfd.cGreenBits = 1;
pfd.cBlueBits = 1;
pfd.cAlphaBits = 1;
pfd.cDepthBits = 1;
pfd.cStencilBits = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
if (visual->doubleBuffer) {
pfd.dwFlags |= PFD_DOUBLEBUFFER;
}
iPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, iPixelFormat, &pfd);
}
~WglDrawable() {
ReleaseDC(hWnd, hDC);
DestroyWindow(hWnd);
}
void
resize(int w, int h) {
if (w == width && h == height) {
return;
}
RECT rClient, rWindow;
GetClientRect(hWnd, &rClient);
GetWindowRect(hWnd, &rWindow);
w += (rWindow.right - rWindow.left) - rClient.right;
h += (rWindow.bottom - rWindow.top) - rClient.bottom;
SetWindowPos(hWnd, NULL, rWindow.left, rWindow.top, w, h, SWP_NOMOVE);
Drawable::resize(w, h);
}
void show(void) {
if (visible) {
return;
}
ShowWindow(hWnd, SW_SHOW);
Drawable::show();
}
void swapBuffers(void) {
SwapBuffers(hDC);
// Drain message queue to prevent window from being considered
// non-responsive
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
};
class WglContext : public Context
{
public:
HGLRC hglrc;
WglContext *shareContext;
WglContext(const Visual *vis, Profile prof, WglContext *share) :
Context(vis, prof),
hglrc(0),
shareContext(share)
{}
~WglContext() {
if (hglrc) {
wglDeleteContext(hglrc);
}
}
};
void
init(void) {
/*
* OpenGL library must be loaded by the time we call GDI.
*/
const char * libgl_filename = getenv("TRACE_LIBGL");
if (!libgl_filename) {
libgl_filename = "OPENGL32";
}
__libGlHandle = LoadLibraryA(libgl_filename);
if (!__libGlHandle) {
std::cerr << "error: unable to open " << libgl_filename << "\n";
exit(1);
}
}
void
cleanup(void) {
}
Visual *
createVisual(bool doubleBuffer, Profile profile) {
if (profile != PROFILE_COMPAT) {
return NULL;
}
Visual *visual = new Visual();
visual->doubleBuffer = doubleBuffer;
return visual;
}
Drawable *
createDrawable(const Visual *visual, int width, int height)
{
return new WglDrawable(visual, width, height);
}
Context *
createContext(const Visual *visual, Context *shareContext, Profile profile)
{
if (profile != PROFILE_COMPAT) {
return NULL;
}
return new WglContext(visual, profile, static_cast<WglContext *>(shareContext));
}
bool
makeCurrent(Drawable *drawable, Context *context)
{
if (!drawable || !context) {
return wglMakeCurrent(NULL, NULL);
} else {
WglDrawable *wglDrawable = static_cast<WglDrawable *>(drawable);
WglContext *wglContext = static_cast<WglContext *>(context);
if (!wglContext->hglrc) {
wglContext->hglrc = wglCreateContext(wglDrawable->hDC);
if (!wglContext->hglrc) {
return false;
}
if (wglContext->shareContext) {
wglShareLists(wglContext->shareContext->hglrc,
wglContext->hglrc);
}
}
return wglMakeCurrent(wglDrawable->hDC, wglContext->hglrc);
}
}
bool
processEvents(void) {
// TODO
return true;
}
} /* namespace glws */
Jump to Line
Something went wrong with that request. Please try again.