diff --git a/Mixer.cpp b/Mixer.cpp index 8697a82..292af8f 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -78,6 +78,10 @@ static void saveSession(const std::string& filename, Session *session) layer->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::LAYER), &xmlDoc)); views->InsertEndChild(layer); + XMLElement *appearance = xmlDoc.NewElement( "Appearance" ); + appearance->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::APPEARANCE), &xmlDoc)); + views->InsertEndChild(appearance); + XMLElement *render = xmlDoc.NewElement( "Rendering" ); render->InsertEndChild( SessionVisitor::NodeToXML(*session->config(View::RENDERING), &xmlDoc)); views->InsertEndChild(render); @@ -432,6 +436,7 @@ void Mixer::attach(Source *s) mixing_.scene.ws()->attach( s->group(View::MIXING) ); geometry_.scene.ws()->attach( s->group(View::GEOMETRY) ); layer_.scene.ws()->attach( s->group(View::LAYER) ); + appearance_.scene.ws()->attach( s->group(View::APPEARANCE) ); } } @@ -447,6 +452,7 @@ void Mixer::detach(Source *s) mixing_.scene.ws()->detatch( s->group(View::MIXING) ); geometry_.scene.ws()->detatch( s->group(View::GEOMETRY) ); layer_.scene.ws()->detatch( s->group(View::LAYER) ); + appearance_.scene.ws()->detatch( s->group(View::APPEARANCE) ); transition_.scene.ws()->detatch( s->group(View::TRANSITION) ); } } @@ -685,6 +691,9 @@ void Mixer::setView(View::Mode m) case View::LAYER: current_view_ = &layer_; break; + case View::APPEARANCE: + current_view_ = &appearance_; + break; case View::MIXING: default: current_view_ = &mixing_; @@ -706,6 +715,8 @@ View *Mixer::view(View::Mode m) return &geometry_; case View::LAYER: return &layer_; + case View::APPEARANCE: + return &appearance_; case View::MIXING: return &mixing_; default: @@ -725,6 +736,7 @@ void Mixer::saveas(const std::string& filename) session_->config(View::MIXING)->copyTransform( mixing_.scene.root() ); session_->config(View::GEOMETRY)->copyTransform( geometry_.scene.root() ); session_->config(View::LAYER)->copyTransform( layer_.scene.root() ); + session_->config(View::APPEARANCE)->copyTransform( appearance_.scene.root() ); // launch a thread to save the session std::thread (saveSession, filename, session_).detach(); @@ -823,6 +835,7 @@ void Mixer::swap() mixing_.scene.root()->copyTransform( session_->config(View::MIXING) ); geometry_.scene.root()->copyTransform( session_->config(View::GEOMETRY) ); layer_.scene.root()->copyTransform( session_->config(View::LAYER) ); + appearance_.scene.root()->copyTransform( session_->config(View::APPEARANCE) ); // set resolution session_->setResolution( session_->config(View::RENDERING)->scale_ ); diff --git a/Mixer.h b/Mixer.h index ca31b2a..1739e79 100644 --- a/Mixer.h +++ b/Mixer.h @@ -114,6 +114,7 @@ protected: MixingView mixing_; GeometryView geometry_; LayerView layer_; + AppearanceView appearance_; TransitionView transition_; guint64 update_time_; diff --git a/Session.cpp b/Session.cpp index 3cdc216..4257261 100644 --- a/Session.cpp +++ b/Session.cpp @@ -28,6 +28,10 @@ Session::Session() : failedSource_(nullptr), active_(true), fading_target_(0.f) config_[View::MIXING] = new Group; config_[View::MIXING]->scale_ = Settings::application.views[View::MIXING].default_scale; config_[View::MIXING]->translation_ = Settings::application.views[View::MIXING].default_translation; + + config_[View::APPEARANCE] = new Group; + config_[View::APPEARANCE]->scale_ = Settings::application.views[View::APPEARANCE].default_scale; + config_[View::APPEARANCE]->translation_ = Settings::application.views[View::APPEARANCE].default_translation; } @@ -43,6 +47,7 @@ Session::~Session() delete config_[View::GEOMETRY]; delete config_[View::LAYER]; delete config_[View::MIXING]; + delete config_[View::APPEARANCE]; } void Session::setActive (bool on) @@ -89,31 +94,6 @@ void Session::update(float dt) // grab frames to recorders & streamers FrameGrabbing::manager().grabFrame(render_.frame(), dt); -// // send frame to recorders -// std::list::iterator iter = iter=grabbers_.begin(); -// // if there is at least once frame grabber -// if (iter != grabbers_.end()) { -// // grab a frame (once for all recorders) -// FrameGrabber::Buffer buf = FrameGrabber::grabFrame(render_.frame()); - -// // give the frame to all recorders -// while (iter != grabbers_.end()) -// { -// FrameGrabber *rec = *iter; -// rec->addFrame(buf, dt); - -// if (rec->finished()) { -// iter = grabbers_.erase(iter); -// delete rec; -// } -// else { -// iter++; -// } -// } - -// gst_buffer_unref(buf.buffer); -// // gst_clear_buffer(&buf.buffer); -// } } @@ -304,66 +284,6 @@ int Session::index(SourceList::iterator it) const return index; } -//void Session::addFrameGrabber(FrameGrabber *rec) -//{ -// if (rec != nullptr) -// grabbers_.push_back(rec); -//} - - -//FrameGrabber *Session::frontFrameGrabber() -//{ -// if (grabbers_.empty()) -// return nullptr; -// else -// return grabbers_.front(); -//} - -//FrameGrabber *Session::getFrameGrabber(uint64_t id) -//{ -// if (id > 0 && grabbers_.size() > 0 ) -// { -// std::list::iterator iter = std::find_if(grabbers_.begin(), grabbers_.end(), FrameGrabber::hasId(id)); -// if (iter != grabbers_.end()) -// return (*iter); -// } - -// return nullptr; -//} - -//void Session::stopAllFrameGrabbers() -//{ -// std::list::iterator iter; -// for (iter=grabbers_.begin(); iter != grabbers_.end(); ) -// (*iter)->stop(); -//} - -//void Session::clearAllFrameGrabbers() -//{ -// std::list::iterator iter; -// for (iter=grabbers_.begin(); iter != grabbers_.end(); ) -// { -// FrameGrabber *rec = *iter; -// rec->stop(); -// iter = grabbers_.erase(iter); -// delete rec; -// } -//} - -//void Session::transferFrameGrabber(Session *dest) -//{ -// if (dest == nullptr) -// return; - -// std::list::iterator iter; -// for (iter=grabbers_.begin(); iter != grabbers_.end(); ) -// { -// dest->grabbers_.push_back(*iter); -// iter = grabbers_.erase(iter); -// } -//} - - void Session::lock() { access_.lock(); diff --git a/Session.h b/Session.h index 48827fb..1169321 100644 --- a/Session.h +++ b/Session.h @@ -58,14 +58,6 @@ public: // get frame result of render inline FrameBuffer *frame () const { return render_.frame(); } -// // Recorders -// void addFrameGrabber(FrameGrabber *rec); -// FrameGrabber *frontFrameGrabber(); -// FrameGrabber *getFrameGrabber(uint64_t id); -// void stopAllFrameGrabbers(); -// void clearAllFrameGrabbers(); -// void transferFrameGrabber(Session *dest); - // configure rendering resolution void setResolution(glm::vec3 resolution); diff --git a/Source.cpp b/Source.cpp index d32d840..91eb343 100644 --- a/Source.cpp +++ b/Source.cpp @@ -120,6 +120,10 @@ Source::Source() : initialized_(false), active_(true), need_update_(true) overlays_[View::LAYER]->visible_ = false; groups_[View::LAYER]->attach(overlays_[View::LAYER]); + // default appearance node + groups_[View::APPEARANCE] = new Group; + groups_[View::APPEARANCE]->visible_ = false; + // empty transition node groups_[View::TRANSITION] = new Group; @@ -156,6 +160,7 @@ Source::~Source() delete groups_[View::MIXING]; delete groups_[View::GEOMETRY]; delete groups_[View::LAYER]; + delete groups_[View::APPEARANCE]; delete groups_[View::TRANSITION]; groups_.clear(); @@ -253,6 +258,7 @@ void Source::attach(FrameBuffer *renderbuffer) groups_[View::RENDERING]->attach(rendersurface_); groups_[View::GEOMETRY]->attach(rendersurface_); groups_[View::MIXING]->attach(rendersurface_); + groups_[View::APPEARANCE]->attach(rendersurface_); // groups_[View::LAYER]->attach(rendersurface_); // for mixing and layer views, add another surface to overlay @@ -277,6 +283,10 @@ void Source::attach(FrameBuffer *renderbuffer) node != groups_[View::LAYER]->end(); node++) { (*node)->scale_.x = renderbuffer_->aspectRatio(); } + for (node = groups_[View::APPEARANCE]->begin(); + node != groups_[View::APPEARANCE]->end(); node++) { + (*node)->scale_.x = renderbuffer_->aspectRatio(); + } // Transition group node is optionnal if ( groups_[View::TRANSITION]->numChildren() > 0 ) { diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 69085e6..c0541c4 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -354,6 +354,8 @@ void UserInterface::handleKeyboard() Mixer::manager().setView(View::GEOMETRY); else if (ImGui::IsKeyPressed( GLFW_KEY_F3 )) Mixer::manager().setView(View::LAYER); + else if (ImGui::IsKeyPressed( GLFW_KEY_F3 )) + Mixer::manager().setView(View::APPEARANCE); else if (ImGui::IsKeyPressed( GLFW_KEY_F12 )) StartScreenshot(); // normal keys // make sure no entry / window box is active @@ -915,12 +917,10 @@ void ToolBox::Render() ImGui::InputText("gstreamer pipeline", buf1, 128); if (ImGui::Button("Create Generic Stream Source") ) { -// GenericStreamSource *s = Mixer::manager().addSource( Mixer::manager().createSourceStream(buf1) ); } - // // display histogram of update time and plot framerate // diff --git a/View.cpp b/View.cpp index 90e1384..4fcc6bf 100644 --- a/View.cpp +++ b/View.cpp @@ -1692,3 +1692,91 @@ View::Cursor TransitionView::drag (glm::vec2 from, glm::vec2 to) } +AppearanceView::AppearanceView() : View(APPEARANCE) +{ + // read default settings + if ( Settings::application.views[mode_].name.empty() ) { + // no settings found: store application default + Settings::application.views[mode_].name = "Source"; + scene.root()->scale_ = glm::vec3(SOURCE_DEFAULT_SCALE, SOURCE_DEFAULT_SCALE, 1.0f); + scene.root()->translation_ = glm::vec3(1.3f, 1.f, 0.0f); + saveSettings(); + } + else + restoreSettings(); + + // Scene background + +} + +void AppearanceView::update(float dt) +{ + View::update(dt); + + // a more complete update is requested + if (View::need_deep_update_) { + + // update rendering of render frame + FrameBuffer *output = Mixer::manager().session()->frame(); + if (output){ + for (NodeSet::iterator node = scene.bg()->begin(); node != scene.bg()->end(); node++) { + (*node)->scale_.x = output->aspectRatio(); + } + } + } +} + +void AppearanceView::zoom (float factor) +{ + float z = scene.root()->scale_.x; + z = CLAMP( z + 0.1f * factor, SOURCE_MIN_SCALE, SOURCE_MAX_SCALE); + scene.root()->scale_.x = z; + scene.root()->scale_.y = z; +} + +void AppearanceView::resize ( int scale ) +{ + float z = CLAMP(0.01f * (float) scale, 0.f, 1.f); + z *= z; + z *= SOURCE_MAX_SCALE - SOURCE_MIN_SCALE; + z += SOURCE_MIN_SCALE; + scene.root()->scale_.x = z; + scene.root()->scale_.y = z; +} + +int AppearanceView::size () +{ + float z = (scene.root()->scale_.x - SOURCE_MIN_SCALE) / (SOURCE_MAX_SCALE - SOURCE_MIN_SCALE); + return (int) ( sqrt(z) * 100.f); +} + + +View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair pick) +{ + if (!s) + return Cursor(); + + // unproject + glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); + + + std::ostringstream info; + info << "Source " ; + + + + return Cursor(Cursor_ResizeNESW, info.str() ); +} + + +View::Cursor AppearanceView::drag (glm::vec2 from, glm::vec2 to) +{ + Cursor ret = View::drag(from, to); + + // Clamp translation to acceptable area + scene.root()->translation_ = glm::clamp(scene.root()->translation_, glm::vec3(-3.f, -1.5f, 0.f), glm::vec3(3.f, 1.5f, 0.f)); + + return ret; +} + diff --git a/View.h b/View.h index dbb1937..267fa32 100644 --- a/View.h +++ b/View.h @@ -16,7 +16,7 @@ class View { public: - typedef enum {RENDERING = 0, MIXING=1, GEOMETRY=2, LAYER=3, TRANSITION=4, INVALID=5 } Mode; + typedef enum {RENDERING = 0, MIXING=1, GEOMETRY=2, LAYER=3, APPEARANCE=4, TRANSITION=5, INVALID=6 } Mode; View(Mode m); virtual ~View() {} @@ -216,6 +216,22 @@ private: SessionSource *transition_source_; }; +class AppearanceView : public View +{ +public: + AppearanceView(); + + void update (float dt) override; + void zoom (float factor) override; + void resize (int) override; + int size () override; + + Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair pick) override; + Cursor drag (glm::vec2, glm::vec2) override; + +private: + +}; #endif // VIEW_H diff --git a/defines.h b/defines.h index 68cec60..443b9c6 100644 --- a/defines.h +++ b/defines.h @@ -39,6 +39,9 @@ #define LAYER_DEFAULT_SCALE 0.8f #define LAYER_MIN_SCALE 0.4f #define LAYER_MAX_SCALE 1.7f +#define SOURCE_DEFAULT_SCALE 1.2f +#define SOURCE_MIN_SCALE 0.2f +#define SOURCE_MAX_SCALE 10.0f #define TRANSITION_DEFAULT_SCALE 3.0f #define TRANSITION_MIN_DURATION 0.2f #define TRANSITION_MAX_DURATION 10.f