Big wxGL classes refactoring/cleanup:

1. Provide the same API, especially, but not limited to, wxGLCanvas and
   wxCLContext ctors (which were completely different in all ports)
2. Extracted common parts into wxGLCanvas/ContextBase classes
3. Deprecate the old API using implicitly created wxGLContext


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45388 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-04-10 17:38:55 +00:00
parent 1f602af615
commit dc3065a56f
25 changed files with 1860 additions and 1996 deletions

View File

@@ -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 <jumpo@bitex.com>
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,140 +176,82 @@ void wxGLModule::UnregisterClasses()
}
}
/*
* GLContext implementation
*/
// ----------------------------------------------------------------------------
// wxGLContext
// ----------------------------------------------------------------------------
IMPLEMENT_CLASS(wxGLContext, wxObject)
wxGLContext::wxGLContext(wxGLCanvas* win, const wxGLContext* other /* for sharing display lists */)
wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext* other)
{
m_glContext = wglCreateContext((HDC) win->GetHDC());
wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") );
m_glContext = wglCreateContext(win->GetHDC());
wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") );
if( other != 0 )
wglShareLists( other->m_glContext, m_glContext );
if ( other )
{
if ( !wglShareLists(other->m_glContext, m_glContext) )
wxLogLastError(_T("wglShareLists"));
}
}
wxGLContext::~wxGLContext()
{
// If this context happens to be the current context, wglDeleteContext() makes it un-current first.
// note that it's ok to delete the context even if it's the current one
wglDeleteContext(m_glContext);
}
void wxGLContext::SetCurrent(const wxGLCanvas& win) const
{
wglMakeCurrent((HDC) win.GetHDC(), m_glContext);
if ( !wglMakeCurrent(win.GetHDC(), m_glContext) )
{
wxLogLastError(_T("wglMakeCurrent"));
}
}
/*
* 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, int *attribList,
const wxPoint& pos, const wxSize& size, long style,
const wxString& name, const wxPalette& palette) : wxWindow()
// ----------------------------------------------------------------------------
// wxGLCanvas construction
// ----------------------------------------------------------------------------
void wxGLCanvas::Init()
{
#if WXWIN_COMPATIBILITY_2_8
m_glContext = NULL;
if (Create(parent, id, pos, size, style, name))
{
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
}
m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
SetupPixelFormat(attribList);
SetupPalette(palette);
// This ctor does *not* create an instance of wxGLContext,
// m_glContext intentionally remains NULL.
#endif
m_hDC = NULL;
}
wxGLCanvas::wxGLCanvas(wxWindow *parent, 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;
Init();
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(this);
}
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()
{
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(this, shared);
}
// 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()
{
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);
wxGLContext *sharedContext=0;
if (shared) sharedContext=shared->GetContext();
m_glContext = new wxGLContext(this, sharedContext);
(void)Create(parent, id, pos, size, style, name, attribList, palette);
}
wxGLCanvas::~wxGLCanvas()
{
delete m_glContext;
#if WXWIN_COMPATIBILITY_2_8
delete m_glContext;
#endif
::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC);
::ReleaseDC(GetHwnd(), m_hDC);
}
// Replaces wxWindow::Create functionality, since we need to use a different
@@ -322,7 +261,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") );
@@ -338,170 +279,246 @@ 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);
return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, 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;
}
static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
// ----------------------------------------------------------------------------
// operations
// ----------------------------------------------------------------------------
void wxGLCanvas::SwapBuffers()
{
if (attribList) {
if ( !::SwapBuffers(m_hDC) )
wxLogLastError(_T("SwapBuffers"));
}
// ----------------------------------------------------------------------------
// pixel format stuff
// ----------------------------------------------------------------------------
static void
AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, const int *attribList)
{
if ( !attribList )
return;
pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_COLORINDEX;
pfd.cColorBits = 0;
int arg=0;
while( (attribList[arg]!=0) )
while ( 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.cColorBits +
(pfd.cRedBits = attribList[arg++]));
break;
case WX_GL_MIN_GREEN:
pfd.cColorBits = (pfd.cColorBits +
(pfd.cGreenBits = attribList[arg++]));
break;
case WX_GL_MIN_BLUE:
pfd.cColorBits = (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.cAccumBits +
(pfd.cAccumRedBits = attribList[arg++]));
break;
case WX_GL_MIN_ACCUM_GREEN:
pfd.cAccumBits = (pfd.cAccumBits +
(pfd.cAccumGreenBits = attribList[arg++]));
break;
case WX_GL_MIN_ACCUM_BLUE:
pfd.cAccumBits = (pfd.cAccumBits +
(pfd.cAccumBlueBits = attribList[arg++]));
break;
case WX_GL_MIN_ACCUM_ALPHA:
pfd.cAccumBits = (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, // 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, // accumulator 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);
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);
}
void wxGLCanvas::SetupPalette(const wxPalette& palette)
bool wxGLCanvas::DoSetup(const int *attribList)
{
int pixelFormat = GetPixelFormat((HDC) m_hDC);
PIXELFORMATDESCRIPTOR pfd;
DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
if (pfd.dwFlags & PFD_NEED_PALETTE)
const int pixelFormat = ChooseMatchingPixelFormat(m_hDC, attribList, &pfd);
if ( !pixelFormat )
{
wxLogLastError(_T("ChoosePixelFormat"));
return false;
}
else
if ( !::SetPixelFormat(m_hDC, pixelFormat, &pfd) )
{
return;
wxLogLastError(_T("SetPixelFormat"));
return false;
}
return true;
}
// ----------------------------------------------------------------------------
// palette stuff
// ----------------------------------------------------------------------------
#if wxUSE_PALETTE
bool wxGLCanvas::SetupPalette(const wxPalette& palette)
{
const int pixelFormat = ::GetPixelFormat(m_hDC);
if ( !pixelFormat )
{
wxLogLastError(_T("GetPixelFormat"));
return false;
}
PIXELFORMATDESCRIPTOR pfd;
if ( !::DescribePixelFormat(m_hDC, pixelFormat, sizeof(pfd), &pfd) )
{
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;
@@ -537,61 +554,13 @@ wxPalette wxGLCanvas::CreateDefaultPalette()
return palette;
}
void wxGLCanvas::SwapBuffers()
{
::SwapBuffers((HDC) m_hDC);
}
void wxGLCanvas::OnSize(wxSizeEvent& WXUNUSED(event))
{
}
void wxGLCanvas::SetCurrent(const wxGLContext& RC) const
{
// 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") );
RC.SetCurrent(*this);
}
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(*this);
}
}
void wxGLCanvas::SetColour(const wxChar *colour)
{
wxColour col = wxTheColourDatabase->Find(colour);
if (col.Ok())
{
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);
}
}
// 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);
}
@@ -599,7 +568,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 */
@@ -607,59 +575,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();
}
}
#endif // wxUSE_PALETTE
//---------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// deprecated wxGLCanvas methods using implicit wxGLContext
// ----------------------------------------------------------------------------
// deprecated constructors creating an implicit m_glContext
#if WXWIN_COMPATIBILITY_2_8
wxGLCanvas::wxGLCanvas(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name,
const int *attribList,
const wxPalette& palette)
{
Init();
if ( Create(parent, id, pos, size, style, name, attribList, palette) )
m_glContext = new wxGLContext(this);
}
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();
if ( Create(parent, id, pos, size, style, name, attribList, palette) )
m_glContext = new wxGLContext(this, shared);
}
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();
if ( Create(parent, id, pos, size, style, name, attribList, palette) )
m_glContext = new wxGLContext(this, shared ? shared->m_glContext : NULL);
}
#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 */
};
if ( !wxGLCanvas::ChooseMatchingPixelFormat(ScreenHDC(), attribList) )
{
wxLogError(_("Failed to initialize OpenGL"));
return false;
}
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;
return true;
}
wxGLApp::~wxGLApp()
{
}
#endif
// wxUSE_GLCANVAS
#endif // wxUSE_GLCANVAS