git-svn-id: svn://db.shs.com.ru/libs@668 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2019-12-10 17:17:52 +00:00
parent 046bcf2bef
commit 69f4c206b9
4 changed files with 59 additions and 26 deletions

View File

@@ -51,6 +51,7 @@ ObjectBase::~ObjectBase() {
if (scene_) { if (scene_) {
scene_->__objectDeleted(this); scene_->__objectDeleted(this);
scene_->setTreeChanged(); scene_->setTreeChanged();
scene_->setTreeStructChanged();
} }
foreach (ObjectBase * c, children_) { foreach (ObjectBase * c, children_) {
c->parent_ = nullptr; c->parent_ = nullptr;
@@ -364,6 +365,8 @@ void ObjectBase::setColor(QColor c, bool with_children) {
void ObjectBase::setMesh(Mesh * v) { void ObjectBase::setMesh(Mesh * v) {
if (scene_)
v = scene_->attachMesh(v);
mesh_ = v; mesh_ = v;
setSceneTreeChanged(); setSceneTreeChanged();
setObjectsChanged(); setObjectsChanged();

View File

@@ -171,6 +171,7 @@ void Scene::removeObject(ObjectBase & o, bool inChildren) {
void Scene::clearObjects(bool deleteAll) { void Scene::clearObjects(bool deleteAll) {
root_->clearChildren(deleteAll); root_->clearChildren(deleteAll);
cleanUnused();
setTreeStructChanged(); setTreeStructChanged();
emitSelectionChanged(); emitSelectionChanged();
} }
@@ -253,6 +254,20 @@ ObjectBase * Scene::selectedObject() const {
} }
void Scene::cleanUnused() {
QSet<Mesh*> ums;
QMapIterator<int, QMap<Mesh*, ObjectBaseList>> it(geometries_used);
while (it.hasNext())
ums |= it.next().value().keys().toSet();
for (int i = 0; i < geometries.size(); ++i) {
if (ums.contains(geometries[i])) continue;
td_geometries << geometries[i];
geometries.removeAt(i);
--i;
}
}
const Box3D & Scene::boundingBox() const { const Box3D & Scene::boundingBox() const {
root_->calculateBoundingBox(); root_->calculateBoundingBox();
return root_->boundingBox(); return root_->boundingBox();
@@ -319,25 +334,8 @@ void Scene::attachObject(ObjectBase * o) {
if (!o) return; if (!o) return;
o->setScene(this); o->setScene(this);
if (o->mesh()) { // search suitable mesh in this scene if (o->mesh()) { // search suitable mesh in this scene
uint ohash = o->mesh()->hash(); o->mesh_ = attachMesh(o->mesh());
bool need_new = true; setObjectMeshChanged(o);
foreach (Mesh * m, geometries) {
if (m == o->mesh()) { // already exists by ptr
need_new = false;
setObjectMeshChanged(o);
break;
}
if (m->hash() == ohash) { // already exists by hash
need_new = false;
o->setMesh(m);
break;
}
}
if (need_new) { // need to clone mesh and add to scene
Mesh * nmesh = o->mesh()->clone();
o->setMesh(nmesh);
geometries << nmesh;
}
} }
if (o->material()) { // search suitable material in this scene if (o->material()) { // search suitable material in this scene
uint ohash = o->material()->hash(); uint ohash = o->material()->hash();
@@ -361,6 +359,25 @@ void Scene::attachObject(ObjectBase * o) {
materials << nmat; materials << nmat;
} }
} }
setTreeStructChanged();
}
Mesh * Scene::attachMesh(Mesh * mesh) {
if (!mesh) return 0;
uint mhash = mesh->hash();
foreach (Mesh * m, geometries) {
if (m == mesh) { // already exists by ptr
return m;
}
if (m->hash() == mhash) { // already exists by hash
return m;
}
}
// need to clone mesh and add to scene
Mesh * nmesh = mesh->clone();
geometries << nmesh;
return nmesh;
} }
@@ -421,14 +438,15 @@ bool Scene::prepare() {
if (tree_changed) { if (tree_changed) {
tree_changed = false; tree_changed = false;
lights_changed = true; lights_changed = true;
if (tree_struct_changed) {
tree_struct_changed = false;
QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection);
}
geometries_used[rpSolid ].clear(); geometries_used[rpSolid ].clear();
geometries_used[rpTransparent].clear(); geometries_used[rpTransparent].clear();
lights_used.clear(); lights_used.clear();
prepareTree(root_); prepareTree(root_);
if (tree_struct_changed) {
tree_struct_changed = false;
cleanUnused();
QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection);
}
} }
mat_changed = false; mat_changed = false;
return true; return true;
@@ -440,7 +458,7 @@ void Scene::destroy() {
selected_top.clear(); selected_top.clear();
emitSelectionChanged(); emitSelectionChanged();
root_->clearChildren(true); root_->clearChildren(true);
qDeleteAll(geometries); td_geometries << geometries;
qDeleteAll(materials); qDeleteAll(materials);
geometries.clear(); geometries.clear();
materials.clear(); materials.clear();
@@ -449,6 +467,15 @@ void Scene::destroy() {
} }
void Scene::destroyUnused(QOpenGLExtraFunctions * f) {
if (!td_geometries.isEmpty()) qDebug() << "destroyUnused" << td_geometries.size();
foreach (Mesh * i, td_geometries)
i->destroy(f);
qDeleteAll(td_geometries);
td_geometries.clear();
}
QDataStream & operator <<(QDataStream & s, const Scene * p) { QDataStream & operator <<(QDataStream & s, const Scene * p) {
ChunkStream cs; ChunkStream cs;
//qDebug() << "place" << p->name() << "..."; //qDebug() << "place" << p->name() << "...";

View File

@@ -77,6 +77,7 @@ public:
void clearSelection(); void clearSelection();
ObjectBaseList selectedObjects(bool top_only = false) const; ObjectBaseList selectedObjects(bool top_only = false) const;
ObjectBase * selectedObject() const; ObjectBase * selectedObject() const;
void cleanUnused();
const Box3D & boundingBox() const; const Box3D & boundingBox() const;
@@ -89,6 +90,7 @@ public:
void dump(); void dump();
void destroy(); void destroy();
void destroyUnused(QOpenGLExtraFunctions * f);
protected: protected:
void prepareTree(ObjectBase * o); void prepareTree(ObjectBase * o);
@@ -99,6 +101,7 @@ protected:
QString uniqueName(QString n, const QSet<QString> & names); QString uniqueName(QString n, const QSet<QString> & names);
void attachObject(ObjectBase * o); void attachObject(ObjectBase * o);
Mesh * attachMesh(Mesh * mesh);
void setTreeChanged(); void setTreeChanged();
void setTreeStructChanged(); void setTreeStructChanged();
void setMaterialsChanged() {mat_changed = true;} void setMaterialsChanged() {mat_changed = true;}
@@ -112,7 +115,7 @@ protected:
bool need_reload_materials, tree_struct_changed; bool need_reload_materials, tree_struct_changed;
QVector<bool> mat_map_changed; QVector<bool> mat_map_changed;
QVector<Mesh*> geometries; QVector<Mesh*> geometries, td_geometries;
QVector<Material*> materials; QVector<Material*> materials;
QMap<int, QMap<Mesh*, ObjectBaseList>> geometries_used; // [pass][mesh] = ObjectBaseList QMap<int, QMap<Mesh*, ObjectBaseList>> geometries_used; // [pass][mesh] = ObjectBaseList

View File

@@ -255,6 +255,7 @@ void Renderer::renderScene() {
Camera * cam = view->camera(); Camera * cam = view->camera();
QOpenGLShaderProgram * prog = 0; QOpenGLShaderProgram * prog = 0;
bool scene_changed = scene.prepare(); bool scene_changed = scene.prepare();
scene.destroyUnused(f);
/// reload materials on change /// reload materials on change
if (scene_changed || scene.need_reload_materials) { if (scene_changed || scene.need_reload_materials) {
@@ -332,7 +333,6 @@ void Renderer::renderScene() {
if (bindShader(srTonemapPass, &prog)) { if (bindShader(srTonemapPass, &prog)) {
prog->setUniformValue("gamma", gamma_); prog->setUniformValue("gamma", gamma_);
prog->setUniformValue("frame_max", tone_proc.frameMax()); prog->setUniformValue("frame_max", tone_proc.frameMax());
//fbo_1x1.bindColorTexture(0, 1);
fbo_out.bindColorTexture(obrSum, 0); fbo_out.bindColorTexture(obrSum, 0);
fbo_out.setWriteBuffer(obrTonemap); fbo_out.setWriteBuffer(obrTonemap);
renderQuad(prog, quad); renderQuad(prog, quad);