X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f48d169c4a57bd4ac2f44e42b9fd26a930bbdca0..e7300ec6d9ebbd1cfa2fcf12c0ce6e5aee85a152:/src/msw/glcanvas.cpp diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 360e36c876..3d3fc51624 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -1,12 +1,12 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: glcanvas.cpp +// Name: src/msw/glcanvas.cpp // Purpose: wxGLCanvas, for using OpenGL with wxWindows under MS Windows // Author: Julian Smart // Modified by: // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -33,7 +33,8 @@ #include -wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass"); +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); @@ -124,9 +125,9 @@ void wxGLContext::SetColour(const char *colour) * wxGLCanvas implementation */ -IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) +IMPLEMENT_CLASS(wxGLCanvas, wxWindow) -BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) +BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow) EVT_SIZE(wxGLCanvas::OnSize) EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged) EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette) @@ -134,7 +135,7 @@ 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) : wxScrolledWindow() + int *attribList, const wxPalette& palette) : wxWindow() { m_glContext = (wxGLContext*) NULL; @@ -142,8 +143,8 @@ wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, if ( ret ) { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); @@ -158,7 +159,7 @@ 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() + : wxWindow() { m_glContext = (wxGLContext*) NULL; @@ -166,8 +167,8 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, if ( ret ) { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); @@ -183,7 +184,7 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, 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 ): - wxScrolledWindow() + wxWindow() { m_glContext = (wxGLContext*) NULL; @@ -191,8 +192,8 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID i if ( ret ) { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); @@ -213,25 +214,16 @@ wxGLCanvas::~wxGLCanvas() ::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) +// 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) { - /* - Suggestion from Kelly Brock (not yet implemented): - - OpenGL corruption fix is simple assuming it doesn't screw anything else - up. Add the following line to the top of the create function: - - wxSize parentSize = GetClientSize(); - - All locations within the function that use 'size' are changed to - 'parentSize'. - The above corrects the initial display corruption with the GeForce and - TNT2, not sure about other NVidia cards yet. - */ - - static bool registeredGLCanvasClass = FALSE; + static bool s_registeredGLCanvasClass = FALSE; // We have to register a special window class because we need // the CS_OWNDC style for GLCanvas. @@ -253,12 +245,10 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, only way to prevent this, the only reliable means, is to set CS_OWNDC." */ - if (!registeredGLCanvasClass) + if (!s_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; @@ -271,15 +261,29 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, // Register the GLCanvas class name wndclass.hbrBackground = (HBRUSH)NULL; wndclass.lpszClassName = wxGLCanvasClassName; - wndclass.style = styleNormal; + wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; - if ( !RegisterClass(&wndclass) ) + if ( !::RegisterClass(&wndclass) ) { wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); return FALSE; } - registeredGLCanvasClass = TRUE; + // Register the GLCanvas class name for windows which don't do full repaint + // on resize + wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw; + wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW); + + if ( !::RegisterClass(&wndclass) ) + { + wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)")); + + ::UnregisterClass(wxGLCanvasClassName, wxhInstance); + + return FALSE; + } + + s_registeredGLCanvasClass = TRUE; } wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); @@ -302,10 +306,7 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, books that contain the wgl function descriptions. */ - msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; - // if ( style & wxCLIP_CHILDREN ) - // msflags |= WS_CLIPCHILDREN; - msflags |= WS_CLIPCHILDREN; + msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; bool want3D; WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); @@ -318,52 +319,17 @@ bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, 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; + return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle); } -void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) +static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, 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, /* prefered 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 (attribList) { pfd.dwFlags &= ~PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_COLORINDEX; pfd.cColorBits = 0; int arg=0; - + while( (attribList[arg]!=0) ) { switch( attribList[arg++] ) @@ -377,11 +343,11 @@ void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) case WX_GL_LEVEL: // this member looks like it may be obsolete if (attribList[arg] > 0) { - pfd.iLayerType = PFD_OVERLAY_PLANE; + pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE; } else if (attribList[arg] < 0) { - pfd.iLayerType = PFD_UNDERLAY_PLANE; + pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE; } else { - pfd.iLayerType = PFD_MAIN_PLANE; + pfd.iLayerType = (BYTE)PFD_MAIN_PLANE; } arg++; break; @@ -407,10 +373,10 @@ void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) // doesn't count in cColorBits pfd.cAlphaBits = attribList[arg++]; break; - case WX_GL_DEPTH_SIZE: + case WX_GL_DEPTH_SIZE: pfd.cDepthBits = attribList[arg++]; break; - case WX_GL_STENCIL_SIZE: + case WX_GL_STENCIL_SIZE: pfd.cStencilBits = attribList[arg++]; break; case WX_GL_MIN_ACCUM_RED: @@ -430,17 +396,42 @@ void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) } } } +} + +void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) +{ + 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, /* prefered 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); + pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); if (pixelFormat == 0) { - MessageBox(WindowFromDC((HDC) m_hDC), wxT("ChoosePixelFormat failed."), wxT("Error"), - MB_ICONERROR | MB_OK); - exit(1); + wxLogWarning(_("ChoosePixelFormat failed.")); } - - if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { - MessageBox(WindowFromDC((HDC) m_hDC), wxT("SetPixelFormat failed."), wxT("Error"), - MB_ICONERROR | MB_OK); - exit(1); + else { + if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { + wxLogWarning(_("SetPixelFormat failed.")); + } } } @@ -456,7 +447,7 @@ void wxGLCanvas::SetupPalette(const wxPalette& palette) } else { - return; + return; } m_palette = palette; @@ -490,20 +481,20 @@ wxPalette wxGLCanvas::CreateDefaultPalette() /* build a simple RGB color palette */ { - int redMask = (1 << pfd.cRedBits) - 1; - int greenMask = (1 << pfd.cGreenBits) - 1; - int blueMask = (1 << pfd.cBlueBits) - 1; - int i; - - for (i=0; ipalPalEntry[i].peRed = - (((i >> pfd.cRedShift) & redMask) * 255) / redMask; - pPal->palPalEntry[i].peGreen = - (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; - pPal->palPalEntry[i].peBlue = - (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; - pPal->palPalEntry[i].peFlags = 0; - } + int redMask = (1 << pfd.cRedBits) - 1; + int greenMask = (1 << pfd.cGreenBits) - 1; + int blueMask = (1 << pfd.cBlueBits) - 1; + int i; + + for (i=0; ipalPalEntry[i].peRed = + (((i >> pfd.cRedShift) & redMask) * 255) / redMask; + pPal->palPalEntry[i].peGreen = + (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask; + pPal->palPalEntry[i].peBlue = + (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask; + pPal->palPalEntry[i].peFlags = 0; + } } HPALETTE hPalette = CreatePalette(pPal); @@ -523,19 +514,6 @@ void wxGLCanvas::SwapBuffers() void wxGLCanvas::OnSize(wxSizeEvent& event) { - int width, height; - GetClientSize(& width, & height); - - if (m_glContext) - { - m_glContext->SetCurrent(); - - glViewport(0, 0, (GLint)width, (GLint)height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 ); - glMatrixMode(GL_MODELVIEW); - } } void wxGLCanvas::SetCurrent() @@ -713,5 +691,53 @@ void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height) { } + +//--------------------------------------------------------------------------- +// wxGLApp +//--------------------------------------------------------------------------- + +IMPLEMENT_CLASS(wxGLApp, wxApp) + +bool wxGLApp::InitGLVisual(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, /* prefered 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; +} + +wxGLApp::~wxGLApp() +{ +} + #endif // wxUSE_GLCANVAS