Cleanup and fixed implementation of clone and render sources.

This commit is contained in:
brunoherbelin
2020-05-23 11:29:27 +02:00
parent 0eb31c7adc
commit 781023a93d
14 changed files with 477 additions and 152 deletions

View File

@@ -279,6 +279,8 @@ set(VMIX_RSC_FILES
./rsc/mesh/circle.ply ./rsc/mesh/circle.ply
./rsc/mesh/icon_video.ply ./rsc/mesh/icon_video.ply
./rsc/mesh/icon_image.ply ./rsc/mesh/icon_image.ply
./rsc/mesh/icon_render.ply
./rsc/mesh/icon_clone.ply
./rsc/mesh/icon_vimix.ply ./rsc/mesh/icon_vimix.ply
) )

View File

@@ -295,6 +295,11 @@ void ImGuiVisitor::visit (RenderSource& s)
{ {
// ImGui::Button("Expand", ImVec2(IMGUI_RIGHT_ALIGN, 0)); // ImGui::Button("Expand", ImVec2(IMGUI_RIGHT_ALIGN, 0));
ImGui::Text("Render"); ImGui::Text("Render");
if (ImGui::Button("Reconnect", ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
s.reconnect();
} }
void ImGuiVisitor::visit (CloneSource& s)
{
// ImGui::Button("Expand", ImVec2(IMGUI_RIGHT_ALIGN, 0));
ImGui::Text("Clone of %s", s.origin()->name());
}

View File

@@ -27,6 +27,7 @@ public:
void visit (MediaSource& s) override; void visit (MediaSource& s) override;
void visit (SessionSource& s) override; void visit (SessionSource& s) override;
void visit (RenderSource& s) override; void visit (RenderSource& s) override;
void visit (CloneSource& s) override;
}; };
#endif // IMGUIVISITOR_H #endif // IMGUIVISITOR_H

View File

@@ -55,6 +55,11 @@ bool MediaSource::failed() const
return mediaplayer_->failed(); return mediaplayer_->failed();
} }
uint MediaSource::texture() const
{
return mediaplayer_->texture();
}
void MediaSource::init() void MediaSource::init()
{ {
if ( mediaplayer_->isOpen() ) { if ( mediaplayer_->isOpen() ) {
@@ -70,48 +75,19 @@ void MediaSource::init()
// create Frame buffer matching size of media player // create Frame buffer matching size of media player
float height = float(mediaplayer()->width()) / mediaplayer()->aspectRatio(); float height = float(mediaplayer()->width()) / mediaplayer()->aspectRatio();
renderbuffer_ = new FrameBuffer(mediaplayer()->width(), (uint)height, true); FrameBuffer *renderbuffer = new FrameBuffer(mediaplayer()->width(), (uint)height, true);
// create the surfaces to draw the frame buffer in the views // set the renderbuffer of the source and attach rendering nodes
// TODO Provide the source custom effect shader attach(renderbuffer);
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
groups_[View::RENDERING]->attach(rendersurface_);
groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->attach(rendersurface_);
groups_[View::LAYER]->attach(rendersurface_);
// for mixing view, add another surface to overlay (for stippled view in transparency) // icon in mixing view
Surface *surfacemix = new FrameBufferSurface(renderbuffer_);
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
if (is) is->stipple = 1.0;
groups_[View::MIXING]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix);
if (mediaplayer_->duration() == GST_CLOCK_TIME_NONE) if (mediaplayer_->duration() == GST_CLOCK_TIME_NONE)
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_image.ply") ); overlays_[View::MIXING]->attach( new Mesh("mesh/icon_image.ply") );
else else
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_video.ply") ); overlays_[View::MIXING]->attach( new Mesh("mesh/icon_video.ply") );
// scale all mixing nodes to match aspect ratio of the media // done init
for (NodeSet::iterator node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = mediaplayer_->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = mediaplayer_->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = mediaplayer_->aspectRatio();
}
// done init once and for all
initialized_ = true; initialized_ = true;
// make visible
groups_[View::RENDERING]->visible_ = true;
groups_[View::MIXING]->visible_ = true;
groups_[View::GEOMETRY]->visible_ = true;
groups_[View::LAYER]->visible_ = true;
} }
} }

View File

@@ -11,8 +11,9 @@ public:
// implementation of source API // implementation of source API
void render() override; void render() override;
void accept (Visitor& v) override;
bool failed() const override; bool failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
// Media specific interface // Media specific interface
void setPath(const std::string &p); void setPath(const std::string &p);

View File

@@ -196,7 +196,7 @@ void Mixer::createSourceFile(std::string path)
} }
else { else {
// (try to) create media source by default // (try to) create media source by default
MediaSource *ms = new MediaSource(); MediaSource *ms = new MediaSource;
ms->setPath(path); ms->setPath(path);
s = ms; s = ms;
} }
@@ -224,6 +224,22 @@ void Mixer::createSourceRender()
insertSource(s); insertSource(s);
} }
void Mixer::createSourceClone(std::string namesource)
{
SourceList::iterator origin = session_->find(namesource);
if (origin != session_->end()) {
// create a source
CloneSource *s = (*origin)->clone();
// get new name
renameSource(s, (*origin)->name());
// add to mixer
insertSource(s);
}
}
void Mixer::insertSource(Source *s) void Mixer::insertSource(Source *s)
{ {
// Add source to Session and set it as current // Add source to Session and set it as current

View File

@@ -36,7 +36,7 @@ public:
// manangement of sources // manangement of sources
void createSourceFile(std::string path); void createSourceFile(std::string path);
void createSourceRender(); void createSourceRender();
void createSourceClone() {} void createSourceClone(std::string namesource);
// operations on sources // operations on sources
void renameSource(Source *s, const std::string &newname); void renameSource(Source *s, const std::string &newname);

View File

@@ -15,6 +15,7 @@
#include "SearchVisitor.h" #include "SearchVisitor.h"
#include "Session.h" #include "Session.h"
#include "SessionCreator.h" #include "SessionCreator.h"
#include "Mixer.h"
void SessionSource::loadSession(const std::string& filename, SessionSource *source) void SessionSource::loadSession(const std::string& filename, SessionSource *source)
@@ -92,6 +93,11 @@ bool SessionSource::failed() const
return loadFailed_; return loadFailed_;
} }
uint SessionSource::texture() const
{
return session_->frame()->texture();
}
void SessionSource::init() void SessionSource::init()
{ {
if ( loadFinished_ && !loadFailed_ ) { if ( loadFinished_ && !loadFailed_ ) {
@@ -107,47 +113,17 @@ void SessionSource::init()
sessionsurface_->setTextureIndex( session_->frame()->texture() ); sessionsurface_->setTextureIndex( session_->frame()->texture() );
// create Frame buffer matching size of session // create Frame buffer matching size of session
renderbuffer_ = new FrameBuffer( session_->frame()->resolution()); FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
// create the surfaces to draw the frame buffer in the views // set the renderbuffer of the source and attach rendering nodes
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); attach(renderbuffer);
groups_[View::RENDERING]->attach(rendersurface_);
groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->attach(rendersurface_);
groups_[View::LAYER]->attach(rendersurface_);
// for mixing view, add another surface to overlay (for stippled view in transparency) // icon in mixing view
Surface *surfacemix = new FrameBufferSurface(renderbuffer_);
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
if (is) is->stipple = 1.0;
groups_[View::MIXING]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix);
// icon session
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_vimix.ply") ); overlays_[View::MIXING]->attach( new Mesh("mesh/icon_vimix.ply") );
// scale all mixing nodes to match aspect ratio of the media // done init
for (NodeSet::iterator node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = session_->frame()->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = session_->frame()->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = session_->frame()->aspectRatio();
}
// done init once and for all
initialized_ = true; initialized_ = true;
// make visible
groups_[View::RENDERING]->visible_ = true;
groups_[View::MIXING]->visible_ = true;
groups_[View::GEOMETRY]->visible_ = true;
groups_[View::LAYER]->visible_ = true;
Log::Info("Source Session %s loading %d sources.", path_.c_str(), session_->numSource()); Log::Info("Source Session %s loading %d sources.", path_.c_str(), session_->numSource());
} }
} }
@@ -155,14 +131,12 @@ void SessionSource::init()
void SessionSource::render() void SessionSource::render()
{ {
if (!initialized_) if (!initialized_)
{
init(); init();
}
else { else {
// update session // update session
session_->update(dt_); session_->update(dt_);
// render the media player into frame buffer // render the sesion into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
renderbuffer_->begin(); renderbuffer_->begin();
sessionsurface_->draw(glm::identity<glm::mat4>(), projection); sessionsurface_->draw(glm::identity<glm::mat4>(), projection);
@@ -176,3 +150,69 @@ void SessionSource::accept(Visitor& v)
v.visit(*this); v.visit(*this);
} }
RenderSource::RenderSource() : Source()
{
// create surface:
sessionsurface_ = new Surface(rendershader_);
}
RenderSource::~RenderSource()
{
// delete surface
delete sessionsurface_;
}
bool RenderSource::failed() const
{
return Mixer::manager().session() == nullptr;
}
uint RenderSource::texture() const
{
return Mixer::manager().session()->frame()->texture();
}
void RenderSource::init()
{
Session *session = Mixer::manager().session();
if (session && session->frame()->texture() != Resource::getTextureBlack()) {
// get the texture index from framebuffer of view, apply it to the surface
sessionsurface_->setTextureIndex( session->frame()->texture() );
// create Frame buffer matching size of output session
FrameBuffer *renderbuffer = new FrameBuffer( session->frame()->resolution());
// set the renderbuffer of the source and attach rendering nodes
attach(renderbuffer);
// icon in mixing view
overlays_[View::MIXING]->attach( new Mesh("mesh/icon_render.ply") );
// done init
initialized_ = true;
Log::Info("Source Render linked to session (%d x %d).", int(session->frame()->resolution().x), int(session->frame()->resolution().y) );
}
}
void RenderSource::render()
{
if (!initialized_)
init();
else {
// render the view into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f);
renderbuffer_->begin();
sessionsurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
}
}
void RenderSource::accept(Visitor& v)
{
Source::accept(v);
v.visit(*this);
}

View File

@@ -12,8 +12,9 @@ public:
// implementation of source API // implementation of source API
void render() override; void render() override;
void accept (Visitor& v) override;
bool failed() const override; bool failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
// Session Source specific interface // Session Source specific interface
void load(const std::string &p); void load(const std::string &p);
@@ -34,4 +35,25 @@ protected:
std::atomic<bool> loadFailed_; std::atomic<bool> loadFailed_;
std::atomic<bool> loadFinished_; std::atomic<bool> loadFinished_;
}; };
class RenderSource : public Source
{
public:
RenderSource();
~RenderSource();
// implementation of source API
void render() override;
bool failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
protected:
void init() override;
Surface *sessionsurface_;
};
#endif // SESSIONSOURCE_H #endif // SESSIONSOURCE_H

View File

@@ -14,7 +14,6 @@
#include "ImageShader.h" #include "ImageShader.h"
#include "ImageProcessingShader.h" #include "ImageProcessingShader.h"
#include "Log.h" #include "Log.h"
#include "Mixer.h"
Source::Source() : initialized_(false), need_update_(true) Source::Source() : initialized_(false), need_update_(true)
{ {
@@ -114,6 +113,8 @@ Source::~Source()
groups_.clear(); groups_.clear();
overlays_.clear(); overlays_.clear();
for (auto it = clones_.begin(); it != clones_.end(); it++)
(*it)->origin_ = nullptr;
} }
void Source::setName (const std::string &name) void Source::setName (const std::string &name)
@@ -135,6 +136,46 @@ void Source::setOverlayVisible(bool on)
(*o).second->visible_ = on; (*o).second->visible_ = on;
} }
void Source::attach(FrameBuffer *renderbuffer)
{
renderbuffer_ = renderbuffer;
// 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]->attach(rendersurface_);
groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->attach(rendersurface_);
groups_[View::LAYER]->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]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix);
// scale all mixing nodes to match aspect ratio of the media
for (NodeSet::iterator node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = renderbuffer_->aspectRatio();
}
// make visible
groups_[View::RENDERING]->visible_ = true;
groups_[View::MIXING]->visible_ = true;
groups_[View::GEOMETRY]->visible_ = true;
groups_[View::LAYER]->visible_ = true;
}
void Source::update(float dt) void Source::update(float dt)
{ {
// keep delta-t // keep delta-t
@@ -187,7 +228,6 @@ Handles *Source::handleNode(Handles::Type t) const
return resize_handle_; return resize_handle_;
} }
bool hasNode::operator()(const Source* elem) const bool hasNode::operator()(const Source* elem) const
{ {
if (elem) if (elem)
@@ -209,95 +249,72 @@ bool hasNode::operator()(const Source* elem) const
return false; return false;
} }
CloneSource *Source::clone()
RenderSource::RenderSource() : Source()
{ {
// create surface: CloneSource *s = new CloneSource(this);
sessionsurface_ = new Surface(rendershader_);
clones_.push_back(s);
return s;
} }
RenderSource::~RenderSource() CloneSource::CloneSource(Source *origin) : Source(), origin_(origin)
{
// create surface:
clonesurface_ = new Surface(rendershader_);
}
CloneSource::~CloneSource()
{ {
// delete surface // delete surface
delete sessionsurface_; delete clonesurface_;
} }
void RenderSource::reconnect() CloneSource *CloneSource::clone()
{ {
sessionsurface_->setTextureIndex( Mixer::manager().session()->frame()->texture() ); // do not clone a clone : clone the original instead
return origin_->clone();
} }
void RenderSource::init() void CloneSource::init()
{ {
Session *session = Mixer::manager().session(); if (origin_ && origin_->texture() != Resource::getTextureBlack()) {
if (session && session->frame()->texture() != Resource::getTextureBlack()) {
// get the texture index from framebuffer of view, apply it to the surface // get the texture index from framebuffer of view, apply it to the surface
sessionsurface_->setTextureIndex( session->frame()->texture() ); clonesurface_->setTextureIndex( origin_->texture() );
// create Frame buffer matching size of session // create Frame buffer matching size of session
renderbuffer_ = new FrameBuffer( session->frame()->resolution()); FrameBuffer *renderbuffer = new FrameBuffer( origin_->frame()->resolution(), true);
// create the surfaces to draw the frame buffer in the views // set the renderbuffer of the source and attach rendering nodes
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); attach(renderbuffer);
groups_[View::RENDERING]->attach(rendersurface_);
groups_[View::GEOMETRY]->attach(rendersurface_);
groups_[View::MIXING]->attach(rendersurface_);
groups_[View::LAYER]->attach(rendersurface_);
// for mixing view, add another surface to overlay (for stippled view in transparency) // icon in mixing view
Surface *surfacemix = new FrameBufferSurface(renderbuffer_); overlays_[View::MIXING]->attach( new Mesh("mesh/icon_clone.ply") );
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
if (is) is->stipple = 1.0;
groups_[View::MIXING]->attach(surfacemix);
groups_[View::LAYER]->attach(surfacemix);
// TODO icon session
// scale all mixing nodes to match aspect ratio of the media // done init
for (NodeSet::iterator node = groups_[View::MIXING]->begin();
node != groups_[View::MIXING]->end(); node++) {
(*node)->scale_.x = session->frame()->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::GEOMETRY]->begin();
node != groups_[View::GEOMETRY]->end(); node++) {
(*node)->scale_.x = session->frame()->aspectRatio();
}
for (NodeSet::iterator node = groups_[View::LAYER]->begin();
node != groups_[View::LAYER]->end(); node++) {
(*node)->scale_.x = session->frame()->aspectRatio();
}
// done init once and for all
initialized_ = true; initialized_ = true;
// make visible Log::Info("Source Clone linked to source %s).", origin_->name().c_str() );
groups_[View::RENDERING]->visible_ = true;
groups_[View::MIXING]->visible_ = true;
groups_[View::GEOMETRY]->visible_ = true;
groups_[View::LAYER]->visible_ = true;
Log::Info("Source Render linked to session (%d x %d).", int(session->frame()->resolution().x), int(session->frame()->resolution().y) );
} }
} }
void RenderSource::render() void CloneSource::render()
{ {
if (!initialized_) if (!initialized_)
init(); init();
else { else {
// render the view into frame buffer // render the view into frame buffer
static glm::mat4 projection = glm::ortho(-1.f, 1.f, -1.f, 1.f, -1.f, 1.f); static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
renderbuffer_->begin(); renderbuffer_->begin();
sessionsurface_->draw(glm::identity<glm::mat4>(), projection); clonesurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end(); renderbuffer_->end();
} }
} }
void CloneSource::accept(Visitor& v)
void RenderSource::accept(Visitor& v)
{ {
Source::accept(v); Source::accept(v);
v.visit(*this); v.visit(*this);
} }

View File

@@ -16,6 +16,11 @@ class MediaPlayer;
class Surface; class Surface;
class Session; class Session;
class Frame; class Frame;
class Source;
class CloneSource;
typedef std::list<Source *> SourceList;
typedef std::list<CloneSource *> CloneList;
class Source class Source
{ {
@@ -30,6 +35,9 @@ public:
inline std::string name () const { return name_; } inline std::string name () const { return name_; }
inline const char *initials() const { return initials_; } inline const char *initials() const { return initials_; }
// cloning mechanism
virtual CloneSource *clone();
// an overlay can be displayed on top of the source // an overlay can be displayed on top of the source
virtual void setOverlayVisible(bool on); virtual void setOverlayVisible(bool on);
@@ -44,6 +52,9 @@ public:
// a Source has a shader to control mixing effects // a Source has a shader to control mixing effects
inline ImageShader *blendingShader() const { return blendingshader_; } inline ImageShader *blendingShader() const { return blendingshader_; }
// every Source has a frame buffer from the renderbuffer
virtual FrameBuffer *frame() const;
// touch to request update // touch to request update
inline void touch() { need_update_ = true; } inline void touch() { need_update_ = true; }
@@ -53,15 +64,13 @@ public:
// accept all kind of visitors // accept all kind of visitors
virtual void accept (Visitor& v); virtual void accept (Visitor& v);
// SPECIFIC implementation for subtypes
// a Source shall informs if the source failed (i.e. shall be deleted) // a Source shall informs if the source failed (i.e. shall be deleted)
virtual bool failed() const { return false; } virtual bool failed() const = 0;
// every Source shall have a frame buffer // a Source shall define a way to get a texture
virtual FrameBuffer *frame() const; virtual uint texture() const = 0;
// every Source shall be rendered into the frame buffer // a Source shall define how to render into the frame buffer
virtual void render() = 0; virtual void render() = 0;
protected: protected:
@@ -79,6 +88,7 @@ protected:
// render() fills in the renderbuffer at every frame // render() fills in the renderbuffer at every frame
// NB: rendershader_ is applied at render() // NB: rendershader_ is applied at render()
FrameBuffer *renderbuffer_; FrameBuffer *renderbuffer_;
void attach(FrameBuffer *renderbuffer);
// the rendersurface draws the renderbuffer in the scene // the rendersurface draws the renderbuffer in the scene
// It is associated to the rendershader for mixing effects // It is associated to the rendershader for mixing effects
@@ -94,16 +104,14 @@ protected:
std::map<View::Mode, Group*> overlays_; std::map<View::Mode, Group*> overlays_;
Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_; Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_;
// update need // update
bool need_update_; bool need_update_;
float dt_; float dt_;
// clones
CloneList clones_;
}; };
// TODO SourceSet sorted by shader
// so that the render loop avoid switching
typedef std::list<Source *> SourceList;
struct hasName: public std::unary_function<Source*, bool> struct hasName: public std::unary_function<Source*, bool>
{ {
inline bool operator()(const Source* elem) const { inline bool operator()(const Source* elem) const {
@@ -125,22 +133,28 @@ private:
}; };
class RenderSource : public Source class CloneSource : public Source
{ {
friend class Source;
public: public:
RenderSource(); CloneSource(Source *origin);
~RenderSource(); ~CloneSource();
// implementation of source API // implementation of source API
void render() override; void render() override;
uint texture() const override { return origin_->texture(); }
bool failed() const override { return origin_ == nullptr; }
void accept (Visitor& v) override; void accept (Visitor& v) override;
void reconnect(); CloneSource *clone();
inline Source *origin() const { return origin_; }
protected: protected:
void init() override; void init() override;
Surface *sessionsurface_; Surface *clonesurface_;
Source *origin_;
}; };

View File

@@ -1131,7 +1131,8 @@ void Navigator::RenderNewPannel()
ImGui::Text(" "); ImGui::Text(" ");
if ( ImGui::Button("Create !", ImVec2(pannel_width - padding_width, 0)) ) { if ( ImGui::Button("Create !", ImVec2(pannel_width - padding_width, 0)) ) {
Mixer::manager().createSourceRender(); Mixer::manager().createSourceClone("toto");
// Mixer::manager().createSourceRender();
selected_button[NAV_NEW] = false; selected_button[NAV_NEW] = false;
} }

192
rsc/mesh/icon_clone.ply Normal file
View File

@@ -0,0 +1,192 @@
ply
format ascii 1.0
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'icons.blend'
element vertex 92
property float x
property float y
property float z
element face 90
property list uchar uint vertex_indices
end_header
-0.116905 1.125589 0.000000
-0.100567 1.256263 0.000000
-0.116905 1.272597 0.000000
0.054982 1.272597 0.000000
0.038644 1.256263 0.000000
0.054982 1.223594 0.000000
-0.100567 1.141923 0.000000
0.038644 1.223594 0.000000
-0.041609 1.209188 0.000000
-0.036139 1.212243 0.000000
-0.042252 1.223594 0.000000
-0.022795 1.222064 0.000000
-0.022482 1.223594 0.000000
-0.023709 1.223594 0.000000
-0.019090 1.223594 0.000000
-0.013966 1.223594 0.000000
-0.007543 1.223594 0.000000
-0.000255 1.223594 0.000000
0.007467 1.223594 0.000000
0.015189 1.223594 0.000000
0.022478 1.223594 0.000000
0.028901 1.223594 0.000000
0.034025 1.223594 0.000000
0.037417 1.223594 0.000000
0.118059 1.223594 0.000000
0.101721 1.207260 0.000000
0.118059 1.076586 0.000000
-0.021857 1.220566 0.000000
-0.020893 1.219098 0.000000
-0.019907 1.217661 0.000000
-0.018898 1.216255 0.000000
-0.017867 1.214879 0.000000
-0.016816 1.213534 0.000000
-0.015745 1.212219 0.000000
-0.029078 1.202373 0.000000
-0.014656 1.210934 0.000000
-0.013548 1.209680 0.000000
-0.012424 1.208455 0.000000
-0.038572 1.196078 0.000000
-0.011284 1.207260 0.000000
0.101721 1.092920 0.000000
-0.021350 1.193891 0.000000
-0.033610 1.184258 0.000000
-0.013237 1.186702 0.000000
-0.005022 1.180712 0.000000
-0.027188 1.173717 0.000000
0.031643 1.164432 0.000000
0.060520 1.136688 0.000000
0.038481 1.182759 0.000000
0.003012 1.175827 0.000000
0.010585 1.171952 0.000000
-0.019773 1.164448 0.000000
0.017414 1.168993 0.000000
0.023216 1.166856 0.000000
-0.043045 1.141923 0.000000
-0.041805 1.165492 0.000000
-0.043045 1.167437 0.000000
0.027710 1.165446 0.000000
-0.040537 1.163581 0.000000
0.030613 1.164670 0.000000
-0.011833 1.156443 0.000000
-0.039243 1.161704 0.000000
-0.037925 1.159861 0.000000
-0.036584 1.158053 0.000000
-0.035222 1.156281 0.000000
-0.003833 1.149693 0.000000
-0.033841 1.154544 0.000000
-0.032442 1.152842 0.000000
-0.031028 1.151177 0.000000
-0.029599 1.149547 0.000000
0.003759 1.144189 0.000000
-0.028158 1.147955 0.000000
-0.026707 1.146399 0.000000
-0.026707 1.145346 0.000000
-0.026707 1.142437 0.000000
0.010476 1.139922 0.000000
-0.026707 1.138043 0.000000
0.015852 1.136886 0.000000
-0.026707 1.132534 0.000000
0.019420 1.135070 0.000000
0.020713 1.134466 0.000000
0.014137 1.116254 0.000000
-0.026707 1.126282 0.000000
-0.043045 1.125589 0.000000
-0.026707 1.119659 0.000000
-0.043045 1.076586 0.000000
-0.026707 1.113037 0.000000
-0.026707 1.106785 0.000000
-0.026707 1.101276 0.000000
-0.026707 1.096882 0.000000
-0.026707 1.093972 0.000000
-0.026707 1.092920 0.000000
3 0 1 2
3 1 3 2
3 1 4 3
3 4 5 3
3 0 6 1
3 7 5 4
3 8 9 10
3 11 12 13
3 11 14 12
3 11 15 14
3 11 16 15
3 11 17 16
3 11 18 17
3 11 19 18
3 11 20 19
3 11 21 20
3 11 22 21
3 11 23 22
3 11 7 23
3 11 5 7
3 11 24 5
3 11 25 24
3 25 26 24
3 27 25 11
3 28 25 27
3 29 25 28
3 30 25 29
3 31 25 30
3 32 25 31
3 33 25 32
3 8 34 9
3 35 25 33
3 36 25 35
3 37 25 36
3 38 34 8
3 39 25 37
3 40 26 25
3 38 41 34
3 42 41 38
3 42 43 41
3 42 44 43
3 45 44 42
3 46 47 48
3 45 49 44
3 45 50 49
3 51 50 45
3 51 52 50
3 51 53 52
3 54 55 56
3 51 57 53
3 54 58 55
3 51 59 57
3 51 46 59
3 60 46 51
3 60 47 46
3 54 61 58
3 54 62 61
3 54 63 62
3 54 64 63
3 65 47 60
3 54 66 64
3 54 67 66
3 54 68 67
3 54 69 68
3 70 47 65
3 54 71 69
3 54 72 71
3 54 73 72
3 54 74 73
3 75 47 70
3 54 76 74
3 0 54 6
3 0 76 54
3 77 47 75
3 0 78 76
3 79 47 77
3 79 80 47
3 80 81 47
3 0 82 78
3 0 83 82
3 83 84 82
3 85 84 83
3 85 86 84
3 85 87 86
3 85 88 87
3 85 89 88
3 85 90 89
3 85 91 90
3 85 40 91
3 85 26 40

38
rsc/mesh/icon_render.ply Normal file
View File

@@ -0,0 +1,38 @@
ply
format ascii 1.0
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'icons.blend'
element vertex 16
property float x
property float y
property float z
element face 12
property list uchar uint vertex_indices
end_header
-0.112918 1.092333 0.000000
-0.093944 1.253571 0.000000
-0.112918 1.272540 0.000000
0.114760 1.272540 0.000000
0.095787 1.253571 0.000000
0.114760 1.092333 0.000000
-0.093944 1.111302 0.000000
0.095787 1.111302 0.000000
-0.084458 1.120787 0.000000
0.086300 1.244086 0.000000
-0.084458 1.244086 0.000000
0.086300 1.120787 0.000000
-0.055998 1.044910 0.000000
0.033185 1.073364 0.000000
-0.031343 1.073364 0.000000
0.057841 1.044910 0.000000
3 0 1 2
3 1 3 2
3 1 4 3
3 4 5 3
3 0 6 1
3 7 5 4
3 8 9 10
3 8 11 9
3 0 7 6
3 0 5 7
3 12 13 14
3 12 15 13