X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/02761f6cd478e3c2c97cf6f93442747f7b029833..22892deac99166c7a125b2f866d436fdf76703c0:/src/msw/glcanvas.cpp diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 0f4ee4b78b..cefcac96a9 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -9,6 +9,14 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #include "wx/wxprec.h" #if defined(__BORLANDC__) @@ -18,8 +26,6 @@ #if wxUSE_GLCANVAS #ifndef WX_PRECOMP - #include "wx/frame.h" - #include "wx/settings.h" #include "wx/intl.h" #include "wx/log.h" #include "wx/app.h" @@ -28,18 +34,22 @@ #include "wx/msw/private.h" -// DLL options compatibility check: -#include "wx/build.h" -WX_CHECK_BUILD_OPTIONS("wxGL") - #include "wx/glcanvas.h" -#if GL_EXT_vertex_array +// from src/msw/window.cpp +LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, + WPARAM wParam, LPARAM lParam); + +#ifdef GL_EXT_vertex_array #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) name #else #define WXUNUSED_WITHOUT_GL_EXT_vertex_array(name) WXUNUSED(name) #endif +// ---------------------------------------------------------------------------- +// libraries +// ---------------------------------------------------------------------------- + /* The following two compiler directives are specific to the Microsoft Visual C++ family of compilers @@ -62,12 +72,16 @@ WX_CHECK_BUILD_OPTIONS("wxGL") # pragma comment( lib, "glu32" ) #endif +// ---------------------------------------------------------------------------- +// constants +// ---------------------------------------------------------------------------- static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass"); static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR"); -LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam); +// ============================================================================ +// implementation +// ============================================================================ // ---------------------------------------------------------------------------- // wxGLModule is responsible for unregistering wxGLCanvasClass Windows class @@ -100,29 +114,12 @@ bool wxGLModule::ms_registeredGLClasses = false; /* static */ bool wxGLModule::RegisterClasses() { - if (ms_registeredGLClasses) + if ( ms_registeredGLClasses ) return true; // 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." - */ - + // style for GLCanvas: some OpenGL drivers are buggy and don't work with + // windows without this style WNDCLASS wndclass; // the fields which are common to all classes @@ -179,167 +176,80 @@ void wxGLModule::UnregisterClasses() } } -/* - * GLContext implementation - */ - -wxGLContext::wxGLContext(bool WXUNUSED(isRGB), wxGLCanvas *win, const wxPalette& WXUNUSED(palette)) -{ - m_window = win; - - m_hDC = win->GetHDC(); - - m_glContext = wglCreateContext((HDC) m_hDC); - wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") ); +// ---------------------------------------------------------------------------- +// wxGLContext +// ---------------------------------------------------------------------------- - wglMakeCurrent((HDC) m_hDC, m_glContext); -} +IMPLEMENT_CLASS(wxGLContext, wxObject) -wxGLContext::wxGLContext( - bool WXUNUSED(isRGB), wxGLCanvas *win, - const wxPalette& WXUNUSED(palette), - const wxGLContext *other /* for sharing display lists */ - ) +wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext* other) { - m_window = win; - - m_hDC = win->GetHDC(); + m_glContext = wglCreateContext(win->GetHDC()); + wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") ); - m_glContext = wglCreateContext((HDC) m_hDC); - wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") ); - - if( other != 0 ) - wglShareLists( other->m_glContext, m_glContext ); - - wglMakeCurrent((HDC) m_hDC, m_glContext); + if ( other ) + { + if ( !wglShareLists(other->m_glContext, m_glContext) ) + wxLogLastError(_T("wglShareLists")); + } } wxGLContext::~wxGLContext() { - if (m_glContext) - { - wglMakeCurrent(NULL, NULL); + // note that it's ok to delete the context even if it's the current one wglDeleteContext(m_glContext); - } -} - -void wxGLContext::SwapBuffers() -{ - if (m_glContext) - { - wglMakeCurrent((HDC) m_hDC, m_glContext); - ::SwapBuffers((HDC) m_hDC); //blits the backbuffer into DC - } -} - -void wxGLContext::SetCurrent() -{ - if (m_glContext) - { - wglMakeCurrent((HDC) m_hDC, m_glContext); - } } -void wxGLContext::SetColour(const wxChar *colour) +bool wxGLContext::SetCurrent(const wxGLCanvas& win) const { - wxColour col = wxTheColourDatabase->Find(colour); - if (col.Ok()) + if ( !wglMakeCurrent(win.GetHDC(), m_glContext) ) { - float r = (float)(col.Red()/256.0); - float g = (float)(col.Green()/256.0); - float b = (float)(col.Blue()/256.0); - glColor3f( r, g, b); + wxLogLastError(_T("wglMakeCurrent")); + return false; } + return true; } - -/* - * wxGLCanvas implementation - */ +// ============================================================================ +// wxGLCanvas +// ============================================================================ IMPLEMENT_CLASS(wxGLCanvas, wxWindow) BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow) - 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, const wxPalette& palette) : wxWindow() -{ - m_glContext = (wxGLContext*) NULL; - - bool ret = Create(parent, id, pos, size, style, name); - - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); - } - - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); - - SetupPixelFormat(attribList); - SetupPalette(palette); - - m_glContext = new wxGLContext(true, this, palette); -} +// ---------------------------------------------------------------------------- +// wxGLCanvas construction +// ---------------------------------------------------------------------------- -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 ) - : wxWindow() +void wxGLCanvas::Init() { - m_glContext = (wxGLContext*) NULL; - - bool ret = Create(parent, id, pos, size, style, name); - - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); - } - - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); - - SetupPixelFormat(attribList); - SetupPalette(palette); - - m_glContext = new wxGLContext(true, this, palette, shared ); +#if WXWIN_COMPATIBILITY_2_8 + m_glContext = NULL; +#endif + m_hDC = NULL; } -// Not very useful for wxMSW, but this is to be wxGTK compliant - -wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *attribList, const wxPalette& palette ): - wxWindow() +wxGLCanvas::wxGLCanvas(wxWindow *parent, + wxWindowID id, + const int *attribList, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name, + const wxPalette& palette) { - m_glContext = (wxGLContext*) NULL; - - bool ret = Create(parent, id, pos, size, style, name); - - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); - } - - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + Init(); - SetupPixelFormat(attribList); - SetupPalette(palette); - - wxGLContext *sharedContext=0; - if (shared) sharedContext=shared->GetContext(); - m_glContext = new wxGLContext(true, this, palette, sharedContext ); + (void)Create(parent, id, pos, size, style, name, attribList, palette); } wxGLCanvas::~wxGLCanvas() { - delete m_glContext; - - ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC); + ::ReleaseDC(GetHwnd(), m_hDC); } // Replaces wxWindow::Create functionality, since we need to use a different @@ -349,7 +259,9 @@ bool wxGLCanvas::Create(wxWindow *parent, const wxPoint& pos, const wxSize& size, long style, - const wxString& name) + const wxString& name, + const int *attribList, + const wxPalette& palette) { wxCHECK_MSG( parent, false, wxT("can't create wxWindow without parent") ); @@ -365,170 +277,265 @@ bool wxGLCanvas::Create(wxWindow *parent, parent->AddChild(this); - DWORD msflags = 0; - /* A general rule with OpenGL and Win32 is that any window that will have a HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS. You can find references about this within the knowledge base and most OpenGL books that contain the wgl function descriptions. */ - WXDWORD exStyle = 0; - msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; - msflags |= MSWGetStyle(style, & exStyle) ; + DWORD msflags = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + msflags |= MSWGetStyle(style, &exStyle); + + if ( !MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle) ) + return false; + + m_hDC = ::GetDC(GetHwnd()); + if ( !m_hDC ) + return false; + + if ( !DoSetup(attribList) ) + return false; + +#if wxUSE_PALETTE + if ( !SetupPalette(palette) ) + return false; +#else // !wxUSE_PALETTE + wxUnusedVar(palette); +#endif // wxUSE_PALETTE/!wxUSE_PALETTE + + return true; +} + +// ---------------------------------------------------------------------------- +// operations +// ---------------------------------------------------------------------------- + +bool wxGLCanvas::SwapBuffers() +{ + if ( !::SwapBuffers(m_hDC) ) + { + wxLogLastError(_T("SwapBuffers")); + return false; + } - return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle); + return true; } -static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList) +// ---------------------------------------------------------------------------- +// pixel format stuff +// ---------------------------------------------------------------------------- + +static void +AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, const int *attribList) { - if (attribList) { + if ( !attribList ) + return; + + // remove default attributes pfd.dwFlags &= ~PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_COLORINDEX; - pfd.cColorBits = 0; - int arg=0; - while( (attribList[arg]!=0) ) + for ( int arg = 0; attribList[arg]; ) { - switch( attribList[arg++] ) - { - case WX_GL_RGBA: - pfd.iPixelType = PFD_TYPE_RGBA; - break; - case WX_GL_BUFFER_SIZE: - pfd.cColorBits = (BYTE)attribList[arg++]; - break; - case WX_GL_LEVEL: - // this member looks like it may be obsolete - if (attribList[arg] > 0) { - pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE; - } else if (attribList[arg] < 0) { - pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE; - } else { - pfd.iLayerType = (BYTE)PFD_MAIN_PLANE; - } - arg++; - break; - case WX_GL_DOUBLEBUFFER: - pfd.dwFlags |= PFD_DOUBLEBUFFER; - break; - case WX_GL_STEREO: - pfd.dwFlags |= PFD_STEREO; - break; - case WX_GL_AUX_BUFFERS: - pfd.cAuxBuffers = (BYTE)attribList[arg++]; - break; - case WX_GL_MIN_RED: - pfd.cColorBits = (BYTE)(pfd.cColorBits + (pfd.cRedBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_GREEN: - pfd.cColorBits = (BYTE)(pfd.cColorBits + (pfd.cGreenBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_BLUE: - pfd.cColorBits = (BYTE)(pfd.cColorBits + (pfd.cBlueBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_ALPHA: - // doesn't count in cColorBits - pfd.cAlphaBits = (BYTE)attribList[arg++]; - break; - case WX_GL_DEPTH_SIZE: - pfd.cDepthBits = (BYTE)attribList[arg++]; - break; - case WX_GL_STENCIL_SIZE: - pfd.cStencilBits = (BYTE)attribList[arg++]; - break; - case WX_GL_MIN_ACCUM_RED: - pfd.cAccumBits = (BYTE)(pfd.cAccumBits + (pfd.cAccumRedBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_ACCUM_GREEN: - pfd.cAccumBits = (BYTE)(pfd.cAccumBits + (pfd.cAccumGreenBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_ACCUM_BLUE: - pfd.cAccumBits = (BYTE)(pfd.cAccumBits + (pfd.cAccumBlueBits = (BYTE)attribList[arg++])); - break; - case WX_GL_MIN_ACCUM_ALPHA: - pfd.cAccumBits = (BYTE)(pfd.cAccumBits + (pfd.cAccumAlphaBits = (BYTE)attribList[arg++])); - break; - default: - break; - } + switch ( attribList[arg++] ) + { + case WX_GL_RGBA: + pfd.iPixelType = PFD_TYPE_RGBA; + break; + + case WX_GL_BUFFER_SIZE: + pfd.cColorBits = attribList[arg++]; + break; + + case WX_GL_LEVEL: + // this member looks like it may be obsolete + if ( attribList[arg] > 0 ) + pfd.iLayerType = PFD_OVERLAY_PLANE; + else if ( attribList[arg] < 0 ) + pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE; + else + pfd.iLayerType = PFD_MAIN_PLANE; + arg++; + break; + + case WX_GL_DOUBLEBUFFER: + pfd.dwFlags |= PFD_DOUBLEBUFFER; + break; + + case WX_GL_STEREO: + pfd.dwFlags |= PFD_STEREO; + break; + + case WX_GL_AUX_BUFFERS: + pfd.cAuxBuffers = attribList[arg++]; + break; + + case WX_GL_MIN_RED: + pfd.cColorBits += (pfd.cRedBits = attribList[arg++]); + break; + + case WX_GL_MIN_GREEN: + pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]); + break; + + case WX_GL_MIN_BLUE: + pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]); + break; + + case WX_GL_MIN_ALPHA: + // doesn't count in cColorBits + pfd.cAlphaBits = attribList[arg++]; + break; + + case WX_GL_DEPTH_SIZE: + pfd.cDepthBits = attribList[arg++]; + break; + + case WX_GL_STENCIL_SIZE: + pfd.cStencilBits = attribList[arg++]; + break; + + case WX_GL_MIN_ACCUM_RED: + pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]); + break; + + case WX_GL_MIN_ACCUM_GREEN: + pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]); + break; + + case WX_GL_MIN_ACCUM_BLUE: + pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]); + break; + + case WX_GL_MIN_ACCUM_ALPHA: + pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]); + break; + } } - } } -void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) +/* static */ +int +wxGLCanvas::ChooseMatchingPixelFormat(HDC hdc, + const int *attribList, + PIXELFORMATDESCRIPTOR *ppfd) { - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ + // default neutral pixel format + PIXELFORMATDESCRIPTOR pfd = + { + sizeof(PIXELFORMATDESCRIPTOR), // size + 1, // version PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* preferred color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ + PFD_DOUBLEBUFFER, // use double-buffering by default + PFD_TYPE_RGBA, // default pixel type + 0, // preferred color depth (don't care) + 0, 0, 0, 0, 0, 0, // color bits and shift bits (ignored) + 0, 0, // alpha bits and shift (ignored) + 0, // accumulation total bits + 0, 0, 0, 0, // accumulator RGBA bits (not used) + 16, // depth buffer + 0, // no stencil buffer + 0, // no auxiliary buffers + PFD_MAIN_PLANE, // main layer + 0, // reserved + 0, 0, 0, // no layer, visible, damage masks }; - AdjustPFDForAttributes(pfd, attribList); + if ( !ppfd ) + ppfd = &pfd; + else + *ppfd = pfd; - int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); - if (pixelFormat == 0) { - wxLogLastError(_T("ChoosePixelFormat")); - } - else { - if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) { - wxLogLastError(_T("SetPixelFormat")); - } - } + AdjustPFDForAttributes(*ppfd, attribList); + + return ::ChoosePixelFormat(hdc, ppfd); +} + +/* static */ +bool wxGLCanvasBase::IsDisplaySupported(const int *attribList) +{ + // We need a device context to test the pixel format, so get one + // for the root window. + return wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) > 0; } -void wxGLCanvas::SetupPalette(const wxPalette& palette) +bool wxGLCanvas::DoSetup(const int *attribList) { - int pixelFormat = GetPixelFormat((HDC) m_hDC); PIXELFORMATDESCRIPTOR pfd; + const int pixelFormat = ChooseMatchingPixelFormat(m_hDC, attribList, &pfd); + if ( !pixelFormat ) + { + wxLogLastError(_T("ChoosePixelFormat")); + return false; + } + + if ( !::SetPixelFormat(m_hDC, pixelFormat, &pfd) ) + { + wxLogLastError(_T("SetPixelFormat")); + return false; + } + + return true; +} + +// ---------------------------------------------------------------------------- +// palette stuff +// ---------------------------------------------------------------------------- - DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); +#if wxUSE_PALETTE - if (pfd.dwFlags & PFD_NEED_PALETTE) +bool wxGLCanvas::SetupPalette(const wxPalette& palette) +{ + const int pixelFormat = ::GetPixelFormat(m_hDC); + if ( !pixelFormat ) { + wxLogLastError(_T("GetPixelFormat")); + return false; } - else + + PIXELFORMATDESCRIPTOR pfd; + if ( !::DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd) ) { - return; + wxLogLastError(_T("DescribePixelFormat")); + return false; } + if ( !(pfd.dwFlags & PFD_NEED_PALETTE) ) + return true; + m_palette = palette; if ( !m_palette.Ok() ) { m_palette = CreateDefaultPalette(); + if ( !m_palette.Ok() ) + return false; } - if (m_palette.Ok()) + if ( !::SelectPalette(m_hDC, GetHpaletteOf(m_palette), FALSE) ) { - ::SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE); - ::RealizePalette((HDC) m_hDC); + wxLogLastError(_T("SelectPalette")); + return false; } + + if ( ::RealizePalette(m_hDC) == GDI_ERROR ) + { + wxLogLastError(_T("RealizePalette")); + return false; + } + + return true; } wxPalette wxGLCanvas::CreateDefaultPalette() { PIXELFORMATDESCRIPTOR pfd; int paletteSize; - int pixelFormat = GetPixelFormat((HDC) m_hDC); + int pixelFormat = GetPixelFormat(m_hDC); - DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); + DescribePixelFormat(m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); paletteSize = 1 << pfd.cColorBits; @@ -564,45 +571,13 @@ wxPalette wxGLCanvas::CreateDefaultPalette() return palette; } -void wxGLCanvas::SwapBuffers() -{ - if (m_glContext) - m_glContext->SwapBuffers(); -} - -void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event)) -{ -} - -void wxGLCanvas::SetCurrent() -{ - // although on MSW it works even if the window is still hidden, it doesn't - // under wxGTK and documentation mentions that SetCurrent() can only be - // called for a shown window, so check it - wxASSERT_MSG( GetParent()->IsShown(), - _T("can't make hidden GL canvas current") ); - - if (m_glContext) - { - m_glContext->SetCurrent(); - } -} - -void wxGLCanvas::SetColour(const wxChar *colour) -{ - if (m_glContext) - m_glContext->SetColour(colour); -} - -// TODO: Have to have this called by parent frame (?) -// So we need wxFrame to call OnQueryNewPalette for all children... void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) { /* realize palette if this is the current window */ if ( GetPalette()->Ok() ) { ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) GetHDC()); + ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette(GetHDC()); Refresh(); event.SetPaletteRealized(true); } @@ -610,7 +585,6 @@ void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) event.SetPaletteRealized(false); } -// I think this doesn't have to be propagated to child windows. void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) { /* realize palette if this is *not* the current window */ @@ -618,199 +592,84 @@ void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) GetPalette()->Ok() && (this != event.GetChangedWindow()) ) { ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) GetHDC()); + ::SelectPalette(GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette(GetHDC()); Refresh(); } } -/* Give extensions proper function names. */ - -/* EXT_vertex_array */ -void glArrayElementEXT(GLint WXUNUSED(i)) -{ -} - -void glColorPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer)) -{ -} - -void glDrawArraysEXT(GLenum WXUNUSED_WITHOUT_GL_EXT_vertex_array(mode), - GLint WXUNUSED_WITHOUT_GL_EXT_vertex_array(first), - GLsizei WXUNUSED_WITHOUT_GL_EXT_vertex_array(count)) -{ -#ifdef GL_EXT_vertex_array - static PFNGLDRAWARRAYSEXTPROC proc = 0; - - if ( !proc ) - { - proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT"); - } - - if ( proc ) - (* proc) (mode, first, count); -#endif -} - -void glEdgeFlagPointerEXT(GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLboolean *WXUNUSED(pointer)) -{ -} - -void glGetPointervEXT(GLenum WXUNUSED(pname), GLvoid* *WXUNUSED(params)) -{ -} - -void glIndexPointerEXT(GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer)) -{ -} - -void glNormalPointerEXT(GLenum WXUNUSED_WITHOUT_GL_EXT_vertex_array(type), - GLsizei WXUNUSED_WITHOUT_GL_EXT_vertex_array(stride), - GLsizei WXUNUSED_WITHOUT_GL_EXT_vertex_array(count), - const GLvoid *WXUNUSED_WITHOUT_GL_EXT_vertex_array(pointer)) -{ -#ifdef GL_EXT_vertex_array - static PFNGLNORMALPOINTEREXTPROC proc = 0; - - if ( !proc ) - { - proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT"); - } - - if ( proc ) - (* proc) (type, stride, count, pointer); -#endif -} - -void glTexCoordPointerEXT(GLint WXUNUSED(size), GLenum WXUNUSED(type), GLsizei WXUNUSED(stride), GLsizei WXUNUSED(count), const GLvoid *WXUNUSED(pointer)) -{ -} - -void glVertexPointerEXT(GLint WXUNUSED_WITHOUT_GL_EXT_vertex_array(size), - GLenum WXUNUSED_WITHOUT_GL_EXT_vertex_array(type), - GLsizei WXUNUSED_WITHOUT_GL_EXT_vertex_array(stride), - GLsizei WXUNUSED_WITHOUT_GL_EXT_vertex_array(count), - const GLvoid *WXUNUSED_WITHOUT_GL_EXT_vertex_array(pointer)) -{ -#ifdef GL_EXT_vertex_array - static PFNGLVERTEXPOINTEREXTPROC proc = 0; +#endif // wxUSE_PALETTE - if ( !proc ) - { - proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT"); - } - if ( proc ) - (* proc) (size, type, stride, count, pointer); -#endif -} - -/* EXT_color_subtable */ -void glColorSubtableEXT(GLenum WXUNUSED(target), GLsizei WXUNUSED(start), GLsizei WXUNUSED(count), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table)) -{ -} - -/* EXT_color_table */ -void glColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLsizei WXUNUSED(width), GLenum WXUNUSED(format), GLenum WXUNUSED(type), const GLvoid *WXUNUSED(table)) -{ -} - -void glCopyColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(internalformat), GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width)) -{ -} - -void glGetColorTableEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(format), GLenum WXUNUSED(type), GLvoid *WXUNUSED(table)) -{ -} - -void glGetColorTableParamaterfvEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLfloat *WXUNUSED(params)) -{ -} +// ---------------------------------------------------------------------------- +// deprecated wxGLCanvas methods using implicit wxGLContext +// ---------------------------------------------------------------------------- -void glGetColorTavleParameterivEXT(GLenum WXUNUSED(target), GLenum WXUNUSED(pname), GLint *WXUNUSED(params)) -{ -} +// deprecated constructors creating an implicit m_glContext +#if WXWIN_COMPATIBILITY_2_8 -/* SGI_compiled_vertex_array */ -void glLockArraysSGI(GLint WXUNUSED(first), GLsizei WXUNUSED(count)) +wxGLCanvas::wxGLCanvas(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name, + const int *attribList, + const wxPalette& palette) { -} + Init(); -void glUnlockArraysSGI() -{ + if ( Create(parent, id, pos, size, style, name, attribList, palette) ) + m_glContext = new wxGLContext(this); } - -/* SGI_cull_vertex */ -void glCullParameterdvSGI(GLenum WXUNUSED(pname), GLdouble* WXUNUSED(params)) +wxGLCanvas::wxGLCanvas(wxWindow *parent, + const wxGLContext *shared, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name, + const int *attribList, + const wxPalette& palette) { -} + Init(); -void glCullParameterfvSGI(GLenum WXUNUSED(pname), GLfloat* WXUNUSED(params)) -{ + if ( Create(parent, id, pos, size, style, name, attribList, palette) ) + m_glContext = new wxGLContext(this, shared); } -/* SGI_index_func */ -void glIndexFuncSGI(GLenum WXUNUSED(func), GLclampf WXUNUSED(ref)) +wxGLCanvas::wxGLCanvas(wxWindow *parent, + const wxGLCanvas *shared, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name, + const int *attribList, + const wxPalette& palette) { -} + Init(); -/* SGI_index_material */ -void glIndexMaterialSGI(GLenum WXUNUSED(face), GLenum WXUNUSED(mode)) -{ + if ( Create(parent, id, pos, size, style, name, attribList, palette) ) + m_glContext = new wxGLContext(this, shared ? shared->m_glContext : NULL); } -/* WIN_swap_hint */ -void glAddSwapHintRectWin(GLint WXUNUSED(x), GLint WXUNUSED(y), GLsizei WXUNUSED(width), GLsizei WXUNUSED(height)) -{ -} +#endif // WXWIN_COMPATIBILITY_2_8 -//--------------------------------------------------------------------------- +// ---------------------------------------------------------------------------- // wxGLApp -//--------------------------------------------------------------------------- - -IMPLEMENT_CLASS(wxGLApp, wxApp) +// ---------------------------------------------------------------------------- -bool wxGLApp::InitGLVisual(int *attribList) +bool wxGLApp::InitGLVisual(const int *attribList) { - int pixelFormat; - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* preferred color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; - - AdjustPFDForAttributes(pfd, attribList); - - // use DC for whole (root) screen, since no windows have yet been created - pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd); - - if (pixelFormat == 0) { - wxLogError(_("Failed to initialize OpenGL")); - return false; - } - - return true; -} + if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) ) + { + wxLogError(_("Failed to initialize OpenGL")); + return false; + } -wxGLApp::~wxGLApp() -{ + return true; } -#endif - // wxUSE_GLCANVAS +#endif // wxUSE_GLCANVAS