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
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)
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;
}

View File

@@ -1,4 +1,5 @@
#include <algorithm>
#include <thread>
#include <tinyxml2.h>
#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_;
}

View File

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

View File

@@ -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;
}

View File

@@ -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();
};

View File

@@ -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)

39
Scene.h
View File

@@ -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;
};

View File

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

View File

@@ -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

View File

@@ -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<ImageShader *>(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();

View File

@@ -1,6 +1,7 @@
#include <iostream>
#include <cstring>
#include <sstream>
#include <thread>
// 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();

View File

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

View File

@@ -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();
}
}

1
View.h
View File

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