mirror of
https://github.com/leozide/leocad
synced 2025-01-01 06:19:55 +01:00
572 lines
15 KiB
C++
572 lines
15 KiB
C++
#include "lc_global.h"
|
|
#include "opengl.h"
|
|
#include "glwindow.h"
|
|
#include "system.h"
|
|
#include "tools.h"
|
|
#include "resource.h"
|
|
|
|
#ifndef WGL_ARB_extensions_string
|
|
#define WGL_ARB_extensions_string 1
|
|
|
|
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
|
|
|
|
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = NULL;
|
|
|
|
#endif // WGL_ARB_extensions_string
|
|
|
|
#ifndef WGL_ARB_multisample
|
|
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
|
#define WGL_SAMPLES_ARB 0x2042
|
|
#endif
|
|
|
|
#ifndef WGL_ARB_pixel_format
|
|
#define WGL_ARB_pixel_format 1
|
|
|
|
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
|
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
|
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
|
|
#define WGL_ACCELERATION_ARB 0x2003
|
|
#define WGL_NEED_PALETTE_ARB 0x2004
|
|
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
|
|
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
|
|
#define WGL_SWAP_METHOD_ARB 0x2007
|
|
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
|
|
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
|
|
#define WGL_TRANSPARENT_ARB 0x200A
|
|
#define WGL_SHARE_DEPTH_ARB 0x200C
|
|
#define WGL_SHARE_STENCIL_ARB 0x200D
|
|
#define WGL_SHARE_ACCUM_ARB 0x200E
|
|
#define WGL_SUPPORT_GDI_ARB 0x200F
|
|
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
|
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
|
#define WGL_STEREO_ARB 0x2012
|
|
#define WGL_PIXEL_TYPE_ARB 0x2013
|
|
#define WGL_COLOR_BITS_ARB 0x2014
|
|
#define WGL_RED_BITS_ARB 0x2015
|
|
#define WGL_RED_SHIFT_ARB 0x2016
|
|
#define WGL_GREEN_BITS_ARB 0x2017
|
|
#define WGL_GREEN_SHIFT_ARB 0x2018
|
|
#define WGL_BLUE_BITS_ARB 0x2019
|
|
#define WGL_BLUE_SHIFT_ARB 0x201A
|
|
#define WGL_ALPHA_BITS_ARB 0x201B
|
|
#define WGL_ALPHA_SHIFT_ARB 0x201C
|
|
#define WGL_ACCUM_BITS_ARB 0x201D
|
|
#define WGL_ACCUM_RED_BITS_ARB 0x201E
|
|
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
|
|
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
|
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
|
#define WGL_DEPTH_BITS_ARB 0x2022
|
|
#define WGL_STENCIL_BITS_ARB 0x2023
|
|
#define WGL_AUX_BUFFERS_ARB 0x2024
|
|
#define WGL_NO_ACCELERATION_ARB 0x2025
|
|
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
|
|
#define WGL_FULL_ACCELERATION_ARB 0x2027
|
|
#define WGL_SWAP_EXCHANGE_ARB 0x2028
|
|
#define WGL_SWAP_COPY_ARB 0x2029
|
|
#define WGL_SWAP_UNDEFINED_ARB 0x202A
|
|
#define WGL_TYPE_RGBA_ARB 0x202B
|
|
#define WGL_TYPE_COLORINDEX_ARB 0x202C
|
|
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
|
|
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
|
|
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
|
|
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
|
|
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
|
|
|
|
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int* piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
|
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, FLOAT *pfValues);
|
|
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int* piAttributes, int *piValues);
|
|
|
|
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = NULL;
|
|
PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB = NULL;
|
|
PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB = NULL;
|
|
|
|
#endif // WGL_ARB_pixel_format
|
|
|
|
struct GLWindowPrivate
|
|
{
|
|
HGLRC m_hrc;
|
|
CDC* m_pDC;
|
|
CPalette* m_pPal;
|
|
HWND m_hWnd;
|
|
HCURSOR Cursor;
|
|
bool Multisample;
|
|
};
|
|
|
|
// ============================================================================
|
|
|
|
BOOL GLWindowPreTranslateMessage(GLWindow *wnd, MSG *pMsg)
|
|
{
|
|
switch (pMsg->message)
|
|
{
|
|
case WM_PAINT:
|
|
{
|
|
GLWindowPrivate* prv = (GLWindowPrivate*)wnd->GetData();
|
|
PAINTSTRUCT ps;
|
|
BeginPaint(prv->m_hWnd, &ps);
|
|
wnd->OnDraw();
|
|
EndPaint(prv->m_hWnd, &ps);
|
|
} break;
|
|
case WM_SIZE:
|
|
wnd->OnSize(LOWORD(pMsg->lParam), HIWORD(pMsg->lParam));
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
wnd->OnLeftButtonDown((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_LBUTTONUP:
|
|
wnd->OnLeftButtonUp((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_LBUTTONDBLCLK:
|
|
wnd->OnLeftButtonDoubleClick((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_MBUTTONDOWN:
|
|
wnd->OnMiddleButtonDown((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_MBUTTONUP:
|
|
wnd->OnMiddleButtonUp((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_RBUTTONDOWN:
|
|
wnd->OnRightButtonDown((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_RBUTTONUP:
|
|
wnd->OnRightButtonUp((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_MOUSEMOVE:
|
|
wnd->OnMouseMove((SHORT)LOWORD(pMsg->lParam), wnd->GetHeight() - (SHORT)HIWORD(pMsg->lParam) - 1,
|
|
(pMsg->wParam & MK_CONTROL) != 0, (pMsg->wParam & MK_SHIFT) != 0);
|
|
break;
|
|
case WM_ERASEBKGND:
|
|
return TRUE;
|
|
case WM_CREATE:
|
|
wnd->OnInitialUpdate();
|
|
break;
|
|
case WM_DESTROY:
|
|
wnd->DestroyContext();
|
|
return FALSE;
|
|
break;
|
|
case WM_SETCURSOR:
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)wnd->GetData();
|
|
|
|
if (prv->Cursor)
|
|
{
|
|
SetCursor(prv->Cursor);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
} break;
|
|
case WM_PALETTECHANGED:
|
|
if ((HWND)pMsg->wParam == pMsg->hwnd) // Responding to own message.
|
|
break;
|
|
case WM_QUERYNEWPALETTE:
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)wnd->GetData();
|
|
|
|
if (prv->m_pPal)
|
|
{
|
|
prv->m_pDC->SelectPalette(prv->m_pPal, FALSE);
|
|
if (prv->m_pDC->RealizePalette() != 0)
|
|
{
|
|
// Some colors changed, so we need to do a repaint.
|
|
InvalidateRect(prv->m_hWnd, NULL, TRUE);
|
|
}
|
|
}
|
|
} break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
LRESULT CALLBACK GLWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static CMapPtrToPtr WindowMap;
|
|
GLWindow *wnd;
|
|
|
|
if (uMsg == WM_CREATE)
|
|
{
|
|
LPCREATESTRUCT cs = (LPCREATESTRUCT)lParam;
|
|
|
|
wnd = (GLWindow*)cs->lpCreateParams;
|
|
wnd->CreateFromWindow(hwnd);
|
|
|
|
WindowMap.SetAt(hwnd, wnd);
|
|
}
|
|
|
|
wnd = (GLWindow*)WindowMap[hwnd];
|
|
|
|
if (wnd)
|
|
{
|
|
MSG msg;
|
|
msg.hwnd = hwnd;
|
|
msg.message = uMsg;
|
|
msg.wParam = wParam;
|
|
msg.lParam = lParam;
|
|
|
|
GLWindowPreTranslateMessage(wnd, &msg);
|
|
|
|
if (uMsg == WM_DESTROY)
|
|
{
|
|
WindowMap.RemoveKey(hwnd);
|
|
}
|
|
}
|
|
|
|
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
|
}
|
|
|
|
static LRESULT CALLBACK TempWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
if (uMsg != WM_CREATE)
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
HDC hDC = GetDC(hWnd);
|
|
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
|
|
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
pfd.cColorBits = 24;
|
|
pfd.cDepthBits = 24;
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
int PixelFormat = ChoosePixelFormat(hDC, &pfd);
|
|
if (PixelFormat == 0)
|
|
return 0;
|
|
|
|
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
|
|
return 0;
|
|
|
|
HGLRC hGLRC = wglCreateContext(hDC);
|
|
wglMakeCurrent(hDC, hGLRC);
|
|
|
|
const GLubyte* Extensions;
|
|
|
|
wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
|
|
|
|
if (wglGetExtensionsStringARB)
|
|
Extensions = (GLubyte*)wglGetExtensionsStringARB(wglGetCurrentDC());
|
|
else
|
|
Extensions = glGetString(GL_EXTENSIONS);
|
|
|
|
GL_InitializeSharedExtensions();
|
|
|
|
if (GL_ExtensionSupported(Extensions, "WGL_ARB_pixel_format"))
|
|
{
|
|
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
|
wglGetPixelFormatAttribfvARB = (PFNWGLGETPIXELFORMATATTRIBFVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribfvARB");
|
|
wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)wglGetProcAddress("wglGetPixelFormatAttribivARB");
|
|
}
|
|
|
|
wglMakeCurrent(NULL, NULL);
|
|
wglDeleteContext(hGLRC);
|
|
|
|
ReleaseDC(hWnd, hDC);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void GL_InitializeExtensions()
|
|
{
|
|
HINSTANCE hInstance;
|
|
WNDCLASS wc;
|
|
|
|
hInstance = GetModuleHandle(NULL);
|
|
|
|
wc.style = CS_OWNDC;
|
|
wc.lpfnWndProc = TempWindowProc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = "LeoCADGLTempWindow";
|
|
|
|
RegisterClass(&wc);
|
|
|
|
HWND hWnd = CreateWindow(wc.lpszClassName, "LeoCAD Temp Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
|
|
|
|
if (hWnd)
|
|
DestroyWindow(hWnd);
|
|
}
|
|
|
|
// ============================================================================
|
|
// GLWindow class
|
|
|
|
GLWindow::GLWindow(GLWindow *share)
|
|
{
|
|
m_pShare = share;
|
|
m_pData = (GLWindowPrivate*)malloc(sizeof(GLWindowPrivate));
|
|
memset(m_pData, 0, sizeof(GLWindowPrivate));
|
|
}
|
|
|
|
GLWindow::~GLWindow()
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
delete prv->m_pDC;
|
|
|
|
free(m_pData);
|
|
}
|
|
|
|
bool GLWindow::CreateFromWindow(void* data)
|
|
{
|
|
GLWindowPrivate* prv = (GLWindowPrivate*)m_pData;
|
|
|
|
prv->m_hWnd = (HWND)data;
|
|
prv->m_pDC = new CClientDC(CWnd::FromHandle(prv->m_hWnd));
|
|
ASSERT(prv->m_pDC != NULL);
|
|
|
|
// Fill in the Pixel Format Descriptor
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
|
|
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
pfd.cColorBits = 24;
|
|
pfd.cDepthBits = 24;
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
int PixelFormat = 0;
|
|
int AASamples = Sys_ProfileLoadInt("Default", "AASamples", 1);
|
|
|
|
if (wglChoosePixelFormatARB && AASamples > 1)
|
|
{
|
|
// Choose a Pixel Format Descriptor (PFD) with multisampling support.
|
|
int iAttributes[] =
|
|
{
|
|
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
|
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
|
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
|
WGL_COLOR_BITS_ARB, 24,
|
|
WGL_DEPTH_BITS_ARB, 24,
|
|
WGL_STENCIL_BITS_ARB, 0,
|
|
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
|
|
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
|
WGL_SAMPLES_ARB, AASamples,
|
|
0, 0
|
|
};
|
|
float fAttributes[] = {0,0};
|
|
UINT NumFormats;
|
|
int MultisamplePixelFormat;
|
|
|
|
int Status = wglChoosePixelFormatARB(prv->m_pDC->m_hDC, iAttributes, fAttributes, 1, &MultisamplePixelFormat, &NumFormats);
|
|
|
|
if (Status && NumFormats > 0)
|
|
{
|
|
PixelFormat = MultisamplePixelFormat;
|
|
prv->Multisample = true;
|
|
}
|
|
}
|
|
|
|
if (!PixelFormat)
|
|
PixelFormat = ChoosePixelFormat(prv->m_pDC->m_hDC, &pfd);
|
|
|
|
if (!PixelFormat)
|
|
return false;
|
|
|
|
if (!SetPixelFormat(prv->m_pDC->m_hDC, PixelFormat, &pfd))
|
|
return false;
|
|
|
|
prv->m_pPal = new CPalette;
|
|
|
|
if (CreateRGBPalette(prv->m_pDC->m_hDC, &prv->m_pPal))
|
|
{
|
|
prv->m_pDC->SelectPalette(prv->m_pPal, FALSE);
|
|
prv->m_pDC->RealizePalette();
|
|
}
|
|
else
|
|
{
|
|
delete prv->m_pPal;
|
|
prv->m_pPal = NULL;
|
|
}
|
|
|
|
// Create a rendering context.
|
|
prv->m_hrc = wglCreateContext(prv->m_pDC->m_hDC);
|
|
if (!prv->m_hrc)
|
|
return false;
|
|
|
|
if (m_pShare)
|
|
{
|
|
GLWindowPrivate *share = (GLWindowPrivate*)m_pShare->m_pData;
|
|
wglShareLists(share->m_hrc, prv->m_hrc);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GLWindow::CreateFromBitmap(void* Data)
|
|
{
|
|
GLWindowPrivate* prv = (GLWindowPrivate*)m_pData;
|
|
|
|
prv->m_pDC = new CDC;
|
|
prv->m_pDC->Attach((HDC)Data);
|
|
ASSERT(prv->m_pDC != NULL);
|
|
|
|
// Fill in the Pixel Format Descriptor
|
|
PIXELFORMATDESCRIPTOR pfd;
|
|
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
|
|
|
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
|
pfd.nVersion = 1;
|
|
pfd.dwFlags = PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI;
|
|
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
pfd.cColorBits = 24;
|
|
pfd.cDepthBits = 16;
|
|
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
|
|
int nPixelFormat = ChoosePixelFormat(prv->m_pDC->m_hDC, &pfd);
|
|
if (nPixelFormat == 0)
|
|
return false;
|
|
|
|
if (!SetPixelFormat(prv->m_pDC->m_hDC, nPixelFormat, &pfd))
|
|
return false;
|
|
|
|
prv->m_pPal = new CPalette;
|
|
|
|
if (CreateRGBPalette(prv->m_pDC->m_hDC, &prv->m_pPal))
|
|
{
|
|
prv->m_pDC->SelectPalette(prv->m_pPal, FALSE);
|
|
prv->m_pDC->RealizePalette();
|
|
}
|
|
else
|
|
{
|
|
delete prv->m_pPal;
|
|
prv->m_pPal = NULL;
|
|
}
|
|
|
|
// Create a rendering context.
|
|
prv->m_hrc = wglCreateContext(prv->m_pDC->m_hDC);
|
|
if (!prv->m_hrc)
|
|
return false;
|
|
|
|
if (m_pShare)
|
|
{
|
|
GLWindowPrivate *share = (GLWindowPrivate*)m_pShare->m_pData;
|
|
wglShareLists(share->m_hrc, prv->m_hrc);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GLWindow::DestroyContext()
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
if (prv->m_pPal)
|
|
{
|
|
CPalette palDefault;
|
|
palDefault.CreateStockObject(DEFAULT_PALETTE);
|
|
prv->m_pDC->SelectPalette(&palDefault, FALSE);
|
|
delete prv->m_pPal;
|
|
prv->m_pPal = NULL;
|
|
}
|
|
|
|
if (prv->m_hrc)
|
|
wglDeleteContext(prv->m_hrc);
|
|
prv->m_hrc = NULL;
|
|
|
|
if (prv->m_pDC)
|
|
delete prv->m_pDC;
|
|
prv->m_pDC = NULL;
|
|
}
|
|
|
|
void GLWindow::OnInitialUpdate()
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
MakeCurrent();
|
|
|
|
if (prv->Multisample)
|
|
glEnable(GL_MULTISAMPLE_ARB);
|
|
}
|
|
|
|
bool GLWindow::MakeCurrent()
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
if (prv->m_pPal)
|
|
{
|
|
prv->m_pDC->SelectPalette(prv->m_pPal, FALSE);
|
|
prv->m_pDC->RealizePalette();
|
|
}
|
|
|
|
return (wglMakeCurrent(prv->m_pDC->m_hDC, prv->m_hrc) != 0);
|
|
}
|
|
|
|
void GLWindow::SwapBuffers()
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
::SwapBuffers(prv->m_pDC->m_hDC);
|
|
}
|
|
|
|
void GLWindow::Redraw(bool ForceRedraw)
|
|
{
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
InvalidateRect(prv->m_hWnd, NULL, FALSE);
|
|
|
|
if (ForceRedraw)
|
|
UpdateWindow(prv->m_hWnd);
|
|
}
|
|
|
|
void GLWindow::CaptureMouse()
|
|
{
|
|
GLWindowPrivate* prv = (GLWindowPrivate*)m_pData;
|
|
SetCapture(prv->m_hWnd);
|
|
}
|
|
|
|
void GLWindow::ReleaseMouse()
|
|
{
|
|
ReleaseCapture();
|
|
}
|
|
|
|
void GLWindow::SetCursor(LC_CURSOR_TYPE Cursor)
|
|
{
|
|
const UINT CursorResources[LC_CURSOR_COUNT] =
|
|
{
|
|
0, // LC_CURSOR_DEFAULT
|
|
IDC_BRICK, // LC_CURSOR_BRICK
|
|
IDC_LIGHT, // LC_CURSOR_LIGHT
|
|
IDC_SPOTLIGHT, // LC_CURSOR_SPOTLIGHT
|
|
IDC_CAMERA, // LC_CURSOR_CAMERA
|
|
IDC_SELECT, // LC_CURSOR_SELECT
|
|
IDC_SELECT_GROUP, // LC_CURSOR_SELECT_GROUP
|
|
IDC_MOVE, // LC_CURSOR_MOVE
|
|
IDC_ROTATE, // LC_CURSOR_ROTATE
|
|
IDC_ROTX, // LC_CURSOR_ROTATEX
|
|
IDC_ROTY, // LC_CURSOR_ROTATEY
|
|
IDC_ERASER, // LC_CURSOR_DELETE
|
|
IDC_PAINT, // LC_CURSOR_PAINT
|
|
IDC_ZOOM, // LC_CURSOR_ZOOM
|
|
IDC_ZOOM_REGION, // LC_CURSOR_ZOOM_REGION
|
|
IDC_PAN, // LC_CURSOR_PAN
|
|
IDC_ROLL, // LC_CURSOR_ROLL
|
|
IDC_ANGLE, // LC_CURSOR_ROTATE_VIEW
|
|
};
|
|
|
|
GLWindowPrivate *prv = (GLWindowPrivate*)m_pData;
|
|
|
|
if (CursorResources[Cursor])
|
|
prv->Cursor = AfxGetApp()->LoadCursor(CursorResources[Cursor]);
|
|
else
|
|
prv->Cursor = NULL;
|
|
|
|
::SetCursor(prv->Cursor);
|
|
}
|