Merge remote-tracking branch 'origin/beta'

This commit is contained in:
Bruno
2024-06-06 14:15:19 +02:00
18 changed files with 197 additions and 91 deletions

Binary file not shown.

View File

@@ -37,7 +37,7 @@
CloneSource::CloneSource(Source *origin, uint64_t id) : Source(id), origin_(origin), paused_(false), filter_(nullptr)
{
// initial name copies the origin name: diplucates are namanged in session
name_ = origin->name();
name_ = origin_name_ = origin->name();
// set symbol
symbol_ = new Symbol(Symbol::CLONE, glm::vec3(0.75f, 0.75f, 0.01f));
@@ -64,6 +64,7 @@ CloneSource::~CloneSource()
void CloneSource::detach()
{
Log::Info("Source '%s' detached from '%s'.", name().c_str(), origin_->name().c_str() );
origin_name_ = origin_->name();
origin_ = nullptr;
}
@@ -233,7 +234,7 @@ uint CloneSource::texture() const
Source::Failure CloneSource::failed() const
{
return (origin_ == nullptr || origin_->failed()) ? FAIL_FATAL : FAIL_NONE;
return (origin_ == nullptr || origin_->failed()) ? FAIL_RETRY : FAIL_NONE;
}
void CloneSource::accept(Visitor& v)
@@ -251,3 +252,10 @@ std::string CloneSource::info() const
{
return "Clone";
}
std::string CloneSource::origin_name() const
{
if (origin_)
return origin_->name();
return origin_name_;
}

View File

@@ -32,6 +32,7 @@ public:
// implementation of cloning mechanism
void detach();
inline Source *origin() const { return origin_; }
std::string origin_name() const;
// Filtering
void setFilter(FrameBufferFilter::Type T);
@@ -44,6 +45,7 @@ protected:
void init() override;
Source *origin_;
std::string origin_name_;
// control
bool paused_;

View File

@@ -171,7 +171,7 @@ bool ImGuiToolkit::ButtonSwitch(const char* label, bool* toggle, const char* too
void _drawIcon(ImVec2 screenpos, int i, int j, bool enabled = true)
void _drawIcon(ImVec2 screenpos, int i, int j, bool enabled = true, ImGuiWindow* window = ImGui::GetCurrentWindow() )
{
// icons.dds is a 20 x 20 grid of icons
if (textureicons == 0)
@@ -184,7 +184,6 @@ void _drawIcon(ImVec2 screenpos, int i, int j, bool enabled = true)
if (!enabled)
tint_color = ImGui::GetStyle().Colors[ImGuiCol_TextDisabled];
ImGuiWindow* window = ImGui::GetCurrentWindow();
ImRect bb(screenpos, screenpos + ImVec2(ImGui::GetTextLineHeightWithSpacing(), ImGui::GetTextLineHeightWithSpacing()));
window->DrawList->AddImage((void*)(intptr_t)textureicons, bb.Min, bb.Max, uv0, uv1, ImGui::GetColorU32(tint_color) );
}
@@ -565,14 +564,8 @@ bool ImGuiToolkit::ComboIcon (const char* label, int* current_item,
*current_item = CLAMP( *current_item, 0, (int) items.size() - 1);
// make some space
char space_buf[] = " ";
const ImVec2 space_size = ImGui::CalcTextSize(" ", NULL);
const int space_num = static_cast<int>( ceil(g.FontSize / space_size.x) );
space_buf[space_num]='\0';
char text_buf[256];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s %s", space_buf, std::get<2>( items.at(*current_item) ).c_str());
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), " %s", std::get<2>( items.at(*current_item) ).c_str());
if ( ImGui::BeginCombo( label, text_buf, ImGuiComboFlags_None) ) {
for (int p = 0; p < (int) items.size(); ++p){
ImGui::PushID((void*)(intptr_t)p);
@@ -600,17 +593,12 @@ bool ImGuiToolkit::SelectableIcon(int i, int j, const char* label, bool selected
{
ImGuiContext& g = *GImGui;
ImVec2 draw_pos = ImGui::GetCursorScreenPos() - g.Style.FramePadding * 0.5;
// make some space
char space_buf[] = " ";
const ImVec2 space_size = ImGui::CalcTextSize(" ", NULL);
const int space_num = static_cast<int>( ceil(g.FontSize / space_size.x) );
space_buf[space_num+1]='\0';
char text_buf[256];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s%s", space_buf, label);
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), " %s", label);
ImGui::PushID( i * 20 + j + ImGui::GetID("##SelectableIcon") );
ImGui::PushID( i * 20 + j + ImGui::GetID(text_buf) );
// draw menu item
bool ret = ImGui::Selectable(text_buf, selected, ImGuiSelectableFlags_None, size_arg);
@@ -627,26 +615,39 @@ bool ImGuiToolkit::SelectableIcon(int i, int j, const char* label, bool selected
return ret;
}
bool ImGuiToolkit::MenuItemIcon (int i, int j, const char* label, const char* shortcut, bool selected, bool enabled)
{
ImVec2 draw_pos = ImGui::GetCursorScreenPos();
// make some space
char space_buf[] = " ";
const ImVec2 space_size = ImGui::CalcTextSize(" ", NULL);
const int space_num = static_cast<int>( ceil(ImGui::GetTextLineHeightWithSpacing() / space_size.x) );
space_buf[space_num]='\0';
ImGuiContext& g = *GImGui;
draw_pos.y -= g.Style.ItemSpacing.y * 0.5f;
char text_buf[256];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), "%s %s", space_buf, label);
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), " %s", label);
// draw menu item
bool ret = ImGui::MenuItem(text_buf, shortcut, selected, enabled);
// draw icon
ImGui::SetCursorScreenPos(draw_pos);
Icon(i, j, enabled);
// overlay of icon on top of first item
_drawIcon(draw_pos, i, j, enabled);
return ret;
}
bool ImGuiToolkit::BeginMenuIcon(int i, int j, const char *label, bool enabled)
{
ImGuiWindow *win = ImGui::GetCurrentWindow();
ImVec2 draw_pos = ImGui::GetCursorScreenPos();
ImGuiContext &g = *GImGui;
draw_pos.y += g.Style.ItemSpacing.y * 0.5f;
char text_buf[256];
ImFormatString(text_buf, IM_ARRAYSIZE(text_buf), " %s", label);
// draw menu item
bool ret = ImGui::BeginMenu(text_buf, enabled);
// overlay of icon on top of first item
_drawIcon(draw_pos, i, j, enabled, win);
return ret;
}
@@ -1763,7 +1764,7 @@ void ImGuiToolkit::SetAccentColor(accent_color color)
colors[ImGuiCol_TextDisabled] = ImVec4(0.55f, 0.55f, 0.55f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.13f, 0.13f, 0.13f, 0.94f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.13f, 0.13f, 0.13f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.16f, 0.16f, 0.16f, 1.00f);
colors[ImGuiCol_Border] = ImVec4(0.69f, 0.69f, 0.69f, 0.25f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.39f, 0.39f, 0.39f, 0.55f);

View File

@@ -28,6 +28,7 @@ namespace ImGuiToolkit
bool ButtonIcon (int i, int j, const char* tooltip = nullptr, bool expanded = false);
bool ButtonIconToggle (int i, int j, bool* toggle, const char *tooltip = nullptr);
bool ButtonIconMultistate (std::vector<std::pair<int, int> > icons, int* state, std::vector<std::string> tooltips);
bool BeginMenuIcon(int i, int j, const char *label, bool enabled = true);
bool MenuItemIcon (int i, int j, const char* label, const char* shortcut = nullptr, bool selected = false, bool enabled = true);
bool SelectableIcon(int i, int j, const char* label, bool selected, const ImVec2& size_arg = ImVec2(0,0));
bool ComboIcon (const char* label, int* current_item, std::vector<std::tuple<int, int, std::string> > items, std::vector<std::string> tooltips = {});

View File

@@ -272,7 +272,7 @@ void ImageFilteringShader::setCode(const std::string &code, std::promise<std::st
custom_shading_.setShaders("shaders/image.vs", shader_code_, (int)n, ret);
}
else if (ret != nullptr) {
ret->set_value("No change.");
ret->set_value("No change");
}
}
@@ -292,7 +292,7 @@ void ImageFilteringShader::copy(ImageFilteringShader const& S)
/// ////
////////////////////////////////////////
ImageFilter::ImageFilter (): FrameBufferFilter(), buffers_({nullptr, nullptr})
ImageFilter::ImageFilter (): FrameBufferFilter(), buffers_({nullptr, nullptr}), channel1_output_session(true)
{
// surface and shader for first pass
shaders_.first = new ImageFilteringShader;
@@ -381,6 +381,7 @@ void ImageFilter::draw (FrameBuffer *input)
input_ = input;
// create first-pass surface and shader, taking as texture the input framebuffer
surfaces_.first->setTextureIndex( input_->texture() );
shaders_.first->secondary_texture = input_->texture();
// (re)create framebuffer for result of first-pass
if (buffers_.first != nullptr)
delete buffers_.first;
@@ -390,6 +391,7 @@ void ImageFilter::draw (FrameBuffer *input)
input_->blit( buffers_.first );
// create second-pass surface and shader, taking as texture the first-pass framebuffer
surfaces_.second->setTextureIndex( buffers_.first->texture() );
shaders_.second->secondary_texture = input_->texture();
// (re)create framebuffer for result of second-pass
if (buffers_.second != nullptr)
delete buffers_.second;
@@ -401,16 +403,18 @@ void ImageFilter::draw (FrameBuffer *input)
if ( enabled() || forced )
{
// FIRST PASS
if (channel1_output_session)
shaders_.first->secondary_texture = Mixer::manager().session()->frame()->texture();
// render input surface into frame buffer
shaders_.first->mask_texture = Mixer::manager().session()->frame()->texture();
buffers_.first->begin();
surfaces_.first->draw(glm::identity<glm::mat4>(), buffers_.first->projection());
buffers_.first->end();
// SECOND PASS
if ( program_.isTwoPass() ) {
if (channel1_output_session)
shaders_.second->secondary_texture = Mixer::manager().session()->frame()->texture();
// render filtered surface from first pass into frame buffer
shaders_.second->mask_texture = Mixer::manager().session()->frame()->texture();
buffers_.second->begin();
surfaces_.second->draw(glm::identity<glm::mat4>(), buffers_.second->projection());
buffers_.second->end();
@@ -525,6 +529,7 @@ std::vector< FilteringProgram > ResampleFilter::programs_ = {
ResampleFilter::ResampleFilter (): ImageFilter(), factor_(RESAMPLE_INVALID)
{
channel1_output_session = false;
}
void ResampleFilter::setFactor(int factor)
@@ -579,7 +584,7 @@ void ResampleFilter::draw (FrameBuffer *input)
// create first-pass surface and shader, taking as texture the input framebuffer
surfaces_.first->setTextureIndex( input_->texture() );
shaders_.first->mask_texture = input_->texture();
shaders_.first->secondary_texture = input_->texture();
// (re)create framebuffer for result of first-pass
if (buffers_.first != nullptr)
delete buffers_.first;
@@ -604,7 +609,7 @@ void ResampleFilter::draw (FrameBuffer *input)
// SECOND PASS for QUARTER resolution (divide by 2 after first pass divide by 2)
// create second-pass surface and shader, taking as texture the first-pass framebuffer
surfaces_.second->setTextureIndex( buffers_.first->texture() );
shaders_.second->mask_texture = input_->texture();
shaders_.second->secondary_texture = input_->texture();
// (re)create framebuffer for result of second-pass
if (buffers_.second != nullptr)
delete buffers_.second;
@@ -662,6 +667,7 @@ std::vector< FilteringProgram > BlurFilter::programs_ = {
BlurFilter::BlurFilter (): ImageFilter(), method_(BLUR_INVALID), mipmap_buffer_(nullptr)
{
mipmap_surface_ = new Surface;
channel1_output_session = false;
}
BlurFilter::~BlurFilter ()
@@ -733,7 +739,7 @@ void BlurFilter::draw (FrameBuffer *input)
// create first-pass surface and shader, taking as texture the input framebuffer
surfaces_.first->setTextureIndex( mipmap_buffer_->texture() );
shaders_.first->mask_texture = input_->texture();
shaders_.first->secondary_texture = input_->texture();
// (re)create framebuffer for result of first-pass
if (buffers_.first != nullptr)
delete buffers_.first;
@@ -743,7 +749,7 @@ void BlurFilter::draw (FrameBuffer *input)
// create second-pass surface and shader, taking as texture the first-pass framebuffer
surfaces_.second->setTextureIndex( buffers_.first->texture() );
shaders_.second->mask_texture = input_->texture();
shaders_.second->secondary_texture = input_->texture();
// (re)create framebuffer for result of second-pass
if (buffers_.second != nullptr)
delete buffers_.second;
@@ -803,6 +809,7 @@ std::vector< FilteringProgram > SharpenFilter::programs_ = {
SharpenFilter::SharpenFilter (): ImageFilter(), method_(SHARPEN_INVALID)
{
channel1_output_session = false;
}
void SharpenFilter::setMethod(int method)
@@ -880,6 +887,7 @@ std::vector< FilteringProgram > SmoothFilter::programs_ = {
SmoothFilter::SmoothFilter (): ImageFilter(), method_(SMOOTH_INVALID)
{
channel1_output_session = false;
}
void SmoothFilter::setMethod(int method)
@@ -950,6 +958,7 @@ std::vector< FilteringProgram > EdgeFilter::programs_ = {
EdgeFilter::EdgeFilter (): ImageFilter(), method_(EDGE_INVALID)
{
channel1_output_session = false;
}
void EdgeFilter::setMethod(int method)
@@ -1020,6 +1029,7 @@ std::vector< FilteringProgram > AlphaFilter::programs_ = {
AlphaFilter::AlphaFilter (): ImageFilter(), operation_(ALPHA_INVALID)
{
channel1_output_session = false;
}
void AlphaFilter::setOperation(int op)

View File

@@ -139,6 +139,7 @@ protected:
std::pair< FrameBuffer *, FrameBuffer * > buffers_;
std::pair< ImageFilteringShader *, ImageFilteringShader *> shaders_;
void updateParameters();
bool channel1_output_session;
};

View File

@@ -43,7 +43,7 @@ const char* MaskShader::mask_icons[4] = { ICON_FA_WINDOW_CLOSE, ICON_FA_EDIT, I
const char* MaskShader::mask_names[4] = { "No mask", "Paint mask", "Shape mask", "Source mask" };
const char* MaskShader::mask_shapes[5] = { "Ellipse", "Oblong", "Rectangle", "Horizontal", "Vertical" };
ImageShader::ImageShader(): Shader(), mask_texture(0), stipple(0.f)
ImageShader::ImageShader(): Shader(), secondary_texture(0), stipple(0.f)
{
// static program shader
program_ = &imageShadingProgram;
@@ -60,21 +60,21 @@ void ImageShader::use()
program_->setUniform("iNodes", iNodes);
// default mask
if (mask_texture == 0)
mask_texture = Resource::getTextureWhite();
if (secondary_texture == 0)
secondary_texture = Resource::getTextureWhite();
// setup mask texture
glActiveTexture(GL_TEXTURE1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture (GL_TEXTURE_2D, mask_texture);
glBindTexture (GL_TEXTURE_2D, secondary_texture);
glActiveTexture(GL_TEXTURE0);
}
void ImageShader::reset()
{
Shader::reset();
mask_texture = 0;
secondary_texture = 0;
// no stippling
stipple = 0.f;
@@ -84,7 +84,7 @@ void ImageShader::reset()
void ImageShader::copy(ImageShader const& S)
{
mask_texture = S.mask_texture;
secondary_texture = S.secondary_texture;
stipple = S.stipple;
iNodes = S.iNodes;
}

View File

@@ -1,8 +1,6 @@
#ifndef IMAGESHADER_H
#define IMAGESHADER_H
#include <string>
#include <map>
#include <sys/types.h>
#include "Shader.h"
@@ -18,7 +16,7 @@ public:
void accept(Visitor& v) override;
void copy(ImageShader const& S);
uint mask_texture;
uint secondary_texture;
// uniforms
float stipple;

View File

@@ -182,8 +182,14 @@ void Mixer::update()
insertSource(candidate_sources_.front().first, candidate_sources_.size() > 1 ? View::INVALID : View::MIXING);
// the second element of the pair is the source to be replaced, i.e. deleted if provided
if (candidate_sources_.front().second != nullptr)
if (candidate_sources_.front().second != nullptr) {
// keep previous name
std::string previous_name = candidate_sources_.front().second->name();
// delete previous
deleteSource(candidate_sources_.front().second);
// rename new source with previous name
candidate_sources_.front().first->setName(previous_name);
}
candidate_sources_.pop_front();
}
@@ -459,10 +465,10 @@ Source * Mixer::createSourceGroup()
return s;
}
Source * Mixer::createSourceClone(const std::string &namesource, bool copy_attributes)
CloneSource * Mixer::createSourceClone(const std::string &namesource, bool copy_attributes)
{
// ready to create a source
Source *s = nullptr;
CloneSource *s = nullptr;
// origin to clone is either the given name or the current
SourceList::iterator origin = session_->end();
@@ -589,9 +595,6 @@ void Mixer::replaceSource(Source *previous, Source *s)
s->setImageProcessingEnabled( previous->imageProcessingEnabled() );
s->blendingShader()->blending = previous->blendingShader()->blending;
// rename s
renameSource(s, previous_name);
// add source 's' and remove source 'previous'
candidate_sources_.push_back( std::make_pair(s, previous) );
}

View File

@@ -50,7 +50,7 @@ public:
// creation of sources
Source * createSourceFile (const std::string &path, bool disable_hw_decoding = false);
Source * createSourceMultifile(const std::list<std::string> &list_files, uint fps);
Source * createSourceClone (const std::string &namesource = "", bool copy_attributes = true);
class CloneSource *createSourceClone(const std::string &namesource = "", bool copy_attributes = true);
Source * createSourceRender ();
Source * createSourceStream (const std::string &gstreamerpipeline);
Source * createSourcePattern(uint pattern, glm::ivec2 res);

View File

@@ -385,7 +385,7 @@ void OutputPreviewWindow::Render()
ImGui::EndMenu();
}
if (ImGui::BeginMenu(ICON_FA_WIFI " Stream"))
if (ImGuiToolkit::BeginMenuIcon(19, 11, "Stream"))
{
// Stream sharing menu
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(IMGUI_COLOR_STREAM, 0.9f));

View File

@@ -821,13 +821,12 @@ void SessionVisitor::visit (CloneSource& s)
cloneNode->SetAttribute("type", "CloneSource");
// origin of clone
if (s.origin()) {
XMLElement *origin = xmlDoc_->NewElement( "origin" );
cloneNode->InsertEndChild(origin);
XMLElement *origin = xmlDoc_->NewElement( "origin" );
XMLText *text = xmlDoc_->NewText( s.origin_name().c_str() );
if (s.origin())
origin->SetAttribute("id", s.origin()->id());
XMLText *text = xmlDoc_->NewText( s.origin()->name().c_str() );
origin->InsertEndChild( text );
}
origin->InsertEndChild( text );
cloneNode->InsertEndChild(origin);
// Filter
xmlCurrent_ = xmlDoc_->NewElement( "Filter" );

View File

@@ -18,6 +18,7 @@ TextEditor _editor;
#include "SystemToolkit.h"
#include "CloneSource.h"
#include "DialogToolkit.h"
#include "UserInterfaceManager.h"
#include "ShaderEditWindow.h"
@@ -141,6 +142,8 @@ void ShaderEditWindow::Render()
return;
}
Source *cs = Mixer::manager().currentSource();
// menu (no title bar)
if (ImGui::BeginMenuBar())
{
@@ -149,6 +152,16 @@ void ShaderEditWindow::Render()
Settings::application.widget.shader_editor = false;
if (ImGui::BeginMenu(IMGUI_TITLE_SHADEREDITOR))
{
// Menu entry to allow creating a custom filter
if (ImGui::MenuItem(ICON_FA_SHARE_SQUARE " Clone source & add filter",
nullptr, nullptr, cs != nullptr)) {
CloneSource *filteredclone = Mixer::manager().createSourceClone();
filteredclone->setFilter(FrameBufferFilter::FILTER_IMAGE);
Mixer::manager().addSource ( filteredclone );
UserInterface::manager().showPannel( Mixer::manager().numSource() );
}
ImGui::Separator();
// reload code from GPU
if (ImGui::MenuItem( ICON_FA_REDO_ALT " Reload", nullptr, nullptr, current_ != nullptr)) {
// force reload
@@ -189,13 +202,6 @@ void ShaderEditWindow::Render()
if (ImGui::MenuItem( ICON_FA_EXTERNAL_LINK_ALT " Browse shadertoy.com"))
SystemToolkit::open("https://www.shadertoy.com/");
// Enable/Disable editor options
ImGui::Separator();
ImGui::MenuItem( ICON_FA_UNDERLINE " Show Shader Inputs", nullptr, &show_shader_inputs_);
bool ws = _editor.IsShowingWhitespaces();
if (ImGui::MenuItem( ICON_FA_ELLIPSIS_H " Show whitespace", nullptr, &ws))
_editor.SetShowWhitespaces(ws);
// output manager menu
ImGui::Separator();
bool pinned = Settings::application.widget.shader_editor_view == Settings::application.current_view;
@@ -231,6 +237,13 @@ void ShaderEditWindow::Render()
if (ImGui::MenuItem( MENU_SELECTALL, SHORTCUT_SELECTALL, nullptr, _editor.GetText().size() > 1 ))
_editor.SetSelection(TextEditor::Coordinates(), TextEditor::Coordinates(_editor.GetTotalLines(), 0));
// Enable/Disable editor options
ImGui::Separator();
ImGui::MenuItem( ICON_FA_UNDERLINE " Show Shader Inputs", nullptr, &show_shader_inputs_);
bool ws = _editor.IsShowingWhitespaces();
if (ImGui::MenuItem( ICON_FA_ELLIPSIS_H " Show whitespace", nullptr, &ws))
_editor.SetShowWhitespaces(ws);
ImGui::EndMenu();
}
@@ -301,11 +314,9 @@ void ShaderEditWindow::Render()
else {
ImageFilter *i = nullptr;
// get current clone source
Source *s = Mixer::manager().currentSource();
// if there is a current source
if (s != nullptr) {
CloneSource *c = dynamic_cast<CloneSource *>(s);
if (cs != nullptr) {
CloneSource *c = dynamic_cast<CloneSource *>(cs);
// if the current source is a clone
if ( c != nullptr ) {
FrameBufferFilter *f = c->filter();
@@ -325,6 +336,7 @@ void ShaderEditWindow::Render()
if (i == nullptr) {
status_ = "-";
_editor.SetText("");
_editor.SetReadOnly(true);
current_ = nullptr;
}
}
@@ -347,10 +359,13 @@ void ShaderEditWindow::Render()
_editor.SetText( filters_[i].code().first );
_editor.SetReadOnly(false);
_editor.SetColorizerEnable(true);
status_ = "Ready.";
status_ = "Ready";
}
// cancel edit clone
else {
// possibility that source was removed
g_printerr("cancel edit clone %ld\n", current_);
// disable editor
_editor.SetReadOnly(true);
_editor.SetColorizerEnable(false);

View File

@@ -948,7 +948,7 @@ void Source::update(float dt)
if (ref_source != nullptr) {
if (ref_source->ready())
// set mask texture to mask source
blendingshader_->mask_texture = ref_source->frame()->texture();
blendingshader_->secondary_texture = ref_source->frame()->texture();
else
// retry for when source will be ready
need_update_ |= SourceUpdate_Mask;
@@ -964,7 +964,7 @@ void Source::update(float dt)
masksurface_->draw(glm::identity<glm::mat4>(), maskbuffer_->projection());
maskbuffer_->end();
// set mask texture to mask buffer
blendingshader_->mask_texture = maskbuffer_->texture();
blendingshader_->secondary_texture = maskbuffer_->texture();
}
}

View File

@@ -535,7 +535,7 @@ bool TextureView::adjustBackground()
shift_crop_.x *= edit_source_->frame()->aspectRatio();
preview_surface_->setTextureIndex(edit_source_->frame()->texture());
preview_shader_->mask_texture = edit_source_->blendingShader()->mask_texture;
preview_shader_->secondary_texture = edit_source_->blendingShader()->secondary_texture;
preview_surface_->scale_ = scale_crop_;
preview_surface_->translation_ = shift_crop_;

View File

@@ -268,6 +268,9 @@ void UserInterface::handleKeyboard()
if ( TryClose() )
Rendering::manager().close();
}
else if (ImGui::IsKeyPressed( Control::layoutKey(GLFW_KEY_F), false )) {
Rendering::manager().mainWindow().toggleFullscreen();
}
else if (ImGui::IsKeyPressed( Control::layoutKey(GLFW_KEY_O), false )) {
// SHIFT + CTRL + O : reopen current session
if (shift_modifier_active && !Mixer::manager().session()->filename().empty())
@@ -1119,6 +1122,9 @@ void UserInterface::showMenuWindows()
if ( ImGui::MenuItem( MENU_INPUTS, SHORTCUT_INPUTS, &Settings::application.widget.inputs) )
UserInterface::manager().inputscontrol.setVisible(Settings::application.widget.inputs);
if ( ImGui::MenuItem( MENU_SHADEREDITOR, SHORTCUT_SHADEREDITOR, &Settings::application.widget.shader_editor) )
UserInterface::manager().shadercontrol.setVisible(Settings::application.widget.shader_editor);
// Show Help
ImGui::MenuItem( MENU_HELP, SHORTCUT_HELP, &Settings::application.widget.help );
// Show Logs
@@ -2514,7 +2520,6 @@ void UserInterface::RenderHelp()
if (ImGui::CollapsingHeader("Views"))
{
ImGui::Columns(2, "viewscolumn", false); // 4-ways, with border
ImGui::SetColumnWidth(0, width_column0);
ImGui::PushTextWrapPos(width_window );
@@ -2543,7 +2548,7 @@ void UserInterface::RenderHelp()
ImGui::PopTextWrapPos();
}
if (ImGui::CollapsingHeader("Windows"))
if (ImGui::CollapsingHeader("Tools"))
{
ImGui::Columns(2, "windowcolumn", false); // 4-ways, with border
ImGui::SetColumnWidth(0, width_column0);
@@ -2577,6 +2582,62 @@ void UserInterface::RenderHelp()
ImGui::PopTextWrapPos();
}
if (ImGui::CollapsingHeader("Files"))
{
{
float H = ImGui::GetFrameHeightWithSpacing();
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_MenuBar;
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f);
ImGui::BeginChild("PlaylistHelp", ImVec2(0, 10.f * H), true, window_flags);
if (ImGui::BeginMenuBar()) {
ImGuiToolkit::Icon(4, 8);
ImGui::Text (" Playlist");
ImGui::EndMenuBar();
}
{
ImGui::BeginChild("SessionHelp", ImVec2(0, 7.f * H), true, window_flags);
if (ImGui::BeginMenuBar()) {
ImGuiToolkit::Icon(7, 1);
ImGui::Text (" Session");
ImGui::EndMenuBar();
}
{
ImGui::BeginChild("SourceHelp", ImVec2(0, 4.f * H), true, window_flags);
if (ImGui::BeginMenuBar()) {
ImGuiToolkit::Icon(14, 11);
ImGui::Text ("Source");
ImGui::EndMenuBar();
}
ImGui::BulletText("Video, image & session files");
ImGui::BulletText("Image sequence (image files)");
ImGui::BulletText("Input devices & streams (e.g. webcams)");
ImGui::BulletText("Patterns & generated graphics (e.g. text)");
ImGui::EndChild();
}
ImGui::PushTextWrapPos(width_window - 10.f);
ImGui::Spacing();
ImGui::Text ("A session contains several sources mixed together and keeps previous versions. "
"It is saved in a .mix file.");
ImGui::PopTextWrapPos();
ImGui::EndChild();
}
ImGui::PushTextWrapPos(width_window - 10.f);
ImGui::Spacing();
ImGui::Text ("A playlist keeps a list of sessions (or lists the .mix files in a folder) "
"for smooth transitions between files.");
ImGui::PopTextWrapPos();
ImGui::EndChild();
ImGui::PopStyleVar();
}
}
if (ImGui::CollapsingHeader("Sources"))
{
ImGui::Columns(2, "sourcecolumn", false); // 4-ways, with border
@@ -3260,6 +3321,7 @@ void Navigator::Render()
if (!std::get<0>(tooltip).empty()) {
// pseudo timeout for showing tooltip
if (_timeout_tooltip > IMGUI_TOOLTIP_TIMEOUT) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
// if a pointer to a Source is provided in tupple
Source *_s = std::get<2>(tooltip);
if (_s != nullptr) {
@@ -3287,7 +3349,7 @@ void Navigator::Render()
// otherwise just show a standard tooltip [action - shortcut key]
else
ImGuiToolkit::ToolTip(std::get<0>(tooltip).c_str(), std::get<1>(tooltip).c_str());
ImGui::PopStyleVar();
}
else
++_timeout_tooltip;
@@ -3499,16 +3561,13 @@ void Navigator::RenderSourcePannel(Source *s, const ImVec2 &iconsize)
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)) )
Mixer::manager().addSource ( Mixer::manager().createSourceClone() );
else if ( ImGui::Button( ICON_FA_SHARE_SQUARE " Clone & Filter", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
Mixer::manager().addSource ( (Source *) Mixer::manager().createSourceClone() );
UserInterface::manager().showPannel( Mixer::manager().numSource() );
}
// replace button
if ( s->cloned() ) {
ImGuiToolkit::ButtonDisabled( ICON_FA_PLUS_SQUARE " Replace", ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::IsItemHovered())
ImGuiToolkit::ToolTip("Cannot replace if source is cloned");
}
else if ( ImGui::Button( ICON_FA_PLUS_SQUARE " Replace", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
if ( ImGui::Button( ICON_FA_PLUS_SQUARE " Replace", ImVec2(ImGui::GetContentRegionAvail().x, 0)) ) {
// prepare panel for new source of same type
MediaSource *file = dynamic_cast<MediaSource *>(s);
MultiFileSource *sequence = dynamic_cast<MultiFileSource *>(s);
@@ -4667,7 +4726,7 @@ void Navigator::RenderMainPannelSession()
width = height * se->frame()->aspectRatio() * ( se->frame()->projectionSize().x / se->frame()->projectionSize().y);
}
// centered image
ImGui::SetCursorPos( ImVec2(pos.x + 0.5f * (preview_width-width), pos.y + 0.5f * (preview_height-height-space)) );
ImGui::SetCursorPos( ImVec2(pos.x + 0.5f * (preview_width-width), pos.y) );
ImGui::Image((void*)(uintptr_t) se->frame()->texture(), ImVec2(width, height));
// right side options for session
@@ -4721,6 +4780,7 @@ void Navigator::RenderMainPannelSession()
if (_thumbnail != nullptr)
_session_thumbnail.fill( _thumbnail );
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
ImGui::BeginTooltip();
if (_session_thumbnail.filled()) {
_session_thumbnail.Render(230);
@@ -4730,6 +4790,7 @@ void Navigator::RenderMainPannelSession()
ImGui::Text(" Automatic thumbnail ");
}
ImGui::EndTooltip();
ImGui::PopStyleVar();
}
}
@@ -4884,10 +4945,12 @@ void Navigator::RenderMainPannelSession()
_undo_thumbnail.reset();
}
// draw thumbnail in tooltip
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
ImGui::BeginTooltip();
_undo_thumbnail.Render(size.x);
ImGui::Text("%s", text.c_str());
ImGui::EndTooltip();
ImGui::PopStyleVar();
++count_over; // prevents display twice on item overlap
}
@@ -5002,10 +5065,12 @@ void Navigator::RenderMainPannelSession()
current_over = _over;
}
// draw thumbnail in tooltip
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
ImGui::BeginTooltip();
_snap_thumbnail.Render(size.x);
ImGui::Text("%s", _snap_date.c_str());
ImGui::EndTooltip();
ImGui::PopStyleVar();
++count_over; // prevents display twice on item overlap
}
}
@@ -5458,6 +5523,7 @@ void Navigator::RenderMainPannelPlaylist()
if ( !_file_info.empty()) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.f, 8.f));
ImGui::BeginTooltip();
ImVec2 p_ = ImGui::GetCursorScreenPos();
_file_thumbnail.Render(240);
@@ -5467,6 +5533,7 @@ void Navigator::RenderMainPannelPlaylist()
ImGui::Text(ICON_FA_TAG);
}
ImGui::EndTooltip();
ImGui::PopStyleVar();
}
}
@@ -6056,7 +6123,7 @@ void Navigator::RenderMainPannel(const ImVec2 &iconsize)
ImGui::EndMenu();
}
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, IMGUI_TOP_ALIGN + 2.f * ImGui::GetTextLineHeightWithSpacing()) );
if (ImGui::BeginMenu("View")) {
if (ImGui::BeginMenu("Tools")) {
UserInterface::manager().showMenuWindows();
ImGui::EndMenu();
}

View File

@@ -232,14 +232,15 @@
#define MENU_TIMER ICON_FA_CLOCK " Timer "
#define TOOLTIP_TIMER "Timer "
#define SHORTCUT_TIMER CTRL_MOD "T"
#define MENU_INPUTS ICON_FA_HAND_PAPER " Inputs mapping "
#define MENU_INPUTS ICON_FA_HAND_PAPER " Input mapping "
#define TOOLTIP_INPUTS "Inputs mapping "
#define SHORTCUT_INPUTS CTRL_MOD "I"
#define MENU_SHADEREDITOR ICON_FA_CODE " Shader Editor "
#define TOOLTIP_SHADEREDITOR "Shader Editor "
#define SHORTCUT_SHADEREDITOR CTRL_MOD "E"
#define TOOLTIP_FULLSCREEN "Fullscreen "
#define SHORTCUT_FULLSCREEN CTRL_MOD "F"
#define TOOLTIP_MAIN "Main menu "
#define TOOLTIP_MAIN "Home panel "
#define SHORTCUT_MAIN "HOME"
#define TOOLTIP_NEW_SOURCE "Insert "
#define SHORTCUT_NEW_SOURCE "INS"