asset browser: implement render toggles, particle and box rendering

This commit is contained in:
sshumakov3
2020-11-17 13:56:04 +03:00
parent 4ef600a4f9
commit 9c62263a36
7 changed files with 263 additions and 98 deletions

View File

@@ -63,6 +63,8 @@ void ModelViewer::resizeGL(int w, int h)
void ModelViewer::tick(float dt)
{
PreviewRenderer::tick(dt);
if (turn)
{
_camera.add_to_yaw(math::degrees(turn));
@@ -84,8 +86,6 @@ void ModelViewer::tick(float dt)
_camera.move_vertical(updown, dt);
}
_animtime += dt * 1000.0f;
}
void ModelViewer::setModel(std::string const& filename)

View File

@@ -32,10 +32,10 @@ namespace noggit
Q_OBJECT
public:
explicit ModelViewer(QWidget* parent = nullptr);
void setModel(std::string const& filename) override;
void setMoveSensitivity(float s) { _move_sensitivity = s / 30.0f; }
float getMoveSensitivity() { return _move_sensitivity; }
explicit ModelViewer(QWidget* parent = nullptr);
void setModel(std::string const& filename) override;
void setMoveSensitivity(float s) { _move_sensitivity = s / 30.0f; }
float getMoveSensitivity() { return _move_sensitivity; }
signals:
void resized();
@@ -52,7 +52,7 @@ namespace noggit
qreal _last_update = 0.f;
float _move_sensitivity = 0.5f;
void tick(float dt);
void tick(float dt) override;
float aspect_ratio() const override;
void initializeGL() override;

View File

@@ -3,6 +3,7 @@
#include <noggit/Log.h>
#include <noggit/ContextObject.hpp>
#include <noggit/ui/FramelessWindow.hpp>
#include <noggit/ui/font_noggit.hpp>
#include <QStandardItemModel>
#include <QItemSelectionModel>
@@ -15,6 +16,7 @@
#include <QSlider>
using namespace noggit::Red::AssetBrowser::Ui;
using namespace noggit::ui;
AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
: QMainWindow(parent, Qt::Window)
@@ -53,6 +55,12 @@ AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
}
);
viewport_overlay_ui->toggleAnimationButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_ANIMATION));
viewport_overlay_ui->toggleModelsButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_DOODADS));
viewport_overlay_ui->toggleParticlesButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_UNUSED));
viewport_overlay_ui->toggleBoundingBoxButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_WITH_BOX));
viewport_overlay_ui->toggleWMOButton->setIcon(font_noggit_icon(font_noggit::icons::VISIBILITY_WMO));
ui->viewport->installEventFilter(overlay);
overlay->show();
@@ -173,6 +181,29 @@ AssetBrowserWidget::AssetBrowserWidget(QWidget *parent)
}
);
// Render toggles
connect(viewport_overlay_ui->toggleWMOButton, &QPushButton::clicked,
[this]() {ui->viewport->_draw_wmo.toggle();});
connect(viewport_overlay_ui->toggleBoundingBoxButton, &QPushButton::clicked,
[this]() {ui->viewport->_draw_boxes.toggle();});
connect(viewport_overlay_ui->toggleParticlesButton, &QPushButton::clicked,
[this]() {ui->viewport->_draw_particles.toggle();});
connect(viewport_overlay_ui->toggleModelsButton, &QPushButton::clicked,
[this]() {ui->viewport->_draw_models.toggle();});
connect(viewport_overlay_ui->toggleAnimationButton, &QPushButton::clicked,
[this]() {ui->viewport->_draw_animated.toggle();});
connect(&ui->viewport->_draw_wmo, &bool_toggle_property::changed,
[this](bool state) {ui->viewport->_draw_wmo.set(state);});
connect(&ui->viewport->_draw_boxes, &bool_toggle_property::changed,
[this](bool state) {ui->viewport->_draw_boxes.set(state);});
connect(&ui->viewport->_draw_particles, &bool_toggle_property::changed,
[this](bool state) {ui->viewport->_draw_particles.set(state);});
connect(&ui->viewport->_draw_models, &bool_toggle_property::changed,
[this](bool state) {ui->viewport->_draw_models.set(state);});
connect(&ui->viewport->_draw_animated, &bool_toggle_property::changed,
[this](bool state) {ui->viewport->_draw_animated.set(state);});
_wmo_group_and_lod_regex = QRegularExpression(".+_\\d{3}(_lod.+)*.wmo");
updateModelData();

View File

@@ -31,7 +31,6 @@ namespace noggit
PreviewRenderer* _preview_renderer;
QRegularExpression _wmo_group_and_lod_regex;
void updateModelData();
void recurseDirectory(Model::TreeManager& tree_mgr, const QString& s_dir, const QString& project_dir);

View File

@@ -30,67 +30,17 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="spacing">
<number>-1</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_8">
<property name="spacing">
<number>-1</number>
</property>
<item>
<widget class="QPushButton" name="toggleAnimationButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="toggleParticlesButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QPushButton" name="toggleModelsButton">
<property name="sizePolicy">
@@ -101,8 +51,8 @@
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
@@ -111,6 +61,9 @@
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Draw models</string>
</property>
<property name="text">
<string/>
</property>
@@ -132,8 +85,8 @@
</property>
<property name="minimumSize">
<size>
<width>16</width>
<height>16</height>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
@@ -142,6 +95,77 @@
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Draw WMOs</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="toggleParticlesButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Draw particles</string>
</property>
<property name="text">
<string/>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="toggleAnimationButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Draw animation</string>
</property>
<property name="text">
<string/>
</property>
@@ -161,12 +185,21 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="toolTip">
<string>Draw bounding boxes</string>
</property>
<property name="text">
<string/>
</property>
@@ -187,7 +220,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<width>550</width>
<height>20</height>
</size>
</property>

View File

@@ -126,7 +126,6 @@ void PreviewRenderer::draw()
{
float culldistance = 10000000;
bool draw_doodads_wmo = true;
math::matrix_4x4 const mvp(model_view().transposed() * projection().transposed());
math::frustum const frustum (mvp);
@@ -151,6 +150,16 @@ void PreviewRenderer::draw()
);
}
if (!_m2_box_program)
{
_m2_box_program.reset
( new opengl::program
{ { GL_VERTEX_SHADER, opengl::shader::src_from_qrc("m2_box_vs") }
, { GL_FRAGMENT_SHADER, opengl::shader::src_from_qrc("m2_box_fs") }
}
);
}
if (!_m2_ribbons_program)
{
_m2_ribbons_program.reset
@@ -180,6 +189,8 @@ void PreviewRenderer::draw()
);
}
if (!_liquid_render)
{
_liquid_render.emplace();
@@ -193,7 +204,7 @@ void PreviewRenderer::draw()
// draw WMOs
std::unordered_map<std::string, std::vector<ModelInstance*>> _wmo_doodads;
if (!_wmo_instances.empty())
if (_draw_wmo.get() && !_wmo_instances.empty())
{
// set anim time only once per frame
{
@@ -233,7 +244,7 @@ void PreviewRenderer::draw()
{
wmo_instance.draw(
wmo_program, model_view().transposed(), projection().transposed(), frustum, culldistance,
math::vector_3d(0.0f, 0.0f, 0.0f), false, false // doodads
math::vector_3d(0.0f, 0.0f, 0.0f), _draw_boxes.get(), _draw_models.get() // doodads
, false, _liquid_render.get(), std::vector<selection_type>(), 0, false, display_mode::in_3D
);
@@ -241,13 +252,10 @@ void PreviewRenderer::draw()
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
gl.enable(GL_CULL_FACE);
if (draw_doodads_wmo)
for (auto& doodad : wmo_instance.get_visible_doodads(frustum, culldistance, _camera.position,
false,display_mode::in_3D))
{
for (auto& doodad : wmo_instance.get_visible_doodads(frustum, culldistance, _camera.position, false,
display_mode::in_3D))
{
_wmo_doodads[doodad->model->filename].push_back(doodad);
}
_wmo_doodads[doodad->model->filename].push_back(doodad);
}
}
@@ -259,8 +267,10 @@ void PreviewRenderer::draw()
std::unordered_map<Model*, std::size_t> model_with_particles;
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
if (_draw_models.get() && !(_model_instances.empty() && _wmo_doodads.empty()))
{
ModelManager::resetAnim();
if (_draw_animated.get())
ModelManager::resetAnim();
opengl::scoped::use_program m2_shader {*_m2_instanced_program.get()};
@@ -285,33 +295,55 @@ void PreviewRenderer::draw()
, _camera.position
, false
, _animtime
, false
, false
, _draw_particles.get()
, _draw_boxes.get()
, model_with_particles
, model_boxes_to_draw
, display_mode::in_3D
);
}
if (draw_doodads_wmo)
for (auto& it : _wmo_doodads)
{
for (auto& it : _wmo_doodads)
it.second[0]->model->draw(
model_view().transposed()
, it.second
, m2_shader
, frustum
, culldistance
, _camera.position
, false
, _animtime
, _draw_particles.get()
, _draw_boxes.get()
, model_with_particles
, model_boxes_to_draw
, display_mode::in_3D
);
}
if(_draw_boxes.get() && !model_boxes_to_draw.empty())
{
opengl::scoped::use_program m2_box_shader{ *_m2_box_program.get() };
m2_box_shader.uniform ("model_view", model_view().transposed());
m2_box_shader.uniform ("projection", projection().transposed());
opengl::scoped::bool_setter<GL_LINE_SMOOTH, GL_TRUE> const line_smooth;
gl.hint (GL_LINE_SMOOTH_HINT, GL_NICEST);
for (auto& it : model_boxes_to_draw)
{
it.second[0]->model->draw(
model_view().transposed()
, it.second
, m2_shader
, frustum
, culldistance
, _camera.position
, false
, _animtime
, false
, false
, model_with_particles
, model_boxes_to_draw
, display_mode::in_3D
);
math::vector_4d color = it.first->is_hidden()
? math::vector_4d(0.f, 0.f, 1.f, 1.f)
: ( it.first->use_fake_geometry()
? math::vector_4d(1.f, 0.f, 0.f, 1.f)
: math::vector_4d(0.75f, 0.75f, 0.75f, 1.f)
)
;
m2_box_shader.uniform("color", color);
it.first->draw_box(m2_box_shader, it.second);
}
}
}
@@ -319,6 +351,45 @@ void PreviewRenderer::draw()
gl.bindVertexArray(0);
gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
// model particles
if (_draw_animated.get() && !model_with_particles.empty())
{
opengl::scoped::bool_setter<GL_CULL_FACE, GL_FALSE> const cull;
opengl::scoped::depth_mask_setter<GL_FALSE> const depth_mask;
opengl::scoped::use_program particles_shader {*_m2_particles_program.get()};
particles_shader.uniform("model_view_projection", mvp);
particles_shader.uniform("tex", 0);
opengl::texture::set_active_texture(0);
for (auto& it : model_with_particles)
{
it.first->draw_particles(model_view().transposed(), particles_shader, it.second);
}
}
if (_draw_animated.get() && !model_with_particles.empty())
{
opengl::scoped::bool_setter<GL_CULL_FACE, GL_FALSE> const cull;
opengl::scoped::depth_mask_setter<GL_FALSE> const depth_mask;
opengl::scoped::use_program ribbon_shader {*_m2_ribbons_program.get()};
ribbon_shader.uniform("model_view_projection", mvp);
ribbon_shader.uniform("tex", 0);
gl.blendFunc(GL_SRC_ALPHA, GL_ONE);
for (auto& it : model_with_particles)
{
it.first->draw_ribbons(ribbon_shader, it.second);
}
}
gl.enable(GL_BLEND);
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
math::matrix_4x4 PreviewRenderer::model_view() const
@@ -436,3 +507,24 @@ void PreviewRenderer::setLightDirection(float y, float z)
}
void PreviewRenderer::update_emitters(float dt)
{
while (dt > 0.1f)
{
ModelManager::updateEmitters(0.1f);
dt -= 0.1f;
}
ModelManager::updateEmitters(dt);
}
void PreviewRenderer::tick(float dt)
{
_animtime += dt * 1000.0f;
if (_draw_animated.get())
{
update_emitters(dt);
}
}

View File

@@ -9,6 +9,7 @@
#include <noggit/WMO.h>
#include <noggit/Model.h>
#include <noggit/ContextObject.hpp>
#include <noggit/bool_toggle_property.hpp>
#include <QOpenGLWidget>
#include <QSettings>
@@ -39,6 +40,12 @@ namespace noggit::Red
void setLightDirection(float y, float z);
bool_toggle_property _draw_models = {true};
bool_toggle_property _draw_wmo = {true};
bool_toggle_property _draw_particles = {true};
bool_toggle_property _draw_animated = {true};
bool_toggle_property _draw_boxes = {false};
protected:
noggit::camera _camera;
@@ -61,10 +68,13 @@ namespace noggit::Red
std::vector<math::vector_3d> calcSceneExtents();
virtual void draw();
virtual void tick(float dt);
virtual math::matrix_4x4 model_view() const;
virtual math::matrix_4x4 projection() const;
virtual float aspect_ratio() const;
void update_emitters(float dt);
private:
int _width;
int _height;