From 530762d1d2ca357c45831b2f0f297ff2b8268bc0 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Mon, 18 May 2020 21:58:50 +0200 Subject: [PATCH] First effective implementation of LayerView (both GUI, sorting and storing in session) --- Scene.cpp | 9 +++++++++ Scene.h | 2 +- Session.cpp | 7 ++++++- SessionCreator.cpp | 3 +++ SessionVisitor.cpp | 4 ++++ Source.cpp | 38 ++++++++++++++++++++++++++------------ Source.h | 25 ++++++++++++++++++------- View.cpp | 12 +++++++++++- 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/Scene.cpp b/Scene.cpp index fe5a176..eb9ac17 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -206,6 +206,15 @@ void Group::attach(Node *child) } +void Group::sort() +{ + // reorder list of nodes + NodeSet ordered_children; + for(auto it = children_.begin(); it != children_.end(); it++) + ordered_children.insert(*it); + children_.swap(ordered_children); +} + void Group::detatch(Node *child) { // find the node with this id, and erase it out of the list of children diff --git a/Scene.h b/Scene.h index 2a3ee16..cb75ade 100644 --- a/Scene.h +++ b/Scene.h @@ -167,12 +167,12 @@ public: virtual void clear(); virtual void attach (Node *child); virtual void detatch (Node *child); + virtual void sort(); NodeSet::iterator begin(); NodeSet::iterator end(); uint numChildren() const; - protected: NodeSet children_; diff --git a/Session.cpp b/Session.cpp index 243c598..39698d1 100644 --- a/Session.cpp +++ b/Session.cpp @@ -5,6 +5,8 @@ #include "Session.h" #include "GarbageVisitor.h" +#include "Log.h" + Session::Session() { config_[View::RENDERING] = new Group; @@ -30,7 +32,10 @@ void Session::update(float dt) { // pre-render of all sources for( SourceList::iterator it = sources_.begin(); it != sources_.end(); it++){ - (*it)->render( ); + // render the source + (*it)->render(); + // update the source + (*it)->update(dt); } // update the scene tree diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 0459a4b..cbefd8d 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -193,6 +193,9 @@ void SessionCreator::visit (Source& s) xmlCurrent_ = sourceNode->FirstChildElement("Geometry"); s.groupNode(View::GEOMETRY)->accept(*this); + xmlCurrent_ = sourceNode->FirstChildElement("Layer"); + s.groupNode(View::LAYER)->accept(*this); + xmlCurrent_ = sourceNode->FirstChildElement("Blending"); s.blendingShader()->accept(*this); diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index c5d15ef..4fe74c1 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -311,6 +311,10 @@ void SessionVisitor::visit (Source& s) sourceNode->InsertEndChild(xmlCurrent_); s.groupNode(View::GEOMETRY)->accept(*this); + xmlCurrent_ = xmlDoc_->NewElement( "Layer" ); + sourceNode->InsertEndChild(xmlCurrent_); + s.groupNode(View::LAYER)->accept(*this); + xmlCurrent_ = xmlDoc_->NewElement( "Blending" ); sourceNode->InsertEndChild(xmlCurrent_); s.blendingShader()->accept(*this); diff --git a/Source.cpp b/Source.cpp index a6ee12e..2f50c55 100644 --- a/Source.cpp +++ b/Source.cpp @@ -14,8 +14,9 @@ #include "MediaPlayer.h" #include "SearchVisitor.h" +#include "Log.h" -Source::Source(const std::string &name) : name_(name), initialized_(false) +Source::Source(const std::string &name) : name_(name), initialized_(false), need_update_(true) { sprintf(initials_, "__"); @@ -107,6 +108,30 @@ void Source::setOverlayVisible(bool on) (*o).second->visible_ = on; } +void Source::update(float dt) +{ + if (need_update_) + { + // ADJUST alpha based on MIXING node + // read position of the mixing node and interpret this as transparency of render output + glm::vec2 dist = glm::vec2(groups_[View::MIXING]->translation_); + float alpha = 1.0 - CLAMP( SQUARE( glm::length(dist) ), 0.f, 1.f ); + blendingshader_->color.a = alpha; + + // MODIFY geometry based on GEOMETRY node + groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_; + groups_[View::RENDERING]->scale_ = groups_[View::GEOMETRY]->scale_; + groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_; + + // MODIFY DEPTH + groups_[View::MIXING]->translation_.z = groups_[View::LAYER]->translation_.z; + groups_[View::GEOMETRY]->translation_.z = groups_[View::LAYER]->translation_.z; + groups_[View::RENDERING]->translation_.z = groups_[View::LAYER]->translation_.z; + + need_update_ = false; + } +} + Handles *Source::handleNode(Handles::Type t) const { if ( t == Handles::ROTATE ) @@ -285,17 +310,6 @@ void MediaSource::render() renderbuffer_->begin(); mediasurface_->draw(glm::identity(), projection); renderbuffer_->end(); - - // ADJUST alpha based on MIXING node - // read position of the mixing node and interpret this as transparency of render output - float alpha = 1.0 - CLAMP( SQUARE( glm::length(groups_[View::MIXING]->translation_) ), 0.f, 1.f ); - blendingshader_->color.a = alpha; - - // MODIFY geometry based on GEOMETRY node - groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_; - groups_[View::RENDERING]->scale_ = groups_[View::GEOMETRY]->scale_; - groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_; - } } diff --git a/Source.h b/Source.h index af85126..4622311 100644 --- a/Source.h +++ b/Source.h @@ -37,24 +37,32 @@ public: inline Node *groupNode(View::Mode m) const { return static_cast(groups_.at(m)); } Handles *handleNode(Handles::Type t) const; - // every Source has a shader to control image processing effects + // a Source has a shader to control image processing effects inline ImageProcessingShader *processingShader() const { return rendershader_; } - // every Source has a shader to control mixing effects + // a Source has a shader to control mixing effects inline ImageShader *blendingShader() const { return blendingshader_; } - // every Source shall have a frame buffer - virtual FrameBuffer *frame() const = 0; + // a Source shall be updated before displayed (Mixing, Geometry and Layer) + void update (float dt); - // every Source shall be rendered before draw - virtual void render() = 0; + // touch to request update + inline void touch() { need_update_ = true; } // accept all kind of visitors virtual void accept (Visitor& v); - // every Source shall informs if the source failed (i.e. shall be deleted) + // SPECIFIC implementation for subtypes + + // a Source shall informs if the source failed (i.e. shall be deleted) virtual bool failed() const { return false; } + // every Source shall have a frame buffer + virtual FrameBuffer *frame() const = 0; + + // every Source shall be rendered into the frame buffer + virtual void render() = 0; + protected: // name std::string name_; @@ -84,6 +92,9 @@ protected: // overlay to be displayed on top of source std::map overlays_; Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_; + + // update need + bool need_update_; }; // TODO SourceSet sorted by shader diff --git a/View.cpp b/View.cpp index 8aef67f..37816ff 100644 --- a/View.cpp +++ b/View.cpp @@ -42,6 +42,9 @@ void View::update(float dt) { // recursive update from root of scene scene.update( dt ); + + // reorder depth + scene.fg()->sort(); } void View::drag (glm::vec2 from, glm::vec2 to) @@ -126,6 +129,8 @@ void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pairtranslation_ = start_translation + gl_Position_to - gl_Position_from; + // request update + s->touch(); } @@ -323,6 +328,8 @@ void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pairtranslation_ = start_translation + gl_Position_to - gl_Position_from; } + // request update + s->touch(); } LayerView::LayerView() : View(LAYER), aspect_ratio(1.f) @@ -379,7 +386,6 @@ void LayerView::zoom (float factor) z = CLAMP( z + 0.1f * factor, 0.2f, 10.f); scene.root()->scale_.x = z; scene.root()->scale_.y = z; - Log::Info("scale layer %f", scene.root()->scale_.x ); } @@ -409,6 +415,10 @@ void LayerView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pairtranslation_.x = CLAMP( sourceNode->translation_.x, -10.f, 0.f); sourceNode->translation_.y = sourceNode->translation_.x / aspect_ratio; + // change depth + sourceNode->translation_.z = -sourceNode->translation_.x; + // request update + s->touch(); }