mirror of
https://github.com/brunoherbelin/vimix.git
synced 2026-06-16 04:27:23 +02:00
BugFix Important fix of Bundle Session source
premultiply alpha should NOT be applied to render session in framebuffer with alpha on surface : added a uniform to image shader to allow this. Fixed other problems related to creation and expand of bundle sources. Added a button to bundle a single source.
This commit is contained in:
@@ -14,6 +14,7 @@ uniform vec4 color;
|
||||
uniform sampler2D iChannel0; // input channel (texture id).
|
||||
uniform sampler2D iChannel1; // input mask
|
||||
uniform float stipple;
|
||||
uniform float premultiply;
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -33,5 +34,5 @@ void main()
|
||||
A = clamp(A, 0.0, 1.0);
|
||||
|
||||
// output RGB with Alpha pre-multiplied
|
||||
FragColor = vec4(RGB * A, A);
|
||||
FragColor = vec4(RGB * mix(1.0 / max(A, 0.001), A, premultiply), A);
|
||||
}
|
||||
|
||||
+2
-1
@@ -43,7 +43,7 @@ const char* MaskShader::mask_icons[4] = { ICON_FA_WINDOW_CLOSE, ICON_FA_EDIT, I
|
||||
const char* MaskShader::mask_names[4] = { "Mask None", "Mask Paint", "Mask Shape", "Mask Source" };
|
||||
const char* MaskShader::mask_shapes[5] = { "Ellipse", "Oblong", "Rectangle", "Horizontal", "Vertical" };
|
||||
|
||||
ImageShader::ImageShader(): Shader(), secondary_texture(0), stipple(0.f)
|
||||
ImageShader::ImageShader(): Shader(), secondary_texture(0), stipple(0.f), premultiply(1.f)
|
||||
{
|
||||
// static program shader
|
||||
program_ = &imageShadingProgram;
|
||||
@@ -57,6 +57,7 @@ void ImageShader::use()
|
||||
|
||||
// set stippling
|
||||
program_->setUniform("stipple", stipple);
|
||||
program_->setUniform("premultiply", premultiply);
|
||||
program_->setUniform("iNodes", iNodes);
|
||||
|
||||
// default mask
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
|
||||
// uniforms
|
||||
float stipple;
|
||||
float premultiply;
|
||||
glm::mat4 iNodes;
|
||||
};
|
||||
|
||||
|
||||
+29
-8
@@ -771,8 +771,27 @@ void Mixer::groupSelection()
|
||||
if (selection().empty())
|
||||
return;
|
||||
|
||||
// work on non-empty selection of sources
|
||||
auto _selection = selection().getCopy();
|
||||
// group the current selection
|
||||
group(selection().getCopy());
|
||||
}
|
||||
|
||||
void Mixer::groupCurrent()
|
||||
{
|
||||
if ( current_source_ != session_->end() ) {
|
||||
|
||||
SourceList L;
|
||||
L.emplace_front( *current_source_ );
|
||||
|
||||
// group the current selection
|
||||
group( L );
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::group(SourceList sourcelist)
|
||||
{
|
||||
// work on non-empty list of sources
|
||||
if (sourcelist.empty())
|
||||
return;
|
||||
|
||||
// create session group where to transfer sources into
|
||||
SessionGroupSource *sessiongroup = new SessionGroupSource;
|
||||
@@ -781,25 +800,25 @@ void Mixer::groupSelection()
|
||||
// prepare for new session group name
|
||||
std::string name;
|
||||
// prepare for depth to place the group source
|
||||
float d = _selection.front()->depth();
|
||||
float d = sourcelist.front()->depth();
|
||||
|
||||
// remember groups before emptying the session
|
||||
std::list<SourceList> allgroups = session_->getMixingGroups();
|
||||
std::list<SourceList> selectgroups;
|
||||
for (auto git = allgroups.begin(); git != allgroups.end(); ++git){
|
||||
selectgroups.push_back( intersect( *git, _selection));
|
||||
selectgroups.push_back( intersect( *git, sourcelist));
|
||||
}
|
||||
|
||||
// browse the selection
|
||||
for (auto sit = _selection.begin(); sit != _selection.end(); ++sit) {
|
||||
// browse the list
|
||||
for (auto sit = sourcelist.begin(); sit != sourcelist.end(); ++sit) {
|
||||
|
||||
// import source into group
|
||||
if ( sessiongroup->import(*sit) ) {
|
||||
// find lower depth in _selection
|
||||
// find lower depth in list
|
||||
d = MIN( (*sit)->depth(), d);
|
||||
// generate name from intials of all sources
|
||||
name += (*sit)->initials();
|
||||
// detach & remove element from selection()
|
||||
// detach & remove element from list
|
||||
detachSource (*sit);
|
||||
// remove source from session
|
||||
session_->removeSource(*sit);
|
||||
@@ -813,6 +832,7 @@ void Mixer::groupSelection()
|
||||
|
||||
// set depth at given location
|
||||
sessiongroup->group(View::LAYER)->translation_.z = d;
|
||||
sessiongroup->group(View::RENDERING)->translation_.z = d;
|
||||
|
||||
// set alpha to full opacity
|
||||
sessiongroup->group(View::MIXING)->translation_.x = 0.f;
|
||||
@@ -1498,6 +1518,7 @@ void Mixer::merge(SessionSource *source)
|
||||
|
||||
// avoid display issues
|
||||
current_view_->update(0.f);
|
||||
unsetCurrentSource();
|
||||
|
||||
// new state in history manager
|
||||
Action::manager().store(info.str());
|
||||
|
||||
+4
-2
@@ -69,8 +69,9 @@ public:
|
||||
int numSource () const;
|
||||
|
||||
// operations on selection
|
||||
void deleteSelection ();
|
||||
void groupSelection ();
|
||||
void deleteSelection ();
|
||||
void groupSelection ();
|
||||
void groupCurrent ();
|
||||
void groupAll (bool only_active = false);
|
||||
void ungroupAll ();
|
||||
void groupSession ();
|
||||
@@ -148,6 +149,7 @@ protected:
|
||||
void attachSource (Source *s);
|
||||
void detachSource (Source *s);
|
||||
bool attached (Source *s) const;
|
||||
void group (SourceList sources);
|
||||
|
||||
void setCurrentSource(SourceList::iterator it);
|
||||
SourceList::iterator current_source_;
|
||||
|
||||
@@ -447,6 +447,11 @@ void SessionGroupSource::init()
|
||||
// get the texture index from framebuffer of session, apply it to the surface
|
||||
texturesurface_->setTextureIndex( session_->frame()->texture() );
|
||||
|
||||
// special case for session group using FrameBuffer_alpha
|
||||
// shader should not pre-multiply alpha
|
||||
ImageShader *ish = static_cast<ImageShader *>(texturesurface_->shader());
|
||||
ish->premultiply = 0.f;
|
||||
|
||||
// create Frame buffer matching size of session
|
||||
FrameBuffer *renderbuffer = new FrameBuffer( session_->frame()->resolution(), FrameBuffer::FrameBuffer_alpha );
|
||||
|
||||
|
||||
+2
-1
@@ -930,6 +930,7 @@ void Source::update(float dt)
|
||||
static glm::mat4 UVtoScene = GlmToolkit::transform(glm::vec3(1.f, -1.f, 0.f),
|
||||
glm::vec3(0.f, 0.f, 0.f),
|
||||
glm::vec3(-2.f, 2.f, 1.f));
|
||||
static glm::mat4 ScenetoUV = glm::inverse(UVtoScene);
|
||||
// Aspect Ratio correction transform : coordinates of Appearance Frame are scaled by render buffer width
|
||||
glm::mat4 Ar = glm::scale(glm::identity<glm::mat4>(), glm::vec3(renderbuffer_->aspectRatio(), 1.f, 1.f) );
|
||||
// Translation : same as Appearance Frame (modified by Ar)
|
||||
@@ -948,7 +949,7 @@ void Source::update(float dt)
|
||||
// 5. Revert aspect ration correction
|
||||
// 6. Apply the Scaling (independent of aspect ratio)
|
||||
// 7. switch back to UV coordinate system
|
||||
texturesurface_->shader()->iTransform = glm::inverse(UVtoScene) * glm::inverse(Sca) * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene;
|
||||
texturesurface_->shader()->iTransform = ScenetoUV * glm::inverse(Sca) * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene;
|
||||
|
||||
// inform mixing group
|
||||
if (mixinggroup_)
|
||||
|
||||
@@ -3464,6 +3464,9 @@ void Navigator::RenderSourcePannel(Source *s, const ImVec2 &iconsize)
|
||||
|
||||
// index indicator
|
||||
ImGui::SetCursorPos(ImVec2(pannel_width_ - 2.8f * ImGui::GetTextLineHeightWithSpacing(), IMGUI_TOP_ALIGN));
|
||||
|
||||
if (Mixer::manager().indexCurrentSource() < 0)
|
||||
Mixer::manager().setCurrentIndex(selected_index);
|
||||
ImGui::TextDisabled("#%d", Mixer::manager().indexCurrentSource());
|
||||
|
||||
ImGui::PopFont();
|
||||
@@ -3564,17 +3567,27 @@ void Navigator::RenderSourcePannel(Source *s, const ImVec2 &iconsize)
|
||||
ImGui::Text(" ");
|
||||
if (s->ready() || s->failed()) {
|
||||
|
||||
ImVec2 size = ImVec2(ImGui::GetContentRegionAvail().x, 0);
|
||||
|
||||
// clone button
|
||||
if ( s->failed() ) {
|
||||
ImGuiToolkit::ButtonDisabled( ICON_FA_SHARE_SQUARE " Clone & Filter", ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
}
|
||||
else if ( ImGui::Button( ICON_FA_SHARE_SQUARE " Clone & Filter", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
|
||||
if ( s->failed() )
|
||||
ImGuiToolkit::ButtonDisabled( ICON_FA_SHARE_SQUARE " Clone & Filter", size);
|
||||
else if ( ImGui::Button( ICON_FA_SHARE_SQUARE " Clone & Filter", size) ) {
|
||||
Mixer::manager().addSource ( (Source *) Mixer::manager().createSourceClone() );
|
||||
UserInterface::manager().showPannel( Mixer::manager().numSource() );
|
||||
}
|
||||
|
||||
// bundle button
|
||||
if ( s->failed() )
|
||||
ImGuiToolkit::ButtonDisabled( ICON_FA_SIGN_IN_ALT " Bundle", ImVec2((size.x - IMGUI_SAME_LINE)/2.f, 0));
|
||||
else if ( ImGui::Button( ICON_FA_SIGN_IN_ALT " Bundle", ImVec2((size.x - IMGUI_SAME_LINE)/2.f, 0)) ) {
|
||||
Mixer::manager().groupCurrent();
|
||||
UserInterface::manager().showPannel( Mixer::manager().numSource() );
|
||||
}
|
||||
|
||||
// replace button
|
||||
if ( ImGui::Button( ICON_FA_PLUS_SQUARE " Replace", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
|
||||
ImGui::SameLine(0, IMGUI_SAME_LINE);
|
||||
if ( ImGui::Button( ICON_FA_PLUS_SQUARE " Replace", ImVec2((size.x - IMGUI_SAME_LINE)/2.f, 0)) ) {
|
||||
// prepare panel for new source of same type
|
||||
MediaSource *file = dynamic_cast<MediaSource *>(s);
|
||||
MultiFileSource *sequence = dynamic_cast<MultiFileSource *>(s);
|
||||
@@ -3587,20 +3600,21 @@ void Navigator::RenderSourcePannel(Source *s, const ImVec2 &iconsize)
|
||||
Settings::application.source.new_type = SOURCE_GENERATED;
|
||||
else
|
||||
Settings::application.source.new_type = SOURCE_CONNECTED;
|
||||
|
||||
// switch to panel new source
|
||||
showPannelSource(NAV_NEW);
|
||||
// set source to be replaced
|
||||
source_to_replace = s;
|
||||
}
|
||||
|
||||
// delete button
|
||||
if ( ImGui::Button( ACTION_DELETE, ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
|
||||
if ( ImGui::Button( ACTION_DELETE, size) ) {
|
||||
Mixer::manager().deleteSource(s);
|
||||
Action::manager().store(sname + std::string(": Deleted"));
|
||||
}
|
||||
// delete all button
|
||||
if ( Mixer::manager().session()->failedSources().size() > 1 ) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_FAILED, 1.));
|
||||
if ( ImGui::Button( ICON_FA_BACKSPACE " Delete all failed", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
|
||||
if ( ImGui::Button( ICON_FA_BACKSPACE " Delete all failed", size) ) {
|
||||
auto failedsources = Mixer::manager().session()->failedSources();
|
||||
for (auto sit = failedsources.cbegin(); sit != failedsources.cend(); ++sit) {
|
||||
Mixer::manager().deleteSource( Mixer::manager().findSource( (*sit)->id() ) );
|
||||
|
||||
Reference in New Issue
Block a user