mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-06 16:00:00 +01:00
Cleanup of surface management in Sources (centralize texturesurface_ in
Source class, avoid mistakes in subclasses). Integration of sources in AppearanceView (not functionnal yet).
This commit is contained in:
@@ -333,6 +333,7 @@ DeviceSource::DeviceSource() : StreamSource()
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::CAMERA, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::CAMERA, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::CAMERA, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
DeviceSource::~DeviceSource()
|
||||
|
||||
@@ -10,8 +10,12 @@
|
||||
|
||||
#include "GlmToolkit.h"
|
||||
|
||||
class FrameBuffer;
|
||||
// use glReadPixel or glGetTextImage
|
||||
// read pixels & pbo should be the fastest
|
||||
// https://stackoverflow.com/questions/38140527/glreadpixels-vs-glgetteximage
|
||||
#define USE_GLREADPIXEL
|
||||
|
||||
class FrameBuffer;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,19 +15,11 @@ MediaSource::MediaSource() : Source(), path_("")
|
||||
{
|
||||
// create media player
|
||||
mediaplayer_ = new MediaPlayer;
|
||||
|
||||
// create media surface:
|
||||
// - textured with original texture from media player
|
||||
// - crop & repeat UV can be managed here
|
||||
// - additional custom shader can be associated
|
||||
surface_ = new Surface(renderingshader_);
|
||||
|
||||
}
|
||||
|
||||
MediaSource::~MediaSource()
|
||||
{
|
||||
// delete media surface & player
|
||||
delete surface_;
|
||||
// delete media player
|
||||
delete mediaplayer_;
|
||||
}
|
||||
|
||||
@@ -68,11 +60,6 @@ uint MediaSource::texture() const
|
||||
return mediaplayer_->texture();
|
||||
}
|
||||
|
||||
void MediaSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
void MediaSource::init()
|
||||
{
|
||||
if ( mediaplayer_->isOpen() ) {
|
||||
@@ -84,7 +71,7 @@ void MediaSource::init()
|
||||
if (mediaplayer_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// get the texture index from media player, apply it to the media surface
|
||||
surface_->setTextureIndex( mediaplayer_->texture() );
|
||||
texturesurface_->setTextureIndex( mediaplayer_->texture() );
|
||||
|
||||
// create Frame buffer matching size of media player
|
||||
float height = float(mediaplayer_->width()) / mediaplayer_->aspectRatio();
|
||||
@@ -97,10 +84,12 @@ void MediaSource::init()
|
||||
if (mediaplayer_->isImage()) {
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::IMAGE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
else {
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::VIDEO, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
// done init
|
||||
@@ -143,8 +132,8 @@ void MediaSource::render()
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
surface_->shader()->color.a = mediaplayer_->currentTimelineFading();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->shader()->color.a = mediaplayer_->currentTimelineFading();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ public:
|
||||
protected:
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
|
||||
std::string path_;
|
||||
MediaPlayer *mediaplayer_;
|
||||
|
||||
@@ -208,6 +208,7 @@ void Mixer::update()
|
||||
mixing_.update(dt_);
|
||||
geometry_.update(dt_);
|
||||
layer_.update(dt_);
|
||||
appearance_.update(dt_);
|
||||
transition_.update(dt_);
|
||||
|
||||
// deep updates shall be performed only 1 frame
|
||||
@@ -565,6 +566,7 @@ void Mixer::setCurrentSource(SourceList::iterator it)
|
||||
|
||||
(*current_source_)->group(View::MIXING)->update_callbacks_.push_back(new BounceScaleCallback);
|
||||
(*current_source_)->group(View::LAYER)->update_callbacks_.push_back(new BounceScaleCallback);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -276,6 +276,7 @@ NetworkSource::NetworkSource() : StreamSource()
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::SHARE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::SHARE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::SHARE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -136,6 +136,7 @@ PatternSource::PatternSource() : StreamSource()
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::PATTERN, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
void PatternSource::setPattern(uint type, glm::ivec2 resolution)
|
||||
|
||||
@@ -72,11 +72,11 @@ void SessionCreator::load(const std::string& filename)
|
||||
}
|
||||
|
||||
int version_major = -1, version_minor = -1;
|
||||
header->QueryIntAttribute("major", &version_major); // TODO incompatible if major is different?
|
||||
header->QueryIntAttribute("major", &version_major);
|
||||
header->QueryIntAttribute("minor", &version_minor);
|
||||
if (version_major != XML_VERSION_MAJOR || version_minor != XML_VERSION_MINOR){
|
||||
Log::Warning("%s is in a different versions of session file. Loading might fail.", filename.c_str());
|
||||
return;
|
||||
// return;
|
||||
}
|
||||
|
||||
// session file seems legit, create a session
|
||||
|
||||
@@ -50,19 +50,10 @@ SessionSource::SessionSource() : Source(), path_("")
|
||||
failed_ = false;
|
||||
wait_for_sources_ = false;
|
||||
session_ = nullptr;
|
||||
|
||||
// create surface:
|
||||
// - textured with original texture from session
|
||||
// - crop & repeat UV can be managed here
|
||||
// - additional custom shader can be associated
|
||||
surface_ = new Surface(renderingshader_);
|
||||
}
|
||||
|
||||
SessionSource::~SessionSource()
|
||||
{
|
||||
// delete surface
|
||||
delete surface_;
|
||||
|
||||
// delete session
|
||||
if (session_)
|
||||
delete session_;
|
||||
@@ -109,11 +100,6 @@ uint SessionSource::texture() const
|
||||
return session_->frame()->texture();
|
||||
}
|
||||
|
||||
void SessionSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
void SessionSource::init()
|
||||
{
|
||||
// init is first about getting the loaded session
|
||||
@@ -161,7 +147,7 @@ void SessionSource::init()
|
||||
session_->update(dt_);
|
||||
|
||||
// get the texture index from framebuffer of session, apply it to the surface
|
||||
surface_->setTextureIndex( session_->frame()->texture() );
|
||||
texturesurface_->setTextureIndex( session_->frame()->texture() );
|
||||
|
||||
// create Frame buffer matching size of session
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution());
|
||||
@@ -172,6 +158,7 @@ void SessionSource::init()
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::SESSION, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// wait for all sources to init
|
||||
if (session_->numSource() > 0)
|
||||
@@ -229,7 +216,7 @@ void SessionSource::render()
|
||||
// render the sesion into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
@@ -244,15 +231,8 @@ void SessionSource::accept(Visitor& v)
|
||||
|
||||
RenderSource::RenderSource(Session *session) : Source(), session_(session)
|
||||
{
|
||||
// create surface:
|
||||
surface_ = new Surface(processingshader_);
|
||||
}
|
||||
|
||||
RenderSource::~RenderSource()
|
||||
{
|
||||
// delete surface
|
||||
delete surface_;
|
||||
}
|
||||
|
||||
bool RenderSource::failed() const
|
||||
{
|
||||
@@ -267,22 +247,14 @@ uint RenderSource::texture() const
|
||||
return session_->frame()->texture();
|
||||
}
|
||||
|
||||
void RenderSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
void RenderSource::init()
|
||||
{
|
||||
if (session_ == nullptr)
|
||||
return;
|
||||
|
||||
if (session_ && session_->frame()->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
FrameBuffer *fb = session_->frame();
|
||||
|
||||
// get the texture index from framebuffer of view, apply it to the surface
|
||||
surface_->setTextureIndex( fb->texture() );
|
||||
texturesurface_->setTextureIndex( fb->texture() );
|
||||
|
||||
// create Frame buffer matching size of output session
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( fb->resolution());
|
||||
@@ -293,6 +265,7 @@ void RenderSource::init()
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::RENDER, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
@@ -309,7 +282,7 @@ void RenderSource::render()
|
||||
// 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();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ public:
|
||||
protected:
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
static void loadSession(const std::string& filename, SessionSource *source);
|
||||
|
||||
std::string path_;
|
||||
@@ -47,7 +46,6 @@ class RenderSource : public Source
|
||||
{
|
||||
public:
|
||||
RenderSource(Session *session);
|
||||
~RenderSource();
|
||||
|
||||
// implementation of source API
|
||||
void render() override;
|
||||
@@ -60,7 +58,6 @@ public:
|
||||
protected:
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
Session *session_;
|
||||
};
|
||||
|
||||
|
||||
12
Settings.cpp
12
Settings.cpp
@@ -22,10 +22,11 @@ void Settings::Save()
|
||||
xmlDoc.InsertFirstChild(pDec);
|
||||
|
||||
XMLElement *pRoot = xmlDoc.NewElement(application.name.c_str());
|
||||
pRoot->SetAttribute("major", APP_VERSION_MAJOR);
|
||||
pRoot->SetAttribute("minor", APP_VERSION_MINOR);
|
||||
xmlDoc.InsertEndChild(pRoot);
|
||||
|
||||
string comment = "Settings for " + application.name;
|
||||
comment += "Version " + std::to_string(APP_VERSION_MAJOR) + "." + std::to_string(APP_VERSION_MINOR);
|
||||
XMLComment *pComment = xmlDoc.NewComment(comment.c_str());
|
||||
pRoot->InsertEndChild(pComment);
|
||||
|
||||
@@ -221,8 +222,15 @@ void Settings::Load()
|
||||
XMLElement *pRoot = xmlDoc.FirstChildElement(application.name.c_str());
|
||||
if (pRoot == nullptr) return;
|
||||
|
||||
// cancel on different root name
|
||||
if (application.name.compare( string( pRoot->Value() ) ) != 0 )
|
||||
// different root name
|
||||
return;
|
||||
|
||||
// cancel on different version
|
||||
int version_major = -1, version_minor = -1;
|
||||
pRoot->QueryIntAttribute("major", &version_major);
|
||||
pRoot->QueryIntAttribute("minor", &version_minor);
|
||||
if (version_major != APP_VERSION_MAJOR || version_minor != APP_VERSION_MINOR)
|
||||
return;
|
||||
|
||||
XMLElement * applicationNode = pRoot->FirstChildElement("Application");
|
||||
|
||||
39
Source.cpp
39
Source.cpp
@@ -124,6 +124,11 @@ Source::Source() : initialized_(false), active_(true), need_update_(true)
|
||||
groups_[View::APPEARANCE] = new Group;
|
||||
groups_[View::APPEARANCE]->visible_ = false;
|
||||
|
||||
overlays_[View::APPEARANCE] = new Group;
|
||||
overlays_[View::APPEARANCE]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->visible_ = false;
|
||||
groups_[View::APPEARANCE]->attach(overlays_[View::APPEARANCE]);
|
||||
|
||||
// empty transition node
|
||||
groups_[View::TRANSITION] = new Group;
|
||||
|
||||
@@ -136,6 +141,13 @@ Source::Source() : initialized_(false), active_(true), need_update_(true)
|
||||
// default to image processing enabled
|
||||
renderingshader_ = (Shader *) processingshader_;
|
||||
|
||||
// create media surface:
|
||||
// - textured with original texture from media player
|
||||
// - crop & repeat UV can be managed here
|
||||
// - additional custom shader can be associated
|
||||
texturesurface_ = new Surface(renderingshader_);
|
||||
|
||||
// will be created at init
|
||||
renderbuffer_ = nullptr;
|
||||
rendersurface_ = nullptr;
|
||||
|
||||
@@ -171,6 +183,8 @@ Source::~Source()
|
||||
// could be created but not used
|
||||
if ( renderingshader_ != processingshader_ )
|
||||
delete processingshader_;
|
||||
|
||||
delete texturesurface_;
|
||||
}
|
||||
|
||||
void Source::setName (const std::string &name)
|
||||
@@ -209,6 +223,9 @@ void Source::setMode(Source::Mode m)
|
||||
for (auto o = overlays_.begin(); o != overlays_.end(); o++)
|
||||
(*o).second->visible_ = current;
|
||||
|
||||
// show in appearance view if current
|
||||
groups_[View::APPEARANCE]->visible_ = current;
|
||||
|
||||
mode_ = m;
|
||||
}
|
||||
|
||||
@@ -241,7 +258,7 @@ void Source::setImageProcessingEnabled (bool on)
|
||||
// apply to nodes in subclasses
|
||||
// this calls replaceShader() on the Primitive and
|
||||
// will delete the previously attached shader
|
||||
replaceRenderingShader();
|
||||
texturesurface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
bool Source::imageProcessingEnabled()
|
||||
@@ -258,7 +275,6 @@ 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
|
||||
@@ -269,6 +285,10 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
groups_[View::MIXING]->attach(surfacemix);
|
||||
groups_[View::LAYER]->attach(surfacemix);
|
||||
|
||||
// for appearance view, a dedicated surface without blending
|
||||
Surface *surfacepreview = new FrameBufferSurface(renderbuffer_);
|
||||
groups_[View::APPEARANCE]->attach(surfacepreview);
|
||||
|
||||
// scale all icon nodes to match aspect ratio of the media
|
||||
NodeSet::iterator node;
|
||||
for (node = groups_[View::MIXING]->begin();
|
||||
@@ -431,17 +451,12 @@ CloneSource *Source::clone()
|
||||
|
||||
CloneSource::CloneSource(Source *origin) : Source(), origin_(origin)
|
||||
{
|
||||
// create surface:
|
||||
surface_ = new Surface(renderingshader_);
|
||||
}
|
||||
|
||||
CloneSource::~CloneSource()
|
||||
{
|
||||
if (origin_)
|
||||
origin_->clones_.remove(this);
|
||||
|
||||
// delete surface
|
||||
delete surface_;
|
||||
}
|
||||
|
||||
CloneSource *CloneSource::clone()
|
||||
@@ -453,17 +468,12 @@ CloneSource *CloneSource::clone()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CloneSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
void CloneSource::init()
|
||||
{
|
||||
if (origin_ && origin_->ready()) {
|
||||
|
||||
// get the texture index from framebuffer of view, apply it to the surface
|
||||
surface_->setTextureIndex( origin_->texture() );
|
||||
texturesurface_->setTextureIndex( origin_->texture() );
|
||||
|
||||
// create Frame buffer matching size of session
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( origin_->frame()->resolution(), true);
|
||||
@@ -474,6 +484,7 @@ void CloneSource::init()
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::CLONE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
@@ -511,7 +522,7 @@ void CloneSource::render()
|
||||
// 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();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
5
Source.h
5
Source.h
@@ -163,14 +163,12 @@ protected:
|
||||
// pointer to the currently attached shader
|
||||
// (will be processingshader_ if image processing is enabled)
|
||||
Shader *renderingshader_;
|
||||
// every sub class will attach the shader to a different node / hierarchy
|
||||
virtual void replaceRenderingShader() = 0;
|
||||
|
||||
// blendingshader provides mixing controls
|
||||
ImageShader *blendingshader_;
|
||||
|
||||
// surface to draw on
|
||||
Surface *surface_;
|
||||
Surface *texturesurface_;
|
||||
|
||||
// mode for display
|
||||
Mode mode_;
|
||||
@@ -217,7 +215,6 @@ protected:
|
||||
CloneSource(Source *origin);
|
||||
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
Source *origin_;
|
||||
};
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ GenericStreamSource::GenericStreamSource() : StreamSource()
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::EMPTY, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
void GenericStreamSource::setDescription(const std::string &desc)
|
||||
@@ -37,38 +38,33 @@ void GenericStreamSource::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
StreamSource::StreamSource() : Source()
|
||||
StreamSource::StreamSource() : Source(), stream_(nullptr)
|
||||
{
|
||||
// create surface
|
||||
surface_ = new Surface(renderingshader_);
|
||||
}
|
||||
|
||||
StreamSource::~StreamSource()
|
||||
{
|
||||
// delete media surface & stream
|
||||
delete surface_;
|
||||
delete stream_;
|
||||
// delete stream
|
||||
if (stream_)
|
||||
delete stream_;
|
||||
}
|
||||
|
||||
bool StreamSource::failed() const
|
||||
{
|
||||
return stream_->failed();
|
||||
return (stream_ != nullptr && stream_->failed() );
|
||||
}
|
||||
|
||||
uint StreamSource::texture() const
|
||||
{
|
||||
return stream_->texture();
|
||||
if (stream_ == nullptr)
|
||||
return Resource::getTextureBlack();
|
||||
else
|
||||
return stream_->texture();
|
||||
}
|
||||
|
||||
void StreamSource::replaceRenderingShader()
|
||||
{
|
||||
surface_->replaceShader(renderingshader_);
|
||||
}
|
||||
|
||||
|
||||
void StreamSource::init()
|
||||
{
|
||||
if ( stream_->isOpen() ) {
|
||||
if ( stream_ && stream_->isOpen() ) {
|
||||
|
||||
// update video
|
||||
stream_->update();
|
||||
@@ -77,7 +73,7 @@ void StreamSource::init()
|
||||
if (stream_->texture() != Resource::getTextureBlack()) {
|
||||
|
||||
// get the texture index from media player, apply it to the media surface
|
||||
surface_->setTextureIndex( stream_->texture() );
|
||||
texturesurface_->setTextureIndex( stream_->texture() );
|
||||
|
||||
// create Frame buffer matching size of media player
|
||||
float height = float(stream_->width()) / stream_->aspectRatio();
|
||||
@@ -106,7 +102,8 @@ void StreamSource::setActive (bool on)
|
||||
|
||||
// change status of media player (only if status changed)
|
||||
if ( active_ != was_active ) {
|
||||
stream_->enable(active_);
|
||||
if (stream_)
|
||||
stream_->enable(active_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +112,8 @@ void StreamSource::update(float dt)
|
||||
Source::update(dt);
|
||||
|
||||
// update stream
|
||||
stream_->update();
|
||||
if (stream_)
|
||||
stream_->update();
|
||||
}
|
||||
|
||||
void StreamSource::render()
|
||||
@@ -126,7 +124,7 @@ void StreamSource::render()
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
surface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
|
||||
protected:
|
||||
void init() override;
|
||||
void replaceRenderingShader() override;
|
||||
|
||||
Stream *stream_;
|
||||
};
|
||||
|
||||
@@ -354,7 +354,7 @@ 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 ))
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F4 ))
|
||||
Mixer::manager().setView(View::APPEARANCE);
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_F12 ))
|
||||
StartScreenshot();
|
||||
@@ -730,7 +730,7 @@ void UserInterface::Render()
|
||||
Log::Render();
|
||||
|
||||
// clear view mode in Transition view
|
||||
if ( !Settings::application.transition.hide_windows || Settings::application.current_view != 4) {
|
||||
if ( !Settings::application.transition.hide_windows || Settings::application.current_view < View::TRANSITION) {
|
||||
|
||||
// windows
|
||||
if (Settings::application.widget.toolbox)
|
||||
@@ -1852,7 +1852,7 @@ void Navigator::Render()
|
||||
pannel_width_ = 5.f * width_; // pannel is 5x the bar
|
||||
padding_width_ = 2.f * style.WindowPadding.x; // panning for alighment
|
||||
height_ = io.DisplaySize.y; // cover vertically
|
||||
sourcelist_height_ = height_ - 6.f * ImGui::GetTextLineHeight(); // space for 3 icons of view
|
||||
sourcelist_height_ = height_ - 8.f * ImGui::GetTextLineHeight(); // space for 4 icons of view
|
||||
float icon_width = width_ - 2.f * style.WindowPadding.x; // icons keep padding
|
||||
ImVec2 iconsize(icon_width, icon_width);
|
||||
|
||||
@@ -1862,7 +1862,7 @@ void Navigator::Render()
|
||||
ImGui::SetNextWindowBgAlpha(0.95f); // Transparent background
|
||||
if (ImGui::Begin( ICON_FA_BARS " Navigator", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
{
|
||||
if (Settings::application.current_view < 4) {
|
||||
if (Settings::application.current_view < View::TRANSITION) {
|
||||
|
||||
// the "=" icon for menu
|
||||
if (ImGui::Selectable( ICON_FA_BARS, &selected_button[NAV_MENU], 0, iconsize))
|
||||
@@ -1908,7 +1908,7 @@ void Navigator::Render()
|
||||
|
||||
}
|
||||
else {
|
||||
// the "=" icon for menu
|
||||
// the ">" icon for transition menu
|
||||
if (ImGui::Selectable( ICON_FA_ARROW_CIRCLE_RIGHT, &selected_button[NAV_TRANS], 0, iconsize))
|
||||
{
|
||||
// Mixer::manager().unsetCurrentSource();
|
||||
@@ -1937,17 +1937,22 @@ void Navigator::Render()
|
||||
Mixer::manager().setView(View::GEOMETRY);
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
if (ImGui::Selectable( ICON_FA_IMAGES, &selected_view[3], 0, iconsize))
|
||||
if (ImGui::Selectable( ICON_FA_LAYER_GROUP, &selected_view[3], 0, iconsize))
|
||||
{
|
||||
Mixer::manager().setView(View::LAYER);
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
if (ImGui::Selectable( ICON_FA_IMAGE, &selected_view[4], 0, iconsize))
|
||||
{
|
||||
Mixer::manager().setView(View::APPEARANCE);
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
if ( view_pannel_visible && !pannel_visible_ )
|
||||
RenderViewPannel( ImVec2(width_, sourcelist_height_), ImVec2(width_, height_ - sourcelist_height_) );
|
||||
RenderViewPannel( ImVec2(width_, sourcelist_height_), ImVec2(width_*0.8f, height_ - sourcelist_height_) );
|
||||
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopFont();
|
||||
@@ -2019,7 +2024,7 @@ void Navigator::RenderViewPannel(ImVec2 draw_pos , ImVec2 draw_size)
|
||||
// Source pannel : *s was checked before
|
||||
void Navigator::RenderSourcePannel(Source *s)
|
||||
{
|
||||
if (s == nullptr || Settings::application.current_view >3)
|
||||
if (s == nullptr || Settings::application.current_view >= View::TRANSITION)
|
||||
return;
|
||||
|
||||
// Next window is a side pannel
|
||||
@@ -2336,7 +2341,7 @@ void Navigator::RenderNewPannel()
|
||||
|
||||
void Navigator::RenderTransitionPannel()
|
||||
{
|
||||
if (Settings::application.current_view < 4) {
|
||||
if (Settings::application.current_view < View::TRANSITION) {
|
||||
hidePannel();
|
||||
return;
|
||||
}
|
||||
|
||||
103
View.cpp
103
View.cpp
@@ -310,7 +310,8 @@ void MixingView::draw()
|
||||
// temporarily force shaders to use opacity blending for rendering icons
|
||||
Shader::force_blending_opacity = true;
|
||||
// draw scene of this view
|
||||
scene.root()->draw(glm::identity<glm::mat4>(), Rendering::manager().Projection());
|
||||
View::draw();
|
||||
// scene.root()->draw(glm::identity<glm::mat4>(), Rendering::manager().Projection());
|
||||
// restore state
|
||||
Shader::force_blending_opacity = false;
|
||||
}
|
||||
@@ -818,7 +819,8 @@ void GeometryView::draw()
|
||||
}
|
||||
|
||||
// draw scene of this view
|
||||
scene.root()->draw(glm::identity<glm::mat4>(), Rendering::manager().Projection());
|
||||
View::draw();
|
||||
// scene.root()->draw(glm::identity<glm::mat4>(), Rendering::manager().Projection());
|
||||
|
||||
// re-draw frames of all sources on top
|
||||
for (auto source_iter = Mixer::manager().session()->begin(); source_iter != Mixer::manager().session()->end(); source_iter++)
|
||||
@@ -1386,8 +1388,8 @@ TransitionView::TransitionView() : View(TRANSITION), transition_source_(nullptr)
|
||||
{
|
||||
// no settings found: store application default
|
||||
Settings::application.views[mode_].name = "Transition";
|
||||
scene.root()->scale_ = glm::vec3(5.f, 5.f, 1.0f);
|
||||
scene.root()->translation_ = glm::vec3(1.8f, 0.f, 0.0f);
|
||||
scene.root()->scale_ = glm::vec3(TRANSITION_DEFAULT_SCALE, TRANSITION_DEFAULT_SCALE, 1.0f);
|
||||
scene.root()->translation_ = glm::vec3(1.f, 0.f, 0.0f);
|
||||
saveSettings();
|
||||
}
|
||||
else
|
||||
@@ -1692,20 +1694,27 @@ View::Cursor TransitionView::drag (glm::vec2 from, glm::vec2 to)
|
||||
}
|
||||
|
||||
|
||||
AppearanceView::AppearanceView() : View(APPEARANCE)
|
||||
AppearanceView::AppearanceView() : View(APPEARANCE), index_source_(-1)
|
||||
{
|
||||
// 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);
|
||||
Settings::application.views[mode_].name = "Appearance";
|
||||
scene.root()->scale_ = glm::vec3(APPEARANCE_DEFAULT_SCALE, APPEARANCE_DEFAULT_SCALE, 1.0f);
|
||||
scene.root()->translation_ = glm::vec3(1.8f, 0.f, 0.0f);
|
||||
saveSettings();
|
||||
}
|
||||
else
|
||||
restoreSettings();
|
||||
|
||||
// Scene background
|
||||
Surface *rect = new Surface;
|
||||
scene.bg()->attach(rect);
|
||||
|
||||
// Geometry Scene foreground
|
||||
Frame *border = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
|
||||
border->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f );
|
||||
scene.fg()->attach(border);
|
||||
|
||||
}
|
||||
|
||||
@@ -1713,23 +1722,21 @@ 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
// // a more complete update is requested (e.g. after switching to view)
|
||||
// // AND no source selected
|
||||
// if (View::need_deep_update_ && Mixer::manager().indexCurrentSource() < 0) {
|
||||
|
||||
// index_source_ = -1;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
void AppearanceView::zoom (float factor)
|
||||
{
|
||||
float z = scene.root()->scale_.x;
|
||||
z = CLAMP( z + 0.1f * factor, SOURCE_MIN_SCALE, SOURCE_MAX_SCALE);
|
||||
z = CLAMP( z + 0.1f * factor, APPEARANCE_MIN_SCALE, APPEARANCE_MAX_SCALE);
|
||||
scene.root()->scale_.x = z;
|
||||
scene.root()->scale_.y = z;
|
||||
}
|
||||
@@ -1738,35 +1745,71 @@ 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;
|
||||
z *= APPEARANCE_MAX_SCALE - APPEARANCE_MIN_SCALE;
|
||||
z += APPEARANCE_MIN_SCALE;
|
||||
scene.root()->scale_.x = z;
|
||||
scene.root()->scale_.y = z;
|
||||
}
|
||||
|
||||
int AppearanceView::size ()
|
||||
int AppearanceView::size ()
|
||||
{
|
||||
float z = (scene.root()->scale_.x - SOURCE_MIN_SCALE) / (SOURCE_MAX_SCALE - SOURCE_MIN_SCALE);
|
||||
float z = (scene.root()->scale_.x - APPEARANCE_MIN_SCALE) / (APPEARANCE_MAX_SCALE - APPEARANCE_MIN_SCALE);
|
||||
return (int) ( sqrt(z) * 100.f);
|
||||
}
|
||||
|
||||
|
||||
void AppearanceView::draw()
|
||||
{
|
||||
// did the current source change?
|
||||
if (index_source_ != Mixer::manager().indexCurrentSource()) {
|
||||
|
||||
// another source is current
|
||||
index_source_ = Mixer::manager().indexCurrentSource();
|
||||
|
||||
float scale = 1.f;
|
||||
Source *s = Mixer::manager().currentSource();
|
||||
if (s != nullptr) {
|
||||
// update rendering frame to match current source AR
|
||||
scale = s->frame()->aspectRatio();
|
||||
}
|
||||
|
||||
// update aspect ratio
|
||||
for (NodeSet::iterator node = scene.bg()->begin(); node != scene.bg()->end(); node++) {
|
||||
(*node)->scale_.x = scale;
|
||||
}
|
||||
for (NodeSet::iterator node = scene.fg()->begin(); node != scene.fg()->end(); node++) {
|
||||
(*node)->scale_.x = scale;
|
||||
}
|
||||
}
|
||||
|
||||
Shader::force_blending_opacity = true;
|
||||
View::draw();
|
||||
Shader::force_blending_opacity = false;
|
||||
|
||||
}
|
||||
|
||||
View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
|
||||
{
|
||||
if (!s)
|
||||
// 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_);
|
||||
// grab coordinates in scene-View reference frame
|
||||
glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||
glm::vec3 scene_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||
glm::vec3 scene_translation = scene_to - scene_from;
|
||||
|
||||
|
||||
std::ostringstream info;
|
||||
info << "Source " ;
|
||||
info << "UV " ;
|
||||
|
||||
ImageShader *shader = s->blendingShader ();
|
||||
shader->uv.x += scene_translation.x;
|
||||
shader->uv.y += scene_translation.y;
|
||||
shader->uv.z += scene_translation.x;
|
||||
shader->uv.w += scene_translation.y;
|
||||
|
||||
|
||||
|
||||
return Cursor(Cursor_ResizeNESW, info.str() );
|
||||
return Cursor(Cursor_ResizeAll, info.str() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
3
View.h
3
View.h
@@ -221,6 +221,8 @@ class AppearanceView : public View
|
||||
public:
|
||||
AppearanceView();
|
||||
|
||||
void draw () override;
|
||||
|
||||
void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
@@ -231,6 +233,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
int index_source_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
13
defines.h
13
defines.h
@@ -39,10 +39,10 @@
|
||||
#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 APPEARANCE_DEFAULT_SCALE 1.6f
|
||||
#define APPEARANCE_MIN_SCALE 0.5f
|
||||
#define APPEARANCE_MAX_SCALE 10.0f
|
||||
#define TRANSITION_DEFAULT_SCALE 5.0f
|
||||
#define TRANSITION_MIN_DURATION 0.2f
|
||||
#define TRANSITION_MAX_DURATION 10.f
|
||||
|
||||
@@ -76,9 +76,4 @@
|
||||
#define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f
|
||||
#define COLOR_STASH_CIRCLE 0.06f, 0.06f, 0.06f
|
||||
|
||||
// use glReadPixel or glGetTextImage
|
||||
// read pixels & pbo should be the fastest
|
||||
// https://stackoverflow.com/questions/38140527/glreadpixels-vs-glgetteximage
|
||||
#define USE_GLREADPIXEL
|
||||
|
||||
#endif // VMIX_DEFINES_H
|
||||
|
||||
Reference in New Issue
Block a user