asset browser: manage render destruction safely

This commit is contained in:
sshumakov3
2020-11-17 16:38:32 +03:00
parent b1e769836c
commit 55e533de4a
7 changed files with 74 additions and 7 deletions

View File

@@ -1033,7 +1033,7 @@ void Model::initAnimated(const MPQFile& f)
{
try
{
_particles.emplace_back (this, f, pdefs[i], _global_sequences.data());
_particles.emplace_back(this, f, pdefs[i], _global_sequences.data(), _context);
}
catch (std::logic_error error)
{
@@ -1048,7 +1048,7 @@ void Model::initAnimated(const MPQFile& f)
if (header.nRibbonEmitters) {
ModelRibbonEmitterDef const* rdefs = reinterpret_cast<ModelRibbonEmitterDef const*>(f.getBuffer() + header.ofsRibbonEmitters);
for (size_t i = 0; i<header.nRibbonEmitters; ++i) {
_ribbons.emplace_back(this, f, rdefs[i], _global_sequences.data());
_ribbons.emplace_back(this, f, rdefs[i], _global_sequences.data(), _context);
}
}

View File

@@ -16,7 +16,11 @@ T lifeRamp(float life, float mid, const T &a, const T &b, const T &c)
else return math::interpolation::linear((life - mid) / (1.0f - mid), b, c);
}
ParticleSystem::ParticleSystem(Model* model_, const MPQFile& f, const ModelParticleEmitterDef &mta, int *globals)
ParticleSystem::ParticleSystem(Model* model_
, const MPQFile& f
, const ModelParticleEmitterDef &mta
, int *globals
, noggit::NoggitRenderContext context)
: model (model_)
, emitter_type(mta.EmitterType)
, emitter ( mta.EmitterType == 1 ? std::unique_ptr<ParticleEmitter> (std::make_unique<PlaneParticleEmitter>())
@@ -50,6 +54,7 @@ ParticleSystem::ParticleSystem(Model* model_, const MPQFile& f, const ModelParti
, parent (&model->bones[mta.bone])
, flags(mta.flags)
, tofs (misc::frand())
, _context(context)
{
math::vector_3d colors2[3];
memcpy(colors2, f.getBuffer() + mta.p.colors.ofsKeys, sizeof(math::vector_3d) * 3);
@@ -108,6 +113,7 @@ ParticleSystem::ParticleSystem(ParticleSystem const& other)
, parent(other.parent)
, flags(other.flags)
, tofs(other.tofs)
, _context(other._context)
{
}
@@ -148,6 +154,7 @@ ParticleSystem::ParticleSystem(ParticleSystem&& other)
, parent(other.parent)
, flags(other.flags)
, tofs(other.tofs)
, _context(other._context)
{
}
@@ -761,7 +768,11 @@ Particle SphereParticleEmitter::newParticle(ParticleSystem* sys, int anim, int t
return p;
}
RibbonEmitter::RibbonEmitter(Model* model_, const MPQFile &f, ModelRibbonEmitterDef const& mta, int *globals)
RibbonEmitter::RibbonEmitter(Model* model_
, const MPQFile &f
, ModelRibbonEmitterDef const& mta
, int *globals
, noggit::NoggitRenderContext context)
: model (model_)
, color (mta.color, f, globals)
, opacity (mta.opacity, f, globals)
@@ -776,12 +787,14 @@ RibbonEmitter::RibbonEmitter(Model* model_, const MPQFile &f, ModelRibbonEmitter
//! \todo figure out actual correct way to calculate length
// in BFD, res is 60 and len is 0.6, the trails are very short (too long here)
// in CoT, res and len are like 10 but the trails are supposed to be much longer (too short here)
, _context(context)
{
_texture_ids = Model::M2Array<uint16_t>(f, mta.ofsTextures, mta.nTextures);
_material_ids = Model::M2Array<uint16_t>(f, mta.ofsMaterials, mta.nMaterials);
// create first segment
segs.emplace_back(tpos, 0);
}
RibbonEmitter::RibbonEmitter(RibbonEmitter const& other)
@@ -803,6 +816,7 @@ RibbonEmitter::RibbonEmitter(RibbonEmitter const& other)
, _texture_ids(other._texture_ids)
, _material_ids(other._material_ids)
, segs(other.segs)
, _context(other._context)
{
}
@@ -826,6 +840,7 @@ RibbonEmitter::RibbonEmitter(RibbonEmitter&& other)
, _texture_ids(other._texture_ids)
, _material_ids(other._material_ids)
, segs(other.segs)
, _context(other._context)
{
}

View File

@@ -82,7 +82,9 @@ class ParticleSystem
public:
float tofs;
ParticleSystem(Model*, const MPQFile& f, const ModelParticleEmitterDef &mta, int *globals);
ParticleSystem(Model*, const MPQFile& f, const ModelParticleEmitterDef &mta,
int *globals, noggit::NoggitRenderContext context);
ParticleSystem(ParticleSystem const& other);
ParticleSystem(ParticleSystem&&);
ParticleSystem& operator= (ParticleSystem const&) = delete;
@@ -112,6 +114,7 @@ private:
GLuint const& _colors_vbo = _buffers[2];
GLuint const& _texcoord_vbo = _buffers[3];
GLuint const& _indices_vbo = _buffers[4];
noggit::NoggitRenderContext _context;
};
@@ -151,7 +154,9 @@ class RibbonEmitter
std::list<RibbonSegment> segs;
public:
RibbonEmitter(Model*, const MPQFile &f, ModelRibbonEmitterDef const& mta, int *globals);
RibbonEmitter(Model*, const MPQFile &f, ModelRibbonEmitterDef const& mta, int *globals
, noggit::NoggitRenderContext context);
RibbonEmitter(RibbonEmitter const& other);
RibbonEmitter(RibbonEmitter&&);
RibbonEmitter& operator= (RibbonEmitter const&) = delete;
@@ -173,4 +178,5 @@ private:
GLuint const& _vertices_vbo = _buffers[0];
GLuint const& _texcoord_vbo = _buffers[1];
GLuint const& _indices_vbo = _buffers[2];
noggit::NoggitRenderContext _context;
};

View File

@@ -15,12 +15,14 @@ using namespace noggit::Red::AssetBrowser;
ModelViewer::ModelViewer(QWidget* parent)
: PreviewRenderer(0, 0, noggit::NoggitRenderContext::ASSET_BROWSER, parent)
, look(false)
, mousedir(-1.0f)
{
setFocusPolicy(Qt::StrongFocus);
setMouseTracking (true);
_offscreen_mode = false;
_startup_time.start();
look = false;
moving = strafing = updown = lookat = turn = 0.0f;
mousedir = -1.0f;

View File

@@ -37,6 +37,8 @@ namespace noggit
void setMoveSensitivity(float s) { _move_sensitivity = s / 30.0f; }
float getMoveSensitivity() { return _move_sensitivity; }
~ModelViewer();
signals:
void resized();
void sensitivity_changed();

View File

@@ -528,4 +528,45 @@ void PreviewRenderer::tick(float dt)
}
}
PreviewRenderer::~PreviewRenderer()
{
if (_offscreen_mode)
{
opengl::context::save_current_context const context_save (::gl);
_offscreen_context.makeCurrent(&_offscreen_surface);
opengl::context::scoped_setter const context_set (::gl, &_offscreen_context);
_model_instances.clear();
_wmo_instances.clear();
_m2_program.reset();
_m2_instanced_program.reset();
_m2_particles_program.reset();
_m2_ribbons_program.reset();
_m2_box_program.reset();
_wmo_program.reset();
_liquid_render = boost::none;
}
else
{
makeCurrent();
opengl::context::scoped_setter const context_set (::gl, context());
_model_instances.clear();
_wmo_instances.clear();
_m2_program.reset();
_m2_instanced_program.reset();
_m2_particles_program.reset();
_m2_ribbons_program.reset();
_m2_box_program.reset();
_wmo_program.reset();
_liquid_render = boost::none;
}
};

View File

@@ -48,6 +48,7 @@ namespace noggit::Red
protected:
bool _offscreen_mode = true;
noggit::camera _camera;
QSettings* _settings;
std::string _filename;