lightpreview: add "Nearest filter" checkbox

This commit is contained in:
Eric Wasylishen 2023-06-11 21:31:57 -06:00
parent 8034215b3a
commit 35fa5bd129
4 changed files with 91 additions and 45 deletions

View File

@ -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>(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);
}

View File

@ -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);

View File

@ -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<const char *> argPtrs;
std::vector<const char *> 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<mbsp_t>(m_bspdata.bsp);

View File

@ -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;
};