diff --git a/lightpreview/glview.cpp b/lightpreview/glview.cpp index d7e5f9a0..c5f21852 100644 --- a/lightpreview/glview.cpp +++ b/lightpreview/glview.cpp @@ -107,6 +107,7 @@ out vec4 color; uniform sampler2D texture_sampler; uniform sampler2DArray lightmap_sampler; uniform float opacity; +uniform bool alpha_test; uniform bool lightmap_only; uniform bool fullbright; uniform bool drawnormals; @@ -121,6 +122,11 @@ void main() { color = vec4(flat_color, opacity); } else { vec3 texcolor = lightmap_only ? vec3(0.5) : texture(texture_sampler, uv).rgb; + + if (!lightmap_only && alpha_test && texture(texture_sampler, uv).a < 0.1) { + discard; + } + vec3 lmcolor = fullbright ? vec3(0.5) : vec3(0); if (!fullbright) @@ -292,6 +298,7 @@ void GLView::initializeGL() m_program_texture_sampler_location = m_program->uniformLocation("texture_sampler"); m_program_lightmap_sampler_location = m_program->uniformLocation("lightmap_sampler"); m_program_opacity_location = m_program->uniformLocation("opacity"); + m_program_alpha_test_location = m_program->uniformLocation("alpha_test"); m_program_lightmap_only_location = m_program->uniformLocation("lightmap_only"); m_program_fullbright_location = m_program->uniformLocation("fullbright"); m_program_drawnormals_location = m_program->uniformLocation("drawnormals"); @@ -382,6 +389,7 @@ void GLView::paintGL() m_program->setUniformValue(m_program_texture_sampler_location, 0 /* texture unit */); m_program->setUniformValue(m_program_lightmap_sampler_location, 1 /* texture unit */); m_program->setUniformValue(m_program_opacity_location, 1.0f); + m_program->setUniformValue(m_program_alpha_test_location, false); m_program->setUniformValue(m_program_lightmap_only_location, m_lighmapOnly); m_program->setUniformValue(m_program_fullbright_location, m_fullbright); m_program->setUniformValue(m_program_drawnormals_location, m_drawNormals); @@ -408,6 +416,12 @@ void GLView::paintGL() active_program->bind(); } + if (draw.key.alpha_test) { + m_program->setUniformValue(m_program_alpha_test_location, true); + } else { + m_program->setUniformValue(m_program_alpha_test_location, false); + } + draw.texture->bind(0 /* texture unit */); lightmap_texture->bind(1 /* texture unit */); @@ -431,6 +445,12 @@ void GLView::paintGL() active_program->bind(); } + if (draw.key.alpha_test) { + m_program->setUniformValue(m_program_alpha_test_location, true); + } else { + m_program->setUniformValue(m_program_alpha_test_location, false); + } + draw.texture->bind(0 /* texture unit */); lightmap_texture->bind(1 /* texture unit */); @@ -631,6 +651,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries // determine opacity float opacity = 1.0f; + bool alpha_test = false; if (bsp.loadversion->game->id == GAME_QUAKE_II) { @@ -648,10 +669,14 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries if (texinfo->flags.native & Q2_SURF_TRANS66) { opacity = 0.66f; } + + if (texinfo->flags.native & Q2_SURF_ALPHATEST) { + alpha_test = true; + } } } - material_key k = {.program = program, .texname = t, .opacity = opacity}; + material_key k = {.program = program, .texname = t, .opacity = opacity, .alpha_test = alpha_test}; faces_by_material_key[k].push_back({.face = &f, .model_offset = origin}); } } diff --git a/lightpreview/glview.h b/lightpreview/glview.h index f46ea881..8fd2d56b 100644 --- a/lightpreview/glview.h +++ b/lightpreview/glview.h @@ -93,8 +93,9 @@ private: QOpenGLShaderProgram *program; std::string texname; float opacity = 1.f; + bool alpha_test = false; - auto as_tuple() const { return std::make_tuple(program, texname, opacity); } + auto as_tuple() const { return std::make_tuple(program, texname, opacity, alpha_test); } bool operator<(const material_key &other) const { return as_tuple() < other.as_tuple(); } }; @@ -117,6 +118,7 @@ private: int m_program_texture_sampler_location = 0; int m_program_lightmap_sampler_location = 0; int m_program_opacity_location = 0; + int m_program_alpha_test_location = 0; int m_program_lightmap_only_location = 0; int m_program_fullbright_location = 0; int m_program_drawnormals_location = 0; diff --git a/lightpreview/mainwindow.cpp b/lightpreview/mainwindow.cpp index 1043ea99..1b58da82 100644 --- a/lightpreview/mainwindow.cpp +++ b/lightpreview/mainwindow.cpp @@ -221,7 +221,7 @@ void MainWindow::fileReloadTimerExpired() if (currentSize != m_fileSize) { qDebug() << "size changed since last write, restarting timer"; - m_fileReloadTimer->start(100); + m_fileReloadTimer->start(150); return; } @@ -254,7 +254,7 @@ void MainWindow::loadFile(const QString &file) m_fileSize = QFileInfo(m_mapFile).size(); // start timer - m_fileReloadTimer->start(25); + m_fileReloadTimer->start(150); }); loadFileInternal(file, false);