lightstyle stuff
This commit is contained in:
parent
901e87bce8
commit
18a5b37d4f
|
|
@ -30,6 +30,7 @@ See file, 'COPYING', for details.
|
|||
#include <QTime>
|
||||
#include <fmt/core.h>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QOpenGLDebugLogger>
|
||||
#include <QStandardPaths>
|
||||
#include <QDateTime>
|
||||
|
||||
|
|
@ -100,17 +101,18 @@ in vec2 uv;
|
|||
in vec2 lightmap_uv;
|
||||
in vec3 normal;
|
||||
flat in vec3 flat_color;
|
||||
flat in uint styles;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D texture_sampler;
|
||||
uniform sampler2D lightmap_sampler;
|
||||
uniform sampler2DArray lightmap_sampler;
|
||||
uniform float opacity;
|
||||
uniform bool lightmap_only;
|
||||
uniform bool fullbright;
|
||||
uniform bool drawnormals;
|
||||
uniform bool showtris;
|
||||
uniform bool drawflat;
|
||||
uniform float style_scalars[256];
|
||||
|
||||
void main() {
|
||||
if (drawnormals) {
|
||||
|
|
@ -120,7 +122,20 @@ void main() {
|
|||
color = vec4(flat_color, opacity);
|
||||
} else {
|
||||
vec3 texcolor = lightmap_only ? vec3(0.5) : texture(texture_sampler, uv).rgb;
|
||||
vec3 lmcolor = fullbright ? vec3(0.5) : texture(lightmap_sampler, lightmap_uv).rgb;
|
||||
vec3 lmcolor = fullbright ? vec3(0.5) : vec3(0);
|
||||
|
||||
if (!fullbright)
|
||||
{
|
||||
for (uint i = 0u; i < 32u; i += 8u)
|
||||
{
|
||||
uint style = (styles >> i) & 0xFFu;
|
||||
|
||||
if (style == 0xFFu)
|
||||
break;
|
||||
|
||||
lmcolor += texture(lightmap_sampler, vec3(lightmap_uv, (float) style)).rgb * style_scalars[style];
|
||||
}
|
||||
}
|
||||
|
||||
// 2.0 for overbright
|
||||
color = vec4(texcolor * lmcolor * 2.0, opacity);
|
||||
|
|
@ -136,11 +151,13 @@ layout (location = 1) in vec2 vertex_uv;
|
|||
layout (location = 2) in vec2 vertex_lightmap_uv;
|
||||
layout (location = 3) in vec3 vertex_normal;
|
||||
layout (location = 4) in vec3 vertex_flat_color;
|
||||
layout (location = 5) in uint vertex_styles;
|
||||
|
||||
out vec2 uv;
|
||||
out vec2 lightmap_uv;
|
||||
out vec3 normal;
|
||||
flat out vec3 flat_color;
|
||||
flat out uint styles;
|
||||
|
||||
uniform mat4 MVP;
|
||||
|
||||
|
|
@ -151,13 +168,27 @@ void main() {
|
|||
lightmap_uv = vertex_lightmap_uv;
|
||||
normal = vertex_normal;
|
||||
flat_color = vertex_flat_color;
|
||||
styles = vertex_styles;
|
||||
}
|
||||
)";
|
||||
|
||||
void GLView::handleLoggedMessage(const QOpenGLDebugMessage &debugMessage)
|
||||
{
|
||||
qDebug() << debugMessage.message();
|
||||
}
|
||||
|
||||
void GLView::initializeGL()
|
||||
{
|
||||
initializeOpenGLFunctions();
|
||||
|
||||
QOpenGLContext *ctx = QOpenGLContext::currentContext();
|
||||
QOpenGLDebugLogger *logger = new QOpenGLDebugLogger(this);
|
||||
|
||||
logger->initialize(); // initializes in the current context, i.e. ctx
|
||||
|
||||
connect(logger, &QOpenGLDebugLogger::messageLogged, this, &GLView::handleLoggedMessage);
|
||||
logger->startLogging();
|
||||
|
||||
// set up shader
|
||||
|
||||
m_program = new QOpenGLShaderProgram();
|
||||
|
|
@ -178,8 +209,8 @@ void GLView::initializeGL()
|
|||
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");
|
||||
m_program_showtris_location = m_program->uniformLocation("showtris");
|
||||
m_program_drawflat_location = m_program->uniformLocation("drawflat");
|
||||
m_program_style_scalars_location = m_program->uniformLocation("style_scalars");
|
||||
m_program->release();
|
||||
|
||||
m_program_wireframe->bind();
|
||||
|
|
@ -232,9 +263,12 @@ void GLView::paintGL()
|
|||
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);
|
||||
m_program->setUniformValue(m_program_showtris_location, m_showTris);
|
||||
m_program->setUniformValue(m_program_drawflat_location, m_drawFlat);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
m_program->setUniformValue(m_program_style_scalars_location + i, 1.f);
|
||||
}
|
||||
|
||||
// opaque draws
|
||||
for (auto &draw : m_drawcalls) {
|
||||
if (draw.opacity != 1.0f)
|
||||
|
|
@ -316,6 +350,17 @@ void GLView::setKeepOrigin(bool keeporigin)
|
|||
m_keepOrigin = keeporigin;
|
||||
}
|
||||
|
||||
void GLView::setLightStyleIntensity(int style_id, int intensity)
|
||||
{
|
||||
makeCurrent();
|
||||
m_program->bind();
|
||||
m_program->setUniformValue(m_program_style_scalars_location + style_id, intensity / 200.f);
|
||||
m_program->release();
|
||||
doneCurrent();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void GLView::takeScreenshot(QString destPath, int w, int h)
|
||||
{
|
||||
// update aspect ratio
|
||||
|
|
@ -347,12 +392,10 @@ void GLView::takeScreenshot(QString destPath, int w, int h)
|
|||
}
|
||||
|
||||
void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries_t &bspx,
|
||||
const std::vector<entdict_t> &entities, const settings::common_settings &settings)
|
||||
const std::vector<entdict_t> &entities, const full_atlas_t &lightmap, const settings::common_settings &settings)
|
||||
{
|
||||
img::load_textures(&bsp, settings);
|
||||
|
||||
// build lightmap atlas
|
||||
auto atlas = build_lightmap_atlas(bsp, bspx, false, true);
|
||||
auto facenormals = BSPX_FaceNormals(bsp, bspx);
|
||||
|
||||
// NOTE: according to https://doc.qt.io/qt-6/qopenglwidget.html#resource-initialization-and-cleanup
|
||||
|
|
@ -365,17 +408,32 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
m_vbo.allocate(0);
|
||||
m_indexBuffer.allocate(0);
|
||||
|
||||
// upload lightmap atlas
|
||||
int32_t highest_depth = 0;
|
||||
|
||||
for (auto &style : lightmap.style_to_lightmap_atlas) {
|
||||
highest_depth = max(highest_depth, style.first);
|
||||
}
|
||||
|
||||
// upload lightmap atlases
|
||||
{
|
||||
const auto &lm_tex = atlas.style_to_lightmap_atlas.at(0);
|
||||
const auto &lm_tex = lightmap.style_to_lightmap_atlas.begin()->second;
|
||||
|
||||
lightmap_texture =
|
||||
std::make_unique<QOpenGLTexture>(QImage(reinterpret_cast<const uint8_t *>(lm_tex.pixels.data()),
|
||||
lm_tex.width, lm_tex.height, QImage::Format_RGBA8888));
|
||||
std::make_unique<QOpenGLTexture>(QOpenGLTexture::Target2DArray);
|
||||
lightmap_texture->setSize(lm_tex.width, lm_tex.height);
|
||||
lightmap_texture->setLayers(highest_depth + 1);
|
||||
|
||||
lightmap_texture->setAutoMipMapGenerationEnabled(false);
|
||||
lightmap_texture->setMagnificationFilter(QOpenGLTexture::Linear);
|
||||
lightmap_texture->setMinificationFilter(QOpenGLTexture::Linear);
|
||||
|
||||
lightmap_texture->setFormat(QOpenGLTexture::TextureFormat::RGBAFormat);
|
||||
|
||||
lightmap_texture->allocateStorage();
|
||||
|
||||
for (auto &style : lightmap.style_to_lightmap_atlas) {
|
||||
lightmap_texture->setData(0, style.first, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, reinterpret_cast<const void *>(style.second.pixels.data()));
|
||||
}
|
||||
}
|
||||
|
||||
// this determines what can be batched together in a draw call
|
||||
|
|
@ -463,6 +521,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
qvec2f lightmap_uv;
|
||||
qvec3f normal;
|
||||
qvec3f flat_color;
|
||||
uint32_t styles;
|
||||
};
|
||||
std::vector<vertex_t> verts;
|
||||
std::vector<uint32_t> indexBuffer;
|
||||
|
|
@ -493,7 +552,7 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
|
||||
const size_t first_vertex_of_face = verts.size();
|
||||
|
||||
const auto lm_uvs = atlas.facenum_to_lightmap_uvs.at(fnum);
|
||||
const auto lm_uvs = lightmap.facenum_to_lightmap_uvs.at(fnum);
|
||||
|
||||
// output a vertex for each vertex of the face
|
||||
for (int j = 0; j < f->numedges; ++j) {
|
||||
|
|
@ -513,11 +572,14 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
vertex_normal = plane_normal;
|
||||
}
|
||||
|
||||
verts.push_back({.pos = pos + model_offset,
|
||||
verts.push_back({
|
||||
.pos = pos + model_offset,
|
||||
.uv = uv,
|
||||
.lightmap_uv = lightmap_uv,
|
||||
.normal = vertex_normal,
|
||||
.flat_color = flat_color});
|
||||
.flat_color = flat_color,
|
||||
.styles = (uint32_t) (f->styles[0]) | (uint32_t) (f->styles[1] << 8) | (uint32_t) (f->styles[2] << 16) | (uint32_t) (f->styles[3] << 24)
|
||||
});
|
||||
}
|
||||
|
||||
// output the vertex indices for this face
|
||||
|
|
@ -571,6 +633,11 @@ void GLView::renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries
|
|||
glVertexAttribPointer(
|
||||
4 /* attrib */, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void *)offsetof(vertex_t, flat_color));
|
||||
|
||||
// styles
|
||||
glEnableVertexAttribArray(5 /* attrib */);
|
||||
glVertexAttribIPointer(
|
||||
5 /* attrib */, 1, GL_UNSIGNED_INT, sizeof(vertex_t), (void *)offsetof(vertex_t, styles));
|
||||
|
||||
doneCurrent();
|
||||
|
||||
// schedule repaint
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ See file, 'COPYING', for details.
|
|||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLDebugMessage>
|
||||
#include <QElapsedTimer>
|
||||
#include <QVector3D>
|
||||
#include <QMatrix4x4>
|
||||
|
|
@ -35,6 +36,7 @@ See file, 'COPYING', for details.
|
|||
#include <common/cmdlib.hh>
|
||||
#include <common/entdata.h>
|
||||
#include <common/bspfile.hh>
|
||||
#include <common/bspinfo.hh>
|
||||
|
||||
enum class keys_t : uint32_t
|
||||
{
|
||||
|
|
@ -105,8 +107,8 @@ private:
|
|||
int m_program_lightmap_only_location = 0;
|
||||
int m_program_fullbright_location = 0;
|
||||
int m_program_drawnormals_location = 0;
|
||||
int m_program_showtris_location = 0;
|
||||
int m_program_drawflat_location = 0;
|
||||
int m_program_style_scalars_location = 0;
|
||||
|
||||
// uniform locations (wireframe program)
|
||||
int m_program_wireframe_mvp_location = 0;
|
||||
|
|
@ -116,7 +118,7 @@ public:
|
|||
~GLView();
|
||||
|
||||
void renderBSP(const QString &file, const mbsp_t &bsp, const bspxentries_t &bspx,
|
||||
const std::vector<entdict_t> &entities, const settings::common_settings &settings);
|
||||
const std::vector<entdict_t> &entities, const full_atlas_t &lightmap, const settings::common_settings &settings);
|
||||
void setCamera(const qvec3d &origin, const qvec3d &fwd);
|
||||
void setLighmapOnly(bool lighmapOnly);
|
||||
void setFullbright(bool fullbright);
|
||||
|
|
@ -124,6 +126,8 @@ public:
|
|||
void setShowTris(bool showtris);
|
||||
void setDrawFlat(bool drawflat);
|
||||
void setKeepOrigin(bool keeporigin);
|
||||
// intensity = 0 to 200
|
||||
void setLightStyleIntensity(int style_id, int intensity);
|
||||
const bool &getKeepOrigin() const { return m_keepOrigin; }
|
||||
|
||||
void takeScreenshot(QString destPath, int w, int h);
|
||||
|
|
@ -136,6 +140,7 @@ protected:
|
|||
private:
|
||||
void startMovementTimer();
|
||||
void stopMovementTimer();
|
||||
void handleLoggedMessage(const QOpenGLDebugMessage &debugMessage);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
|
|
|
|||
|
|
@ -37,11 +37,16 @@ See file, 'COPYING', for details.
|
|||
#include <QGroupBox>
|
||||
#include <QRadioButton>
|
||||
#include <QTimer>
|
||||
#include <QScrollArea>
|
||||
#include <QSlider>
|
||||
#include <QFrame>
|
||||
#include <QLabel>
|
||||
|
||||
#include <common/bspfile.hh>
|
||||
#include <qbsp/qbsp.hh>
|
||||
#include <vis/vis.hh>
|
||||
#include <light/light.hh>
|
||||
#include <common/bspinfo.hh>
|
||||
|
||||
#include "glview.h"
|
||||
|
||||
|
|
@ -92,6 +97,20 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
formLayout->addRow(showtris);
|
||||
formLayout->addRow(keepposition);
|
||||
|
||||
lightstyles = new QVBoxLayout();
|
||||
|
||||
auto *lightstyles_group = new QGroupBox(tr("Lightstyles"));
|
||||
lightstyles_group->setLayout(lightstyles);
|
||||
|
||||
auto *scrollArea = new QScrollArea();
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setWidget(lightstyles_group);
|
||||
scrollArea->setBackgroundRole(QPalette::Window);
|
||||
scrollArea->setFrameShadow(QFrame::Plain);
|
||||
scrollArea->setFrameShape(QFrame::NoFrame);
|
||||
|
||||
formLayout->addRow(scrollArea);
|
||||
|
||||
auto *form = new QWidget();
|
||||
form->setLayout(formLayout);
|
||||
|
||||
|
|
@ -310,6 +329,48 @@ void MainWindow::reload()
|
|||
loadFileInternal(m_mapFile, true);
|
||||
}
|
||||
|
||||
class QLightStyleSlider : public QFrame
|
||||
{
|
||||
public:
|
||||
int32_t style_id;
|
||||
|
||||
QLightStyleSlider(int32_t style_id, GLView *glView) :
|
||||
QFrame(),
|
||||
style_id(style_id),
|
||||
glView(glView)
|
||||
{
|
||||
auto *style_layout = new QHBoxLayout();
|
||||
|
||||
auto *style = new QSlider(Qt::Horizontal);
|
||||
style->setRange(0, 200);
|
||||
style->setValue(100);
|
||||
style->setSingleStep(1);
|
||||
style->setTickPosition(QSlider::TicksBothSides);
|
||||
style->setTickInterval(50);
|
||||
|
||||
connect(style, &QSlider::valueChanged,
|
||||
this, &QLightStyleSlider::setValue);
|
||||
|
||||
auto *style_label = new QLabel();
|
||||
style_label->setText(QString::asprintf("%i", style_id));
|
||||
|
||||
style_layout->addWidget(style_label);
|
||||
style_layout->addWidget(style);
|
||||
|
||||
setLayout(style_layout);
|
||||
setFrameShadow(QFrame::Plain);
|
||||
setFrameShape(QFrame::NoFrame);
|
||||
}
|
||||
|
||||
private:
|
||||
void setValue(int value)
|
||||
{
|
||||
glView->setLightStyleIntensity(style_id, value);
|
||||
}
|
||||
|
||||
GLView *glView;
|
||||
};
|
||||
|
||||
void MainWindow::loadFileInternal(const QString &file, bool is_reload)
|
||||
{
|
||||
qDebug() << "loadFileInternal " << file;
|
||||
|
|
@ -370,7 +431,10 @@ void MainWindow::loadFileInternal(const QString &file, bool is_reload)
|
|||
|
||||
auto ents = EntData_Parse(bsp);
|
||||
|
||||
glView->renderBSP(file, bsp, d.bspx.entries, ents, render_settings);
|
||||
// build lightmap atlas
|
||||
auto atlas = build_lightmap_atlas(bsp, d.bspx.entries, false, true);
|
||||
|
||||
glView->renderBSP(file, bsp, d.bspx.entries, ents, atlas, render_settings);
|
||||
|
||||
if (!is_reload && !glView->getKeepOrigin()) {
|
||||
for (auto &ent : ents) {
|
||||
|
|
@ -393,4 +457,17 @@ void MainWindow::loadFileInternal(const QString &file, bool is_reload)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set lightstyle data
|
||||
if (!is_reload) {
|
||||
while ( QWidget* w = lightstyles->parentWidget()->findChild<QWidget*>(QString(), Qt::FindDirectChildrenOnly) ) {
|
||||
delete w;
|
||||
}
|
||||
|
||||
for (auto &style_entry : atlas.style_to_lightmap_atlas) {
|
||||
|
||||
auto *style = new QLightStyleSlider(style_entry.first, glView);
|
||||
lightstyles->addWidget(style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ See file, 'COPYING', for details.
|
|||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class GLView;
|
||||
class QFileSystemWatcher;
|
||||
|
|
@ -61,4 +62,5 @@ private:
|
|||
QLineEdit *qbsp_options;
|
||||
QLineEdit *vis_options;
|
||||
QLineEdit *light_options;
|
||||
QVBoxLayout *lightstyles;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue