Sun, 09 Apr 2023 12:23:32 +0300
`PartRenderer::renderVao` no longer throws if bad array class is given, this is now checked on compile time
#include "src/mainwindow.h" #include "src/modelsubwindow.h" #include "src/version.h" #include <QTextBrowser> #include <QOpenGLWidget> #include <ui_about.h> static constexpr MemberData<MainWindow, QAction*, gl::RenderStyle> renderStyleButtons[] = { { offsetof(MainWindow, actionRenderStyleNormal), gl::RenderStyle::Normal }, { offsetof(MainWindow, actionRenderStyleBfc), gl::RenderStyle::BfcRedGreen }, { offsetof(MainWindow, actionRenderStyleRandom), gl::RenderStyle::RandomColors }, { offsetof(MainWindow, actionRenderStylePickScene), gl::RenderStyle::PickScene }, }; MainWindow::MainWindow(QWidget *parent) : QMainWindow{parent} { this->setupUi(this); for (const auto& memberData : ::renderStyleButtons) { QAction* action = memberData.memberInstance(this); const gl::RenderStyle newStyle = memberData.payload; QObject::connect(action, &QAction::triggered, [this, newStyle]{ Q_EMIT this->renderStyleSelected(newStyle); this->setRenderStyle(newStyle); }); } this->connect(this->actionAbout, &QAction::triggered, this, &MainWindow::showAboutDialog); } void MainWindow::setRenderStyle(gl::RenderStyle style) { for (const auto& memberData : ::renderStyleButtons) { QAction* const action = memberData.memberInstance(this); const gl::RenderStyle buttonRenderStyle = memberData.payload; action->setChecked(style == buttonRenderStyle); } } static QStringList getGLExtensions(QWidget* parent) { // We need to have GL activated at least once in order to able to retrieve // GL extensions properly. To make sure this is the case, we create a // temporary, plain OpenGL widget. While it is active, we call glewInit(). // If this is not done, this function will crash. QOpenGLWidget glWidget{parent}; glWidget.show(); glewInit(); GLint numExtensions; glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); QStringList extensionsList; for (GLint i = 0; i < numExtensions; i++) { const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); extensionsList.push_back(reinterpret_cast<const char*>(ext)); } glWidget.hide(); return extensionsList; } void MainWindow::showAboutDialog() { QDialog dialog{this}; Ui_About ui; ui.setupUi(&dialog); const char* glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION)); const QString extensions = getGLExtensions(this).join(" "); for (QTextBrowser* browser : dialog.findChildren<QTextBrowser*>()) { browser->setHtml( browser->toHtml() .replace("%APPNAME%", CMAKE_PROJECT_NAME) .replace("%COPYRIGHT%", COPYRIGHT) .replace("%QTVERSION%", qVersion()) .replace("%VERSION%", detailedVersionString(QLocale::LongFormat)) .replace("%REVDATE%", revisionDateString(QLocale::LongFormat)) .replace("%BUILDTYPE%", CMAKE_BUILD_TYPE) .replace("%COMPILER_ID%", CMAKE_CXX_COMPILER_ID) .replace("%COMPILER_VERSION%", CMAKE_CXX_COMPILER_VERSION) .replace("%COMPILER_FLAGS%", CMAKE_CXX_FLAGS) .replace("%COMPILER_CPU%", CMAKE_SYSTEM_PROCESSOR) .replace("%COMPILER_SYSTEM%", CMAKE_SYSTEM) .replace("%GLMVERSIONSTRING%", GLM_VERSION_MESSAGE) .replace("%GL_VERSION%", glVersion) .replace("%GL_EXTENSIONS%", extensions) ); } dialog.setWindowTitle(QObject::tr("About %1").arg(CMAKE_PROJECT_NAME)); dialog.exec(); }