diff --git a/docs/changes.txt b/docs/changes.txt index 92a0efab73..156e0bf467 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -83,7 +83,7 @@ Changes in behaviour not resulting in compilation errors - wxGLCanvas now uses physical pixels on high DPI displays under platforms where they're different from logical ones (wxGTK3, wxOSX). Multiply logical - coordinates, e.g. returned by wxWindow::GetSize() by GetContentScaleFactor() + coordinates, e.g. returned by wxWindow::GetSize() by GetOpenGLScaleFactor() before using them with OpenGL functions. - wxGTK now uses wxID_NONE item ID for wxEVT_MENU_HIGHLIGHT events sent when diff --git a/include/wx/glcanvas.h b/include/wx/glcanvas.h index d21f0d45b8..0da03844e8 100644 --- a/include/wx/glcanvas.h +++ b/include/wx/glcanvas.h @@ -258,6 +258,11 @@ public: // as a parameter wxGLContextAttrs& GetGLCTXAttrs() { return m_GLCTXAttrs; } + // Return the factor to apply to transform window coordinates (e.g. sizes) + // to OpenGL coordinates: it can be different from 1 on the platforms where + // logical pixels are different from physical ones (i.e. wxGTK3 and wxOSX). + virtual double GetOpenGLScaleFactor() const; + // deprecated methods using the implicit wxGLContext #if WXWIN_COMPATIBILITY_2_8 wxDEPRECATED( wxGLContext* GetContext() const ); diff --git a/include/wx/gtk/glcanvas.h b/include/wx/gtk/glcanvas.h index ff0eddd141..663e3efabc 100644 --- a/include/wx/gtk/glcanvas.h +++ b/include/wx/gtk/glcanvas.h @@ -60,6 +60,8 @@ public: virtual bool SetBackgroundStyle(wxBackgroundStyle style) wxOVERRIDE; + virtual double GetOpenGLScaleFactor() const wxOVERRIDE; + // implement wxGLCanvasX11 methods // -------------------------------- diff --git a/include/wx/osx/glcanvas.h b/include/wx/osx/glcanvas.h index 34af46fdd5..663cec1fd4 100644 --- a/include/wx/osx/glcanvas.h +++ b/include/wx/osx/glcanvas.h @@ -100,7 +100,7 @@ public: // implement wxGLCanvasBase methods virtual bool SwapBuffers() wxOVERRIDE; - + virtual double GetOpenGLScaleFactor() const wxOVERRIDE; // Mac-specific functions // ---------------------- diff --git a/interface/wx/glcanvas.h b/interface/wx/glcanvas.h index ba0cbc1d96..711367722f 100644 --- a/interface/wx/glcanvas.h +++ b/interface/wx/glcanvas.h @@ -752,7 +752,7 @@ enum platforms where wxWindow uses logical pixels, affected by the coordinate scaling, on high DPI displays. Thus, if you want to set the OpenGL view port to the size of entire window, you must multiply the result returned by - wxWindow::GetClientSize() by wxWindow::GetContentScaleFactor() before + wxWindow::GetClientSize() by wxGLCanvas::GetOpenGLScaleFactor() before passing it to @c glViewport(). Same considerations apply to other OpenGL functions and other coordinates, notably those retrieved from wxMouseEvent in the event handlers. @@ -936,6 +936,23 @@ public: */ bool SetCurrent(const wxGLContext& context) const; + /** + Returns the scale factor for transformation between logical and + physical OpenGL coordinates. + + This factor is always 1 on the platforms where logical pixels are the + same as physical ones, in any DPI (such as MSW), but can be different + from it on the platforms where logical and physical pixels may differ + due to DPI scaling (such as GTK 3 or macOS). + + To handle the differences between the platforms, always multiply the + values expressed in window coordinates (window sizes, mouse position + etc) by this factor before passing them to OpenGL functions. + + @since 3.1.4 + */ + double GetOpenGLScaleFactor() const; + /** Swaps the double-buffer of this window, making the back-buffer the front-buffer and vice versa, so that the output of the previous OpenGL diff --git a/samples/opengl/cube/cube.cpp b/samples/opengl/cube/cube.cpp index 254812e0d8..9410fb4e1e 100644 --- a/samples/opengl/cube/cube.cpp +++ b/samples/opengl/cube/cube.cpp @@ -349,7 +349,7 @@ void TestGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) // multiple canvases: If we updated the viewport in the wxSizeEvent // handler, changing the size of one canvas causes a viewport setting that // is wrong when next another canvas is repainted. - const wxSize ClientSize = GetClientSize() * GetContentScaleFactor(); + const wxSize ClientSize = GetClientSize() * GetOpenGLScaleFactor(); TestGLContext& canvas = wxGetApp().GetContext(this, m_useStereo); glViewport(0, 0, ClientSize.x, ClientSize.y); diff --git a/samples/opengl/isosurf/isosurf.cpp b/samples/opengl/isosurf/isosurf.cpp index 9dd47a162f..19306d34a4 100644 --- a/samples/opengl/isosurf/isosurf.cpp +++ b/samples/opengl/isosurf/isosurf.cpp @@ -280,7 +280,7 @@ void TestGLCanvas::OnSize(wxSizeEvent& event) // This is OK here only because there is only one canvas that uses the // context. See the cube sample for that case that multiple canvases are // made current with one context. - const wxSize size = event.GetSize() * GetContentScaleFactor(); + const wxSize size = event.GetSize() * GetOpenGLScaleFactor(); glViewport(0, 0, size.x, size.y); } diff --git a/samples/opengl/penguin/penguin.cpp b/samples/opengl/penguin/penguin.cpp index b5992a6b46..e7fcc76a96 100644 --- a/samples/opengl/penguin/penguin.cpp +++ b/samples/opengl/penguin/penguin.cpp @@ -306,7 +306,7 @@ void TestGLCanvas::ResetProjectionMode() // or more than one wxGLContext in the application. SetCurrent(*m_glRC); - const wxSize ClientSize = GetClientSize() * GetContentScaleFactor(); + const wxSize ClientSize = GetClientSize() * GetOpenGLScaleFactor(); // It's up to the application code to update the OpenGL viewport settings. // In order to avoid extensive context switching, consider doing this in diff --git a/samples/opengl/pyramid/pyramid.cpp b/samples/opengl/pyramid/pyramid.cpp index 5123a917ab..92a0cde651 100644 --- a/samples/opengl/pyramid/pyramid.cpp +++ b/samples/opengl/pyramid/pyramid.cpp @@ -565,7 +565,7 @@ void MyGLCanvas::OnSize(wxSizeEvent& event) SetCurrent(*m_oglContext); // It's up to the application code to update the OpenGL viewport settings. - const wxSize size = event.GetSize() * GetContentScaleFactor(); + const wxSize size = event.GetSize() * GetOpenGLScaleFactor(); m_winHeight = size.y; m_oglManager->SetViewport(0, 0, size.x, m_winHeight); diff --git a/src/common/glcmn.cpp b/src/common/glcmn.cpp index e0c056aa9a..206fd9a6cf 100644 --- a/src/common/glcmn.cpp +++ b/src/common/glcmn.cpp @@ -376,6 +376,11 @@ bool wxGLCanvasBase::ParseAttribList(const int *attribList, return true; } +double wxGLCanvasBase::GetOpenGLScaleFactor() const +{ + return 1.0; +} + // ============================================================================ // compatibility layer for OpenGL 3 and OpenGL ES // ============================================================================ diff --git a/src/gtk/glcanvas.cpp b/src/gtk/glcanvas.cpp index 67c7c50f73..9d703884a4 100644 --- a/src/gtk/glcanvas.cpp +++ b/src/gtk/glcanvas.cpp @@ -271,4 +271,13 @@ void wxGLCanvas::GTKInitImplicitContext() #endif // WXWIN_COMPATIBILITY_2_8 +double wxGLCanvas::GetOpenGLScaleFactor() const +{ +#ifdef __WXGTK3__ + return GetContentScaleFactor(); +#else + return 1.0; +#endif +} + #endif // wxUSE_GLCANVAS diff --git a/src/osx/glcanvas_osx.cpp b/src/osx/glcanvas_osx.cpp index 71d7dd02cf..90b0677774 100644 --- a/src/osx/glcanvas_osx.cpp +++ b/src/osx/glcanvas_osx.cpp @@ -562,6 +562,11 @@ bool wxGLCanvas::IsAGLMultiSampleAvailable() return s_isMultiSampleAvailable != 0; } +double wxGLCanvas::GetOpenGLScaleFactor() const +{ + return GetContentScaleFactor(); +} + /* static */ bool wxGLCanvasBase::IsDisplaySupported(const wxGLAttributes& dispAttrs) {