Integration procedural GLSL masks

This commit is contained in:
Bruno
2020-12-27 14:05:03 +01:00
parent 69d9d9473b
commit 34c24d99df
20 changed files with 510 additions and 258 deletions

View File

@@ -290,6 +290,8 @@ set(VMIX_RSC_FILES
./rsc/shaders/simple.fs ./rsc/shaders/simple.fs
./rsc/shaders/simple.vs ./rsc/shaders/simple.vs
./rsc/shaders/image.fs ./rsc/shaders/image.fs
./rsc/shaders/mask_elipse.fs
./rsc/shaders/mask_box.fs
./rsc/shaders/image.vs ./rsc/shaders/image.vs
./rsc/shaders/imageprocessing.fs ./rsc/shaders/imageprocessing.fs
./rsc/fonts/Hack-Regular.ttf ./rsc/fonts/Hack-Regular.ttf
@@ -321,6 +323,7 @@ set(VMIX_RSC_FILES
./rsc/images/soft_shadow.dds ./rsc/images/soft_shadow.dds
./rsc/mesh/disk.ply ./rsc/mesh/disk.ply
./rsc/mesh/circle.ply ./rsc/mesh/circle.ply
./rsc/mesh/corner.ply
./rsc/mesh/shadow.ply ./rsc/mesh/shadow.ply
./rsc/mesh/glow.ply ./rsc/mesh/glow.ply
./rsc/mesh/border_round.ply ./rsc/mesh/border_round.ply

View File

@@ -161,6 +161,7 @@ void ImGuiVisitor::visit(Shader &n)
{ {
ImGui::PushID(std::to_string(n.id()).c_str()); ImGui::PushID(std::to_string(n.id()).c_str());
// Base color
// if (ImGuiToolkit::ButtonIcon(10, 2)) { // if (ImGuiToolkit::ButtonIcon(10, 2)) {
// n.blending = Shader::BLEND_OPACITY; // n.blending = Shader::BLEND_OPACITY;
// n.color = glm::vec4(1.f, 1.f, 1.f, 1.f); // n.color = glm::vec4(1.f, 1.f, 1.f, 1.f);
@@ -201,29 +202,26 @@ void ImGuiVisitor::visit(Shader &n)
ImGui::PopID(); ImGui::PopID();
} }
void ImGuiVisitor::visit(ImageShader &n) //void ImGuiVisitor::visit(ImageShader &n)
{ //{
ImGui::PushID(std::to_string(n.id()).c_str()); // ImGui::PushID(std::to_string(n.id()).c_str());
// // get index of the mask used in this ImageShader
// get index of the mask used in this ImageShader // int item_current = n.mask;
int item_current = n.mask; //// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0;
//// ImGui::SameLine(0, 10);
// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0; // ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// ImGui::SameLine(0, 10); // // combo list of masks
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); // if ( ImGui::Combo("Mask", &item_current, ImageShader::mask_names, IM_ARRAYSIZE(ImageShader::mask_names) ) )
// combo list of masks // {
if ( ImGui::Combo("Mask", &item_current, ImageShader::mask_names, IM_ARRAYSIZE(ImageShader::mask_names) ) ) // if (item_current < (int) ImageShader::mask_presets.size())
{ // n.mask = item_current;
if (item_current < (int) ImageShader::mask_presets.size()) // else {
n.mask = item_current; // // TODO ask for custom mask
else { // }
// TODO ask for custom mask // Action::manager().store("Mask "+ std::string(ImageShader::mask_names[n.mask]), n.id());
} // }
Action::manager().store("Mask "+ std::string(ImageShader::mask_names[n.mask]), n.id()); // ImGui::PopID();
} //}
ImGui::PopID();
}
void ImGuiVisitor::visit(ImageProcessingShader &n) void ImGuiVisitor::visit(ImageProcessingShader &n)
{ {

View File

@@ -9,19 +9,18 @@ public:
ImGuiVisitor(); ImGuiVisitor();
// Elements of Scene // Elements of Scene
void visit(Scene& n) override; void visit (Scene& n) override;
void visit(Node& n) override; void visit (Node& n) override;
void visit(Group& n) override; void visit (Group& n) override;
void visit(Switch& n) override; void visit (Switch& n) override;
void visit(Primitive& n) override; void visit (Primitive& n) override;
void visit(MediaSurface& n) override; void visit (MediaSurface& n) override;
void visit(FrameBufferSurface& n) override; void visit (FrameBufferSurface& n) override;
// Elements with attributes // Elements with attributes
void visit(MediaPlayer& n) override; void visit (MediaPlayer& n) override;
void visit(Shader& n) override; void visit (Shader& n) override;
void visit(ImageShader& n) override; void visit (ImageProcessingShader& n) override;
void visit(ImageProcessingShader& n) override;
void visit (Source& s) override; void visit (Source& s) override;
void visit (MediaSource& s) override; void visit (MediaSource& s) override;
void visit (SessionSource& s) override; void visit (SessionSource& s) override;

View File

@@ -4,27 +4,16 @@
#include "Visitor.h" #include "Visitor.h"
#include "ImageShader.h" #include "ImageShader.h"
#include "Resource.h" #include "Resource.h"
#include "rsc/fonts/IconsFontAwesome5.h"
//#include
static ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs"); static ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs");
const char* ImageShader::mask_names[11] = { "None", "Glow", "Halo", "Circle", "Round", "Vignette", "Top", "Botton", "Left", "Right", "Custom" }; const char* MaskShader::mask_names[3] = { ICON_FA_EXPAND, ICON_FA_CIRCLE, ICON_FA_SQUARE };
std::vector< uint > ImageShader::mask_presets; std::vector< ShadingProgram* > MaskShader::mask_programs;
ImageShader::ImageShader(): Shader(), mask(0), custom_textureindex(0), stipple(0.0) ImageShader::ImageShader(): Shader(), /*mask(0), custom_textureindex(0),*/ stipple(0.0)
{ {
// first initialization
if ( mask_presets.empty() ) {
mask_presets.push_back(Resource::getTextureWhite());
mask_presets.push_back(Resource::getTextureImage("images/mask_glow.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_halo.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_circle.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_roundcorner.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_vignette.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_top.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_bottom.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_left.png"));
mask_presets.push_back(Resource::getTextureImage("images/mask_linear_right.png"));
}
// static program shader // static program shader
program_ = &imageShadingProgram; program_ = &imageShadingProgram;
// reset instance // reset instance
@@ -38,12 +27,9 @@ void ImageShader::use()
program_->setUniform("stipple", stipple); program_->setUniform("stipple", stipple);
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
if ( mask < 10 )
glBindTexture(GL_TEXTURE_2D, mask_presets[mask]);
else
glBindTexture(GL_TEXTURE_2D, custom_textureindex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, mask_texture);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
@@ -54,18 +40,16 @@ void ImageShader::reset()
Shader::reset(); Shader::reset();
// default mask // default mask
mask = 0; mask_texture = Resource::getTextureWhite();
custom_textureindex = mask_presets[0];
// no stippling // no stippling
stipple = 0.f; stipple = 0.f;
} }
void ImageShader::operator = (const ImageShader &S ) void ImageShader::operator = (const ImageShader &S)
{ {
Shader::operator =(S); Shader::operator =(S);
mask = S.mask; mask_texture = S.mask_texture;
custom_textureindex = S.custom_textureindex;
stipple = S.stipple; stipple = S.stipple;
} }
@@ -74,3 +58,59 @@ void ImageShader::accept(Visitor& v) {
Shader::accept(v); Shader::accept(v);
v.visit(*this); v.visit(*this);
} }
MaskShader::MaskShader(): Shader(), mode(0)
{
// first initialization
if ( mask_programs.empty() ) {
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/simple.fs"));
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_elipse.fs"));
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_box.fs"));
}
// reset instance
reset();
// static program shader
program_ = mask_programs[0];
}
void MaskShader::use()
{
// select program to use
mode = CLAMP(mode, 0, mask_programs.size()-1);
program_ = mask_programs[mode];
// actual use of shader program
Shader::use();
// set parameters
program_->setUniform("blur", blur);
program_->setUniform("size", size);
}
void MaskShader::reset()
{
Shader::reset();
// default mask
mode = 0;
blur = 0.5f;
size = glm::vec2(1.f, 1.f);
}
void MaskShader::operator = (const MaskShader &S)
{
Shader::operator =(S);
mode = S.mode;
blur = S.blur;
size = S.size;
}
void MaskShader::accept(Visitor& v) {
Shader::accept(v);
v.visit(*this);
}

View File

@@ -20,15 +20,35 @@ public:
void use() override; void use() override;
void reset() override; void reset() override;
void accept(Visitor& v) override; void accept(Visitor& v) override;
void operator = (const ImageShader &S); void operator = (const ImageShader &S);
uint mask; uint mask_texture;
uint custom_textureindex;
float stipple;
static const char* mask_names[11]; // uniforms
static std::vector< uint > mask_presets; float stipple;
};
class MaskShader : public Shader
{
public:
MaskShader();
void use() override;
void reset() override;
void accept(Visitor& v) override;
void operator = (const MaskShader &S);
uint mode;
// uniforms
float blur;
glm::vec2 size;
static const char* mask_names[3];
static std::vector< ShadingProgram* > mask_programs;
}; };
#endif // IMAGESHADER_H #endif // IMAGESHADER_H

View File

@@ -173,7 +173,6 @@ void MediaSurface::accept(Visitor& v)
FrameBufferSurface::FrameBufferSurface(FrameBuffer *fb, Shader *s) : Surface(s), frame_buffer_(fb) FrameBufferSurface::FrameBufferSurface(FrameBuffer *fb, Shader *s) : Surface(s), frame_buffer_(fb)
{ {
} }
void FrameBufferSurface::draw(glm::mat4 modelview, glm::mat4 projection) void FrameBufferSurface::draw(glm::mat4 modelview, glm::mat4 projection)

View File

@@ -109,52 +109,6 @@ SessionLoader::SessionLoader(Session *session): Visitor(), session_(session)
} }
//Source *SessionLoader::createSource(XMLElement *sourceNode)
//{
// // source to load
// Source *load_source = nullptr;
// // check if a source with the given id exists in the session
// uint64_t id__ = 0;
// sourceNode->QueryUnsigned64Attribute("id", &id__);
// SourceList::iterator sit = session_->find(id__);
// // no source with this id exists
// if ( sit == session_->end() ) {
// // create a new source depending on type
// const char *pType = sourceNode->Attribute("type");
// if (!pType)
// continue;
// if ( std::string(pType) == "MediaSource") {
// load_source = new MediaSource;
// }
// else if ( std::string(pType) == "SessionSource") {
// load_source = new SessionSource;
// }
// else if ( std::string(pType) == "RenderSource") {
// load_source = new RenderSource(session_);
// }
// else if ( std::string(pType) == "PatternSource") {
// load_source = new PatternSource;
// }
// else if ( std::string(pType) == "DeviceSource") {
// load_source = new DeviceSource;
// }
// // skip failed (including clones)
// if (!load_source)
// continue;
// // add source to session
// session_->addSource(load_source);
// }
// // get reference to the existing source
// else
// load_source = *sit;
// return load_source;
//}
void SessionLoader::load(XMLElement *sessionNode) void SessionLoader::load(XMLElement *sessionNode)
{ {
sources_id_.clear(); sources_id_.clear();
@@ -431,9 +385,24 @@ void SessionLoader::visit(ImageShader &n)
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms"); XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
if (uniforms) { if (uniforms) {
uniforms->QueryFloatAttribute("stipple", &n.stipple); uniforms->QueryFloatAttribute("stipple", &n.stipple);
uniforms->QueryUnsignedAttribute("mask", &n.mask);
} }
}
void SessionLoader::visit(MaskShader &n)
{
const char *pType = xmlCurrent_->Attribute("type");
if ( std::string(pType) != "MaskShader" )
return;
xmlCurrent_->QueryUnsignedAttribute("mode", &n.mode);
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
if (uniforms) {
uniforms->QueryFloatAttribute("blur", &n.blur);
XMLElement* size = uniforms->FirstChildElement("size");
if (size)
tinyxml2::XMLElementToGLM( size->FirstChildElement("vec2"), n.size);
}
} }
void SessionLoader::visit(ImageProcessingShader &n) void SessionLoader::visit(ImageProcessingShader &n)
@@ -474,24 +443,29 @@ void SessionLoader::visit (Source& s)
s.setName(pName); s.setName(pName);
xmlCurrent_ = sourceNode->FirstChildElement("Mixing"); xmlCurrent_ = sourceNode->FirstChildElement("Mixing");
s.groupNode(View::MIXING)->accept(*this); if (xmlCurrent_) s.groupNode(View::MIXING)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Geometry"); xmlCurrent_ = sourceNode->FirstChildElement("Geometry");
s.groupNode(View::GEOMETRY)->accept(*this); if (xmlCurrent_) s.groupNode(View::GEOMETRY)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Layer"); xmlCurrent_ = sourceNode->FirstChildElement("Layer");
s.groupNode(View::LAYER)->accept(*this); if (xmlCurrent_) s.groupNode(View::LAYER)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Appearance"); xmlCurrent_ = sourceNode->FirstChildElement("Appearance");
s.groupNode(View::APPEARANCE)->accept(*this); if (xmlCurrent_) s.groupNode(View::APPEARANCE)->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Blending"); xmlCurrent_ = sourceNode->FirstChildElement("Blending");
s.blendingShader()->accept(*this); if (xmlCurrent_) s.blendingShader()->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("Mask");
if (xmlCurrent_) s.maskShader()->accept(*this);
xmlCurrent_ = sourceNode->FirstChildElement("ImageProcessing"); xmlCurrent_ = sourceNode->FirstChildElement("ImageProcessing");
bool on = xmlCurrent_->BoolAttribute("enabled", true); if (xmlCurrent_) {
s.processingShader()->accept(*this); bool on = xmlCurrent_->BoolAttribute("enabled", true);
s.setImageProcessingEnabled(on); s.processingShader()->accept(*this);
s.setImageProcessingEnabled(on);
}
// restore current // restore current
xmlCurrent_ = sourceNode; xmlCurrent_ = sourceNode;

View File

@@ -41,6 +41,7 @@ public:
void visit (MediaPlayer& n) override; void visit (MediaPlayer& n) override;
void visit (Shader& n) override; void visit (Shader& n) override;
void visit (ImageShader& n) override; void visit (ImageShader& n) override;
void visit (MaskShader& n) override;
void visit (ImageProcessingShader& n) override; void visit (ImageProcessingShader& n) override;
// Sources // Sources

View File

@@ -203,9 +203,23 @@ void SessionVisitor::visit(ImageShader &n)
XMLElement *uniforms = xmlDoc_->NewElement("uniforms"); XMLElement *uniforms = xmlDoc_->NewElement("uniforms");
uniforms->SetAttribute("stipple", n.stipple); uniforms->SetAttribute("stipple", n.stipple);
uniforms->SetAttribute("mask", n.mask);
xmlCurrent_->InsertEndChild(uniforms); xmlCurrent_->InsertEndChild(uniforms);
}
void SessionVisitor::visit(MaskShader &n)
{
// Shader of a textured type
xmlCurrent_->SetAttribute("type", "MaskShader");
xmlCurrent_->SetAttribute("id", n.id());
xmlCurrent_->SetAttribute("mode", n.mode);
XMLElement *uniforms = xmlDoc_->NewElement("uniforms");
uniforms->SetAttribute("blur", n.blur);
XMLElement *size = xmlDoc_->NewElement("size");
size->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.size) );
uniforms->InsertEndChild(size);
xmlCurrent_->InsertEndChild(uniforms);
} }
void SessionVisitor::visit(ImageProcessingShader &n) void SessionVisitor::visit(ImageProcessingShader &n)
@@ -351,6 +365,10 @@ void SessionVisitor::visit (Source& s)
sourceNode->InsertEndChild(xmlCurrent_); sourceNode->InsertEndChild(xmlCurrent_);
s.blendingShader()->accept(*this); s.blendingShader()->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "Mask" );
sourceNode->InsertEndChild(xmlCurrent_);
s.maskShader()->accept(*this);
xmlCurrent_ = xmlDoc_->NewElement( "ImageProcessing" ); xmlCurrent_ = xmlDoc_->NewElement( "ImageProcessing" );
xmlCurrent_->SetAttribute("enabled", s.imageProcessingEnabled()); xmlCurrent_->SetAttribute("enabled", s.imageProcessingEnabled());
sourceNode->InsertEndChild(xmlCurrent_); sourceNode->InsertEndChild(xmlCurrent_);

View File

@@ -38,6 +38,7 @@ public:
void visit(MediaPlayer& n) override; void visit(MediaPlayer& n) override;
void visit(Shader& n) override; void visit(Shader& n) override;
void visit(ImageShader& n) override; void visit(ImageShader& n) override;
void visit(MaskShader& n) override;
void visit(ImageProcessingShader& n) override; void visit(ImageProcessingShader& n) override;
// Sources // Sources

View File

@@ -1,5 +1,6 @@
#include "Shader.h" #include "Shader.h"
#include "Resource.h" #include "Resource.h"
#include "FrameBuffer.h"
#include "Log.h" #include "Log.h"
#include "Visitor.h" #include "Visitor.h"
#include "RenderingManager.h" #include "RenderingManager.h"
@@ -119,14 +120,20 @@ void ShadingProgram::setUniform<float>(const std::string& name, float val1, floa
} }
template<> template<>
void ShadingProgram::setUniform<glm::vec4>(const std::string& name, glm::vec4 val) { void ShadingProgram::setUniform<glm::vec2>(const std::string& name, glm::vec2 val) {
glm::vec4 v(val); glm::vec2 v(val);
glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v)); glUniform2fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
} }
template<> template<>
void ShadingProgram::setUniform<glm::vec3>(const std::string& name, glm::vec3 val) { void ShadingProgram::setUniform<glm::vec3>(const std::string& name, glm::vec3 val) {
glm::vec3 v(val); glm::vec3 v(val);
glUniform3fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
}
template<>
void ShadingProgram::setUniform<glm::vec4>(const std::string& name, glm::vec4 val) {
glm::vec4 v(val);
glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v)); glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
} }
@@ -208,7 +215,7 @@ void Shader::use()
program_->setUniform("iTransform", iTransform); program_->setUniform("iTransform", iTransform);
program_->setUniform("color", color); program_->setUniform("color", color);
iResolution = glm::vec3( Rendering::manager().currentAttrib().viewport, 0.f); glm::vec3 iResolution = glm::vec3( Rendering::manager().currentAttrib().viewport, 0.f);
program_->setUniform("iResolution", iResolution); program_->setUniform("iResolution", iResolution);
// Blending Function // Blending Function
@@ -238,7 +245,6 @@ void Shader::reset()
projection = glm::identity<glm::mat4>(); projection = glm::identity<glm::mat4>();
modelview = glm::identity<glm::mat4>(); modelview = glm::identity<glm::mat4>();
iTransform = glm::identity<glm::mat4>(); iTransform = glm::identity<glm::mat4>();
iResolution = glm::vec3(1280.f, 720.f, 0.f);
color = glm::vec4(1.f, 1.f, 1.f, 1.f); color = glm::vec4(1.f, 1.f, 1.f, 1.f);
} }

View File

@@ -7,6 +7,7 @@
// Forward declare classes referenced // Forward declare classes referenced
class Visitor; class Visitor;
class FrameBuffer;
class ShadingProgram class ShadingProgram
{ {
@@ -22,13 +23,13 @@ public:
static void enduse(); static void enduse();
private: private:
void checkCompileErr(); void checkCompileErr();
void checkLinkingErr(); void checkLinkingErr();
void compile(); void compile();
void link(); void link();
unsigned int vertex_id_, fragment_id_, id_; unsigned int vertex_id_, fragment_id_, id_;
std::string vertex_code_; std::string vertex_code_;
std::string fragment_code_; std::string fragment_code_;
std::string vertex_file_; std::string vertex_file_;
std::string fragment_file_; std::string fragment_file_;
@@ -71,7 +72,6 @@ public:
protected: protected:
ShadingProgram *program_; ShadingProgram *program_;
glm::vec3 iResolution;
}; };

View File

@@ -179,12 +179,18 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo
// create objects // create objects
stored_status_ = new Group; stored_status_ = new Group;
// those will be associated to nodes later // simple image shader (with texturing) for blending
blendingshader_ = new ImageShader; blendingshader_ = new ImageShader;
// mask produced by dedicated shader
maskshader_ = new MaskShader;
masksurface_ = new Surface(maskshader_);
// filtered image shader (with texturing and processing) for rendering
processingshader_ = new ImageProcessingShader; processingshader_ = new ImageProcessingShader;
// default to image processing enabled // default rendering with image processing enabled
renderingshader_ = (Shader *) processingshader_; renderingshader_ = (Shader *) processingshader_;
// for drawing in mixing view
mixingshader_ = new ImageShader; mixingshader_ = new ImageShader;
mixingshader_->stipple = 1.0; mixingshader_->stipple = 1.0;
@@ -198,6 +204,7 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo
renderbuffer_ = nullptr; renderbuffer_ = nullptr;
rendersurface_ = nullptr; rendersurface_ = nullptr;
mixingsurface_ = nullptr; mixingsurface_ = nullptr;
maskbuffer_ = nullptr;
} }
@@ -213,6 +220,8 @@ Source::~Source()
delete stored_status_; delete stored_status_;
if (renderbuffer_) if (renderbuffer_)
delete renderbuffer_; delete renderbuffer_;
if (maskbuffer_)
delete maskbuffer_;
// all groups and their children are deleted in the scene // all groups and their children are deleted in the scene
// this includes rendersurface_, overlays, blendingshader_ and rendershader_ // this includes rendersurface_, overlays, blendingshader_ and rendershader_
@@ -368,6 +377,11 @@ void Source::attach(FrameBuffer *renderbuffer)
} }
} }
// (re) create the masking buffer
if (maskbuffer_)
delete maskbuffer_;
maskbuffer_ = new FrameBuffer( renderbuffer->resolution() );
// make the source visible // make the source visible
if ( mode_ == UNINITIALIZED ) if ( mode_ == UNINITIALIZED )
setMode(VISIBLE); setMode(VISIBLE);
@@ -410,7 +424,7 @@ void Source::update(float dt)
dt_ = dt; dt_ = dt;
// update nodes if needed // update nodes if needed
if (renderbuffer_ && mixingsurface_ && need_update_) if (renderbuffer_ && mixingsurface_ && maskbuffer_ && need_update_)
{ {
// Log::Info("UPDATE %s %f", initials_, dt); // Log::Info("UPDATE %s %f", initials_, dt);
@@ -472,9 +486,17 @@ void Source::update(float dt)
// 7. switch back to UV coordinate system // 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 = glm::inverse(UVtoScene) * glm::inverse(Sca) * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene;
// draw nask in mask frame buffer
maskbuffer_->begin();
masksurface_->draw(glm::identity<glm::mat4>(), maskbuffer_->projection());
maskbuffer_->end();
// set the rendered mask as mask for blending
blendingshader_->mask_texture = maskbuffer_->texture();
// do not update next frame // do not update next frame
need_update_ = false; need_update_ = false;
} }
} }
FrameBuffer *Source::frame() const FrameBuffer *Source::frame() const

View File

@@ -11,6 +11,7 @@
#define DEFAULT_MIXING_TRANSLATION -1.f, 1.f #define DEFAULT_MIXING_TRANSLATION -1.f, 1.f
class ImageShader; class ImageShader;
class MaskShader;
class ImageProcessingShader; class ImageProcessingShader;
class FrameBuffer; class FrameBuffer;
class FrameBufferSurface; class FrameBufferSurface;
@@ -77,6 +78,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_; }
// a Source has a shader used to render mask
inline MaskShader *maskShader () const { return maskshader_; }
// a Source has a shader used to render in fbo // a Source has a shader used to render in fbo
inline Shader *renderingShader () const { return renderingshader_; } inline Shader *renderingShader () const { return renderingshader_; }
@@ -171,6 +175,11 @@ protected:
ImageShader *blendingshader_; ImageShader *blendingshader_;
ImageShader *mixingshader_; ImageShader *mixingshader_;
// shader and buffer to draw mask
MaskShader *maskshader_;
FrameBuffer *maskbuffer_;
Surface *masksurface_;
// surface to draw on // surface to draw on
Surface *texturesurface_; Surface *texturesurface_;

View File

@@ -1976,7 +1976,7 @@ void Navigator::Render()
} }
if (ImGui::IsItemHovered()) if (ImGui::IsItemHovered())
about = "Layers [F3]"; about = "Layers [F3]";
if (ImGui::Selectable( ICON_FA_SIGN, &selected_view[4], 0, iconsize)) if (ImGui::Selectable( ICON_FA_VECTOR_SQUARE, &selected_view[4], 0, iconsize))
{ {
Mixer::manager().setView(View::APPEARANCE); Mixer::manager().setView(View::APPEARANCE);
view_pannel_visible = previous_view == Settings::application.current_view; view_pannel_visible = previous_view == Settings::application.current_view;

356
View.cpp
View File

@@ -823,14 +823,11 @@ void showContextMenu(View::Mode m, const char* label)
if (ImGui::BeginPopup(label)) { if (ImGui::BeginPopup(label)) {
Source *s = Mixer::manager().currentSource(); Source *s = Mixer::manager().currentSource();
if (s != nullptr) { if (s != nullptr) {
if (ImGui::Selectable( ICON_FA_CROSSHAIRS " Center" )){ if (ImGui::Selectable( ICON_FA_VECTOR_SQUARE " Reset" )){
s->group(m)->translation_ = glm::vec3(0.f);
s->touch();
}
else if (ImGui::Selectable( ICON_FA_VECTOR_SQUARE " Reset" )){
s->group(m)->scale_ = glm::vec3(1.f); s->group(m)->scale_ = glm::vec3(1.f);
s->group(m)->rotation_.z = 0; s->group(m)->rotation_.z = 0;
s->group(m)->crop_ = glm::vec3(1.f); s->group(m)->crop_ = glm::vec3(1.f);
s->group(m)->translation_ = glm::vec3(0.f);
s->touch(); s->touch();
} }
else if (ImGui::Selectable( ICON_FA_EXPAND " Fit" )){ else if (ImGui::Selectable( ICON_FA_EXPAND " Fit" )){
@@ -848,6 +845,10 @@ void showContextMenu(View::Mode m, const char* label)
s->group(m)->translation_ = glm::vec3(0.f); s->group(m)->translation_ = glm::vec3(0.f);
s->touch(); s->touch();
} }
else if (ImGui::Selectable( ICON_FA_CROSSHAIRS " Center" )){
s->group(m)->translation_ = glm::vec3(0.f);
s->touch();
}
else if (ImGui::Selectable( ICON_FA_PERCENTAGE " Original aspect ratio" )){ //ICON_FA_ARROWS_ALT_H else if (ImGui::Selectable( ICON_FA_PERCENTAGE " Original aspect ratio" )){ //ICON_FA_ARROWS_ALT_H
s->group(m)->scale_.x = s->group(m)->scale_.y; s->group(m)->scale_.x = s->group(m)->scale_.y;
s->group(m)->scale_ *= s->group(m)->crop_; s->group(m)->scale_ *= s->group(m)->crop_;
@@ -1853,6 +1854,7 @@ AppearanceView::AppearanceView() : View(APPEARANCE), edit_source_(nullptr), need
else else
restoreSettings(); restoreSettings();
//
// Scene background // Scene background
// //
// global dark // global dark
@@ -1860,62 +1862,108 @@ AppearanceView::AppearanceView() : View(APPEARANCE), edit_source_(nullptr), need
tmp->scale_ = glm::vec3(20.f, 20.f, 1.f); tmp->scale_ = glm::vec3(20.f, 20.f, 1.f);
tmp->shader()->color = glm::vec4( 0.1f, 0.1f, 0.1f, 0.6f ); tmp->shader()->color = glm::vec4( 0.1f, 0.1f, 0.1f, 0.6f );
scene.bg()->attach(tmp); scene.bg()->attach(tmp);
// frame showing the source original shape // frame showing the source original shape
backgroundchecker_ = new ImageSurface("images/checker.dds"); background_surface_= new Surface( new Shader);
background_surface_->scale_ = glm::vec3(20.f, 20.f, 1.f);
background_surface_->shader()->color = glm::vec4( COLOR_BGROUND, 1.0f );
scene.bg()->attach(background_surface_);
background_frame_ = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
background_frame_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 0.6f );
scene.bg()->attach(background_frame_);
// frame with checkerboard background to show cropped preview
preview_checker_ = new ImageSurface("images/checker.dds");
static glm::mat4 Tra = glm::scale(glm::translate(glm::identity<glm::mat4>(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f)); static glm::mat4 Tra = glm::scale(glm::translate(glm::identity<glm::mat4>(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f));
backgroundchecker_->shader()->iTransform = Tra; preview_checker_->shader()->iTransform = Tra;
scene.bg()->attach(backgroundchecker_); scene.bg()->attach(preview_checker_);
backgroundframe_ = new Frame(Frame::SHARP, Frame::THIN, Frame::GLOW); preview_frame_ = new Frame(Frame::SHARP, Frame::THIN, Frame::GLOW);
backgroundframe_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f ); preview_frame_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f );
scene.bg()->attach(backgroundframe_); scene.bg()->attach(preview_frame_);
// Horizontal axis
horizontal_line_ = new Mesh("mesh/h_line.ply");
horizontal_line_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
horizontal_line_->translation_ = glm::vec3(0.f, 1.12f, 0.0f);
horizontal_line_->scale_.x = 1.0f;
horizontal_line_->scale_.y = 3.0f;
scene.bg()->attach(horizontal_line_);
show_horizontal_scale_ = false;
horizontal_mark_ = new Mesh("mesh/h_mark.ply");
horizontal_mark_->translation_ = glm::vec3(0.f, 1.12f, 0.0f);
horizontal_mark_->scale_ = glm::vec3(2.5f, -2.5f, 0.0f);
horizontal_mark_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
scene.bg()->attach(horizontal_mark_);
// vertical axis
vertical_line_ = new Group;
Mesh *line = new Mesh("mesh/h_line.ply");
line->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
line->translation_ = glm::vec3(-0.12f, 0.0f, 0.0f);
line->scale_.x = 1.0f;
line->scale_.y = 3.0f;
line->rotation_.z = M_PI_2;
vertical_line_->attach(line);
vertical_mark_ = new Mesh("mesh/h_mark.ply");
vertical_mark_->translation_ = glm::vec3(-0.12f, 0.0f, 0.0f);
vertical_mark_->scale_ = glm::vec3(2.5f, -2.5f, 0.0f);
vertical_mark_->rotation_.z = M_PI_2;
vertical_mark_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
vertical_line_->attach(vertical_mark_);
scene.bg()->attach(vertical_line_);
//
// surface to show the texture of the source // surface to show the texture of the source
surfacepreview = new Surface; // to attach source preview //
surfacepreview->translation_.z = 0.002f; preview_shader_ = new ImageShader;
scene.bg()->attach(surfacepreview); preview_surface_ = new Surface(preview_shader_); // to attach source preview
preview_surface_->translation_.z = 0.002f;
scene.bg()->attach(preview_surface_);
// // Horizontal axis
// horizontal_line_ = new Mesh("mesh/h_line.ply");
// horizontal_line_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
// horizontal_line_->translation_ = glm::vec3(0.f, 1.12f, 0.0f);
// horizontal_line_->scale_.x = 1.0f;
// horizontal_line_->scale_.y = 3.0f;
//// scene.bg()->attach(horizontal_line_);
// show_horizontal_scale_ = false;
// horizontal_mark_ = new Mesh("mesh/h_mark.ply");
// horizontal_mark_->translation_ = glm::vec3(0.f, 1.12f, 0.0f);
// horizontal_mark_->scale_ = glm::vec3(2.5f, -2.5f, 0.0f);
// horizontal_mark_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
//// scene.bg()->attach(horizontal_mark_);
// // vertical axis
// vertical_line_ = new Group;
// Mesh *line = new Mesh("mesh/h_line.ply");
// line->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
// line->translation_ = glm::vec3(-0.12f, 0.0f, 0.0f);
// line->scale_.x = 1.0f;
// line->scale_.y = 3.0f;
// line->rotation_.z = M_PI_2;
//// vertical_line_->attach(line);
// vertical_mark_ = new Mesh("mesh/h_mark.ply");
// vertical_mark_->translation_ = glm::vec3(-0.12f, 0.0f, 0.0f);
// vertical_mark_->scale_ = glm::vec3(2.5f, -2.5f, 0.0f);
// vertical_mark_->rotation_.z = M_PI_2;
// vertical_mark_->shader()->color = glm::vec4( COLOR_TRANSITION_LINES, 0.9f );
// vertical_line_->attach(vertical_mark_);
//// scene.bg()->attach(vertical_line_);
/// Tests
// test_buffer = new FrameBuffer(800, 450);
// Log::Info("test_buffer %s", test_buffer->info().c_str());
// test_shader = new MaskShader;
// test_shader->type = 0;
// test_shader->blur = 0.0;
// test_surface = new Surface(test_shader);
// preview_mask_ = new FrameBufferSurface(test_buffer); // to attach source preview
// preview_mask_->translation_.z = 0.002f;
//// scene.bg()->attach(preview_mask_);
// Scene foreground // Scene foreground
// //
// crop icons // // crop icons
crop_horizontal_ = new Symbol(Symbol::ARROWS); // crop_horizontal_ = new Symbol(Symbol::ARROWS);
crop_horizontal_->translation_ = glm::vec3(1.0f, 1.12f, 0.f); // crop_horizontal_->translation_ = glm::vec3(1.0f, 1.12f, 0.f);
scene.fg()->attach(crop_horizontal_); //// scene.fg()->attach(crop_horizontal_);
crop_vertical_ = new Symbol(Symbol::ARROWS); // crop_vertical_ = new Symbol(Symbol::ARROWS);
crop_vertical_->rotation_.z = M_PI_2; // crop_vertical_->rotation_.z = M_PI_2;
crop_vertical_->translation_ = glm::vec3(-1.12f, -1.0f, 0.f); // crop_vertical_->translation_ = glm::vec3(-1.12f, -1.0f, 0.f);
scene.fg()->attach(crop_vertical_); //// scene.fg()->attach(crop_vertical_);
//
// User interface foreground // User interface foreground
// //
// Mask manipulation
mask_node_ = new Group;
mask_square_ = new Frame(Frame::SHARP, Frame::LARGE, Frame::NONE);
mask_square_->color = glm::vec4( 0.2f, 1.f, 1.f, 1.0f ); //BLUE
mask_node_->attach(mask_square_);
mask_handle_ = new Handles(Handles::CROP);
mask_handle_->color = glm::vec4( 0.2f, 1.f, 1.f, 1.0f ); //BLUE
mask_node_->attach(mask_handle_);
mask_circle_ = new Mesh("mesh/circle.ply");
mask_circle_->shader()->color = glm::vec4( 0.2f, 1.f, 1.f, 1.0f );
mask_node_->attach(mask_circle_);
mask_corner_ = new Mesh("mesh/corner.ply");
mask_corner_->shader()->color = glm::vec4( 0.2f, 1.f, 1.f, 0.9f );
mask_corner_->translation_ = glm::vec3(-1.f, -1.0f, 0.0f);
mask_node_->attach(mask_corner_);
scene.fg()->attach(mask_node_);
// Source manipulation (texture coordinates)
//
// point to show POSITION // point to show POSITION
overlay_position_ = new Symbol(Symbol::SQUARE_POINT); overlay_position_ = new Symbol(Symbol::SQUARE_POINT);
overlay_position_->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f ); overlay_position_->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f );
@@ -2081,7 +2129,11 @@ std::pair<Node *, glm::vec2> AppearanceView::pick(glm::vec2 P)
pick = *itp; pick = *itp;
break; break;
} }
else if ( (*itp).first == crop_horizontal_ || (*itp).first == crop_vertical_ ) { // else if ( (*itp).first == crop_horizontal_ || (*itp).first == crop_vertical_ ) {
// pick = *itp;
// break;
// }
else if ( (*itp).first == mask_handle_ ) {
pick = *itp; pick = *itp;
break; break;
} }
@@ -2110,36 +2162,63 @@ std::pair<Node *, glm::vec2> AppearanceView::pick(glm::vec2 P)
void AppearanceView::adjustBackground() void AppearanceView::adjustBackground()
{ {
// by default consider edit source is null // by default consider edit source is null
mask_node_->visible_ = false;
float image_original_width = 1.f; float image_original_width = 1.f;
// glm::vec2 image_crop_area = glm::vec2(1.f, 1.f); glm::vec3 scale = glm::vec3(1.f);
surfacepreview->setTextureIndex( Resource::getTextureTransparent() ); preview_surface_->setTextureIndex( Resource::getTextureTransparent() );
// if its a valid index // if its a valid index
if (edit_source_ != nullptr) { if (edit_source_ != nullptr) {
// update rendering frame to match edit source AR // update rendering frame to match edit source AR
image_original_width = edit_source_->frame()->aspectRatio(); image_original_width = edit_source_->frame()->aspectRatio();
surfacepreview->setTextureIndex( edit_source_->frame()->texture() ); scale = edit_source_->mixingsurface_->scale_;
surfacepreview->scale_ = edit_source_->mixingsurface_->scale_;
preview_surface_->setTextureIndex( edit_source_->frame()->texture() );
preview_shader_->mask_texture = edit_source_->blendingShader()->mask_texture;
preview_surface_->scale_ = scale;
mask_node_->visible_ = edit_source_->maskShader()->mode > 0;
mask_circle_->visible_ = edit_source_->maskShader()->mode == 1;
mask_square_->visible_ = edit_source_->maskShader()->mode == 2;
mask_node_->scale_ = scale * glm::vec3(edit_source_->maskShader()->size, 1.f);
mask_corner_->scale_.y = mask_node_->scale_.x / mask_node_->scale_.y;
// crop_horizontal_->translation_.x = image_original_width * edit_source_->maskShader()->size.x;
// crop_vertical_->translation_.y = -edit_source_->maskShader()->size.y;
// crop_vertical_->translation_.x = -image_original_width - 0.12f;
///// Tests
// preview_mask_->scale_ = edit_source_->mixingsurface_->scale_;
// surfacepreview->scale_.x = image_original_width;
// image_crop_area.x *= image_original_width;
} }
// update objects in the scene to represent the image and crop area
// /// Tests
// // update mask
// test_buffer->begin();
// test_surface->draw(glm::identity<glm::mat4>(), test_buffer->projection());
// test_buffer->end();
// background scene // background scene
horizontal_line_->scale_.x = image_original_width; // horizontal_line_->scale_.x = image_original_width;
vertical_line_->translation_.x = -image_original_width; // vertical_line_->translation_.x = -image_original_width;
backgroundframe_->scale_.x = image_original_width;
backgroundchecker_->scale_.x = image_original_width;
glm::mat4 Ar = glm::scale(glm::identity<glm::mat4>(), glm::vec3(image_original_width, 1.f, 1.f) );
static glm::mat4 Tra = glm::scale(glm::translate(glm::identity<glm::mat4>(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f));
backgroundchecker_->shader()->iTransform = Ar * Tra;
// foreground background_surface_->scale_.x = image_original_width;
// crop_horizontal_->translation_.x = image_crop_area.x; background_surface_->scale_.y = 1.f;
// crop_vertical_->translation_.y = -image_crop_area.y; background_frame_->scale_.x = image_original_width;
// crop_vertical_->translation_.x = -image_original_width - 0.12f; preview_frame_->scale_ = scale;
preview_checker_->scale_ = scale;
glm::mat4 Ar = glm::scale(glm::identity<glm::mat4>(), scale );
static glm::mat4 Tra = glm::scale(glm::translate(glm::identity<glm::mat4>(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f));
preview_checker_->shader()->iTransform = Ar * Tra;
// backgroundchecker_->scale_.x = image_original_width;
// glm::mat4 Ar = glm::scale(glm::identity<glm::mat4>(), glm::vec3(image_original_width, 1.f, 1.f) );
// static glm::mat4 Tra = glm::scale(glm::translate(glm::identity<glm::mat4>(), glm::vec3( -32.f, -32.f, 0.f)), glm::vec3( 64.f, 64.f, 1.f));
// backgroundchecker_->shader()->iTransform = Ar * Tra;
} }
@@ -2203,19 +2282,55 @@ void AppearanceView::draw()
// } // }
// } // }
// draw general view // draw general view
Shader::force_blending_opacity = true; Shader::force_blending_opacity = true;
View::draw(); View::draw();
Shader::force_blending_opacity = false; Shader::force_blending_opacity = false;
// force to redraw the frame of the edit source (even if source is not visible) // if source active
if (edit_source_ != nullptr){ if (edit_source_ != nullptr){
// force to redraw the frame of the edit source (even if source is not visible)
DrawVisitor dv(edit_source_->frames_[mode_], Rendering::manager().Projection(), true); DrawVisitor dv(edit_source_->frames_[mode_], Rendering::manager().Projection(), true);
scene.accept(dv); scene.accept(dv);
// display interface
glm::vec2 P = Rendering::manager().project(glm::vec3(-background_frame_->scale_.x - 0.03f, 1.2f, 0.f), scene.root()->transform_, false);
ImGui::SetNextWindowPos(ImVec2(P.x, P.y), ImGuiCond_Always);
if (ImGui::Begin("##AppearanceMaskOptions", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground
| ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings
| ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav))
{
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE);
int type = edit_source_->maskShader()->mode;
ImGui::SetNextItemWidth(100.f);
if ( ImGui::Combo("Mask ", &type, MaskShader::mask_names, IM_ARRAYSIZE(MaskShader::mask_names) ) ) {
edit_source_->maskShader()->mode = type;
edit_source_->touch();
need_edit_update_ = true;
}
if (edit_source_->maskShader()->mode > 0) {
int val = int(edit_source_->maskShader()->blur * 100.f);
ImGui::SameLine();
ImGui::SetNextItemWidth(190.f);
if (ImGui::DragInt("Smooth", &val, 1, 0, 100, "%d%%") ) {
edit_source_->maskShader()->blur = float(val) / 100.f;
edit_source_->touch();
need_edit_update_ = true;
}
}
ImGui::PopFont();
ImGui::End();
}
} }
show_vertical_scale_ = false; // show_vertical_scale_ = false;
show_horizontal_scale_ = false; // show_horizontal_scale_ = false;
// display popup menu // display popup menu
if (show_context_menu_) { if (show_context_menu_) {
@@ -2224,6 +2339,7 @@ void AppearanceView::draw()
} }
showContextMenu(mode_,"AppearanceContextMenu"); showContextMenu(mode_,"AppearanceContextMenu");
} }
View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
@@ -2241,44 +2357,70 @@ View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std:
// work on the edited source // work on the edited source
if ( edit_source_ != nullptr ) { if ( edit_source_ != nullptr ) {
// picking on the resizing handles in the corners // match edit source AR
if ( pick.first == crop_horizontal_ ) { // float image_original_width = edit_source_->frame()->aspectRatio();
float max_width = edit_source_->frame()->aspectRatio(); glm::vec3 scale = edit_source_->mixingsurface_->scale_;
// discretized scaling with ALT glm::vec3 delta = glm::vec3(0.1) / glm::vec3(scene.root()->scale_.x, scene.root()->scale_.y, 1.0);
float val = scene_to.x;
if (UserInterface::manager().altModifier()) { if ( pick.first == mask_handle_ ) {
val = ROUND(val, 5.f); // compute scaling of mask
show_horizontal_scale_ = true; glm::vec3 val = -scene_to + delta;
} val /= scale;
// crop horizontally
// edit_source_->texturesurface_->scale_.x = CLAMP(val, 0.2f, max_width) / max_width;
// edit_source_->touch();
// // update background and frame
// adjustBackground();
// // cursor indication
// info << "Crop " << std::fixed << std::setprecision(3) << max_width * edit_source_->texturesurface_->scale_.x;
// info << " x " << edit_source_->texturesurface_->scale_.y;
ret.type = Cursor_ResizeEW;
}
if ( pick.first == crop_vertical_ ) {
float max_width = edit_source_->frame()->aspectRatio();
float val = -scene_to.y;
// discretized scaling with ALT // discretized scaling with ALT
if (UserInterface::manager().altModifier()) { if (UserInterface::manager().altModifier()) {
val = ROUND(val, 5.f); val.x = ROUND(val.x, 5.f);
show_vertical_scale_ = true; val.y = ROUND(val.y, 5.f);
} }
// crop vertically // crop mask horizontally
// edit_source_->texturesurface_->scale_.y = CLAMP(val, 0.2f, 1.0f); edit_source_->maskShader()->size.x = CLAMP(val.x, 0.3f, 2.f);
// edit_source_->touch(); edit_source_->maskShader()->size.y = CLAMP(val.y, 0.3f, 2.f);
// // update background and frame edit_source_->touch();
// adjustBackground(); // update
// // cursor indication need_edit_update_ = true;
// info << "Crop " << std::fixed << std::setprecision(3) << max_width * edit_source_->texturesurface_->scale_.x ; // cursor indication
// info << " x " << edit_source_->texturesurface_->scale_.y; info << "Mask " << std::fixed << std::setprecision(3) << edit_source_->maskShader()->size.x;
ret.type = Cursor_ResizeNS; info << " x " << edit_source_->maskShader()->size.y;
ret.type = Cursor_ResizeNESW;
} }
// // picking on the resizing handles in the corners
// if ( pick.first == crop_horizontal_ ) {
// float max_width = edit_source_->frame()->aspectRatio();
// // discretized scaling with ALT
// float val = scene_to.x;
// if (UserInterface::manager().altModifier()) {
// val = ROUND(val, 5.f);
// show_horizontal_scale_ = true;
// }
// // crop mask horizontally
// edit_source_->maskShader()->size.x = CLAMP(val, 0.2f, max_width) / max_width;
// edit_source_->touch();
// // update
// need_edit_update_ = true;
// // cursor indication
// info << "Mask " << std::fixed << std::setprecision(3) << max_width * edit_source_->maskShader()->size.x;
// info << " x " << edit_source_->maskShader()->size.y;
// ret.type = Cursor_ResizeEW;
// }
// if ( pick.first == crop_vertical_ ) {
// float max_width = edit_source_->frame()->aspectRatio();
// float val = -scene_to.y;
// // discretized scaling with ALT
// if (UserInterface::manager().altModifier()) {
// val = ROUND(val, 5.f);
// show_vertical_scale_ = true;
// }
// // crop mask vertically
// edit_source_->maskShader()->size.y = CLAMP(val, 0.2f, 1.0f);
// edit_source_->touch();
// // update
// need_edit_update_ = true;
// // cursor indication
// info << "Mask " << std::fixed << std::setprecision(3) << max_width * edit_source_->maskShader()->size.x ;
// info << " x " << edit_source_->maskShader()->size.y;
// ret.type = Cursor_ResizeNS;
// }
// store action in history // store action in history
current_action_ = edit_source_->name() + ": " + info.str(); current_action_ = edit_source_->name() + ": " + info.str();
current_id_ = edit_source_->id(); current_id_ = edit_source_->id();

40
View.h
View File

@@ -249,17 +249,35 @@ private:
Source *getEditOrCurrentSource(); Source *getEditOrCurrentSource();
void adjustBackground(); void adjustBackground();
Surface *surfacepreview;
Surface *backgroundchecker_; // /// tests
Frame *backgroundframe_; // Surface *preview_mask_;
Mesh *horizontal_line_; // Surface *test_surface;
Mesh *horizontal_mark_; // class MaskShader *test_shader;
bool show_horizontal_scale_; // FrameBuffer *test_buffer;
Group *vertical_line_;
Mesh *vertical_mark_;
bool show_vertical_scale_; Surface *preview_surface_;
Symbol *crop_horizontal_; class ImageShader *preview_shader_;
Symbol *crop_vertical_; Surface *preview_checker_;
Frame *preview_frame_;
Surface *background_surface_;
Frame *background_frame_;
// Mesh *horizontal_line_;
// Mesh *horizontal_mark_;
// bool show_horizontal_scale_;
// Group *vertical_line_;
// Mesh *vertical_mark_;
// bool show_vertical_scale_;
// Symbol *crop_horizontal_;
// Symbol *crop_vertical_;
Group *mask_node_;
Frame *mask_square_;
Mesh *mask_circle_;
Mesh *mask_corner_;
class Handles *mask_handle_;
Symbol *overlay_position_; Symbol *overlay_position_;
Symbol *overlay_position_cross_; Symbol *overlay_position_cross_;
Symbol *overlay_scaling_; Symbol *overlay_scaling_;

View File

@@ -25,6 +25,7 @@ class Stream;
class MediaPlayer; class MediaPlayer;
class Shader; class Shader;
class ImageShader; class ImageShader;
class MaskShader;
class ImageProcessingShader; class ImageProcessingShader;
class Source; class Source;
class MediaSource; class MediaSource;
@@ -64,6 +65,7 @@ public:
virtual void visit (MediaPlayer&) {} virtual void visit (MediaPlayer&) {}
virtual void visit (Shader&) {} virtual void visit (Shader&) {}
virtual void visit (ImageShader&) {} virtual void visit (ImageShader&) {}
virtual void visit (MaskShader&) {}
virtual void visit (ImageProcessingShader&) {} virtual void visit (ImageProcessingShader&) {}
// utility // utility

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -7,7 +7,7 @@ in vec2 vertexUV;
// from General Shader // from General Shader
uniform vec3 iResolution; // viewport image resolution (in pixels) uniform vec3 iResolution; // viewport image resolution (in pixels)
uniform mat4 iTransform; // UV image transformation uniform mat4 iTransform; // image transformation
uniform vec4 color; uniform vec4 color;
uniform vec4 uv; uniform vec4 uv;