From 692d84a0858929a3defac35826473e70510d5119 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 11 Jul 2024 16:40:55 +0200 Subject: [PATCH 1/4] Gui: Add class Multisample to check supported MSAA modes --- src/Gui/CMakeLists.txt | 2 + src/Gui/Multisample.cpp | 105 ++++++++++++++++++++++++++++++++++++++++ src/Gui/Multisample.h | 70 +++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 src/Gui/Multisample.cpp create mode 100644 src/Gui/Multisample.h diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index f68985438e..12cb574698 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -850,6 +850,7 @@ SET(View3D_CPP_SRCS Flag.cpp GLBuffer.cpp GLPainter.cpp + Multisample.cpp MouseSelection.cpp NavigationStyle.cpp InventorNavigationStyle.cpp @@ -882,6 +883,7 @@ SET(View3D_SRCS Flag.h GLBuffer.h GLPainter.h + Multisample.h MouseSelection.h NavigationStyle.h GestureNavigationStyle.h diff --git a/src/Gui/Multisample.cpp b/src/Gui/Multisample.cpp new file mode 100644 index 0000000000..a76d8fb3ed --- /dev/null +++ b/src/Gui/Multisample.cpp @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#endif + +#include "Multisample.h" + +using namespace Gui; + +// clang-format off +static constexpr auto numMSAA {6}; +static constexpr auto idStr {0}; +static constexpr auto idEnum {1}; +static constexpr auto idMSAA {2}; +static constexpr std::array, numMSAA> textMSAA {{ + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "None"), AntiAliasing::None, 0}, + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "Line Smoothing"), AntiAliasing::MSAA1x, 1}, + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "MSAA 2x"), AntiAliasing::MSAA2x, 2}, + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "MSAA 4x"), AntiAliasing::MSAA4x, 4}, + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "MSAA 6x"), AntiAliasing::MSAA6x, 6}, + {QT_TRANSLATE_NOOP("Gui::Dialog::DlgSettings3DView", "MSAA 8x"), AntiAliasing::MSAA8x, 8}, +}}; +// clang-format on + +Multisample::Multisample() +{ + context.setFormat(format); + context.create(); + offscreen.setFormat(format); + offscreen.create(); + context.makeCurrent(&offscreen); +} + +bool Multisample::testSamples(int num) const +{ + // This is always true + if (num == 0 || num == 1) { + return true; + } + + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::Depth); + fboFormat.setSamples(num); + QOpenGLFramebufferObject fbo(100, 100, fboFormat); // NOLINT + return fbo.format().samples() == num; +} + +std::vector> Multisample::supported() const +{ + std::vector> modes; + std::for_each(textMSAA.begin(), textMSAA.end(), [&modes, this](const auto& mode) { + if (testSamples(std::get(mode))) { + const char* context = "Gui::Dialog::DlgSettings3DView"; + QString str = QCoreApplication::translate(context, std::get(mode).data()); + modes.emplace_back(str, std::get(mode)); + } + }); + return modes; +} + +int Multisample::toSamples(AntiAliasing msaa) +{ + auto it = std::find_if(textMSAA.begin(), textMSAA.end(), [msaa](const auto& mode) { + return std::get(mode) == msaa; + }); + if (it != textMSAA.end()) { + return std::get(*it); + } + return 0; +} + +AntiAliasing Multisample::toAntiAliasing(int samples) +{ + auto it = std::find_if(textMSAA.begin(), textMSAA.end(), [samples](const auto& mode) { + return std::get(mode) == samples; + }); + if (it != textMSAA.end()) { + return std::get(*it); + } + return AntiAliasing::None; +} diff --git a/src/Gui/Multisample.h b/src/Gui/Multisample.h new file mode 100644 index 0000000000..2c90da75d6 --- /dev/null +++ b/src/Gui/Multisample.h @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 Werner Mayer * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#ifndef GUI_MULTISAMPLE_H +#define GUI_MULTISAMPLE_H + +#include +#include +#include +#include +#include +#include + +namespace Gui +{ + +/** @name Anti-Aliasing modes of the rendered 3D scene + * Specifies Anti-Aliasing (AA) method + * - Smoothing enables OpenGL line and vertex smoothing (basically deprecated) + * - MSAA is hardware multi sampling (with 2, 4, 6 or 8 passes), a quite common and efficient AA technique + */ +//@{ +enum class AntiAliasing { + None = 0, + MSAA1x = 1, + MSAA2x = 2, + MSAA4x = 3, + MSAA6x = 5, + MSAA8x = 4 +}; +//@} + +class GuiExport Multisample +{ +public: + Multisample(); + bool testSamples(int num) const; + std::vector> supported() const; + static int toSamples(AntiAliasing msaa); + static AntiAliasing toAntiAliasing(int samples); + +private: + QSurfaceFormat format; + QOpenGLContext context; + QOffscreenSurface offscreen; +}; + +} // namespace Gui + +#endif // GUI_MULTISAMPLE_H From 6c02b8f10f02ba4ecdf48920e32e13c948e9db79 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 11 Jul 2024 17:39:23 +0200 Subject: [PATCH 2/4] Gui: Use of Multisample class --- src/Gui/Multisample.cpp | 16 +++++ src/Gui/Multisample.h | 2 + .../PreferencePages/DlgSettings3DViewImp.cpp | 66 ++----------------- src/Gui/View3DInventorViewer.cpp | 22 +------ src/Gui/View3DInventorViewer.h | 16 ----- 5 files changed, 28 insertions(+), 94 deletions(-) diff --git a/src/Gui/Multisample.cpp b/src/Gui/Multisample.cpp index a76d8fb3ed..b97e06b25a 100644 --- a/src/Gui/Multisample.cpp +++ b/src/Gui/Multisample.cpp @@ -28,6 +28,8 @@ #endif #include "Multisample.h" +#include +#include using namespace Gui; @@ -103,3 +105,17 @@ AntiAliasing Multisample::toAntiAliasing(int samples) } return AntiAliasing::None; } + +AntiAliasing Multisample::readMSAAFromSettings() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/View"); + return AntiAliasing(hGrp->GetInt("AntiAliasing", int(Gui::AntiAliasing::None))); +} + +void Multisample::writeMSAAToSettings(AntiAliasing msaa) +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/View"); + hGrp->SetInt("AntiAliasing", long(msaa)); +} diff --git a/src/Gui/Multisample.h b/src/Gui/Multisample.h index 2c90da75d6..359e20df5a 100644 --- a/src/Gui/Multisample.h +++ b/src/Gui/Multisample.h @@ -58,6 +58,8 @@ public: std::vector> supported() const; static int toSamples(AntiAliasing msaa); static AntiAliasing toAntiAliasing(int samples); + static AntiAliasing readMSAAFromSettings(); + static void writeMSAAToSettings(AntiAliasing msaa); private: QSurfaceFormat format; diff --git a/src/Gui/PreferencePages/DlgSettings3DViewImp.cpp b/src/Gui/PreferencePages/DlgSettings3DViewImp.cpp index 9fc095a637..47775784ba 100644 --- a/src/Gui/PreferencePages/DlgSettings3DViewImp.cpp +++ b/src/Gui/PreferencePages/DlgSettings3DViewImp.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include "DlgSettings3DViewImp.h" @@ -97,88 +98,35 @@ void DlgSettings3DViewImp::loadSettings() loadMarkerSize(); } -namespace { -class GLFormatCheck { -public: - GLFormatCheck() { - context.setFormat(format); - context.create(); - offscreen.setFormat(format); - offscreen.create(); - context.makeCurrent(&offscreen); - } - - bool testSamples(int num) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::Depth); - fboFormat.setSamples(num); - QOpenGLFramebufferObject fbo(100, 100, fboFormat); // NOLINT - return fbo.format().samples() == num; - } - -private: - QSurfaceFormat format; - QOpenGLContext context; - QOffscreenSurface offscreen; -}; -} - void DlgSettings3DViewImp::addAntiAliasing() { - QString none = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "None"); - QString line = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "Line Smoothing"); - QString msaa2x = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "MSAA 2x"); - QString msaa4x = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "MSAA 4x"); - QString msaa6x = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "MSAA 6x"); - QString msaa8x = QCoreApplication::translate("Gui::Dialog::DlgSettings3DView", "MSAA 8x"); ui->comboAliasing->clear(); - ui->comboAliasing->addItem(none, int(Gui::View3DInventorViewer::None)); - ui->comboAliasing->addItem(line, int(Gui::View3DInventorViewer::Smoothing)); // Do the samples checks only once - static std::vector> modes; + static std::vector> modes; static bool formatCheck = true; if (formatCheck) { formatCheck = false; - GLFormatCheck check; - // NOLINTBEGIN - if (check.testSamples(2)) { - modes.emplace_back(msaa2x, int(Gui::View3DInventorViewer::MSAA2x)); - } - if (check.testSamples(4)) { - modes.emplace_back(msaa4x, int(Gui::View3DInventorViewer::MSAA4x)); - } - if (check.testSamples(6)) { - modes.emplace_back(msaa6x, int(Gui::View3DInventorViewer::MSAA6x)); - } - if (check.testSamples(8)) { - modes.emplace_back(msaa8x, int(Gui::View3DInventorViewer::MSAA8x)); - } - // NOLINTEND + Multisample check; + modes = check.supported(); } for (const auto& it : modes) { - ui->comboAliasing->addItem(it.first, it.second); + ui->comboAliasing->addItem(it.first, int(it.second)); } } void DlgSettings3DViewImp::saveAntiAliasing() { - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/View"); - int index = ui->comboAliasing->currentIndex(); int aliasing = ui->comboAliasing->itemData(index).toInt(); - hGrp->SetInt("AntiAliasing", aliasing); + Multisample::writeMSAAToSettings(static_cast(aliasing)); } void DlgSettings3DViewImp::loadAntiAliasing() { - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/View"); - - int aliasing = int(hGrp->GetInt("AntiAliasing", int(Gui::View3DInventorViewer::None))); + int aliasing = int(Multisample::readMSAAFromSettings()); int index = ui->comboAliasing->findData(aliasing); if (index != -1) { ui->comboAliasing->setCurrentIndex(index); diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index d7020b280a..d168c25f55 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -95,6 +95,7 @@ #include "Document.h" #include "GLPainter.h" #include "MainWindow.h" +#include "Multisample.h" #include "NaviCube.h" #include "NavigationStyle.h" #include "Selection.h" @@ -1965,25 +1966,8 @@ void View3DInventorViewer::clearGraphicsItems() int View3DInventorViewer::getNumSamples() { - long samples = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/View")->GetInt("AntiAliasing", 0); - - // NOLINTBEGIN - switch (samples) { - case View3DInventorViewer::MSAA2x: - return 2; - case View3DInventorViewer::MSAA4x: - return 4; - case View3DInventorViewer::MSAA6x: - return 6; - case View3DInventorViewer::MSAA8x: - return 8; - case View3DInventorViewer::Smoothing: - return 1; - default: - return 0; - } - // NOLINTEND + Gui::AntiAliasing msaa = Multisample::readMSAAFromSettings(); + return Multisample::toSamples(msaa); } GLenum View3DInventorViewer::getInternalTextureFormat() diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 5d0e2597ab..3e581c73f3 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -110,22 +110,6 @@ public: }; //@} - /** @name Anti-Aliasing modes of the rendered 3D scene - * Specifies Anti-Aliasing (AA) method - * - Smoothing enables OpenGL line and vertex smoothing (basically deprecated) - * - MSAA is hardware multi sampling (with 2, 4 or 8 passes), a quite common and efficient AA technique - */ - //@{ - enum AntiAliasing { - None = 0, - Smoothing = 1, - MSAA2x = 2, - MSAA4x = 3, - MSAA6x = 5, - MSAA8x = 4 - }; - //@} - /** @name Render mode */ //@{ From c644736e7514d46d90f1c122078ae2f20e28bc42 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 11 Jul 2024 17:40:55 +0200 Subject: [PATCH 3/4] Gui: Allow to set MSAA 4x option Fixes #15369 --- src/Gui/PreferencePages/DlgSettings3DView.ui | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Gui/PreferencePages/DlgSettings3DView.ui b/src/Gui/PreferencePages/DlgSettings3DView.ui index 0854dd66a5..bac76fd636 100644 --- a/src/Gui/PreferencePages/DlgSettings3DView.ui +++ b/src/Gui/PreferencePages/DlgSettings3DView.ui @@ -265,7 +265,7 @@ but slower response to any scene changes. - + 120 @@ -275,12 +275,6 @@ but slower response to any scene changes. What kind of multisample anti-aliasing is used - - AntiAliasing - - - View - From cde1a6412f926d32af7ce10b2f7838928cfaf669 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 11 Jul 2024 17:57:02 +0200 Subject: [PATCH 4/4] Gui: Ignore readability-convert-member-functions-to-static for Multisample::testSamples --- src/Gui/Multisample.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Gui/Multisample.cpp b/src/Gui/Multisample.cpp index b97e06b25a..b00f5d2620 100644 --- a/src/Gui/Multisample.cpp +++ b/src/Gui/Multisample.cpp @@ -57,6 +57,7 @@ Multisample::Multisample() context.makeCurrent(&offscreen); } +// NOLINTNEXTLINE(readability-convert-member-functions-to-static) bool Multisample::testSamples(int num) const { // This is always true