Cleanup Scene (in particular group) for simplified use in views

(background and foreground).
This commit is contained in:
brunoherbelin
2020-05-09 10:12:04 +02:00
parent c1b76de6e0
commit ef34bed90a
15 changed files with 123 additions and 131 deletions

View File

@@ -34,7 +34,7 @@ void GarbageVisitor::visit(Node &n)
// take the node out of the Tree // take the node out of the Tree
if (current_) if (current_)
current_->detatchChild(&n); current_->detatch(&n);
} }

View File

@@ -333,7 +333,7 @@ Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive
} }
// default non texture shader (deleted in 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) { if (textureindex) {
// replace previous shader with a new Image Shader // replace previous shader with a new Image Shader
replaceShader( new ImageShader() ); replaceShader( new ImageShader );
// set texture // set texture
textureindex_ = textureindex; textureindex_ = textureindex;
} }

View File

@@ -1,4 +1,5 @@
#include <algorithm> #include <algorithm>
#include <thread>
#include <tinyxml2.h> #include <tinyxml2.h>
#include "tinyxml2Toolkit.h" #include "tinyxml2Toolkit.h"
@@ -16,11 +17,26 @@ using namespace tinyxml2;
#include "GarbageVisitor.h" #include "GarbageVisitor.h"
#include "SessionVisitor.h" #include "SessionVisitor.h"
#include "SessionCreator.h" #include "SessionCreator.h"
#include "MediaPlayer.h" #include "MediaPlayer.h"
#include "Mixer.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) Mixer::Mixer() : session_(nullptr), current_view_(nullptr)
{ {
// this initializes with a new empty session // this initializes with a new empty session
@@ -78,9 +94,9 @@ void Mixer::insertSource(Source *s)
// add sources Nodes to ALL views // add sources Nodes to ALL views
// Mixing Node // Mixing Node
mixing_.scene.root()->addChild(s->group(View::MIXING)); mixing_.scene.fg()->attach(s->group(View::MIXING));
// Geometry Node // Geometry Node
geometry_.scene.root()->addChild(s->group(View::GEOMETRY)); geometry_.scene.fg()->attach(s->group(View::GEOMETRY));
} }
void Mixer::deleteSource(Source *s) void Mixer::deleteSource(Source *s)
@@ -95,15 +111,8 @@ void Mixer::deleteSource(Source *s)
unsetCurrentSource(); unsetCurrentSource();
// remove source Nodes from views // remove source Nodes from views
// GarbageVisitor mixingremover(s->group(View::MIXING)); mixing_.scene.fg()->detatch( s->group(View::MIXING) );
// mixingremover.visit(mixing_.scene); geometry_.scene.fg()->detatch( s->group(View::GEOMETRY) );
// 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) );
// delete source // delete source
session_->deleteSource(s); session_->deleteSource(s);
@@ -306,8 +315,8 @@ bool Mixer::open(const std::string& filename)
SourceList::iterator source_iter; SourceList::iterator source_iter;
for (source_iter = new_session->begin(); source_iter != new_session->end(); source_iter++) for (source_iter = new_session->begin(); source_iter != new_session->end(); source_iter++)
{ {
mixing_.scene.root()->addChild( (*source_iter)->group(View::MIXING) ); mixing_.scene.fg()->attach( (*source_iter)->group(View::MIXING) );
geometry_.scene.root()->addChild( (*source_iter)->group(View::GEOMETRY) ); 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) void Mixer::newSession(Session *newsession)
{ {
// delete session & detatch nodes from views
// delete session : delete all sources
if (session_) { if (session_) {
// remove nodes from views // remove nodes from views
for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++) for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++)
{ {
// GarbageVisitor mixingremover( (*source_iter)->group(View::MIXING) ); mixing_.scene.fg()->detatch( (*source_iter)->group(View::MIXING) );
// mixingremover.visit(mixing_.scene); geometry_.scene.fg()->detatch( (*source_iter)->group(View::GEOMETRY) );
// 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) );
} }
// clear session // clear session: delete all sources
delete session_; delete session_;
} }

View File

@@ -94,5 +94,6 @@ void PickingVisitor::visit(LineCircle &n)
void PickingVisitor::visit(Scene &n) void PickingVisitor::visit(Scene &n)
{ {
// TODO : maybe pick only foreground ?
n.root()->accept(*this); n.root()->accept(*this);
} }

View File

@@ -42,7 +42,8 @@ Surface::Surface(Shader *s) : Primitive(s), textureindex_(0)
Surface::~Surface() Surface::~Surface()
{ {
// do NOT delete vao_ (unique)
vao_ = 0;
} }
void Surface::init() void Surface::init()
@@ -290,8 +291,8 @@ void LineSquare::accept(Visitor& v)
LineSquare::~LineSquare() LineSquare::~LineSquare()
{ {
if (shader_) // do NOT delete vao_ (unique)
delete shader_; vao_ = 0;
} }
@@ -344,6 +345,6 @@ void LineCircle::accept(Visitor& v)
LineCircle::~LineCircle() LineCircle::~LineCircle()
{ {
if (shader_) // do NOT delete vao_ (unique)
delete shader_; vao_ = 0;
} }

View File

@@ -21,6 +21,7 @@ class Surface : public Primitive {
public: public:
Surface(Shader *s = new ImageShader); Surface(Shader *s = new ImageShader);
virtual ~Surface();
void init () override; void init () override;
void draw (glm::mat4 modelview, glm::mat4 projection) override; void draw (glm::mat4 modelview, glm::mat4 projection) override;
@@ -31,7 +32,6 @@ public:
protected: protected:
uint textureindex_; uint textureindex_;
virtual ~Surface();
}; };

View File

@@ -64,7 +64,6 @@ void Node::accept(Visitor& v)
// Primitive // Primitive
Primitive::~Primitive() Primitive::~Primitive()
{ {
if ( vao_ ) if ( vao_ )
@@ -181,14 +180,16 @@ void Primitive::replaceShader( Shader *newshader )
// Group // Group
Group::~Group() Group::~Group()
{ {
Log::Info("Delete Group %d ", id()); clear();
}
void Group::clear()
{
for(NodeSet::iterator it = children_.begin(); it != children_.end(); ) { 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_--; (*it)->refcount_--;
// if this group was the only remaining parent // if this group was the only remaining parent
if ( (*it)->refcount_ < 1 ) { if ( (*it)->refcount_ < 1 ) {
Log::Info(" Deleting %d (%d)", (*it)->id(), (*it)->refcount_);
// delete // delete
delete (*it); delete (*it);
} }
@@ -197,22 +198,15 @@ Group::~Group()
} }
} }
void Group::addChild(Node *child) void Group::attach(Node *child)
{ {
children_.insert(child); children_.insert(child);
child->refcount_++; 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 // 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) // 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())); 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 // detatch child from group parent
children_.erase(it); children_.erase(it);
child->refcount_--; 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 ) void Group::update( float dt )
@@ -306,17 +295,17 @@ void Switch::accept(Visitor& v)
v.visit(*this); v.visit(*this);
} }
void Switch::addChild(Node *child) void Switch::attach(Node *child)
{ {
Group::addChild(child); Group::attach(child);
setActiveChild(child); setActiveChild(child);
} }
//void Switch::detatchChild(Node *child) void Switch::detatch(Node *child)
//{ {
// Group::detatchChild(child); Group::detatch(child);
// active_ = children_.begin(); active_ = children_.begin();
//} }
void Switch::unsetActiveChild () void Switch::unsetActiveChild ()
@@ -396,37 +385,46 @@ void Animation::accept(Visitor& v)
v.visit(*this); v.visit(*this);
} }
Scene::Scene(): root_(nullptr) Scene::Scene(): root_(nullptr), foreground_(nullptr), background_(nullptr)
{ {
root_ = new Group; 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() 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); void Scene::clearForeground()
remover.visit(*this); {
foreground_->clear();
}
// // remove this node to the list of chidren of all its parents void Scene::clearBackground()
// for(auto parent = node->parents_.begin(); parent != node->parents_.end(); parent++){ {
// (*parent)->children_.erase(node); background_->clear();
// }
// node->parents_.clear();
// limbo->addChild(node);
} }
void Scene::update(float dt) void Scene::update(float dt)
{ {
root_->update( dt ); root_->update( dt );
} }
void Scene::accept(Visitor& v) void Scene::accept(Visitor& v)

39
Scene.h
View File

@@ -47,6 +47,7 @@ class Node {
public: public:
Node (); Node ();
virtual ~Node ();
// unique identifyer generated at instanciation // unique identifyer generated at instanciation
inline int id () const { return id_; } inline int id () const { return id_; }
@@ -71,7 +72,6 @@ public:
glm::mat4 transform_; glm::mat4 transform_;
glm::vec3 scale_, rotation_, translation_; glm::vec3 scale_, rotation_, translation_;
virtual ~Node ();
}; };
@@ -96,7 +96,7 @@ class Primitive : public Node {
public: public:
Primitive(Shader *s = nullptr) : Node(), shader_(s), vao_(0), drawMode_(0), drawCount_(0) {} Primitive(Shader *s = nullptr) : Node(), shader_(s), vao_(0), drawMode_(0), drawCount_(0) {}
virtual ~Primitive();
virtual void init () override; virtual void init () override;
virtual void accept (Visitor& v) override; virtual void accept (Visitor& v) override;
@@ -105,7 +105,6 @@ public:
inline Shader *shader () const { return shader_; } inline Shader *shader () const { return shader_; }
void replaceShader (Shader* newshader); void replaceShader (Shader* newshader);
virtual ~Primitive();
protected: protected:
Shader* shader_; Shader* shader_;
uint vao_, drawMode_, drawCount_; uint vao_, drawMode_, drawCount_;
@@ -168,8 +167,9 @@ public:
virtual void accept (Visitor& v) override; virtual void accept (Visitor& v) override;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) override; virtual void draw (glm::mat4 modelview, glm::mat4 projection) override;
virtual void addChild (Node *child); virtual void clear();
virtual void detatchChild (Node *child); virtual void attach (Node *child);
virtual void detatch (Node *child);
NodeSet::iterator begin(); NodeSet::iterator begin();
NodeSet::iterator end(); NodeSet::iterator end();
@@ -197,8 +197,8 @@ public:
virtual void accept (Visitor& v) override; virtual void accept (Visitor& v) override;
virtual void draw (glm::mat4 modelview, glm::mat4 projection) override; virtual void draw (glm::mat4 modelview, glm::mat4 projection) override;
void addChild (Node *child) override; void attach (Node *child) override;
// void detatchChild (Node *child) override; void detatch (Node *child) override;
void unsetActiveChild (); void unsetActiveChild ();
void setActiveChild (Node *child); 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 { class Scene {
Group *root_; Group *root_;
Group *background_;
Group *foreground_;
public: public:
Scene(); Scene();
~Scene(); ~Scene();
void accept (Visitor& v); void accept (Visitor& v);
void update(float dt); void update(float dt);
// void addNode(Node *); void clear();
void clearBackground();
void clearForeground();
Group *root() { return root_; } 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;
}; };

View File

@@ -37,5 +37,6 @@ void SearchVisitor::visit(Switch &n)
void SearchVisitor::visit(Scene &n) void SearchVisitor::visit(Scene &n)
{ {
// TODO maybe search only forground?
n.root()->accept(*this); n.root()->accept(*this);
} }

View File

@@ -38,7 +38,7 @@ void Session::update(float dt)
SourceList::iterator Session::addSource(Source *s) SourceList::iterator Session::addSource(Source *s)
{ {
// insert the source in the rendering // 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 // insert the source to the beginning of the list
sources_.push_front(s); sources_.push_front(s);
// return the iterator to the source created at the beginning // return the iterator to the source created at the beginning
@@ -53,18 +53,13 @@ SourceList::iterator Session::deleteSource(Source *s)
if (its != sources_.end()) { if (its != sources_.end()) {
// remove Node from the rendering scene // remove Node from the rendering scene
// GarbageVisitor remover(s->group(View::RENDERING)); render_.scene.fg()->detatch( s->group(View::RENDERING) );
// remover.visit(render_.scene);
render_.scene.root()->detatchChild( s->group(View::RENDERING) );
// erase the source from the update list & get next element // erase the source from the update list & get next element
its = sources_.erase(its); its = sources_.erase(its);
// delete the source : safe now // delete the source : safe now
delete s; delete s;
// NB: GarbageVisitor ends here, and deletes the Group RENDERING
} }
// return end of next element // return end of next element

View File

@@ -28,15 +28,15 @@ Source::Source(const std::string &name) : name_(name), initialized_(false)
Frame *frame = new Frame(Frame::ROUND_THIN); Frame *frame = new Frame(Frame::ROUND_THIN);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 0.9f); 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); groups_[View::MIXING]->scale_ = glm::vec3(0.15f, 0.15f, 1.f);
// default geometry nodes // default geometry nodes
groups_[View::GEOMETRY] = new Group; groups_[View::GEOMETRY] = new Group;
// will be associated to nodes later // will be associated to nodes later
blendingshader_ = new ImageShader(); blendingshader_ = new ImageShader;
rendershader_ = new ImageProcessingShader(); rendershader_ = new ImageProcessingShader;
renderbuffer_ = nullptr; renderbuffer_ = nullptr;
rendersurface_ = nullptr; rendersurface_ = nullptr;
overlay_ = nullptr; overlay_ = nullptr;
@@ -112,14 +112,14 @@ MediaSource::MediaSource(const std::string &name) : Source(name), uri_("")
overlay_->translation_.z = 0.1; overlay_->translation_.z = 0.1;
overlay_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f); overlay_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
overlay_->visible_ = false; overlay_->visible_ = false;
groups_[View::MIXING]->addChild(overlay_); groups_[View::MIXING]->attach(overlay_);
} }
MediaSource::~MediaSource() MediaSource::~MediaSource()
{ {
// TODO delete media surface with visitor // TODO delete media surface with visitor
//delete mediasurface_; delete mediasurface_;
delete mediaplayer_; delete mediaplayer_;
// TODO verify that all surfaces and node is deleted in Source destructor // 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 // create the surfaces to draw the frame buffer in the views
// TODO Provide the source custom effect shader // TODO Provide the source custom effect shader
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
groups_[View::RENDERING]->addChild(rendersurface_); groups_[View::RENDERING]->attach(rendersurface_);
groups_[View::GEOMETRY]->addChild(rendersurface_); groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->addChild(rendersurface_); groups_[View::MIXING]->attach(rendersurface_);
// for mixing view, add another surface to overlay (for stippled view in transparency) // for mixing view, add another surface to overlay (for stippled view in transparency)
Surface *surfacemix = new FrameBufferSurface(renderbuffer_); Surface *surfacemix = new FrameBufferSurface(renderbuffer_);
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader()); ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
if (is) is->stipple = 1.0; 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 // scale all mixing nodes to match aspect ratio of the media
for (NodeSet::iterator node = groups_[View::MIXING]->begin(); for (NodeSet::iterator node = groups_[View::MIXING]->begin();

View File

@@ -1,6 +1,7 @@
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <thread>
// ImGui // ImGui
#include "imgui.h" #include "imgui.h"
@@ -49,17 +50,16 @@
#include "TextEditor.h" #include "TextEditor.h"
static TextEditor editor; static TextEditor editor;
// utility functions
//static std::thread *FileDialogThread_;
static bool FileDialogPending_ = false;
static bool FileDialogFinished_ = false;
static std::string FileDialogFilename_ = "";
void ShowAboutGStreamer(bool* p_open); void ShowAboutGStreamer(bool* p_open);
void ShowAboutOpengl(bool* p_open); void ShowAboutOpengl(bool* p_open);
void ShowAbout(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) static void FileDialogOpen(std::string path)
{ {
FileDialogPending_ = true; FileDialogPending_ = true;
@@ -379,7 +379,6 @@ void UserInterface::Terminate()
void UserInterface::showMenuFile() void UserInterface::showMenuFile()
{ {
// TODO : New
if (ImGui::MenuItem( ICON_FA_FILE " New", "Ctrl+W", false, !FileDialogPending_)) { if (ImGui::MenuItem( ICON_FA_FILE " New", "Ctrl+W", false, !FileDialogPending_)) {
Mixer::manager().newSession(); Mixer::manager().newSession();
navigator.hidePannel(); navigator.hidePannel();

View File

@@ -1,7 +1,6 @@
#ifndef __UI_MANAGER_H_ #ifndef __UI_MANAGER_H_
#define __UI_MANAGER_H_ #define __UI_MANAGER_H_
#include <thread>
#include <string> #include <string>
#include <list> #include <list>
using namespace std; using namespace std;

View File

@@ -54,18 +54,16 @@ MixingView::MixingView() : View(MIXING)
else else
restoreSettings(); restoreSettings();
// Mixing scene // Mixing scene background
backgound_ = new Group;
scene.root()->addChild(backgound_);
Mesh *disk = new Mesh("mesh/disk.ply"); Mesh *disk = new Mesh("mesh/disk.ply");
disk->setTexture(textureMixingQuadratic()); disk->setTexture(textureMixingQuadratic());
backgound_->addChild(disk); scene.bg()->attach(disk);
glm::vec4 pink( 0.8f, 0.f, 0.8f, 1.f ); glm::vec4 pink( 0.8f, 0.f, 0.8f, 1.f );
Mesh *circle = new Mesh("mesh/circle.ply"); Mesh *circle = new Mesh("mesh/circle.ply");
circle->shader()->color = pink; circle->shader()->color = pink;
backgound_->addChild(circle); scene.bg()->attach(circle);
} }
@@ -238,17 +236,14 @@ GeometryView::GeometryView() : View(GEOMETRY)
else else
restoreSettings(); restoreSettings();
// Geometry Scene // Geometry Scene background
backgound_ = new Group;
scene.root()->addChild(backgound_);
Surface *rect = new Surface; Surface *rect = new Surface;
backgound_->addChild(rect); scene.bg()->attach(rect);
Frame *border = new Frame(Frame::SHARP_THIN); Frame *border = new Frame(Frame::SHARP_THIN);
border->overlay_ = new Mesh("mesh/border_vertical_overlay.ply"); border->overlay_ = new Mesh("mesh/border_vertical_overlay.ply");
border->color = glm::vec4( 0.8f, 0.f, 0.8f, 1.f ); 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 // update rendering of render frame
FrameBuffer *output = Mixer::manager().session()->frame(); FrameBuffer *output = Mixer::manager().session()->frame();
if (output){ 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(); (*node)->scale_.x = output->aspectRatio();
} }
} }

1
View.h
View File

@@ -29,7 +29,6 @@ public:
protected: protected:
Mode mode_; Mode mode_;
Group *backgound_;
}; };