From 4afcdf5f4a323828f9aed13a5e3e810c1df76123 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Feb 2023 15:36:43 +0000 Subject: [PATCH 1/5] Define wxGLAttributes::Defaults() only once Don't duplicate the same function in all port-specific implementations when it is, and should be, the same for all of them. Note that the calls to SetNeedsARB() in the MSW version was redundant because both Samplers() and SampleBuffers() already call it anyhow. No real changes. --- include/wx/glcanvas.h | 8 +++++++- src/msw/glcanvas.cpp | 7 ------- src/osx/glcanvas_osx.cpp | 7 ------- src/qt/glcanvas.cpp | 10 ---------- src/unix/glegl.cpp | 6 ------ src/unix/glx11.cpp | 6 ------ 6 files changed, 7 insertions(+), 37 deletions(-) diff --git a/include/wx/glcanvas.h b/include/wx/glcanvas.h index a3bf461765..dd5407b94a 100644 --- a/include/wx/glcanvas.h +++ b/include/wx/glcanvas.h @@ -156,11 +156,17 @@ public: wxGLAttributes& Stencil(int val); wxGLAttributes& MinAcumRGBA(int mRed, int mGreen, int mBlue, int mAlpha); wxGLAttributes& PlatformDefaults(); - wxGLAttributes& Defaults(); wxGLAttributes& SampleBuffers(int val); wxGLAttributes& Samplers(int val); wxGLAttributes& FrameBuffersRGB(); void EndList(); // No more values can be chained + + // This function is the same for all ports and so is implemented here + // instead of in port-specific files. + wxGLAttributes& Defaults() + { + return RGBA().Depth(16).DoubleBuffer().SampleBuffers(1).Samplers(4); + } }; // ---------------------------------------------------------------------------- diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 47c9acd9e8..c66537b00e 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -530,13 +530,6 @@ wxGLAttributes& wxGLAttributes::PlatformDefaults() return *this; } -wxGLAttributes& wxGLAttributes::Defaults() -{ - RGBA().Depth(16).DoubleBuffer().SampleBuffers(1).Samplers(4); - SetNeedsARB(); - return *this; -} - // ---------------------------------------------------------------------------- // wxGLContext // ---------------------------------------------------------------------------- diff --git a/src/osx/glcanvas_osx.cpp b/src/osx/glcanvas_osx.cpp index 86c5feb4e9..72cfc89af4 100644 --- a/src/osx/glcanvas_osx.cpp +++ b/src/osx/glcanvas_osx.cpp @@ -350,13 +350,6 @@ wxGLAttributes& wxGLAttributes::PlatformDefaults() return *this; } -wxGLAttributes& wxGLAttributes::Defaults() -{ - RGBA().Depth(16).DoubleBuffer().SampleBuffers(1).Samplers(4); - return *this; -} - - // ---------------------------------------------------------------------------- // wxGLContext // ---------------------------------------------------------------------------- diff --git a/src/qt/glcanvas.cpp b/src/qt/glcanvas.cpp index 0e4000c7e8..a5cc62c1c0 100644 --- a/src/qt/glcanvas.cpp +++ b/src/qt/glcanvas.cpp @@ -317,16 +317,6 @@ wxGLAttributes& wxGLAttributes::PlatformDefaults() return *this; } -wxGLAttributes& wxGLAttributes::Defaults() -{ - RGBA().DoubleBuffer(); -// if ( wxGLCanvasX11::GetGLXVersion() < 13 ) -// Depth(1).MinRGBA(1, 1, 1, 0); -// else - Depth(16).SampleBuffers(1).Samplers(4); - return *this; -} - //--------------------------------------------------------------------------- // wxGlContext diff --git a/src/unix/glegl.cpp b/src/unix/glegl.cpp index ca7c90c1b3..90e468f419 100644 --- a/src/unix/glegl.cpp +++ b/src/unix/glegl.cpp @@ -269,12 +269,6 @@ wxGLAttributes& wxGLAttributes::PlatformDefaults() return *this; } -wxGLAttributes& wxGLAttributes::Defaults() -{ - RGBA().DoubleBuffer().Depth(16).SampleBuffers(1).Samplers(4); - return *this; -} - // ============================================================================ // wxGLContext implementation diff --git a/src/unix/glx11.cpp b/src/unix/glx11.cpp index 0a9c7a52fc..fa73d16557 100644 --- a/src/unix/glx11.cpp +++ b/src/unix/glx11.cpp @@ -427,12 +427,6 @@ wxGLAttributes& wxGLAttributes::PlatformDefaults() return *this; } -wxGLAttributes& wxGLAttributes::Defaults() -{ - RGBA().DoubleBuffer().Depth(16).SampleBuffers(1).Samplers(4); - return *this; -} - // ============================================================================ // wxGLContext implementation From 46857a73ba82bb09fcc6bb42d3d4c886354b9243 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Feb 2023 15:40:04 +0000 Subject: [PATCH 2/5] Don't use multi-sampling in wxGLAttributes::Defaults() This prevents wxGLCanvas from working on limited OpenGL implementations not providing it, such as VMWare OpenGL driver, and doesn't seem to be really necessary as multi-sampling can always be explicitly requested if the application does want to use it. Closes #23121. --- docs/changes.txt | 4 ++++ include/wx/glcanvas.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changes.txt b/docs/changes.txt index fdbc5cb67f..508e0bc99a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -27,6 +27,10 @@ Changes in behaviour not resulting in compilation errors - wxMSW doesn't support versions of Microsoft Windows before Windows 7. If you need Windows XP or Vista support, please use wxWidgets 3.2. +- wxGLCanvas doesn't use multi-sampling by default any longer, please use + wxGLAttributes::Samplers(1).SampleBuffers(4) explicitly if you need to keep + using the same attributes that were previously used by default. + - As first mentioned in 3.0 release notes, the value of wxTHREAD_WAIT_DEFAULT, used by wxThread::Delete() and Wait() by default, has changed from wxTHREAD_WAIT_YIELD to wxTHREAD_WAIT_BLOCK for safety and consistency. diff --git a/include/wx/glcanvas.h b/include/wx/glcanvas.h index dd5407b94a..19c0914307 100644 --- a/include/wx/glcanvas.h +++ b/include/wx/glcanvas.h @@ -165,7 +165,7 @@ public: // instead of in port-specific files. wxGLAttributes& Defaults() { - return RGBA().Depth(16).DoubleBuffer().SampleBuffers(1).Samplers(4); + return RGBA().Depth(16).DoubleBuffer(); } }; From 1f9113b40a6641756cf557069a7669fe90dc8e47 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Feb 2023 16:03:56 +0000 Subject: [PATCH 3/5] Add default ctor to wxGLCanvas It didn't make any sense to have Create() functions in this class without the default ctor as they could be never used -- calling them would result in creating the window twice. Add the default ctor to make this class more similar to all the other windows. --- include/wx/gtk/glcanvas.h | 2 ++ include/wx/msw/glcanvas.h | 7 +++---- include/wx/osx/glcanvas.h | 4 +++- include/wx/qt/glcanvas.h | 2 ++ include/wx/x11/glcanvas.h | 2 ++ interface/wx/glcanvas.h | 9 +++++++++ src/msw/glcanvas.cpp | 9 --------- src/osx/glcanvas_osx.cpp | 1 - 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/include/wx/gtk/glcanvas.h b/include/wx/gtk/glcanvas.h index b69bcf9f46..ca356c5870 100644 --- a/include/wx/gtk/glcanvas.h +++ b/include/wx/gtk/glcanvas.h @@ -29,6 +29,8 @@ class WXDLLIMPEXP_GL wxGLCanvas : public wxGLCanvasImpl { typedef wxGLCanvasImpl BaseType; public: + wxGLCanvas() = default; + wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, wxWindowID id = wxID_ANY, diff --git a/include/wx/msw/glcanvas.h b/include/wx/msw/glcanvas.h index 241d223d8d..1666aa5494 100644 --- a/include/wx/msw/glcanvas.h +++ b/include/wx/msw/glcanvas.h @@ -47,6 +47,8 @@ private: class WXDLLIMPEXP_GL wxGLCanvas : public wxGLCanvasBase { public: + wxGLCanvas() = default; + explicit // avoid implicitly converting a wxWindow* to wxGLCanvas wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, @@ -115,9 +117,6 @@ public: #endif // wxUSE_PALETTE protected: - // common part of all ctors - void Init(); - // the real window creation function, Create() may reuse it twice as we may // need to create an OpenGL window to query the available extensions and // then potentially delete and recreate it with another pixel format @@ -133,7 +132,7 @@ protected: // HDC for this window, we keep it all the time - HDC m_hDC; + HDC m_hDC = nullptr; private: wxDECLARE_EVENT_TABLE(); diff --git a/include/wx/osx/glcanvas.h b/include/wx/osx/glcanvas.h index 1971c82b07..2aa6cb0fcd 100644 --- a/include/wx/osx/glcanvas.h +++ b/include/wx/osx/glcanvas.h @@ -60,6 +60,8 @@ private: class WXDLLIMPEXP_GL wxGLCanvas : public wxGLCanvasBase { public: + wxGLCanvas() = default; + wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, wxWindowID id = wxID_ANY, @@ -126,7 +128,7 @@ protected: long style, const wxString& name); - WXGLPixelFormat m_glFormat; + WXGLPixelFormat m_glFormat = nullptr; wxGLAttributes m_GLAttrs; wxDECLARE_EVENT_TABLE(); diff --git a/include/wx/qt/glcanvas.h b/include/wx/qt/glcanvas.h index 2fd3409e8d..1cf84efba8 100644 --- a/include/wx/qt/glcanvas.h +++ b/include/wx/qt/glcanvas.h @@ -34,6 +34,8 @@ public: class WXDLLIMPEXP_GL wxGLCanvas : public wxGLCanvasBase { public: + wxGLCanvas() = default; + explicit // avoid implicitly converting a wxWindow* to wxGLCanvas wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, diff --git a/include/wx/x11/glcanvas.h b/include/wx/x11/glcanvas.h index baf89b67ed..fdad407d90 100644 --- a/include/wx/x11/glcanvas.h +++ b/include/wx/x11/glcanvas.h @@ -17,6 +17,8 @@ class WXDLLIMPEXP_GL wxGLCanvas : public wxGLCanvasX11 { public: + wxGLCanvas() = default; + wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, wxWindowID id = wxID_ANY, diff --git a/interface/wx/glcanvas.h b/interface/wx/glcanvas.h index 711e631ebe..0b0e1f7bd7 100644 --- a/interface/wx/glcanvas.h +++ b/interface/wx/glcanvas.h @@ -785,6 +785,15 @@ enum class wxGLCanvas : public wxWindow { public: + /** + Default constructor not creating the window. + + Create() must be used to actually create it later. + + @since 3.3.0 + */ + wxGLCanvas(); + /** Creates a window with the given parameters. Notice that you need to create and use a wxGLContext to output to this window. diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index c66537b00e..bbe8331c6d 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -641,11 +641,6 @@ wxEND_EVENT_TABLE() // wxGLCanvas construction // ---------------------------------------------------------------------------- -void wxGLCanvas::Init() -{ - m_hDC = nullptr; -} - wxGLCanvas::wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, wxWindowID id, @@ -655,8 +650,6 @@ wxGLCanvas::wxGLCanvas(wxWindow *parent, const wxString& name, const wxPalette& palette) { - Init(); - (void)Create(parent, dispAttrs, id, pos, size, style, name, palette); } @@ -669,8 +662,6 @@ wxGLCanvas::wxGLCanvas(wxWindow *parent, const wxString& name, const wxPalette& palette) { - Init(); - (void)Create(parent, id, pos, size, style, name, attribList, palette); } diff --git a/src/osx/glcanvas_osx.cpp b/src/osx/glcanvas_osx.cpp index 72cfc89af4..5fdfac4df0 100644 --- a/src/osx/glcanvas_osx.cpp +++ b/src/osx/glcanvas_osx.cpp @@ -465,7 +465,6 @@ bool wxGLCanvas::Create(wxWindow *parent, const wxString& name, const wxPalette& WXUNUSED(palette)) { - m_glFormat = nullptr; // Don't allow an empty list if ( !dispAttrs.GetGLAttrs() ) { From 30e79481a8dd672c211c3b7e6dfabf10b74ad9d9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Feb 2023 16:05:07 +0000 Subject: [PATCH 4/5] Remove unused event table macros from some wxGLCanvas files No real changes, just don't define the event table unnecessarily. --- include/wx/osx/glcanvas.h | 1 - include/wx/qt/glcanvas.h | 2 -- src/osx/glcanvas_osx.cpp | 3 --- 3 files changed, 6 deletions(-) diff --git a/include/wx/osx/glcanvas.h b/include/wx/osx/glcanvas.h index 2aa6cb0fcd..5bc460238e 100644 --- a/include/wx/osx/glcanvas.h +++ b/include/wx/osx/glcanvas.h @@ -131,7 +131,6 @@ protected: WXGLPixelFormat m_glFormat = nullptr; wxGLAttributes m_GLAttrs; - wxDECLARE_EVENT_TABLE(); wxDECLARE_CLASS(wxGLCanvas); }; diff --git a/include/wx/qt/glcanvas.h b/include/wx/qt/glcanvas.h index 1cf84efba8..378813cc95 100644 --- a/include/wx/qt/glcanvas.h +++ b/include/wx/qt/glcanvas.h @@ -81,8 +81,6 @@ public: static bool ConvertWXAttrsToQtGL(const int *wxattrs, QGLFormat &format); private: - -// wxDECLARE_EVENT_TABLE(); wxDECLARE_CLASS(wxGLCanvas); }; diff --git a/src/osx/glcanvas_osx.cpp b/src/osx/glcanvas_osx.cpp index 5fdfac4df0..bd699ca0af 100644 --- a/src/osx/glcanvas_osx.cpp +++ b/src/osx/glcanvas_osx.cpp @@ -410,9 +410,6 @@ wxGLContext::~wxGLContext() wxIMPLEMENT_CLASS(wxGLCanvas, wxWindow); -wxBEGIN_EVENT_TABLE(wxGLCanvas, wxWindow) -wxEND_EVENT_TABLE() - wxGLCanvas::wxGLCanvas(wxWindow *parent, const wxGLAttributes& dispAttrs, wxWindowID id, From be1807f29b54a3112a0fa11c6f675526b1044657 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 14 Feb 2023 16:05:51 +0000 Subject: [PATCH 5/5] Use wxGLAttributes instead of int[] in cube OpenGL sample This is slightly more readable. Also test for stereo support before trying to create a window using it. --- samples/opengl/cube/cube.cpp | 44 ++++++++++++++++++++---------------- samples/opengl/cube/cube.h | 2 +- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/samples/opengl/cube/cube.cpp b/samples/opengl/cube/cube.cpp index 83fe9bab0f..d0368156e4 100644 --- a/samples/opengl/cube/cube.cpp +++ b/samples/opengl/cube/cube.cpp @@ -309,29 +309,27 @@ wxBEGIN_EVENT_TABLE(TestGLCanvas, wxGLCanvas) EVT_TIMER(SpinTimer, TestGLCanvas::OnSpinTimer) wxEND_EVENT_TABLE() -TestGLCanvas::TestGLCanvas(wxWindow *parent, int *attribList) +TestGLCanvas::TestGLCanvas(wxWindow *parent, bool useStereo) // With perspective OpenGL graphics, the wxFULL_REPAINT_ON_RESIZE style // flag should always be set, because even making the canvas smaller should // be followed by a paint event that updates the entire canvas with new // viewport settings. - : wxGLCanvas(parent, wxID_ANY, attribList, - wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), - m_xangle(30.0), + : m_xangle(30.0), m_yangle(30.0), m_spinTimer(this,SpinTimer), - m_useStereo(false), + m_useStereo(useStereo), m_stereoWarningAlreadyDisplayed(false) { - if ( attribList ) + wxGLAttributes attribs = wxGLAttributes().Defaults(); + if ( useStereo ) + attribs.Stereo(); + attribs.EndList(); + + if ( !wxGLCanvas::Create(parent, attribs, wxID_ANY, + wxDefaultPosition, wxDefaultSize, + wxFULL_REPAINT_ON_RESIZE) ) { - int i = 0; - while ( attribList[i] != 0 ) - { - if ( attribList[i] == WX_GL_STEREO ) - m_useStereo = true; - ++i; - } + wxLogError("Creating OpenGL window failed."); } } @@ -458,9 +456,7 @@ wxEND_EVENT_TABLE() MyFrame::MyFrame( bool stereoWindow ) : wxFrame(nullptr, wxID_ANY, "wxWidgets OpenGL Cube Sample") { - int stereoAttribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_STEREO, 0 }; - - new TestGLCanvas(this, stereoWindow ? stereoAttribList : nullptr); + new TestGLCanvas(this, stereoWindow); SetIcon(wxICON(sample)); @@ -481,7 +477,8 @@ MyFrame::MyFrame( bool stereoWindow ) Show(); // test IsDisplaySupported() function: - static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; + wxGLAttributes attribs; + attribs.RGBA().DoubleBuffer().EndList(); wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); @@ -508,5 +505,14 @@ void MyFrame::OnNewWindow( wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnNewStereoWindow( wxCommandEvent& WXUNUSED(event) ) { - new MyFrame(true); + wxGLAttributes attribs; + attribs.RGBA().DoubleBuffer().Stereo().EndList(); + if ( wxGLCanvas::IsDisplaySupported(attribs) ) + { + new MyFrame(true); + } + else + { + wxLogError("Stereo not supported by OpenGL on this system, sorry."); + } } diff --git a/samples/opengl/cube/cube.h b/samples/opengl/cube/cube.h index 02d0eb0d75..a04fac1407 100644 --- a/samples/opengl/cube/cube.h +++ b/samples/opengl/cube/cube.h @@ -65,7 +65,7 @@ private: class TestGLCanvas : public wxGLCanvas { public: - TestGLCanvas(wxWindow *parent, int *attribList = nullptr); + TestGLCanvas(wxWindow *parent, bool useStereo); private: void OnPaint(wxPaintEvent& event);