diff --git a/lightpreview/glview.cpp b/lightpreview/glview.cpp index e982050c..27f541e3 100644 --- a/lightpreview/glview.cpp +++ b/lightpreview/glview.cpp @@ -551,6 +551,20 @@ void GLView::setLightStyleIntensity(int style_id, int intensity) update(); } +void GLView::setMagFilter(QOpenGLTexture::Filter filter) +{ + m_filter = filter; + + if (placeholder_texture) + placeholder_texture->setMagnificationFilter(m_filter); + + for (auto &dc : m_drawcalls) { + dc.texture->setMagnificationFilter(m_filter); + } + + update(); +} + void GLView::takeScreenshot(QString destPath, int w, int h) { // update aspect ratio @@ -632,7 +646,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries placeholder_texture->setSize(64, 64); placeholder_texture->setFormat(QOpenGLTexture::TextureFormat::RGBA8_UNorm); placeholder_texture->setAutoMipMapGenerationEnabled(true); - placeholder_texture->setMagnificationFilter(QOpenGLTexture::Linear); + placeholder_texture->setMagnificationFilter(m_filter); placeholder_texture->setMinificationFilter(QOpenGLTexture::Linear); placeholder_texture->allocateStorage(); @@ -752,19 +766,20 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries skybox_texture = std::make_shared(QOpenGLTexture::TargetCubeMap); - { QImage up_img; { - auto up = img::load_texture(fmt::format("env/{}up", skybox), false, bsp.loadversion->game, settings, true); - up_img = QImage((const uchar *) std::get<0>(up)->pixels.data(), std::get<0>(up)->width, std::get<0>(up)->height, QImage::Format_RGB32); + auto up = + img::load_texture(fmt::format("env/{}up", skybox), false, bsp.loadversion->game, settings, true); + up_img = QImage((const uchar *)std::get<0>(up)->pixels.data(), std::get<0>(up)->width, + std::get<0>(up)->height, QImage::Format_RGB32); up_img = std::move(up_img.transformed(QTransform().rotate(-90.0)).mirrored(false, true)); } skybox_texture->setSize(up_img.width(), up_img.height()); skybox_texture->setFormat(QOpenGLTexture::TextureFormat::RGBA8_UNorm); skybox_texture->setAutoMipMapGenerationEnabled(true); - skybox_texture->setMagnificationFilter(QOpenGLTexture::Linear); + skybox_texture->setMagnificationFilter(m_filter); skybox_texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); skybox_texture->setMaximumAnisotropy(16); skybox_texture->allocateStorage(); @@ -777,8 +792,10 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries { QImage down_img; { - auto down = img::load_texture(fmt::format("env/{}dn", skybox), false, bsp.loadversion->game, settings, true); - down_img = QImage((const uchar *) std::get<0>(down)->pixels.data(), std::get<0>(down)->width, std::get<0>(down)->height, QImage::Format_RGB32); + auto down = + img::load_texture(fmt::format("env/{}dn", skybox), false, bsp.loadversion->game, settings, true); + down_img = QImage((const uchar *)std::get<0>(down)->pixels.data(), std::get<0>(down)->width, + std::get<0>(down)->height, QImage::Format_RGB32); down_img = std::move(down_img.transformed(QTransform().rotate(90.0)).mirrored(true, false)); } @@ -788,8 +805,10 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries { QImage left_img; { - auto left = img::load_texture(fmt::format("env/{}lf", skybox), false, bsp.loadversion->game, settings, true); - left_img = QImage((const uchar *) std::get<0>(left)->pixels.data(), std::get<0>(left)->width, std::get<0>(left)->height, QImage::Format_RGB32); + auto left = + img::load_texture(fmt::format("env/{}lf", skybox), false, bsp.loadversion->game, settings, true); + left_img = QImage((const uchar *)std::get<0>(left)->pixels.data(), std::get<0>(left)->width, + std::get<0>(left)->height, QImage::Format_RGB32); left_img = std::move(left_img.transformed(QTransform().rotate(-90.0)).mirrored(true, false)); } skybox_texture->setData(0, 0, QOpenGLTexture::CubeMapNegativeX, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, @@ -798,8 +817,10 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries { QImage right_img; { - auto right = img::load_texture(fmt::format("env/{}rt", skybox), false, bsp.loadversion->game, settings, true); - right_img = QImage((const uchar *) std::get<0>(right)->pixels.data(), std::get<0>(right)->width, std::get<0>(right)->height, QImage::Format_RGB32); + auto right = + img::load_texture(fmt::format("env/{}rt", skybox), false, bsp.loadversion->game, settings, true); + right_img = QImage((const uchar *)std::get<0>(right)->pixels.data(), std::get<0>(right)->width, + std::get<0>(right)->height, QImage::Format_RGB32); right_img = std::move(right_img.transformed(QTransform().rotate(90.0)).mirrored(true, false)); } skybox_texture->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, @@ -808,8 +829,10 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries { QImage front_img; { - auto front = img::load_texture(fmt::format("env/{}ft", skybox), false, bsp.loadversion->game, settings, true); - front_img = QImage((const uchar *) std::get<0>(front)->pixels.data(), std::get<0>(front)->width, std::get<0>(front)->height, QImage::Format_RGB32); + auto front = + img::load_texture(fmt::format("env/{}ft", skybox), false, bsp.loadversion->game, settings, true); + front_img = QImage((const uchar *)std::get<0>(front)->pixels.data(), std::get<0>(front)->width, + std::get<0>(front)->height, QImage::Format_RGB32); front_img = std::move(front_img.mirrored(true, false)); } skybox_texture->setData(0, 0, QOpenGLTexture::CubeMapNegativeY, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, @@ -818,8 +841,10 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries { QImage back_img; { - auto back = img::load_texture(fmt::format("env/{}bk", skybox), false, bsp.loadversion->game, settings, true); - back_img = QImage((const uchar *) std::get<0>(back)->pixels.data(), std::get<0>(back)->width, std::get<0>(back)->height, QImage::Format_RGB32); + auto back = + img::load_texture(fmt::format("env/{}bk", skybox), false, bsp.loadversion->game, settings, true); + back_img = QImage((const uchar *)std::get<0>(back)->pixels.data(), std::get<0>(back)->width, + std::get<0>(back)->height, QImage::Format_RGB32); back_img = std::move(back_img.transformed(QTransform().rotate(-180.0)).mirrored(true, false)); } skybox_texture->setData(0, 0, QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, @@ -925,7 +950,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries qtexture->setMaximumAnisotropy(16); qtexture->setAutoMipMapGenerationEnabled(true); - qtexture->setMagnificationFilter(QOpenGLTexture::Linear); + qtexture->setMagnificationFilter(m_filter); qtexture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); } diff --git a/lightpreview/glview.h b/lightpreview/glview.h index ce8d1d39..e3aff7f3 100644 --- a/lightpreview/glview.h +++ b/lightpreview/glview.h @@ -82,6 +82,7 @@ private: bool m_showTris = false; bool m_drawFlat = false; bool m_keepOrigin = false; + QOpenGLTexture::Filter m_filter = QOpenGLTexture::Linear; QOpenGLVertexArrayObject m_vao; QOpenGLBuffer m_vbo; @@ -157,6 +158,7 @@ public: void setKeepOrigin(bool keeporigin); // intensity = 0 to 200 void setLightStyleIntensity(int style_id, int intensity); + void setMagFilter(QOpenGLTexture::Filter filter); const bool &getKeepOrigin() const { return m_keepOrigin; } void takeScreenshot(QString destPath, int w, int h); diff --git a/lightpreview/mainwindow.cpp b/lightpreview/mainwindow.cpp index 59bac52f..9e469e79 100644 --- a/lightpreview/mainwindow.cpp +++ b/lightpreview/mainwindow.cpp @@ -151,6 +151,8 @@ void MainWindow::createPropertiesSidebar() auto *keepposition = new QCheckBox(tr("Keep Camera Pos")); + nearest = new QCheckBox(tr("Nearest Filter")); + formLayout->addRow(tr("qbsp"), qbsp_options); formLayout->addRow(vis_checkbox, vis_options); formLayout->addRow(tr("light"), light_options); @@ -158,6 +160,7 @@ void MainWindow::createPropertiesSidebar() formLayout->addRow(rendermode_group); formLayout->addRow(showtris); formLayout->addRow(keepposition); + formLayout->addRow(nearest); lightstyles = new QVBoxLayout(); @@ -187,6 +190,10 @@ void MainWindow::createPropertiesSidebar() vis_checkbox->setChecked(s.value("vis_enabled").toBool()); vis_options->setText(s.value("vis_options").toString()); light_options->setText(s.value("light_options").toString()); + nearest->setChecked(s.value("nearest").toBool()); + if (nearest->isChecked()) { + glView->setMagFilter(QOpenGLTexture::Nearest); + } // setup event handlers @@ -197,6 +204,8 @@ void MainWindow::createPropertiesSidebar() connect(showtris, &QAbstractButton::toggled, this, [=](bool checked) { glView->setShowTris(checked); }); connect(drawflat, &QAbstractButton::toggled, this, [=](bool checked) { glView->setDrawFlat(checked); }); connect(keepposition, &QAbstractButton::toggled, this, [=](bool checked) { glView->setKeepOrigin(checked); }); + connect(nearest, &QAbstractButton::toggled, this, + [=](bool checked) { glView->setMagFilter(checked ? QOpenGLTexture::Nearest : QOpenGLTexture::Linear); }); connect(glView, &GLView::cameraMoved, this, &MainWindow::displayCameraPositionInfo); // set up load timer @@ -210,10 +219,10 @@ void MainWindow::createOutputLog() { QDockWidget *dock = new QDockWidget(tr("Output Log"), this); - auto *textEdit = new QTextEdit(); + m_outputTextEdit = new QTextEdit(); // finish dock widget setup - dock->setWidget(textEdit); + dock->setWidget(m_outputTextEdit); addDockWidget(Qt::BottomDockWidgetArea, dock); viewMenu->addAction(dock->toggleViewAction()); } @@ -511,6 +520,7 @@ void MainWindow::loadFileInternal(const QString &file, bool is_reload) s.setValue("vis_enabled", vis_checkbox->isChecked()); s.setValue("vis_options", vis_options->text()); s.setValue("light_options", light_options->text()); + s.setValue("nearest", nearest->isChecked()); // update title bar setWindowFilePath(file); @@ -522,39 +532,44 @@ void MainWindow::loadFileInternal(const QString &file, bool is_reload) settings::common_settings render_settings; - if (fs_path.extension().compare(".bsp") == 0) { + try { + if (fs_path.extension().compare(".bsp") == 0) { - LoadBSPFile(fs_path, &m_bspdata); + LoadBSPFile(fs_path, &m_bspdata); - auto opts = ParseArgs(light_options); + auto opts = ParseArgs(light_options); - std::vector argPtrs; + std::vector argPtrs; - argPtrs.push_back(""); + argPtrs.push_back(""); - for (const std::string &arg : opts) { - argPtrs.push_back(arg.data()); + for (const std::string &arg : opts) { + argPtrs.push_back(arg.data()); + } + + render_settings.preinitialize(argPtrs.size(), argPtrs.data()); + render_settings.initialize(argPtrs.size() - 1, argPtrs.data() + 1); + render_settings.postinitialize(argPtrs.size(), argPtrs.data()); + + m_bspdata.version->game->init_filesystem(fs_path, render_settings); + + ConvertBSPFormat(&m_bspdata, &bspver_generic); + + } else { + m_bspdata = QbspVisLight_Common(fs_path, ParseArgs(qbsp_options), ParseArgs(vis_options), + ParseArgs(light_options), vis_checkbox->isChecked()); + + // FIXME: move to a lightpreview_settings + settings::common_settings settings; + + // FIXME: copy the -path args from light + settings.paths.copy_from(::light_options.paths); + + m_bspdata.loadversion->game->init_filesystem(file.toStdString(), settings); } - - render_settings.preinitialize(argPtrs.size(), argPtrs.data()); - render_settings.initialize(argPtrs.size() - 1, argPtrs.data() + 1); - render_settings.postinitialize(argPtrs.size(), argPtrs.data()); - - m_bspdata.version->game->init_filesystem(fs_path, render_settings); - - ConvertBSPFormat(&m_bspdata, &bspver_generic); - - } else { - m_bspdata = QbspVisLight_Common(fs_path, ParseArgs(qbsp_options), ParseArgs(vis_options), - ParseArgs(light_options), vis_checkbox->isChecked()); - - // FIXME: move to a lightpreview_settings - settings::common_settings settings; - - // FIXME: copy the -path args from light - settings.paths.copy_from(::light_options.paths); - - m_bspdata.loadversion->game->init_filesystem(file.toStdString(), settings); + } catch (const settings::parse_exception &p) { + m_outputTextEdit->append(QString::fromUtf8(p.what()) + QString::fromLatin1("\n")); + return; } const auto &bsp = std::get(m_bspdata.bsp); diff --git a/lightpreview/mainwindow.h b/lightpreview/mainwindow.h index 68449428..e704c193 100644 --- a/lightpreview/mainwindow.h +++ b/lightpreview/mainwindow.h @@ -29,6 +29,7 @@ class QFileSystemWatcher; class QLineEdit; class QCheckBox; class QStringList; +class QTextEdit; class MainWindow : public QMainWindow { @@ -70,6 +71,7 @@ private: GLView *glView = nullptr; QCheckBox *vis_checkbox = nullptr; + QCheckBox *nearest = nullptr; QLineEdit *qbsp_options = nullptr; QLineEdit *vis_options = nullptr; @@ -78,4 +80,6 @@ private: QMenu *viewMenu = nullptr; QMenu *openRecentMenu = nullptr; + + QTextEdit *m_outputTextEdit = nullptr; };