From ef34bed90a1defb5577f6cc5f00355e22de922d8 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sat, 9 May 2020 10:12:04 +0200 Subject: [PATCH] Cleanup Scene (in particular group) for simplified use in views (background and foreground). --- GarbageVisitor.cpp | 2 +- Mesh.cpp | 4 +-- Mixer.cpp | 53 +++++++++++++-------------- PickingVisitor.cpp | 1 + Primitives.cpp | 11 +++--- Primitives.h | 2 +- Scene.cpp | 78 ++++++++++++++++++++-------------------- Scene.h | 39 ++++++++++---------- SearchVisitor.cpp | 1 + Session.cpp | 9 ++--- Source.cpp | 18 +++++----- UserInterfaceManager.cpp | 15 ++++---- UserInterfaceManager.h | 1 - View.cpp | 19 ++++------ View.h | 1 - 15 files changed, 123 insertions(+), 131 deletions(-) diff --git a/GarbageVisitor.cpp b/GarbageVisitor.cpp index b2925a8..7d58d6f 100644 --- a/GarbageVisitor.cpp +++ b/GarbageVisitor.cpp @@ -34,7 +34,7 @@ void GarbageVisitor::visit(Node &n) // take the node out of the Tree if (current_) - current_->detatchChild(&n); + current_->detatch(&n); } diff --git a/Mesh.cpp b/Mesh.cpp index 1762041..7c4cc90 100644 --- a/Mesh.cpp +++ b/Mesh.cpp @@ -333,7 +333,7 @@ Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive } // default non texture shader (deleted in Primitive) - shader_ = new Shader(); + shader_ = new Shader; } @@ -341,7 +341,7 @@ void Mesh::setTexture(uint textureindex) { if (textureindex) { // replace previous shader with a new Image Shader - replaceShader( new ImageShader() ); + replaceShader( new ImageShader ); // set texture textureindex_ = textureindex; } diff --git a/Mixer.cpp b/Mixer.cpp index 54722f3..d0dff1c 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "tinyxml2Toolkit.h" @@ -16,11 +17,26 @@ using namespace tinyxml2; #include "GarbageVisitor.h" #include "SessionVisitor.h" #include "SessionCreator.h" - #include "MediaPlayer.h" #include "Mixer.h" +// static objects for multithreaded session loading +static bool sessionLoadPending_ = false; +static bool sessionLoadFinished_ = false; +static Session *loadedSession; + +static void loadSession(const std::string& filename, ) +{ + sessionLoadPending_ = true; + + + sessionLoadFinished_ = true; +} + + + + Mixer::Mixer() : session_(nullptr), current_view_(nullptr) { // this initializes with a new empty session @@ -78,9 +94,9 @@ void Mixer::insertSource(Source *s) // add sources Nodes to ALL views // Mixing Node - mixing_.scene.root()->addChild(s->group(View::MIXING)); + mixing_.scene.fg()->attach(s->group(View::MIXING)); // Geometry Node - geometry_.scene.root()->addChild(s->group(View::GEOMETRY)); + geometry_.scene.fg()->attach(s->group(View::GEOMETRY)); } void Mixer::deleteSource(Source *s) @@ -95,15 +111,8 @@ void Mixer::deleteSource(Source *s) unsetCurrentSource(); // remove source Nodes from views -// GarbageVisitor mixingremover(s->group(View::MIXING)); -// mixingremover.visit(mixing_.scene); -// GarbageVisitor geomremover(s->group(View::GEOMETRY)); -// geomremover.visit(geometry_.scene); - - Log::Info("MIXING"); - mixing_.scene.root()->detatchChild( s->group(View::MIXING) ); - Log::Info("GEOMETRY"); - geometry_.scene.root()->detatchChild( s->group(View::GEOMETRY) ); + mixing_.scene.fg()->detatch( s->group(View::MIXING) ); + geometry_.scene.fg()->detatch( s->group(View::GEOMETRY) ); // delete source session_->deleteSource(s); @@ -306,8 +315,8 @@ bool Mixer::open(const std::string& filename) SourceList::iterator source_iter; for (source_iter = new_session->begin(); source_iter != new_session->end(); source_iter++) { - mixing_.scene.root()->addChild( (*source_iter)->group(View::MIXING) ); - geometry_.scene.root()->addChild( (*source_iter)->group(View::GEOMETRY) ); + mixing_.scene.fg()->attach( (*source_iter)->group(View::MIXING) ); + geometry_.scene.fg()->attach( (*source_iter)->group(View::GEOMETRY) ); } } @@ -331,23 +340,15 @@ bool Mixer::open(const std::string& filename) void Mixer::newSession(Session *newsession) { - - // delete session : delete all sources + // delete session & detatch nodes from views if (session_) { // remove nodes from views for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++) { -// GarbageVisitor mixingremover( (*source_iter)->group(View::MIXING) ); -// mixingremover.visit(mixing_.scene); -// GarbageVisitor geomremover( (*source_iter)->group(View::GEOMETRY) ); -// geomremover.visit(geometry_.scene); - - Log::Info("MIXING"); - mixing_.scene.root()->detatchChild( (*source_iter)->group(View::MIXING) ); - Log::Info("GEOMETRY"); - geometry_.scene.root()->detatchChild( (*source_iter)->group(View::GEOMETRY) ); + mixing_.scene.fg()->detatch( (*source_iter)->group(View::MIXING) ); + geometry_.scene.fg()->detatch( (*source_iter)->group(View::GEOMETRY) ); } - // clear session + // clear session: delete all sources delete session_; } diff --git a/PickingVisitor.cpp b/PickingVisitor.cpp index 8c72454..396ac32 100644 --- a/PickingVisitor.cpp +++ b/PickingVisitor.cpp @@ -94,5 +94,6 @@ void PickingVisitor::visit(LineCircle &n) void PickingVisitor::visit(Scene &n) { + // TODO : maybe pick only foreground ? n.root()->accept(*this); } diff --git a/Primitives.cpp b/Primitives.cpp index 4ffa6b6..11b8651 100644 --- a/Primitives.cpp +++ b/Primitives.cpp @@ -42,7 +42,8 @@ Surface::Surface(Shader *s) : Primitive(s), textureindex_(0) Surface::~Surface() { - + // do NOT delete vao_ (unique) + vao_ = 0; } void Surface::init() @@ -290,8 +291,8 @@ void LineSquare::accept(Visitor& v) LineSquare::~LineSquare() { - if (shader_) - delete shader_; + // do NOT delete vao_ (unique) + vao_ = 0; } @@ -344,6 +345,6 @@ void LineCircle::accept(Visitor& v) LineCircle::~LineCircle() { - if (shader_) - delete shader_; + // do NOT delete vao_ (unique) + vao_ = 0; } diff --git a/Primitives.h b/Primitives.h index db5f062..e63b951 100644 --- a/Primitives.h +++ b/Primitives.h @@ -21,6 +21,7 @@ class Surface : public Primitive { public: Surface(Shader *s = new ImageShader); + virtual ~Surface(); void init () override; void draw (glm::mat4 modelview, glm::mat4 projection) override; @@ -31,7 +32,6 @@ public: protected: uint textureindex_; - virtual ~Surface(); }; diff --git a/Scene.cpp b/Scene.cpp index 5608a78..50da090 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -64,7 +64,6 @@ void Node::accept(Visitor& v) // Primitive - Primitive::~Primitive() { if ( vao_ ) @@ -181,14 +180,16 @@ void Primitive::replaceShader( Shader *newshader ) // Group Group::~Group() { - Log::Info("Delete Group %d ", id()); + clear(); +} + +void Group::clear() +{ for(NodeSet::iterator it = children_.begin(); it != children_.end(); ) { - Log::Info(" Child %d (%d)", (*it)->id(), (*it)->refcount_); + // one less ref to this node (*it)->refcount_--; // if this group was the only remaining parent if ( (*it)->refcount_ < 1 ) { - - Log::Info(" Deleting %d (%d)", (*it)->id(), (*it)->refcount_); // delete delete (*it); } @@ -197,22 +198,15 @@ Group::~Group() } } -void Group::addChild(Node *child) +void Group::attach(Node *child) { children_.insert(child); child->refcount_++; - -// children_.push_back(child); // list test - -// child->parents_.push_back(this); } -void Group::detatchChild(Node *child) +void Group::detatch(Node *child) { - - Log::Info("Group %d (N=%d) detaching %d", id(), numChildren(), child->id()); - // find the node with this id, and erase it out of the list of children // NB: do NOT delete with remove : this takes all nodes with same depth (i.e. equal depth in set) NodeSet::iterator it = std::find_if(children_.begin(), children_.end(), hasId(child->id())); @@ -220,13 +214,8 @@ void Group::detatchChild(Node *child) // detatch child from group parent children_.erase(it); child->refcount_--; -// // detatch parent from child -// (*it)->parents_.remove(this); } -// children_.remove(child); - Log::Info("Group %d (N=%d)", id(), numChildren()); - } void Group::update( float dt ) @@ -306,17 +295,17 @@ void Switch::accept(Visitor& v) v.visit(*this); } -void Switch::addChild(Node *child) +void Switch::attach(Node *child) { - Group::addChild(child); + Group::attach(child); setActiveChild(child); } -//void Switch::detatchChild(Node *child) -//{ -// Group::detatchChild(child); -// active_ = children_.begin(); -//} +void Switch::detatch(Node *child) +{ + Group::detatch(child); + active_ = children_.begin(); +} void Switch::unsetActiveChild () @@ -396,37 +385,46 @@ void Animation::accept(Visitor& v) v.visit(*this); } -Scene::Scene(): root_(nullptr) +Scene::Scene(): root_(nullptr), foreground_(nullptr), background_(nullptr) { root_ = new Group; + + background_ = new Group; + background_->translation_.z = 0; + foreground_ = new Group; + // TODO Verify depth for foreground + foreground_->translation_.z = 1; + + root_->attach(background_); + root_->attach(foreground_); } Scene::~Scene() { -// deleteNode(root_); - + // bg and fg are deleted as children of root + delete root_; } -void Scene::deleteNode(Node *node) +void Scene::clear() { + clearForeground(); + clearBackground(); +} - GarbageVisitor remover(node); - remover.visit(*this); +void Scene::clearForeground() +{ + foreground_->clear(); +} -// // remove this node to the list of chidren of all its parents -// for(auto parent = node->parents_.begin(); parent != node->parents_.end(); parent++){ -// (*parent)->children_.erase(node); -// } -// node->parents_.clear(); - -// limbo->addChild(node); +void Scene::clearBackground() +{ + background_->clear(); } void Scene::update(float dt) { root_->update( dt ); - } void Scene::accept(Visitor& v) diff --git a/Scene.h b/Scene.h index 1774641..e79d817 100644 --- a/Scene.h +++ b/Scene.h @@ -47,6 +47,7 @@ class Node { public: Node (); + virtual ~Node (); // unique identifyer generated at instanciation inline int id () const { return id_; } @@ -71,7 +72,6 @@ public: glm::mat4 transform_; glm::vec3 scale_, rotation_, translation_; - virtual ~Node (); }; @@ -96,7 +96,7 @@ class Primitive : public Node { public: Primitive(Shader *s = nullptr) : Node(), shader_(s), vao_(0), drawMode_(0), drawCount_(0) {} - + virtual ~Primitive(); virtual void init () override; virtual void accept (Visitor& v) override; @@ -105,7 +105,6 @@ public: inline Shader *shader () const { return shader_; } void replaceShader (Shader* newshader); - virtual ~Primitive(); protected: Shader* shader_; uint vao_, drawMode_, drawCount_; @@ -168,8 +167,9 @@ public: virtual void accept (Visitor& v) override; virtual void draw (glm::mat4 modelview, glm::mat4 projection) override; - virtual void addChild (Node *child); - virtual void detatchChild (Node *child); + virtual void clear(); + virtual void attach (Node *child); + virtual void detatch (Node *child); NodeSet::iterator begin(); NodeSet::iterator end(); @@ -197,8 +197,8 @@ public: virtual void accept (Visitor& v) override; virtual void draw (glm::mat4 modelview, glm::mat4 projection) override; - void addChild (Node *child) override; -// void detatchChild (Node *child) override; + void attach (Node *child) override; + void detatch (Node *child) override; void unsetActiveChild (); void setActiveChild (Node *child); @@ -238,31 +238,34 @@ protected: }; - -// A scene contains a root node and gives a simplified API to add nodes +/** + * @brief A Scene holds a root node with two children; a background and a foreground + * + * Nodes should be added to foreground and background only (not root) + * The update() is called on the root (both background and foreground) + * + */ class Scene { Group *root_; + Group *background_; + Group *foreground_; public: Scene(); ~Scene(); void accept (Visitor& v); - void update(float dt); -// void addNode(Node *); - + void clear(); + void clearBackground(); + void clearForeground(); Group *root() { return root_; } + Group *bg() { return background_; } + Group *fg() { return foreground_; } - // Node *find(int id); - // void remove(Node *n); - // - void deleteNode(Node *node); - -// static Group *limbo; }; diff --git a/SearchVisitor.cpp b/SearchVisitor.cpp index 7ee1fe5..6879d3e 100644 --- a/SearchVisitor.cpp +++ b/SearchVisitor.cpp @@ -37,5 +37,6 @@ void SearchVisitor::visit(Switch &n) void SearchVisitor::visit(Scene &n) { + // TODO maybe search only forground? n.root()->accept(*this); } diff --git a/Session.cpp b/Session.cpp index 3c28504..b4d9b9a 100644 --- a/Session.cpp +++ b/Session.cpp @@ -38,7 +38,7 @@ void Session::update(float dt) SourceList::iterator Session::addSource(Source *s) { // insert the source in the rendering - render_.scene.root()->addChild(s->group(View::RENDERING)); + render_.scene.fg()->attach(s->group(View::RENDERING)); // insert the source to the beginning of the list sources_.push_front(s); // return the iterator to the source created at the beginning @@ -53,18 +53,13 @@ SourceList::iterator Session::deleteSource(Source *s) if (its != sources_.end()) { // remove Node from the rendering scene -// GarbageVisitor remover(s->group(View::RENDERING)); -// remover.visit(render_.scene); - - render_.scene.root()->detatchChild( s->group(View::RENDERING) ); + render_.scene.fg()->detatch( s->group(View::RENDERING) ); // erase the source from the update list & get next element its = sources_.erase(its); // delete the source : safe now delete s; - - // NB: GarbageVisitor ends here, and deletes the Group RENDERING } // return end of next element diff --git a/Source.cpp b/Source.cpp index 47d8235..b270e5f 100644 --- a/Source.cpp +++ b/Source.cpp @@ -28,15 +28,15 @@ Source::Source(const std::string &name) : name_(name), initialized_(false) Frame *frame = new Frame(Frame::ROUND_THIN); frame->translation_.z = 0.1; frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 0.9f); - groups_[View::MIXING]->addChild(frame); + groups_[View::MIXING]->attach(frame); groups_[View::MIXING]->scale_ = glm::vec3(0.15f, 0.15f, 1.f); // default geometry nodes groups_[View::GEOMETRY] = new Group; // will be associated to nodes later - blendingshader_ = new ImageShader(); - rendershader_ = new ImageProcessingShader(); + blendingshader_ = new ImageShader; + rendershader_ = new ImageProcessingShader; renderbuffer_ = nullptr; rendersurface_ = nullptr; overlay_ = nullptr; @@ -112,14 +112,14 @@ MediaSource::MediaSource(const std::string &name) : Source(name), uri_("") overlay_->translation_.z = 0.1; overlay_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); overlay_->visible_ = false; - groups_[View::MIXING]->addChild(overlay_); + groups_[View::MIXING]->attach(overlay_); } MediaSource::~MediaSource() { // TODO delete media surface with visitor - //delete mediasurface_; + delete mediasurface_; delete mediaplayer_; // TODO verify that all surfaces and node is deleted in Source destructor @@ -164,15 +164,15 @@ void MediaSource::init() // create the surfaces to draw the frame buffer in the views // TODO Provide the source custom effect shader rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); - groups_[View::RENDERING]->addChild(rendersurface_); - groups_[View::GEOMETRY]->addChild(rendersurface_); - groups_[View::MIXING]->addChild(rendersurface_); + groups_[View::RENDERING]->attach(rendersurface_); + groups_[View::GEOMETRY]->attach(rendersurface_); + groups_[View::MIXING]->attach(rendersurface_); // for mixing view, add another surface to overlay (for stippled view in transparency) Surface *surfacemix = new FrameBufferSurface(renderbuffer_); ImageShader *is = static_cast(surfacemix->shader()); if (is) is->stipple = 1.0; - groups_[View::MIXING]->addChild(surfacemix); + groups_[View::MIXING]->attach(surfacemix); // scale all mixing nodes to match aspect ratio of the media for (NodeSet::iterator node = groups_[View::MIXING]->begin(); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 7a30877..a8f6381 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -1,6 +1,7 @@ #include #include #include +#include // ImGui #include "imgui.h" @@ -49,17 +50,16 @@ #include "TextEditor.h" static TextEditor editor; - -//static std::thread *FileDialogThread_; -static bool FileDialogPending_ = false; -static bool FileDialogFinished_ = false; -static std::string FileDialogFilename_ = ""; - - +// utility functions void ShowAboutGStreamer(bool* p_open); void ShowAboutOpengl(bool* p_open); void ShowAbout(bool* p_open); +// static objects for multithreaded file dialog +static bool FileDialogPending_ = false; +static bool FileDialogFinished_ = false; +static std::string FileDialogFilename_ = ""; + static void FileDialogOpen(std::string path) { FileDialogPending_ = true; @@ -379,7 +379,6 @@ void UserInterface::Terminate() void UserInterface::showMenuFile() { - // TODO : New if (ImGui::MenuItem( ICON_FA_FILE " New", "Ctrl+W", false, !FileDialogPending_)) { Mixer::manager().newSession(); navigator.hidePannel(); diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index f64fd17..32f5313 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -1,7 +1,6 @@ #ifndef __UI_MANAGER_H_ #define __UI_MANAGER_H_ -#include #include #include using namespace std; diff --git a/View.cpp b/View.cpp index 75fb97e..8f1fa73 100644 --- a/View.cpp +++ b/View.cpp @@ -54,18 +54,16 @@ MixingView::MixingView() : View(MIXING) else restoreSettings(); - // Mixing scene - backgound_ = new Group; - scene.root()->addChild(backgound_); + // Mixing scene background Mesh *disk = new Mesh("mesh/disk.ply"); disk->setTexture(textureMixingQuadratic()); - backgound_->addChild(disk); + scene.bg()->attach(disk); glm::vec4 pink( 0.8f, 0.f, 0.8f, 1.f ); Mesh *circle = new Mesh("mesh/circle.ply"); circle->shader()->color = pink; - backgound_->addChild(circle); + scene.bg()->attach(circle); } @@ -238,17 +236,14 @@ GeometryView::GeometryView() : View(GEOMETRY) else restoreSettings(); - // Geometry Scene - backgound_ = new Group; - scene.root()->addChild(backgound_); - + // Geometry Scene background Surface *rect = new Surface; - backgound_->addChild(rect); + scene.bg()->attach(rect); Frame *border = new Frame(Frame::SHARP_THIN); border->overlay_ = new Mesh("mesh/border_vertical_overlay.ply"); border->color = glm::vec4( 0.8f, 0.f, 0.8f, 1.f ); - backgound_->addChild(border); + scene.bg()->attach(border); } @@ -263,7 +258,7 @@ void GeometryView::draw() // update rendering of render frame FrameBuffer *output = Mixer::manager().session()->frame(); if (output){ - for (NodeSet::iterator node = backgound_->begin(); node != backgound_->end(); node++) { + for (NodeSet::iterator node = scene.bg()->begin(); node != scene.bg()->end(); node++) { (*node)->scale_.x = output->aspectRatio(); } } diff --git a/View.h b/View.h index d49240d..73bb44d 100644 --- a/View.h +++ b/View.h @@ -29,7 +29,6 @@ public: protected: Mode mode_; - Group *backgound_; };