X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6a1120ad4cc05520f989449ffc953a217782af72..d59efe01ea62f90077c3e43db08bbfbce4f9f544:/utils/glcanvas/win/glcanvas.cpp diff --git a/utils/glcanvas/win/glcanvas.cpp b/utils/glcanvas/win/glcanvas.cpp index 252bcb8c0c..bbd7d026b9 100644 --- a/utils/glcanvas/win/glcanvas.cpp +++ b/utils/glcanvas/win/glcanvas.cpp @@ -23,36 +23,57 @@ #include #endif -#include "GL/gl.h" +#include #include "glcanvas.h" +wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass"); + +LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + /* * GLContext implementation */ -wxGLContext::wxGLContext(bool isRGB, wxWindow *win, const wxPalette& palette) +wxGLContext::wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette) { m_window = win; - m_hDC = (WXHDC) ::GetDC((HWND) win->GetHWND()); - - SetupPixelFormat(); - SetupPalette(palette); + m_hDC = win->GetHDC(); m_glContext = wglCreateContext((HDC) m_hDC); + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); + wglMakeCurrent((HDC) m_hDC, m_glContext); } +wxGLContext::wxGLContext( + bool isRGB, wxGLCanvas *win, + const wxPalette& palette, + const wxGLContext *other /* for sharing display lists */ +) +{ + m_window = win; + + m_hDC = win->GetHDC(); + + m_glContext = wglCreateContext((HDC) m_hDC); + wxCHECK_RET( m_glContext, "Couldn't create OpenGl context" ); + + if( other != 0 ) + wglShareLists( other->m_glContext, m_glContext ); + + wglMakeCurrent((HDC) m_hDC, m_glContext); +} + wxGLContext::~wxGLContext() { if (m_glContext) { wglMakeCurrent(NULL, NULL); - wglDeleteContext(m_glContext); + wglDeleteContext(m_glContext); } - - ::ReleaseDC((HWND) m_window->GetHWND(), (HDC) m_hDC); } void wxGLContext::SwapBuffers() @@ -92,7 +113,164 @@ void wxGLContext::SetColour(const char *colour) } } -void wxGLContext::SetupPixelFormat() // (HDC hDC) + +/* + * wxGLCanvas implementation + */ + +IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) + +BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) + EVT_SIZE(wxGLCanvas::OnSize) + EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged) + EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette) +END_EVENT_TABLE() + +wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, + int *attribList /* not used yet! */, const wxPalette& palette): + wxScrolledWindow(parent, id, pos, size, style, name) +{ + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette); +} + +wxGLCanvas::wxGLCanvas( wxWindow *parent, + const wxGLContext *shared, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name, + int *attribList, const wxPalette& palette ) + : wxScrolledWindow() +// : wxScrolledWindow(parent, id, pos, size, style, name) +{ + bool ret = Create(parent, id, pos, size, style, name); + + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } + + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + + SetupPixelFormat(); + SetupPalette(palette); + + m_glContext = new wxGLContext(TRUE, this, palette, shared ); +} + +wxGLCanvas::~wxGLCanvas() +{ + if (m_glContext) + delete m_glContext; + + ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); +} + +// Replaces wxWindow::Create functionality, since we need to use a different window class +bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, const wxSize& size, long style, const wxString& name) +{ + static bool registeredGLCanvasClass = FALSE; + + // We have to register a special window class because we need + // the CS_OWNDC style for GLCanvas. + +/* + From Angel Popov + + Here are two snips from a dicussion in the OpenGL Gamedev list that explains + how this problem can be fixed: + + "There are 5 common DCs available in Win95. These are aquired when you call + GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. + OWNDC flagged windows do not get their DC from the common DC pool, the issue + is they require 800 bytes each from the limited 64Kb local heap for GDI." + + "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps + do), Win95 will actually "steal" it from you. MakeCurrent fails, + apparently, because Windows re-assigns the HDC to a different window. The + only way to prevent this, the only reliable means, is to set CS_OWNDC." +*/ + + if (!registeredGLCanvasClass) + { + WNDCLASS wndclass; + + static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; + + // the fields which are common to all classes + wndclass.lpfnWndProc = (WNDPROC)wxWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for? + wndclass.hInstance = wxhInstance; + wndclass.hIcon = (HICON) NULL; + wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); + wndclass.lpszMenuName = NULL; + + // Register the GLCanvas class name + wndclass.hbrBackground = (HBRUSH)NULL; + wndclass.lpszClassName = wxGLCanvasClassName; + wndclass.style = styleNormal; + + if ( !RegisterClass(&wndclass) ) + { + wxLogLastError("RegisterClass(wxGLCanvasClass)"); + + return FALSE; + } + registeredGLCanvasClass = TRUE; + } + + wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); + + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; + + parent->AddChild(this); + + DWORD msflags = 0; + if ( style & wxBORDER ) + msflags |= WS_BORDER; + if ( style & wxTHICK_FRAME ) + msflags |= WS_THICKFRAME; + + msflags |= WS_CHILD | WS_VISIBLE; + if ( style & wxCLIP_CHILDREN ) + msflags |= WS_CLIPCHILDREN; + + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + { + msflags |= WS_BORDER; + } + + // calculate the value to return from WM_GETDLGCODE handler + if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + { + // want everything: i.e. all keys and WM_CHAR message + m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | + DLGC_WANTTAB | DLGC_WANTMESSAGE; + } + + MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, + pos.x, pos.y, + WidthDefault(size.x), HeightDefault(size.y), + msflags, NULL, exStyle); + + return TRUE; + +} + +void wxGLCanvas::SetupPixelFormat() // (HDC hDC) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size */ @@ -130,7 +308,7 @@ void wxGLContext::SetupPixelFormat() // (HDC hDC) } } -void wxGLContext::SetupPalette(const wxPalette& palette) +void wxGLCanvas::SetupPalette(const wxPalette& palette) { int pixelFormat = GetPixelFormat((HDC) m_hDC); PIXELFORMATDESCRIPTOR pfd; @@ -159,7 +337,7 @@ void wxGLContext::SetupPalette(const wxPalette& palette) } } -wxPalette wxGLContext::CreateDefaultPalette() +wxPalette wxGLCanvas::CreateDefaultPalette() { PIXELFORMATDESCRIPTOR pfd; int paletteSize; @@ -201,32 +379,6 @@ wxPalette wxGLContext::CreateDefaultPalette() return palette; } -/* - * wxGLCanvas implementation - */ - -IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) - -BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) - EVT_SIZE(wxGLCanvas::OnSize) - EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged) - EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette) -END_EVENT_TABLE() - -wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *attribList /* not used yet! */, const wxPalette& palette): - wxScrolledWindow(parent, id, pos, size, style, name) -{ - m_glContext = new wxGLContext(TRUE, this, palette); -} - -wxGLCanvas::~wxGLCanvas() -{ - if (m_glContext) - delete m_glContext; -} - void wxGLCanvas::SwapBuffers() { if (m_glContext) @@ -269,10 +421,10 @@ void wxGLCanvas::SetColour(const char *colour) void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) { /* realize palette if this is the current window */ - if (m_glContext && m_glContext->GetPalette()->Ok()) { - ::UnrealizeObject((HPALETTE) m_glContext->GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) m_glContext->GetHDC(), (HPALETTE) m_glContext->GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) m_glContext->GetHDC()); + if ( GetPalette()->Ok() ) { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); Refresh(); event.SetPaletteRealized(TRUE); } @@ -284,14 +436,12 @@ void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) { /* realize palette if this is *not* the current window */ - if ( m_glContext && - m_glContext->GetPalette() && - m_glContext->GetPalette()->Ok() && - (this != event.GetChangedWindow()) ) + if ( GetPalette() && + GetPalette()->Ok() && (this != event.GetChangedWindow()) ) { - ::UnrealizeObject((HPALETTE) m_glContext->GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) m_glContext->GetHDC(), (HPALETTE) m_glContext->GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) m_glContext->GetHDC()); + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); Refresh(); } }