Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5262b8ae29 | ||
|
|
1028aeea9f | ||
|
|
e02071047a | ||
|
|
227658d2fc | ||
|
|
56dc299fc9 | ||
|
|
f7e1ff14d9 | ||
|
|
9e865b3677 | ||
|
|
e4da7de06f | ||
|
|
67f45793da | ||
|
|
5a2949609e | ||
|
|
f20597656e | ||
|
|
aaf700baba | ||
|
|
a3e121d6a0 | ||
|
|
d3269e8aaa | ||
|
|
b9104df26e | ||
|
|
717f560326 | ||
|
|
6fdb93a020 | ||
|
|
767b0d8084 | ||
|
|
52eb9284f7 | ||
|
|
c355486955 | ||
|
|
0e8f87d6c6 | ||
|
|
dbd3c071e8 | ||
|
|
398995648a | ||
|
|
3fc9401d97 | ||
|
|
d31320ae4b | ||
|
|
fe54afbe1c | ||
|
|
6b5ccb4450 | ||
|
|
805baa75f4 | ||
|
|
b1dd2f0bc9 | ||
|
|
f8e926040a | ||
|
|
11690dfb8c | ||
|
|
63369223ca | ||
|
|
a1e81b58b1 | ||
|
|
cf2b6b4b39 | ||
|
|
c4e584a1da | ||
|
|
25b58b76f3 | ||
|
|
b346403887 | ||
|
|
e0cd560dfb | ||
|
|
4313e51530 | ||
|
|
e2bb90208e | ||
|
|
85d72a1c0e | ||
|
|
a073ab41dd | ||
|
|
34c24d99df | ||
|
|
69d9d9473b | ||
|
|
a58c06c617 | ||
|
|
b7a54d0512 | ||
|
|
1677582034 | ||
|
|
44b888fd04 | ||
|
|
78f9216d32 | ||
|
|
1ea0ec53af | ||
|
|
688823e63f |
2
.gitignore
vendored
@@ -16,3 +16,5 @@ rules.ninja
|
||||
/vmix
|
||||
/vimix_*.snap
|
||||
/CMakeLists.txt.user.*
|
||||
|
||||
rsc/shaders/paint.fs
|
||||
|
||||
@@ -91,6 +91,10 @@ set(THREAD_LIBRARY Threads::Threads)
|
||||
find_package(PNG REQUIRED)
|
||||
set(PNG_LIBRARY PNG::PNG)
|
||||
|
||||
find_package(ICU REQUIRED COMPONENTS i18n io uc)
|
||||
macro_log_feature(ICU_FOUND "ICU" "International Components for Unicode" "http://site.icu-project.org" TRUE)
|
||||
|
||||
|
||||
#
|
||||
# GLFW3
|
||||
# NB: set glfw3_PATH to /usr/local/Cellar/glfw/3.3.2/lib/cmake/glfw3
|
||||
@@ -227,6 +231,7 @@ include_directories(
|
||||
${STB_INCLUDE_DIR}
|
||||
${DIRENT_INCLUDE_DIR}
|
||||
${OSCPACK_INCLUDE_DIR}
|
||||
${ICU_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
||||
@@ -290,6 +295,12 @@ set(VMIX_RSC_FILES
|
||||
./rsc/shaders/simple.fs
|
||||
./rsc/shaders/simple.vs
|
||||
./rsc/shaders/image.fs
|
||||
./rsc/shaders/mask_elipse.fs
|
||||
./rsc/shaders/mask_box.fs
|
||||
./rsc/shaders/mask_round.fs
|
||||
./rsc/shaders/mask_horizontal.fs
|
||||
./rsc/shaders/mask_vertical.fs
|
||||
./rsc/shaders/mask_draw.fs
|
||||
./rsc/shaders/image.vs
|
||||
./rsc/shaders/imageprocessing.fs
|
||||
./rsc/fonts/Hack-Regular.ttf
|
||||
@@ -321,6 +332,7 @@ set(VMIX_RSC_FILES
|
||||
./rsc/images/soft_shadow.dds
|
||||
./rsc/mesh/disk.ply
|
||||
./rsc/mesh/circle.ply
|
||||
./rsc/mesh/corner.ply
|
||||
./rsc/mesh/shadow.ply
|
||||
./rsc/mesh/glow.ply
|
||||
./rsc/mesh/border_round.ply
|
||||
@@ -334,10 +346,13 @@ set(VMIX_RSC_FILES
|
||||
./rsc/mesh/border_handles_overlay_filled.ply
|
||||
./rsc/mesh/border_handles_sharp.ply
|
||||
./rsc/mesh/border_handles_menu.ply
|
||||
./rsc/mesh/border_handles_crop.ply
|
||||
./rsc/mesh/border_handles_shadow.ply
|
||||
./rsc/mesh/border_large_sharp.ply
|
||||
./rsc/mesh/border_vertical_overlay.ply
|
||||
./rsc/mesh/perspective_layer.ply
|
||||
./rsc/mesh/perspective_axis_left.ply
|
||||
./rsc/mesh/perspective_axis_right.ply
|
||||
./rsc/mesh/shadow_perspective.ply
|
||||
./rsc/mesh/point.ply
|
||||
./rsc/mesh/square_point.ply
|
||||
@@ -361,6 +376,7 @@ set(VMIX_RSC_FILES
|
||||
./rsc/mesh/icon_clock_hand.ply
|
||||
./rsc/mesh/icon_grid.ply
|
||||
./rsc/mesh/icon_rightarrow.ply
|
||||
./rsc/mesh/icon_crop.ply
|
||||
./rsc/mesh/h_line.ply
|
||||
./rsc/mesh/h_mark.ply
|
||||
)
|
||||
@@ -438,6 +454,9 @@ target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
|
||||
IMGUI
|
||||
OSCPACK
|
||||
vmix::rc
|
||||
ICU::i18n
|
||||
ICU::io
|
||||
ICU::uc
|
||||
${PLATFORM_LIBS}
|
||||
)
|
||||
|
||||
|
||||
@@ -159,10 +159,10 @@ Handles::Handles(Type type) : Node(), type_(type)
|
||||
static Mesh *handle_rotation = new Mesh("mesh/border_handles_rotation.ply");
|
||||
static Mesh *handle_corner = new Mesh("mesh/border_handles_overlay.ply");
|
||||
static Mesh *handle_scale = new Mesh("mesh/border_handles_scale.ply");
|
||||
static Mesh *handle_restore = new Mesh("mesh/border_handles_menu.ply");
|
||||
static Mesh *handle_crop = new Mesh("mesh/border_handles_crop.ply");
|
||||
static Mesh *handle_menu = new Mesh("mesh/border_handles_menu.ply");
|
||||
static Mesh *handle_shadow = new Mesh("mesh/border_handles_shadow.ply", "images/soft_shadow.dds");
|
||||
|
||||
color = glm::vec4( 1.f, 1.f, 0.f, 1.f);
|
||||
if ( type_ == Handles::ROTATE ) {
|
||||
handle_ = handle_rotation;
|
||||
}
|
||||
@@ -170,14 +170,17 @@ Handles::Handles(Type type) : Node(), type_(type)
|
||||
handle_ = handle_scale;
|
||||
}
|
||||
else if ( type_ == Handles::MENU ) {
|
||||
handle_ = handle_restore;
|
||||
handle_ = handle_menu;
|
||||
}
|
||||
else if ( type_ == Handles::CROP ) {
|
||||
handle_ = handle_crop;
|
||||
}
|
||||
else {
|
||||
handle_ = handle_corner;
|
||||
}
|
||||
|
||||
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
|
||||
corner_ = glm::vec2(0.f, 0.f);
|
||||
|
||||
shadow_ = handle_shadow;
|
||||
}
|
||||
|
||||
@@ -207,6 +210,7 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
|
||||
// set color
|
||||
handle_->shader()->color = color;
|
||||
handle_active->shader()->color = color;
|
||||
|
||||
// extract rotation from modelview
|
||||
glm::mat4 ctm;
|
||||
@@ -300,6 +304,18 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
shadow_->draw( ctm, projection );
|
||||
handle_->draw( ctm, projection );
|
||||
}
|
||||
else if ( type_ == Handles::CROP ){
|
||||
// one icon in bottom right corner
|
||||
// 1. Fixed displacement by (0.12,0.12) along the rotation..
|
||||
ctm = GlmToolkit::transform(glm::vec4(0.f), rot, mirror);
|
||||
glm::vec4 pos = ctm * glm::vec4(mirror.x * 0.12f, mirror.x * 0.12f, 0.f, 1.f);
|
||||
// 2. ..from the bottom right corner (1,1)
|
||||
vec = ( modelview * glm::vec4(-1.f, -1.f, 0.f, 1.f) ) + pos;
|
||||
ctm = GlmToolkit::transform(vec, rot, glm::vec3(mirror.x, mirror.y, 1.f));
|
||||
// 3. draw
|
||||
shadow_->draw( ctm, projection );
|
||||
handle_->draw( ctm, projection );
|
||||
}
|
||||
else if ( type_ == Handles::MENU ){
|
||||
// one icon in top left corner
|
||||
// 1. Fixed displacement by (-0.12,0.12) along the rotation..
|
||||
@@ -325,36 +341,59 @@ void Handles::accept(Visitor& v)
|
||||
|
||||
Symbol::Symbol(Type t, glm::vec3 pos) : Node(), type_(t)
|
||||
{
|
||||
static Mesh *shadow= new Mesh("mesh/border_handles_shadow.ply", "images/soft_shadow.dds");
|
||||
static Mesh *shadows[(int)EMPTY+1] = {nullptr};
|
||||
static Mesh *icons[(int)EMPTY+1] = {nullptr};
|
||||
if (icons[0] == nullptr) {
|
||||
icons[CIRCLE_POINT] = new Mesh("mesh/point.ply");
|
||||
shadows[CIRCLE_POINT] = nullptr;
|
||||
icons[SQUARE_POINT] = new Mesh("mesh/square_point.ply");
|
||||
icons[IMAGE] = new Mesh("mesh/icon_image.ply");
|
||||
icons[VIDEO] = new Mesh("mesh/icon_video.ply");
|
||||
icons[SESSION] = new Mesh("mesh/icon_vimix.ply");
|
||||
icons[CLONE] = new Mesh("mesh/icon_clone.ply");
|
||||
icons[RENDER] = new Mesh("mesh/icon_render.ply");
|
||||
icons[PATTERN] = new Mesh("mesh/icon_gear.ply");
|
||||
icons[CAMERA] = new Mesh("mesh/icon_camera.ply");
|
||||
icons[SHARE] = new Mesh("mesh/icon_share.ply");
|
||||
icons[DOTS] = new Mesh("mesh/icon_dots.ply");
|
||||
icons[BUSY] = new Mesh("mesh/icon_circles.ply");
|
||||
icons[LOCK] = new Mesh("mesh/icon_lock.ply");
|
||||
icons[UNLOCK] = new Mesh("mesh/icon_unlock.ply");
|
||||
icons[CROP] = new Mesh("mesh/icon_rightarrow.ply");
|
||||
icons[CIRCLE] = new Mesh("mesh/icon_circle.ply");
|
||||
icons[CLOCK] = new Mesh("mesh/icon_clock.ply");
|
||||
icons[CLOCK_H] = new Mesh("mesh/icon_clock_hand.ply");
|
||||
icons[SQUARE] = new Mesh("mesh/icon_square.ply");
|
||||
icons[CROSS] = new Mesh("mesh/icon_cross.ply");
|
||||
icons[GRID] = new Mesh("mesh/icon_grid.ply");
|
||||
icons[EMPTY] = new Mesh("mesh/icon_empty.ply");
|
||||
shadows[SQUARE_POINT] = nullptr;
|
||||
icons[IMAGE] = new Mesh("mesh/icon_image.ply");
|
||||
shadows[IMAGE] = shadow;
|
||||
icons[VIDEO] = new Mesh("mesh/icon_video.ply");
|
||||
shadows[VIDEO] = shadow;
|
||||
icons[SESSION] = new Mesh("mesh/icon_vimix.ply");
|
||||
shadows[SESSION]= shadow;
|
||||
icons[CLONE] = new Mesh("mesh/icon_clone.ply");
|
||||
shadows[CLONE] = shadow;
|
||||
icons[RENDER] = new Mesh("mesh/icon_render.ply");
|
||||
shadows[RENDER] = shadow;
|
||||
icons[PATTERN] = new Mesh("mesh/icon_gear.ply");
|
||||
shadows[PATTERN]= shadow;
|
||||
icons[CAMERA] = new Mesh("mesh/icon_camera.ply");
|
||||
shadows[CAMERA] = shadow;
|
||||
icons[SHARE] = new Mesh("mesh/icon_share.ply");
|
||||
shadows[SHARE] = shadow;
|
||||
icons[DOTS] = new Mesh("mesh/icon_dots.ply");
|
||||
shadows[DOTS] = nullptr;
|
||||
icons[BUSY] = new Mesh("mesh/icon_circles.ply");
|
||||
shadows[BUSY] = nullptr;
|
||||
icons[LOCK] = new Mesh("mesh/icon_lock.ply");
|
||||
shadows[LOCK] = shadow;
|
||||
icons[UNLOCK] = new Mesh("mesh/icon_unlock.ply");
|
||||
shadows[UNLOCK] = shadow;
|
||||
icons[ARROWS] = new Mesh("mesh/icon_rightarrow.ply");
|
||||
shadows[ARROWS] = shadow;
|
||||
icons[CIRCLE] = new Mesh("mesh/icon_circle.ply");
|
||||
shadows[CIRCLE] = nullptr;
|
||||
icons[CLOCK] = new Mesh("mesh/icon_clock.ply");
|
||||
shadows[CLOCK] = nullptr;
|
||||
icons[CLOCK_H] = new Mesh("mesh/icon_clock_hand.ply");
|
||||
shadows[CLOCK_H]= nullptr;
|
||||
icons[SQUARE] = new Mesh("mesh/icon_square.ply");
|
||||
shadows[SQUARE] = nullptr;
|
||||
icons[CROSS] = new Mesh("mesh/icon_cross.ply");
|
||||
shadows[CROSS] = nullptr;
|
||||
icons[GRID] = new Mesh("mesh/icon_grid.ply");
|
||||
shadows[GRID] = nullptr;
|
||||
icons[EMPTY] = new Mesh("mesh/icon_empty.ply");
|
||||
shadows[EMPTY] = shadow;
|
||||
}
|
||||
|
||||
static Mesh *shadow= new Mesh("mesh/border_handles_shadow.ply", "images/soft_shadow.dds");
|
||||
|
||||
symbol_ = icons[type_];
|
||||
shadow_ = shadow;
|
||||
shadow_ = shadows[type_];
|
||||
translation_ = pos;
|
||||
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
|
||||
}
|
||||
@@ -397,7 +436,8 @@ void Symbol::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
// generate matrix
|
||||
ctm = GlmToolkit::transform(tran, rot, sca);
|
||||
|
||||
shadow_->draw( ctm, projection );
|
||||
if (shadow_)
|
||||
shadow_->draw( ctm, projection );
|
||||
symbol_->draw( ctm, projection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ protected:
|
||||
class Handles : public Node
|
||||
{
|
||||
public:
|
||||
typedef enum { RESIZE = 0, RESIZE_H, RESIZE_V, ROTATE, SCALE, MENU } Type;
|
||||
typedef enum { RESIZE = 0, RESIZE_H, RESIZE_V, ROTATE, SCALE, CROP, MENU } Type;
|
||||
Handles(Type type);
|
||||
~Handles();
|
||||
|
||||
@@ -61,7 +61,7 @@ class Symbol : public Node
|
||||
{
|
||||
public:
|
||||
typedef enum { CIRCLE_POINT = 0, SQUARE_POINT, IMAGE, VIDEO, SESSION, CLONE, RENDER, PATTERN, CAMERA, SHARE,
|
||||
DOTS, BUSY, LOCK, UNLOCK, CROP, CIRCLE, SQUARE, CLOCK, CLOCK_H, GRID, CROSS, EMPTY } Type;
|
||||
DOTS, BUSY, LOCK, UNLOCK, ARROWS, CROP, CIRCLE, SQUARE, CLOCK, CLOCK_H, GRID, CROSS, EMPTY } Type;
|
||||
Symbol(Type t = CIRCLE_POINT, glm::vec3 pos = glm::vec3(0.f));
|
||||
~Symbol();
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ void DrawVisitor::loop(int num, glm::mat4 transform)
|
||||
|
||||
void DrawVisitor::visit(Node &n)
|
||||
{
|
||||
// force visible status if required
|
||||
bool v = n.visible_;
|
||||
if (force_)
|
||||
n.visible_ = true;
|
||||
|
||||
// draw the target
|
||||
if ( target_ && n.id() == target_->id()) {
|
||||
|
||||
@@ -37,6 +42,9 @@ void DrawVisitor::visit(Node &n)
|
||||
done_ = true;
|
||||
}
|
||||
|
||||
// restore visibility
|
||||
n.visible_ = v;
|
||||
|
||||
if (done_) return;
|
||||
|
||||
// update transform
|
||||
@@ -60,17 +68,23 @@ void DrawVisitor::visit(Group &n)
|
||||
|
||||
void DrawVisitor::visit(Scene &n)
|
||||
{
|
||||
done_ = false;
|
||||
modelview_ = glm::identity<glm::mat4>();
|
||||
n.root()->accept(*this);
|
||||
}
|
||||
|
||||
void DrawVisitor::visit(Switch &n)
|
||||
{
|
||||
// no need to traverse deeper if this node was drawn already
|
||||
if (done_) return;
|
||||
|
||||
// traverse acive child
|
||||
glm::mat4 mv = modelview_;
|
||||
n.activeChild()->accept(*this);
|
||||
if ( n.activeChild()->visible_ || force_)
|
||||
n.activeChild()->accept(*this);
|
||||
modelview_ = mv;
|
||||
}
|
||||
|
||||
void DrawVisitor::visit(Primitive &n)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
171
FrameBuffer.cpp
@@ -1,3 +1,5 @@
|
||||
#include <sstream>
|
||||
|
||||
#include "FrameBuffer.h"
|
||||
#include "ImageShader.h"
|
||||
#include "Resource.h"
|
||||
@@ -7,10 +9,12 @@
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <stb_image.h>
|
||||
#include <stb_image_write.h>
|
||||
|
||||
const char* FrameBuffer::aspect_ratio_name[5] = { "4:3", "3:2", "16:10", "16:9", "21:9" };
|
||||
glm::vec2 FrameBuffer::aspect_ratio_size[5] = { glm::vec2(4.f,3.f), glm::vec2(3.f,2.f), glm::vec2(16.f,10.f), glm::vec2(16.f,9.f) , glm::vec2(21.f,9.f) };
|
||||
const char* FrameBuffer::resolution_name[4] = { "720", "1080", "1440", "4K" };
|
||||
const char* FrameBuffer::resolution_name[4] = { "720", "1080", "1440", "2160" };
|
||||
float FrameBuffer::resolution_height[4] = { 720.f, 1080.f, 1440.f, 2160.f };
|
||||
|
||||
|
||||
@@ -22,6 +26,31 @@ glm::vec3 FrameBuffer::getResolutionFromParameters(int ar, int h)
|
||||
return res;
|
||||
}
|
||||
|
||||
glm::ivec2 FrameBuffer::getParametersFromResolution(glm::vec3 res)
|
||||
{
|
||||
glm::ivec2 p = glm::ivec2(-1);
|
||||
|
||||
// get aspect ratio parameter
|
||||
static int num_ar = ((int)(sizeof(FrameBuffer::aspect_ratio_size) / sizeof(*FrameBuffer::aspect_ratio_size)));
|
||||
float myratio = res.x / res.y;
|
||||
for(int ar = 0; ar < num_ar; ar++) {
|
||||
if ( myratio - (FrameBuffer::aspect_ratio_size[ar].x / FrameBuffer::aspect_ratio_size[ar].y ) < EPSILON){
|
||||
p.x = ar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// get height parameter
|
||||
static int num_height = ((int)(sizeof(FrameBuffer::resolution_height) / sizeof(*FrameBuffer::resolution_height)));
|
||||
for(int h = 0; h < num_height; h++) {
|
||||
if ( res.y - FrameBuffer::resolution_height[h] < 1){
|
||||
p.y = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
FrameBuffer::FrameBuffer(glm::vec3 resolution, bool useAlpha, bool multiSampling):
|
||||
textureid_(0), intermediate_textureid_(0), framebufferid_(0), intermediate_framebufferid_(0),
|
||||
use_alpha_(useAlpha), use_multi_sampling_(multiSampling)
|
||||
@@ -102,6 +131,12 @@ FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
if (framebufferid_)
|
||||
glDeleteFramebuffers(1, &framebufferid_);
|
||||
if (intermediate_framebufferid_)
|
||||
glDeleteFramebuffers(1, &intermediate_framebufferid_);
|
||||
if (textureid_)
|
||||
glDeleteTextures(1, &textureid_);
|
||||
if (intermediate_textureid_)
|
||||
glDeleteTextures(1, &intermediate_textureid_);
|
||||
}
|
||||
|
||||
|
||||
@@ -121,20 +156,14 @@ float FrameBuffer::aspectRatio() const
|
||||
|
||||
std::string FrameBuffer::info() const
|
||||
{
|
||||
std::string s = "";
|
||||
glm::ivec2 p = FrameBuffer::getParametersFromResolution(resolution());
|
||||
std::ostringstream info;
|
||||
|
||||
static int num_ar = ((int)(sizeof(FrameBuffer::aspect_ratio_size) / sizeof(*FrameBuffer::aspect_ratio_size)));
|
||||
float myratio = aspectRatio();
|
||||
for(int i= 0; i < num_ar; i++) {
|
||||
if ( myratio - (FrameBuffer::aspect_ratio_size[i].x / FrameBuffer::aspect_ratio_size[i].y ) < EPSILON)
|
||||
{
|
||||
s += std::string( FrameBuffer::aspect_ratio_name[i]) + ", ";
|
||||
break;
|
||||
}
|
||||
}
|
||||
info << attrib_.viewport.x << "x" << attrib_.viewport.y;
|
||||
if (p.x > -1)
|
||||
info << "px, " << FrameBuffer::aspect_ratio_name[p.x];
|
||||
|
||||
s += std::to_string(width()) + "x" + std::to_string(height()) + " px";
|
||||
return s;
|
||||
return info.str();
|
||||
}
|
||||
|
||||
glm::vec3 FrameBuffer::resolution() const
|
||||
@@ -142,7 +171,7 @@ glm::vec3 FrameBuffer::resolution() const
|
||||
return glm::vec3(attrib_.viewport.x, attrib_.viewport.y, 0.f);
|
||||
}
|
||||
|
||||
void FrameBuffer::begin()
|
||||
void FrameBuffer::begin(bool clear)
|
||||
{
|
||||
if (!framebufferid_)
|
||||
init();
|
||||
@@ -151,7 +180,8 @@ void FrameBuffer::begin()
|
||||
|
||||
Rendering::manager().pushAttrib(attrib_);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
if (clear)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void FrameBuffer::end()
|
||||
@@ -176,7 +206,7 @@ void FrameBuffer::release()
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
void FrameBuffer::readPixels()
|
||||
void FrameBuffer::readPixels(uint8_t *target_data)
|
||||
{
|
||||
if (!framebufferid_)
|
||||
return;
|
||||
@@ -191,21 +221,24 @@ void FrameBuffer::readPixels()
|
||||
else
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, (use_alpha_? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, 0);
|
||||
glReadPixels(0, 0, attrib_.viewport.x, attrib_.viewport.y, (use_alpha_? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, target_data);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
bool FrameBuffer::blit(FrameBuffer *other)
|
||||
bool FrameBuffer::blit(FrameBuffer *destination)
|
||||
{
|
||||
if (!framebufferid_ || !other || !other->framebufferid_)
|
||||
if (!framebufferid_ || !destination)
|
||||
return false;
|
||||
|
||||
if (!destination->framebufferid_)
|
||||
destination->init();
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferid_);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, other->framebufferid_);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destination->framebufferid_);
|
||||
// blit to the frame buffer object
|
||||
glBlitFramebuffer(0, 0, attrib_.viewport.x, attrib_.viewport.y,
|
||||
0, 0, other->width(), other->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
0, 0, destination->width(), destination->height(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -252,16 +285,100 @@ glm::mat4 FrameBuffer::projection() const
|
||||
return projection_;
|
||||
}
|
||||
|
||||
|
||||
glm::vec2 FrameBuffer::projectionArea() const
|
||||
{
|
||||
return projection_crop_;
|
||||
return projection_area_;
|
||||
}
|
||||
|
||||
void FrameBuffer::setProjectionArea(glm::vec2 c)
|
||||
{
|
||||
projection_crop_.x = CLAMP(c.x, 0.1f, 1.f);
|
||||
projection_crop_.y = CLAMP(c.y, 0.1f, 1.f);
|
||||
projection_ = glm::ortho(-projection_crop_.x, projection_crop_.x, projection_crop_.y, -projection_crop_.y, -1.f, 1.f);
|
||||
projection_area_.x = CLAMP(c.x, 0.1f, 1.f);
|
||||
projection_area_.y = CLAMP(c.y, 0.1f, 1.f);
|
||||
projection_ = glm::ortho(-projection_area_.x, projection_area_.x, projection_area_.y, -projection_area_.y, -1.f, 1.f);
|
||||
}
|
||||
|
||||
|
||||
FrameBufferImage::FrameBufferImage(int w, int h) :
|
||||
rgb(nullptr), width(w), height(h)
|
||||
{
|
||||
if (width>0 && height>0)
|
||||
rgb = new uint8_t[width*height*3];
|
||||
}
|
||||
|
||||
FrameBufferImage::FrameBufferImage(jpegBuffer jpgimg) :
|
||||
rgb(nullptr), width(0), height(0)
|
||||
{
|
||||
int c = 0;
|
||||
if (jpgimg.buffer != nullptr && jpgimg.len >0)
|
||||
rgb = stbi_load_from_memory(jpgimg.buffer, jpgimg.len, &width, &height, &c, 3);
|
||||
}
|
||||
|
||||
FrameBufferImage::~FrameBufferImage() {
|
||||
if (rgb!=nullptr)
|
||||
delete rgb;
|
||||
}
|
||||
|
||||
FrameBufferImage::jpegBuffer FrameBufferImage::getJpeg()
|
||||
{
|
||||
jpegBuffer jpgimg;
|
||||
|
||||
// if we hold a valid image
|
||||
if (rgb!=nullptr && width>0 && height>0) {
|
||||
|
||||
// allocate JPEG buffer
|
||||
// (NB: JPEG will need less than this but we can't know before...)
|
||||
jpgimg.buffer = (unsigned char *) malloc( width * height * 3 * sizeof(unsigned char));
|
||||
|
||||
stbi_write_jpg_to_func( [](void *context, void *data, int size)
|
||||
{
|
||||
memcpy(((FrameBufferImage::jpegBuffer*)context)->buffer + ((FrameBufferImage::jpegBuffer*)context)->len, data, size);
|
||||
((FrameBufferImage::jpegBuffer*)context)->len += size;
|
||||
}
|
||||
,&jpgimg, width, height, 3, rgb, FBI_JPEG_QUALITY);
|
||||
}
|
||||
|
||||
return jpgimg;
|
||||
}
|
||||
|
||||
FrameBufferImage *FrameBuffer::image(){
|
||||
|
||||
FrameBufferImage *img = nullptr;
|
||||
|
||||
// not ready
|
||||
if (!framebufferid_)
|
||||
return img;
|
||||
|
||||
// allocate image
|
||||
img = new FrameBufferImage(attrib_.viewport.x, attrib_.viewport.y);
|
||||
|
||||
// get pixels into image
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // set buffer target readpixel
|
||||
readPixels(img->rgb);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
bool FrameBuffer::fill(FrameBufferImage *image)
|
||||
{
|
||||
if (!framebufferid_)
|
||||
init();
|
||||
|
||||
// not compatible for RGB
|
||||
if (use_alpha_ || use_multi_sampling_)
|
||||
return false;
|
||||
|
||||
// invalid image
|
||||
if ( image == nullptr ||
|
||||
image->rgb==nullptr ||
|
||||
image->width !=attrib_.viewport.x ||
|
||||
image->height!=attrib_.viewport.y )
|
||||
return false;
|
||||
|
||||
// fill texture with image
|
||||
glBindTexture(GL_TEXTURE_2D, textureid_);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image->width, image->height,
|
||||
GL_RGB, GL_UNSIGNED_BYTE, image->rgb);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,35 @@
|
||||
#ifndef FRAMEBUFFER_H
|
||||
#define FRAMEBUFFER_H
|
||||
|
||||
#include "Scene.h"
|
||||
#include "RenderingManager.h"
|
||||
|
||||
#define FBI_JPEG_QUALITY 90
|
||||
|
||||
/**
|
||||
* @brief The FrameBufferImage class stores an RGB image in RAM
|
||||
* Direct access to rgb array, and exchange format to JPEG in RAM
|
||||
*/
|
||||
class FrameBufferImage
|
||||
{
|
||||
public:
|
||||
uint8_t *rgb = nullptr;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
struct jpegBuffer {
|
||||
unsigned char *buffer = nullptr;
|
||||
uint len = 0;
|
||||
};
|
||||
jpegBuffer getJpeg();
|
||||
|
||||
FrameBufferImage(int w, int h);
|
||||
FrameBufferImage(jpegBuffer jpgimg);
|
||||
~FrameBufferImage();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The FrameBuffer class holds an OpenGL Frame Buffer Object.
|
||||
*/
|
||||
class FrameBuffer {
|
||||
|
||||
public:
|
||||
@@ -13,6 +39,7 @@ public:
|
||||
static const char* resolution_name[4];
|
||||
static float resolution_height[4];
|
||||
static glm::vec3 getResolutionFromParameters(int ar, int h);
|
||||
static glm::ivec2 getParametersFromResolution(glm::vec3 res);
|
||||
// unbind any framebuffer object
|
||||
static void release();
|
||||
|
||||
@@ -21,15 +48,14 @@ public:
|
||||
~FrameBuffer();
|
||||
|
||||
// Bind & push attribs to prepare draw
|
||||
void begin();
|
||||
void begin(bool clear = true);
|
||||
// pop attrib and unbind to end draw
|
||||
void end();
|
||||
|
||||
// blit copy to another, returns true on success
|
||||
bool blit(FrameBuffer *other);
|
||||
bool blit(FrameBuffer *destination);
|
||||
// bind the FrameBuffer in READ and perform glReadPixels
|
||||
// return the size of the buffer
|
||||
void readPixels();
|
||||
// (to be used after preparing a target PBO)
|
||||
void readPixels(uint8_t* target_data = 0);
|
||||
|
||||
// clear color
|
||||
inline void setClearColor(glm::vec4 color) { attrib_.clear_color = color; }
|
||||
@@ -42,7 +68,7 @@ public:
|
||||
float aspectRatio() const;
|
||||
std::string info() const;
|
||||
|
||||
// projection and crop
|
||||
// projection area (crop)
|
||||
glm::mat4 projection() const;
|
||||
glm::vec2 projectionArea() const;
|
||||
void setProjectionArea(glm::vec2 c);
|
||||
@@ -54,16 +80,21 @@ public:
|
||||
// index for texturing
|
||||
uint texture() const;
|
||||
|
||||
// get and fill image
|
||||
FrameBufferImage *image();
|
||||
bool fill(FrameBufferImage *image);
|
||||
|
||||
private:
|
||||
void init();
|
||||
void checkFramebufferStatus();
|
||||
|
||||
RenderingAttrib attrib_;
|
||||
glm::mat4 projection_;
|
||||
glm::vec2 projection_crop_;
|
||||
glm::vec2 projection_area_;
|
||||
uint textureid_, intermediate_textureid_;
|
||||
uint framebufferid_, intermediate_framebufferid_;
|
||||
bool use_alpha_, use_multi_sampling_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include <iomanip>
|
||||
using namespace std;
|
||||
|
||||
#include <gst/gl/gl.h>
|
||||
|
||||
#include "GstToolkit.h"
|
||||
|
||||
string GstToolkit::time_to_string(guint64 t, time_string_mode m)
|
||||
@@ -54,6 +56,16 @@ string GstToolkit::time_to_string(guint64 t, time_string_mode m)
|
||||
}
|
||||
|
||||
|
||||
std::string GstToolkit::filename_to_uri(std::string path)
|
||||
{
|
||||
// set uri to open
|
||||
gchar *uritmp = gst_filename_to_uri(path.c_str(), NULL);
|
||||
std::string uri( uritmp );
|
||||
g_free(uritmp);
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
list<string> GstToolkit::all_plugins()
|
||||
{
|
||||
list<string> pluginlist;
|
||||
@@ -121,3 +133,40 @@ string GstToolkit::gst_version()
|
||||
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
|
||||
// see https://developer.ridgerun.com/wiki/index.php?title=GStreamer_modify_the_elements_rank
|
||||
|
||||
std::list<std::string> GstToolkit::enable_gpu_decoding_plugins()
|
||||
{
|
||||
static list<string> pluginslist;
|
||||
static GstRegistry* plugins_register = nullptr;
|
||||
|
||||
if ( plugins_register == nullptr ) {
|
||||
plugins_register = gst_registry_get();
|
||||
|
||||
#if GST_GL_HAVE_PLATFORM_GLX
|
||||
// https://gstreamer.freedesktop.org/documentation/nvcodec/index.html?gi-language=c#plugin-nvcodec
|
||||
const char *plugins[6] = { "nvh264dec", "nvh265dec", "nvmpeg2videodec",
|
||||
"nvmpeg4videodec", "nvvp8dec", "nvvp9dec" };
|
||||
const int N = 6;
|
||||
#elif GST_GL_HAVE_PLATFORM_CGL
|
||||
const char *plugins[1] = { "vtdec_hw" };
|
||||
const int N = 1;
|
||||
#else
|
||||
const char *plugins[0] = { };
|
||||
const int N = 0;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
GstPluginFeature* feature = gst_registry_lookup_feature(plugins_register, plugins[i]);
|
||||
if(feature != NULL) {
|
||||
pluginslist.push_front( string( plugins[i] ) );
|
||||
gst_plugin_feature_set_rank(feature, GST_RANK_PRIMARY + 1);
|
||||
gst_object_unref(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pluginslist;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,14 @@ typedef enum {
|
||||
} time_string_mode;
|
||||
|
||||
std::string time_to_string(guint64 t, time_string_mode m = TIME_STRING_ADJUSTED);
|
||||
std::string filename_to_uri(std::string filename);
|
||||
|
||||
std::string gst_version();
|
||||
std::list<std::string> all_plugins();
|
||||
std::list<std::string> all_plugin_features(std::string pluginname);
|
||||
|
||||
std::list<std::string> all_plugins();
|
||||
std::list<std::string> enable_gpu_decoding_plugins();
|
||||
|
||||
std::list<std::string> all_plugin_features(std::string pluginname);
|
||||
bool enable_feature (std::string name, bool enable);
|
||||
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@ std::map <ImGuiToolkit::font_style, ImFont*>fontmap;
|
||||
void ImGuiToolkit::ButtonOpenUrl( const char* url, const ImVec2& size_arg )
|
||||
{
|
||||
char label[512];
|
||||
sprintf( label, "%s %s", ICON_FA_EXTERNAL_LINK_ALT, url );
|
||||
|
||||
std::string str = SystemToolkit::transliterate( url );
|
||||
sprintf( label, "%s %s", ICON_FA_EXTERNAL_LINK_ALT, str.c_str() );
|
||||
|
||||
if ( ImGui::Button(label, size_arg) )
|
||||
SystemToolkit::open(url);
|
||||
@@ -137,12 +139,8 @@ bool ImGuiToolkit::ButtonIcon(int i, int j, const char *tooltip)
|
||||
bool ret = ImGui::ImageButton((void*)(intptr_t)textureicons, ImVec2(ImGui::GetTextLineHeightWithSpacing(),ImGui::GetTextLineHeightWithSpacing()), uv0, uv1, 3);
|
||||
ImGui::PopID();
|
||||
|
||||
if (tooltip != nullptr && ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text("%s", tooltip);
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
if (tooltip != nullptr)
|
||||
ImGuiToolkit::ToolTip(tooltip);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -271,17 +269,31 @@ void ImGuiToolkit::ShowIconsWindow(bool* p_open)
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ImGuiToolkit::ToolTip(const char* desc)
|
||||
{
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_DEFAULT);
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::Text(desc);
|
||||
ImGui::EndTooltip();
|
||||
ImGui::PopFont();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to display a little (?) mark which shows a tooltip when hovered.
|
||||
// In your own code you may want to display an actual icon if you are using a merged icon fonts (see docs/FONTS.txt)
|
||||
void ImGuiToolkit::HelpMarker(const char* desc)
|
||||
void ImGuiToolkit::HelpMarker(const char* desc, const char* icon)
|
||||
{
|
||||
ImGui::TextDisabled( ICON_FA_QUESTION_CIRCLE );
|
||||
ImGui::TextDisabled( icon );
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::BeginTooltip();
|
||||
ImGuiToolkit::PushFont(ImGuiToolkit::FONT_DEFAULT);
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||
ImGui::TextUnformatted(desc);
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::PopFont();
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@ namespace ImGuiToolkit
|
||||
bool IconToggle (int i, int j, int i_toggle, int j_toggle, bool* toggle, const char *tooltips[] = nullptr);
|
||||
void ButtonOpenUrl (const char* url, const ImVec2& size_arg = ImVec2(0,0));
|
||||
|
||||
void HelpMarker (const char* desc);
|
||||
void ToolTip (const char* desc);
|
||||
void HelpMarker (const char* desc, const char* icon = ICON_FA_QUESTION_CIRCLE);
|
||||
|
||||
// utility sliders
|
||||
bool TimelineSlider (const char* label, guint64 *time, guint64 start, guint64 end, guint64 step, const float width);
|
||||
|
||||
@@ -161,6 +161,7 @@ void ImGuiVisitor::visit(Shader &n)
|
||||
{
|
||||
ImGui::PushID(std::to_string(n.id()).c_str());
|
||||
|
||||
// Base color
|
||||
// if (ImGuiToolkit::ButtonIcon(10, 2)) {
|
||||
// n.blending = Shader::BLEND_OPACITY;
|
||||
// n.color = glm::vec4(1.f, 1.f, 1.f, 1.f);
|
||||
@@ -201,29 +202,26 @@ void ImGuiVisitor::visit(Shader &n)
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void ImGuiVisitor::visit(ImageShader &n)
|
||||
{
|
||||
ImGui::PushID(std::to_string(n.id()).c_str());
|
||||
|
||||
// get index of the mask used in this ImageShader
|
||||
int item_current = n.mask;
|
||||
|
||||
// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0;
|
||||
// ImGui::SameLine(0, 10);
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// 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;
|
||||
else {
|
||||
// TODO ask for custom mask
|
||||
}
|
||||
Action::manager().store("Mask "+ std::string(ImageShader::mask_names[n.mask]), n.id());
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
//void ImGuiVisitor::visit(ImageShader &n)
|
||||
//{
|
||||
// ImGui::PushID(std::to_string(n.id()).c_str());
|
||||
// // get index of the mask used in this ImageShader
|
||||
// int item_current = n.mask;
|
||||
//// if (ImGuiToolkit::ButtonIcon(10, 3)) n.mask = 0;
|
||||
//// ImGui::SameLine(0, 10);
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// // 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;
|
||||
// else {
|
||||
// // TODO ask for custom mask
|
||||
// }
|
||||
// Action::manager().store("Mask "+ std::string(ImageShader::mask_names[n.mask]), n.id());
|
||||
// }
|
||||
// ImGui::PopID();
|
||||
//}
|
||||
|
||||
void ImGuiVisitor::visit(ImageProcessingShader &n)
|
||||
{
|
||||
@@ -258,7 +256,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n)
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// ImGui::SliderFloat4("Levels", glm::value_ptr(n.levels), 0.0, 1.0);
|
||||
|
||||
if (ImGuiToolkit::ButtonIcon(4, 1)) {
|
||||
if (ImGuiToolkit::ButtonIcon(5, 16)) {
|
||||
n.brightness = 0.f;
|
||||
n.contrast = 0.f;
|
||||
Action::manager().store("B & C 0.0 0.0", n.id());
|
||||
@@ -277,7 +275,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n)
|
||||
Action::manager().store(oss.str(), n.id());
|
||||
}
|
||||
|
||||
if (ImGuiToolkit::ButtonIcon(2, 1)) {
|
||||
if (ImGuiToolkit::ButtonIcon(9, 16)) {
|
||||
n.saturation = 0.f;
|
||||
Action::manager().store("Saturation 0.0", n.id());
|
||||
}
|
||||
@@ -363,7 +361,7 @@ void ImGuiVisitor::visit(ImageProcessingShader &n)
|
||||
Action::manager().store(oss.str(), n.id());
|
||||
}
|
||||
|
||||
if (ImGuiToolkit::ButtonIcon(7, 1)) {
|
||||
if (ImGuiToolkit::ButtonIcon(6, 16)) {
|
||||
n.invert = 0;
|
||||
Action::manager().store("Invert None", n.id());
|
||||
}
|
||||
@@ -396,20 +394,32 @@ void ImGuiVisitor::visit (Source& s)
|
||||
// preview
|
||||
float preview_width = ImGui::GetContentRegionAvail().x IMGUI_RIGHT_ALIGN;
|
||||
float width = preview_width;
|
||||
float height = width / s.frame()->aspectRatio();
|
||||
float height = s.frame()->projectionArea().y * width / ( s.frame()->projectionArea().x * s.frame()->aspectRatio());
|
||||
if (height > 230) {
|
||||
height = 230;
|
||||
width = height * s.frame()->aspectRatio();
|
||||
width = height * s.frame()->aspectRatio() * ( s.frame()->projectionArea().x / s.frame()->projectionArea().y);
|
||||
}
|
||||
ImGui::Image((void*)(uintptr_t) s.frame()->texture(), ImVec2(width, height));
|
||||
|
||||
ImVec2 pos = ImGui::GetCursorPos(); // remember where we were...
|
||||
|
||||
ImGui::SetCursorPos( ImVec2(preview_width + 15, pos.y -height ) );
|
||||
if (s.active())
|
||||
ImGuiToolkit::Icon(10, 4);
|
||||
// inform on visibility status
|
||||
ImGui::SetCursorPos( ImVec2(preview_width + 20, pos.y -height ) );
|
||||
if (s.active()) {
|
||||
if (s.blendingShader()->color.a > 0.f)
|
||||
ImGuiToolkit::HelpMarker("Visible", ICON_FA_EYE);
|
||||
else
|
||||
ImGuiToolkit::HelpMarker("Not visible", ICON_FA_EYE_SLASH);
|
||||
}
|
||||
else
|
||||
ImGuiToolkit::Icon(11, 4);
|
||||
ImGuiToolkit::HelpMarker("Inactive", ICON_FA_SNOWFLAKE);
|
||||
|
||||
// Inform on status of lock
|
||||
ImGui::SetCursorPos( ImVec2(preview_width + 20, pos.y -height + ImGui::GetFrameHeight()) );
|
||||
if (s.locked())
|
||||
ImGuiToolkit::HelpMarker("Locked", ICON_FA_LOCK);
|
||||
else
|
||||
ImGuiToolkit::HelpMarker("Unlocked", ICON_FA_LOCK_OPEN);
|
||||
|
||||
// toggle enable/disable image processing
|
||||
bool on = s.imageProcessingEnabled();
|
||||
|
||||
@@ -9,19 +9,18 @@ public:
|
||||
ImGuiVisitor();
|
||||
|
||||
// Elements of Scene
|
||||
void visit(Scene& n) override;
|
||||
void visit(Node& n) override;
|
||||
void visit(Group& n) override;
|
||||
void visit(Switch& n) override;
|
||||
void visit(Primitive& n) override;
|
||||
void visit(MediaSurface& n) override;
|
||||
void visit(FrameBufferSurface& n) override;
|
||||
void visit (Scene& n) override;
|
||||
void visit (Node& n) override;
|
||||
void visit (Group& n) override;
|
||||
void visit (Switch& n) override;
|
||||
void visit (Primitive& n) override;
|
||||
void visit (MediaSurface& n) override;
|
||||
void visit (FrameBufferSurface& n) override;
|
||||
|
||||
// Elements with attributes
|
||||
void visit(MediaPlayer& n) override;
|
||||
void visit(Shader& n) override;
|
||||
void visit(ImageShader& n) override;
|
||||
void visit(ImageProcessingShader& n) override;
|
||||
void visit (MediaPlayer& n) override;
|
||||
void visit (Shader& n) override;
|
||||
void visit (ImageProcessingShader& n) override;
|
||||
void visit (Source& s) override;
|
||||
void visit (MediaSource& s) override;
|
||||
void visit (SessionSource& s) override;
|
||||
|
||||
115
ImageShader.cpp
@@ -4,27 +4,17 @@
|
||||
#include "Visitor.h"
|
||||
#include "ImageShader.h"
|
||||
#include "Resource.h"
|
||||
#include "rsc/fonts/IconsFontAwesome5.h"
|
||||
//#include
|
||||
|
||||
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" };
|
||||
std::vector< uint > ImageShader::mask_presets;
|
||||
const char* MaskShader::mask_names[3] = { ICON_FA_EXPAND, ICON_FA_EDIT, ICON_FA_SHAPES };
|
||||
const char* MaskShader::mask_shapes[5] = { "Elipse", "Oblong", "Rectangle", "Horizontal", "Vertical" };
|
||||
std::vector< ShadingProgram* > MaskShader::mask_programs;
|
||||
|
||||
ImageShader::ImageShader(): Shader(), mask(0), custom_textureindex(0), stipple(0.0)
|
||||
ImageShader::ImageShader(): Shader(), 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
|
||||
program_ = &imageShadingProgram;
|
||||
// reset instance
|
||||
@@ -38,12 +28,9 @@ void ImageShader::use()
|
||||
program_->setUniform("stipple", stipple);
|
||||
|
||||
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_T, GL_CLAMP_TO_EDGE);
|
||||
glBindTexture(GL_TEXTURE_2D, mask_texture);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@@ -54,18 +41,16 @@ void ImageShader::reset()
|
||||
Shader::reset();
|
||||
|
||||
// default mask
|
||||
mask = 0;
|
||||
custom_textureindex = mask_presets[0];
|
||||
mask_texture = Resource::getTextureWhite();
|
||||
// no stippling
|
||||
stipple = 0.f;
|
||||
}
|
||||
|
||||
void ImageShader::operator = (const ImageShader &S )
|
||||
void ImageShader::operator = (const ImageShader &S)
|
||||
{
|
||||
Shader::operator =(S);
|
||||
|
||||
mask = S.mask;
|
||||
custom_textureindex = S.custom_textureindex;
|
||||
mask_texture = S.mask_texture;
|
||||
stipple = S.stipple;
|
||||
}
|
||||
|
||||
@@ -74,3 +59,83 @@ void ImageShader::accept(Visitor& v) {
|
||||
Shader::accept(v);
|
||||
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/image.vs", "shaders/mask_draw.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_round.fs"));
|
||||
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_box.fs"));
|
||||
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_horizontal.fs"));
|
||||
mask_programs.push_back(new ShadingProgram("shaders/simple.vs", "shaders/mask_vertical.fs"));
|
||||
}
|
||||
// reset instance
|
||||
reset();
|
||||
// static program shader
|
||||
program_ = mask_programs[0];
|
||||
}
|
||||
|
||||
void MaskShader::use()
|
||||
{
|
||||
// select program to use
|
||||
mode = CLAMP(mode, 0, 2);
|
||||
shape = CLAMP(shape, 0, 4);
|
||||
program_ = mode < 2 ? mask_programs[mode] : mask_programs[shape+2] ;
|
||||
|
||||
// actual use of shader program
|
||||
Shader::use();
|
||||
|
||||
// shape parameters
|
||||
size = shape < HORIZONTAL ? glm::max(glm::abs(size), glm::vec2(0.2)) : size;
|
||||
program_->setUniform("size", size);
|
||||
program_->setUniform("blur", blur);
|
||||
|
||||
// brush parameters
|
||||
program_->setUniform("cursor", cursor);
|
||||
program_->setUniform("brush", brush);
|
||||
program_->setUniform("option", option);
|
||||
program_->setUniform("effect", effect);
|
||||
}
|
||||
|
||||
void MaskShader::reset()
|
||||
{
|
||||
Shader::reset();
|
||||
|
||||
// default mask
|
||||
mode = 0;
|
||||
|
||||
// default shape
|
||||
shape = 0;
|
||||
blur = 0.5f;
|
||||
size = glm::vec2(1.f, 1.f);
|
||||
|
||||
// default brush
|
||||
cursor = glm::vec4(-10.f, -10.f, 1.f, 1.f);
|
||||
brush = glm::vec3(0.5f, 0.1f, 0.f);
|
||||
option = 0;
|
||||
effect = 0;
|
||||
}
|
||||
|
||||
void MaskShader::operator = (const MaskShader &S)
|
||||
{
|
||||
Shader::operator =(S);
|
||||
|
||||
mode = S.mode;
|
||||
shape = S.shape;
|
||||
blur = S.blur;
|
||||
size = S.size;
|
||||
}
|
||||
|
||||
|
||||
void MaskShader::accept(Visitor& v) {
|
||||
Shader::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#ifndef IMAGESHADER_H
|
||||
#ifndef IMAGESHADER_H
|
||||
#define IMAGESHADER_H
|
||||
|
||||
#include <string>
|
||||
@@ -14,21 +14,59 @@ class ImageShader : public Shader
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
ImageShader();
|
||||
|
||||
void use() override;
|
||||
void reset() override;
|
||||
void accept(Visitor& v) override;
|
||||
|
||||
void operator = (const ImageShader &S);
|
||||
|
||||
uint mask;
|
||||
uint custom_textureindex;
|
||||
float stipple;
|
||||
uint mask_texture;
|
||||
|
||||
static const char* mask_names[11];
|
||||
static std::vector< uint > mask_presets;
|
||||
// uniforms
|
||||
float stipple;
|
||||
};
|
||||
|
||||
|
||||
class MaskShader : public Shader
|
||||
{
|
||||
|
||||
public:
|
||||
MaskShader();
|
||||
|
||||
void use() override;
|
||||
void reset() override;
|
||||
void accept(Visitor& v) override;
|
||||
void operator = (const MaskShader &S);
|
||||
|
||||
enum Modes {
|
||||
NONE = 0,
|
||||
PAINT = 1,
|
||||
SHAPE = 2
|
||||
};
|
||||
uint mode;
|
||||
|
||||
enum Shapes {
|
||||
ELIPSE = 0,
|
||||
OBLONG = 1,
|
||||
RECTANGLE = 2,
|
||||
HORIZONTAL = 3,
|
||||
VERTICAL = 4
|
||||
};
|
||||
uint shape;
|
||||
|
||||
// uniforms
|
||||
glm::vec2 size;
|
||||
float blur;
|
||||
|
||||
int option;
|
||||
int effect;
|
||||
glm::vec4 cursor;
|
||||
glm::vec3 brush;
|
||||
|
||||
static const char* mask_names[3];
|
||||
static const char* mask_shapes[5];
|
||||
static std::vector< ShadingProgram* > mask_programs;
|
||||
};
|
||||
|
||||
#endif // IMAGESHADER_H
|
||||
|
||||
@@ -13,6 +13,7 @@ using namespace std;
|
||||
#include "Visitor.h"
|
||||
#include "SystemToolkit.h"
|
||||
#include "GlmToolkit.h"
|
||||
#include "GstToolkit.h"
|
||||
|
||||
#include "MediaPlayer.h"
|
||||
|
||||
@@ -186,12 +187,10 @@ static MediaInfo UriDiscoverer_(std::string uri)
|
||||
void MediaPlayer::open(string path)
|
||||
{
|
||||
// set path
|
||||
filename_ = path;
|
||||
filename_ = SystemToolkit::transliterate( path );
|
||||
|
||||
// set uri to open
|
||||
gchar *uritmp = gst_filename_to_uri(path.c_str(), NULL);
|
||||
uri_ = string( uritmp );
|
||||
g_free(uritmp);
|
||||
uri_ = GstToolkit::filename_to_uri(path);
|
||||
|
||||
// reset
|
||||
ready_ = false;
|
||||
@@ -779,7 +778,7 @@ void MediaPlayer::update()
|
||||
fill_texture(read_index);
|
||||
|
||||
// double update for pre-roll frame and dual PBO (ensure frame is displayed now)
|
||||
if (frame_[read_index].status == PREROLL && pbo_size_ > 0)
|
||||
if ( (frame_[read_index].status == PREROLL || seeking_ ) && pbo_size_ > 0)
|
||||
fill_texture(read_index);
|
||||
}
|
||||
|
||||
|
||||
@@ -86,13 +86,15 @@ void MediaSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
|
||||
// deep update to reorder
|
||||
View::need_deep_update_++;
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source '%s' linked to Media %s.", name().c_str(), std::to_string(mediaplayer_->id()).c_str());
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
touch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
30
Mixer.cpp
@@ -211,8 +211,9 @@ void Mixer::update()
|
||||
appearance_.update(dt_);
|
||||
transition_.update(dt_);
|
||||
|
||||
// deep updates shall be performed only 1 frame
|
||||
View::need_deep_update_ = false;
|
||||
// deep update was performed
|
||||
if (View::need_deep_update_ > 0)
|
||||
View::need_deep_update_--;
|
||||
}
|
||||
|
||||
void Mixer::draw()
|
||||
@@ -641,6 +642,21 @@ void Mixer::setCurrentNext()
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::setCurrentPrevious()
|
||||
{
|
||||
if (session_->numSource() > 0) {
|
||||
|
||||
SourceList::iterator it = current_source_;
|
||||
|
||||
if (it == session_->begin()) {
|
||||
it = session_->end();
|
||||
}
|
||||
|
||||
it--;
|
||||
setCurrentSource( it );
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::unsetCurrentSource()
|
||||
{
|
||||
// discard overlay for previously current source
|
||||
@@ -707,7 +723,7 @@ void Mixer::setView(View::Mode m)
|
||||
}
|
||||
|
||||
// need to deeply update view to apply eventual changes
|
||||
View::need_deep_update_ = true;
|
||||
View::need_deep_update_++;
|
||||
|
||||
Settings::application.current_view = (int) m;
|
||||
}
|
||||
@@ -750,6 +766,8 @@ void Mixer::saveas(const std::string& filename)
|
||||
|
||||
void Mixer::load(const std::string& filename)
|
||||
{
|
||||
if (filename.empty())
|
||||
return;
|
||||
|
||||
#ifdef THREADED_LOADING
|
||||
// load only one at a time
|
||||
@@ -849,9 +867,6 @@ void Mixer::swap()
|
||||
// transfer fading
|
||||
session_->setFading( MAX(back_session_->fading(), session_->fading()), true );
|
||||
|
||||
// request complete update for views
|
||||
View::need_deep_update_ = true;
|
||||
|
||||
// no current source
|
||||
current_source_ = session_->end();
|
||||
current_source_index_ = -1;
|
||||
@@ -900,6 +915,9 @@ void Mixer::clear()
|
||||
// swap current with empty
|
||||
sessionSwapRequested_ = true;
|
||||
|
||||
// need to deeply update view to apply eventual changes
|
||||
View::need_deep_update_++;
|
||||
|
||||
Log::Info("New session ready.");
|
||||
}
|
||||
|
||||
|
||||
1
Mixer.h
@@ -59,6 +59,7 @@ public:
|
||||
void setCurrentSource (Node *node);
|
||||
void setCurrentSource (uint64_t id);
|
||||
void setCurrentNext ();
|
||||
void setCurrentPrevious ();
|
||||
void unsetCurrentSource ();
|
||||
|
||||
void setCurrentIndex (int index);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Visitor.h"
|
||||
#include "Log.h"
|
||||
|
||||
#define MAX_PATTERN 23
|
||||
#define MAX_PATTERN 24
|
||||
|
||||
// smpte (0) – SMPTE 100%% color bars
|
||||
// snow (1) – Random (television snow)
|
||||
@@ -38,59 +38,62 @@
|
||||
// spokes (22) – Spokes
|
||||
// gradient (23) – Gradient
|
||||
// colors (24) – Colors
|
||||
const char* pattern_internal_[24] = { "videotestsrc pattern=black",
|
||||
"videotestsrc pattern=white",
|
||||
"videotestsrc pattern=gradient",
|
||||
"videotestsrc pattern=checkers-1 ! video/x-raw,format=GRAY8 ! videoconvert",
|
||||
"videotestsrc pattern=checkers-8 ! video/x-raw,format=GRAY8 ! videoconvert",
|
||||
"videotestsrc pattern=circular",
|
||||
"frei0r-src-lissajous0r ratiox=0.001 ratioy=0.999 ! videoconvert",
|
||||
"videotestsrc pattern=pinwheel",
|
||||
"videotestsrc pattern=spokes",
|
||||
"videotestsrc pattern=red",
|
||||
"videotestsrc pattern=green",
|
||||
"videotestsrc pattern=blue",
|
||||
"videotestsrc pattern=smpte100",
|
||||
"videotestsrc pattern=colors",
|
||||
"videotestsrc pattern=smpte",
|
||||
"videotestsrc pattern=snow",
|
||||
"videotestsrc pattern=blink",
|
||||
"videotestsrc pattern=zone-plate",
|
||||
"videotestsrc pattern=chroma-zone-plate",
|
||||
"videotestsrc pattern=bar horizontal-speed=5",
|
||||
"videotestsrc pattern=ball",
|
||||
"frei0r-src-ising0r",
|
||||
"videotestsrc pattern=black ! timeoverlay halignment=center valignment=center font-desc=\"Sans, 72\" ",
|
||||
"videotestsrc pattern=black ! clockoverlay halignment=center valignment=center font-desc=\"Sans, 72\" "
|
||||
const char* pattern_internal_[MAX_PATTERN] = { "videotestsrc pattern=black",
|
||||
"videotestsrc pattern=white",
|
||||
"videotestsrc pattern=gradient",
|
||||
"videotestsrc pattern=checkers-1 ! video/x-raw,format=GRAY8 ! videoconvert",
|
||||
"videotestsrc pattern=checkers-8 ! video/x-raw,format=GRAY8 ! videoconvert",
|
||||
"videotestsrc pattern=circular",
|
||||
"frei0r-src-lissajous0r ratiox=0.001 ratioy=0.999 ! videoconvert",
|
||||
"videotestsrc pattern=pinwheel",
|
||||
"videotestsrc pattern=spokes",
|
||||
"videotestsrc pattern=red",
|
||||
"videotestsrc pattern=green",
|
||||
"videotestsrc pattern=blue",
|
||||
"videotestsrc pattern=smpte100",
|
||||
"videotestsrc pattern=colors",
|
||||
"videotestsrc pattern=smpte",
|
||||
"videotestsrc pattern=snow",
|
||||
"videotestsrc pattern=blink",
|
||||
"videotestsrc pattern=zone-plate",
|
||||
"videotestsrc pattern=chroma-zone-plate",
|
||||
"videotestsrc pattern=bar horizontal-speed=5",
|
||||
"videotestsrc pattern=ball",
|
||||
"frei0r-src-ising0r",
|
||||
"videotestsrc pattern=black ! timeoverlay halignment=center valignment=center font-desc=\"Sans, 72\" ",
|
||||
"videotestsrc pattern=black ! clockoverlay halignment=center valignment=center font-desc=\"Sans, 72\" "
|
||||
};
|
||||
|
||||
std::vector<std::string> Pattern::pattern_types = { "Black",
|
||||
"White",
|
||||
"Gradient",
|
||||
"Checkers 1x1 px",
|
||||
"Checkers 8x8 px",
|
||||
"Circles",
|
||||
"Lissajous",
|
||||
"Pinwheel",
|
||||
"Spokes",
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue",
|
||||
"Color bars",
|
||||
"RGB grid",
|
||||
"SMPTE test pattern",
|
||||
"Television snow",
|
||||
"Blink",
|
||||
"Fresnel zone plate",
|
||||
"Chroma zone plate",
|
||||
"Bar moving",
|
||||
"Ball bouncing",
|
||||
"Blob",
|
||||
"Timer",
|
||||
"Clock"
|
||||
};
|
||||
"White",
|
||||
"Gradient",
|
||||
"Checkers 1x1 px",
|
||||
"Checkers 8x8 px",
|
||||
"Circles",
|
||||
"Lissajous",
|
||||
"Pinwheel",
|
||||
"Spokes",
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue",
|
||||
"Color bars",
|
||||
"RGB grid",
|
||||
"SMPTE test pattern",
|
||||
"Television snow",
|
||||
"Blink",
|
||||
"Fresnel zone plate",
|
||||
"Chroma zone plate",
|
||||
"Bar moving",
|
||||
"Ball bouncing"
|
||||
#if GST_VERSION_MINOR > 17
|
||||
,
|
||||
"Blob",
|
||||
"Timer",
|
||||
"Clock"
|
||||
#endif
|
||||
};
|
||||
|
||||
Pattern::Pattern() : Stream(), type_(MAX_PATTERN+1) // invalid pattern
|
||||
Pattern::Pattern() : Stream(), type_(MAX_PATTERN) // invalid pattern
|
||||
{
|
||||
|
||||
}
|
||||
@@ -103,7 +106,7 @@ glm::ivec2 Pattern::resolution()
|
||||
|
||||
void Pattern::open( uint pattern, glm::ivec2 res )
|
||||
{
|
||||
type_ = MIN(pattern, MAX_PATTERN);
|
||||
type_ = MIN(pattern, MAX_PATTERN-1);
|
||||
std::string gstreamer_pattern = pattern_internal_[type_];
|
||||
|
||||
// there is always a special case...
|
||||
|
||||
@@ -126,6 +126,13 @@ void PickingVisitor::visit(Handles &n)
|
||||
glm::vec4 S = glm::inverse(modelview_) * glm::vec4( 0.05f, 0.05f, 0.f, 0.f );
|
||||
float scale = glm::length( glm::vec2(S) );
|
||||
|
||||
// extract rotation from modelview
|
||||
glm::mat4 ctm;
|
||||
glm::vec3 rot(0.f);
|
||||
glm::vec4 vec = modelview_ * glm::vec4(1.f, 0.f, 0.f, 0.f);
|
||||
rot.z = glm::orientedAngle( glm::vec3(1.f, 0.f, 0.f), glm::normalize(glm::vec3(vec)), glm::vec3(0.f, 0.f, 1.f) );
|
||||
ctm = glm::rotate(glm::identity<glm::mat4>(), -rot.z, glm::vec3(0.f, 0.f, 1.f)) * modelview_ ;
|
||||
|
||||
bool picked = false;
|
||||
if ( n.type() == Handles::RESIZE ) {
|
||||
// 4 corners
|
||||
@@ -146,21 +153,23 @@ void PickingVisitor::visit(Handles &n)
|
||||
}
|
||||
else if ( n.type() == Handles::ROTATE ){
|
||||
// the icon for rotation is on the right top corner at (0.12, 0.12) in scene coordinates
|
||||
glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.1f, 0.1f, 0.f, 0.f );
|
||||
float l = glm::length( glm::vec2(vec) );
|
||||
picked = glm::length( glm::vec2( 1.f + l, 1.f + l) - glm::vec2(P) ) < 1.5f * scale;
|
||||
glm::vec4 pos = glm::inverse(ctm) * glm::vec4( 0.12f, 0.12f, 0.f, 0.f );
|
||||
picked = glm::length( glm::vec2( 1.f, 1.f) + glm::vec2(pos) - glm::vec2(P) ) < 1.5f * scale;
|
||||
}
|
||||
else if ( n.type() == Handles::SCALE ){
|
||||
// the icon for scaling is on the right bottom corner at (0.12, -0.12) in scene coordinates
|
||||
glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.1f, 0.1f, 0.f, 0.f );
|
||||
float l = glm::length( glm::vec2(vec) );
|
||||
picked = glm::length( glm::vec2( 1.f + l, -1.f - l) - glm::vec2(P) ) < 1.5f * scale;
|
||||
glm::vec4 pos = glm::inverse(ctm) * glm::vec4( 0.12f, -0.12f, 0.f, 0.f );
|
||||
picked = glm::length( glm::vec2( 1.f, -1.f) + glm::vec2(pos) - glm::vec2(P) ) < 1.5f * scale;
|
||||
}
|
||||
else if ( n.type() == Handles::CROP ){
|
||||
// the icon for cropping is on the left bottom corner at (0.12, 0.12) in scene coordinates
|
||||
glm::vec4 pos = glm::inverse(ctm) * glm::vec4( 0.12f, 0.12f, 0.f, 0.f );
|
||||
picked = glm::length( glm::vec2( -1.f, -1.f) + glm::vec2(pos) - glm::vec2(P) ) < 1.5f * scale;
|
||||
}
|
||||
else if ( n.type() == Handles::MENU ){
|
||||
// the icon for restore is on the left top corner at (-0.12, 0.12) in scene coordinates
|
||||
glm::vec4 vec = glm::inverse(modelview_) * glm::vec4( 0.1f, 0.1f, 0.f, 0.f );
|
||||
float l = glm::length( glm::vec2(vec) );
|
||||
picked = glm::length( glm::vec2( -1.f - l, 1.f + l) - glm::vec2(P) ) < 1.5f * scale;
|
||||
glm::vec4 pos = glm::inverse(ctm) * glm::vec4( -0.12f, 0.12f, 0.f, 0.f );
|
||||
picked = glm::length( glm::vec2( -1.f, 1.f) + glm::vec2(pos) - glm::vec2(P) ) < 1.5f * scale;
|
||||
}
|
||||
|
||||
if ( picked )
|
||||
|
||||
@@ -171,19 +171,8 @@ void MediaSurface::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
FrameBufferSurface::FrameBufferSurface(FrameBuffer *fb, Shader *s) : Surface(s), frame_buffer_(fb)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void FrameBufferSurface::init()
|
||||
{
|
||||
Surface::init();
|
||||
|
||||
// set aspect ratio
|
||||
scale_.x = frame_buffer_->aspectRatio();
|
||||
|
||||
}
|
||||
|
||||
void FrameBufferSurface::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
@@ -204,7 +193,6 @@ void FrameBufferSurface::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
|
||||
Points::Points(std::vector<glm::vec3> points, glm::vec4 color, uint pointsize) : Primitive(new Shader)
|
||||
{
|
||||
for(size_t i = 0; i < points.size(); ++i)
|
||||
@@ -218,8 +206,6 @@ Points::Points(std::vector<glm::vec3> points, glm::vec4 color, uint pointsize) :
|
||||
pointsize_ = pointsize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Points::draw(glm::mat4 modelview, glm::mat4 projection)
|
||||
{
|
||||
if ( !initialized() )
|
||||
|
||||
@@ -94,7 +94,6 @@ class FrameBufferSurface : public Surface {
|
||||
public:
|
||||
FrameBufferSurface(FrameBuffer *fb, Shader *s = new ImageShader);
|
||||
|
||||
void init () override;
|
||||
void draw (glm::mat4 modelview, glm::mat4 projection) override;
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ and (recursively) clone all the internal git Dependencies.
|
||||
|
||||
**Ubuntu**
|
||||
|
||||
apt-get install build-essential cmake libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
|
||||
apt-get install build-essential cmake libpng-dev libglfw3-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libicu-dev
|
||||
|
||||
**OSX with Brew**
|
||||
|
||||
brew install cmake libpng glfw gstreamer gst-libav gst-plugins-bad gst-plugins-base gst-plugins-good gst-plugins-ugly
|
||||
brew install cmake libpng glfw gstreamer gst-libav gst-plugins-bad gst-plugins-base gst-plugins-good gst-plugins-ugly icu4c
|
||||
|
||||
@@ -157,6 +157,15 @@ bool Rendering::init()
|
||||
g_setenv ("GST_GL_API", "opengl3", TRUE);
|
||||
gst_init (NULL, NULL);
|
||||
|
||||
// increase selection rank for GPU decoding plugins
|
||||
if (Settings::application.render.gpu_decoding) {
|
||||
std::list<std::string> gpuplugins = GstToolkit::enable_gpu_decoding_plugins();
|
||||
if (gpuplugins.size() > 0) {
|
||||
Log::Info("Video decoding favoring the following GPU decoding plugin(s):");
|
||||
for(auto it = gpuplugins.begin(); it != gpuplugins.end(); it++)
|
||||
Log::Info(" - %s", (*it).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//#if GST_GL_HAVE_PLATFORM_WGL
|
||||
// global_gl_context = gst_gl_context_new_wrapped (display, (guintptr) wglGetCurrentContext (),
|
||||
@@ -186,9 +195,6 @@ bool Rendering::init()
|
||||
glfwSetKeyCallback( output_.window(), WindowEscapeFullscreen);
|
||||
glfwSetMouseButtonCallback( output_.window(), WindowToggleFullscreen);
|
||||
|
||||
|
||||
// GstDeviceMonitor *dm = GstToolkit::setup_raw_video_source_device_monitor();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -267,6 +273,12 @@ void Rendering::draw()
|
||||
// no g_main_loop_run(loop) : update global GMainContext
|
||||
g_main_context_iteration(NULL, FALSE);
|
||||
|
||||
// software framerate limiter 60FPS if not v-sync
|
||||
if ( Settings::application.render.vsync < 1 ) {
|
||||
int dt = 18000 - int( 1000.f * Mixer::manager().dt() );
|
||||
if (dt > 100)
|
||||
g_usleep( dt );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ Node::Node() : initialized_(false), visible_(true), refcount_(0)
|
||||
scale_ = glm::vec3(1.f);
|
||||
rotation_ = glm::vec3(0.f);
|
||||
translation_ = glm::vec3(0.f);
|
||||
crop_ = glm::vec3(1.f);
|
||||
}
|
||||
|
||||
Node::~Node ()
|
||||
@@ -53,6 +54,7 @@ void Node::copyTransform(Node *other)
|
||||
scale_ = other->scale_;
|
||||
rotation_ = other->rotation_;
|
||||
translation_ = other->translation_;
|
||||
crop_ = other->crop_;
|
||||
}
|
||||
|
||||
void Node::update( float dt)
|
||||
|
||||
2
Scene.h
@@ -70,7 +70,7 @@ public:
|
||||
bool visible_;
|
||||
uint refcount_;
|
||||
glm::mat4 transform_;
|
||||
glm::vec3 scale_, rotation_, translation_;
|
||||
glm::vec3 scale_, rotation_, translation_, crop_;
|
||||
|
||||
// animation update callbacks
|
||||
// list of callbacks to call at each update
|
||||
|
||||
@@ -39,7 +39,7 @@ void Screenshot::captureGL(int x, int y, int w, int h)
|
||||
{
|
||||
Width = w - x;
|
||||
Height = h - y;
|
||||
unsigned int size = Width * Height * 4;
|
||||
unsigned int size = Width * Height * 3;
|
||||
|
||||
// create BPO
|
||||
if (Pbo == 0)
|
||||
@@ -58,7 +58,7 @@ void Screenshot::captureGL(int x, int y, int w, int h)
|
||||
|
||||
// screenshot to PBO (fast)
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
Pbo_full = true;
|
||||
|
||||
// done
|
||||
@@ -85,6 +85,7 @@ void Screenshot::save(std::string filename)
|
||||
|
||||
// ready for next
|
||||
Pbo_full = false;
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -128,11 +129,9 @@ void Screenshot::storeToFile(Screenshot *s, std::string filename)
|
||||
ScreenshotSavePending_ = true;
|
||||
// got data to save ?
|
||||
if (s && s->Data) {
|
||||
// make it usable
|
||||
s->RemoveAlpha();
|
||||
s->FlipVertical();
|
||||
// save file
|
||||
stbi_write_png(filename.c_str(), s->Width, s->Height, 4, s->Data, s->Width * 4);
|
||||
stbi_flip_vertically_on_write(true);
|
||||
stbi_write_png(filename.c_str(), s->Width, s->Height, 3, s->Data, s->Width * 3);
|
||||
}
|
||||
ScreenshotSavePending_ = false;
|
||||
}
|
||||
|
||||
@@ -106,10 +106,8 @@ SourceList::iterator Session::addSource(Source *s)
|
||||
SourceList::iterator its = find(s);
|
||||
// ok, its NOT in the list !
|
||||
if (its == sources_.end()) {
|
||||
|
||||
// insert the source in the rendering
|
||||
render_.scene.ws()->attach(s->group(View::RENDERING));
|
||||
|
||||
// insert the source to the beginning of the list
|
||||
sources_.push_front(s);
|
||||
}
|
||||
@@ -130,13 +128,10 @@ SourceList::iterator Session::deleteSource(Source *s)
|
||||
SourceList::iterator its = find(s);
|
||||
// ok, its in the list !
|
||||
if (its != sources_.end()) {
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
its = sources_.erase(its);
|
||||
|
||||
// delete the source : safe now
|
||||
delete s;
|
||||
}
|
||||
@@ -158,10 +153,8 @@ void Session::removeSource(Source *s)
|
||||
SourceList::iterator its = find(s);
|
||||
// ok, its in the list !
|
||||
if (its != sources_.end()) {
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
sources_.erase(its);
|
||||
}
|
||||
@@ -179,10 +172,8 @@ Source *Session::popSource()
|
||||
if (its != sources_.end())
|
||||
{
|
||||
s = *its;
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
sources_.erase(its);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,10 @@ void SessionCreator::load(const std::string& filename)
|
||||
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());
|
||||
Log::Warning("%s session file is in version v%d.%d. but this vimix program expects v%d.%d.\n"
|
||||
"Loading might fail or lead to different or incomplete configuration.\n"
|
||||
"You can save this session again to avoid this warning.",
|
||||
filename.c_str(), version_major, version_minor, XML_VERSION_MAJOR, XML_VERSION_MINOR);
|
||||
// return;
|
||||
}
|
||||
|
||||
@@ -100,6 +103,7 @@ void SessionCreator::loadConfig(XMLElement *viewsNode)
|
||||
SessionLoader::XMLToNode( viewsNode->FirstChildElement("Mixing"), *session_->config(View::MIXING));
|
||||
SessionLoader::XMLToNode( viewsNode->FirstChildElement("Geometry"), *session_->config(View::GEOMETRY));
|
||||
SessionLoader::XMLToNode( viewsNode->FirstChildElement("Layer"), *session_->config(View::LAYER));
|
||||
SessionLoader::XMLToNode( viewsNode->FirstChildElement("Appearance"), *session_->config(View::APPEARANCE));
|
||||
SessionLoader::XMLToNode( viewsNode->FirstChildElement("Rendering"), *session_->config(View::RENDERING));
|
||||
}
|
||||
}
|
||||
@@ -109,52 +113,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)
|
||||
{
|
||||
sources_id_.clear();
|
||||
@@ -347,6 +305,9 @@ void SessionLoader::XMLToNode(tinyxml2::XMLElement *xml, Node &n)
|
||||
XMLElement *rotationNode = node->FirstChildElement("rotation");
|
||||
if (rotationNode)
|
||||
tinyxml2::XMLElementToGLM( rotationNode->FirstChildElement("vec3"), n.rotation_);
|
||||
XMLElement *cropNode = node->FirstChildElement("crop");
|
||||
if (cropNode)
|
||||
tinyxml2::XMLElementToGLM( cropNode->FirstChildElement("vec3"), n.crop_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,9 +389,26 @@ void SessionLoader::visit(ImageShader &n)
|
||||
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
|
||||
if (uniforms) {
|
||||
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);
|
||||
xmlCurrent_->QueryUnsignedAttribute("shape", &n.shape);
|
||||
|
||||
XMLElement* uniforms = xmlCurrent_->FirstChildElement("uniforms");
|
||||
if (uniforms) {
|
||||
uniforms->QueryFloatAttribute("blur", &n.blur);
|
||||
uniforms->QueryIntAttribute("option", &n.option);
|
||||
XMLElement* size = uniforms->FirstChildElement("size");
|
||||
if (size)
|
||||
tinyxml2::XMLElementToGLM( size->FirstChildElement("vec2"), n.size);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionLoader::visit(ImageProcessingShader &n)
|
||||
@@ -471,27 +449,55 @@ void SessionLoader::visit (Source& s)
|
||||
s.setName(pName);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Mixing");
|
||||
s.groupNode(View::MIXING)->accept(*this);
|
||||
if (xmlCurrent_) s.groupNode(View::MIXING)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Geometry");
|
||||
s.groupNode(View::GEOMETRY)->accept(*this);
|
||||
if (xmlCurrent_) s.groupNode(View::GEOMETRY)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Layer");
|
||||
s.groupNode(View::LAYER)->accept(*this);
|
||||
if (xmlCurrent_) s.groupNode(View::LAYER)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Appearance");
|
||||
s.groupNode(View::APPEARANCE)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Crop");
|
||||
s.renderingSurface()->accept(*this);
|
||||
if (xmlCurrent_) s.groupNode(View::APPEARANCE)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Blending");
|
||||
s.blendingShader()->accept(*this);
|
||||
if (xmlCurrent_) s.blendingShader()->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Mask");
|
||||
if (xmlCurrent_) {
|
||||
// read the mask shader attributes
|
||||
s.maskShader()->accept(*this);
|
||||
// if there is an Image mask stored
|
||||
XMLElement* imageNode = xmlCurrent_->FirstChildElement("Image");
|
||||
if (imageNode) {
|
||||
// if there is an internal array of data
|
||||
XMLElement* array = imageNode->FirstChildElement("array");
|
||||
if (array) {
|
||||
// create a temporary jpeg with size of the array
|
||||
FrameBufferImage::jpegBuffer jpgimg;
|
||||
array->QueryUnsignedAttribute("len", &jpgimg.len);
|
||||
// ok, we got a size of data to load
|
||||
if (jpgimg.len>0) {
|
||||
// allocate jpeg buffer
|
||||
jpgimg.buffer = (unsigned char*) malloc(jpgimg.len);
|
||||
// actual decoding of array
|
||||
if (XMLElementDecodeArray(array, jpgimg.buffer, jpgimg.len) )
|
||||
// create and set the image from jpeg
|
||||
s.setMask(new FrameBufferImage(jpgimg));
|
||||
// free temporary buffer
|
||||
if (jpgimg.buffer)
|
||||
free(jpgimg.buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("ImageProcessing");
|
||||
bool on = xmlCurrent_->BoolAttribute("enabled", true);
|
||||
s.processingShader()->accept(*this);
|
||||
s.setImageProcessingEnabled(on);
|
||||
if (xmlCurrent_) {
|
||||
bool on = xmlCurrent_->BoolAttribute("enabled", true);
|
||||
s.processingShader()->accept(*this);
|
||||
s.setImageProcessingEnabled(on);
|
||||
}
|
||||
|
||||
// restore current
|
||||
xmlCurrent_ = sourceNode;
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
void visit (MediaPlayer& n) override;
|
||||
void visit (Shader& n) override;
|
||||
void visit (ImageShader& n) override;
|
||||
void visit (MaskShader& n) override;
|
||||
void visit (ImageProcessingShader& n) override;
|
||||
|
||||
// Sources
|
||||
|
||||
@@ -116,6 +116,8 @@ void SessionSource::init()
|
||||
}
|
||||
else {
|
||||
|
||||
session_->update(dt_);
|
||||
|
||||
if (wait_for_sources_) {
|
||||
|
||||
// force update of of all sources
|
||||
@@ -145,8 +147,7 @@ void SessionSource::init()
|
||||
// set resolution
|
||||
session_->setResolution( session_->config(View::RENDERING)->scale_ );
|
||||
|
||||
// deep update once to draw framebuffer
|
||||
View::need_deep_update_ = true;
|
||||
// update to draw framebuffer
|
||||
session_->update(dt_);
|
||||
|
||||
// get the texture index from framebuffer of session, apply it to the surface
|
||||
@@ -173,6 +174,8 @@ void SessionSource::init()
|
||||
Node *loader = overlays_[View::TRANSITION]->back();
|
||||
overlays_[View::TRANSITION]->detach(loader);
|
||||
delete loader;
|
||||
// deep update to reorder
|
||||
View::need_deep_update_++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,9 +253,11 @@ void RenderSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// deep update to reorder
|
||||
View::need_deep_update_++;
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
|
||||
Log::Info("Source Render linked to session (%d x %d).", int(fb->resolution().x), int(fb->resolution().y) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ tinyxml2::XMLElement *SessionVisitor::NodeToXML(Node &n, tinyxml2::XMLDocument *
|
||||
rotation->InsertEndChild( XMLElementFromGLM(doc, n.rotation_) );
|
||||
newelement->InsertEndChild(rotation);
|
||||
|
||||
XMLElement *crop = doc->NewElement("crop");
|
||||
crop->InsertEndChild( XMLElementFromGLM(doc, n.crop_) );
|
||||
newelement->InsertEndChild(crop);
|
||||
|
||||
return newelement;
|
||||
}
|
||||
|
||||
@@ -199,9 +203,24 @@ void SessionVisitor::visit(ImageShader &n)
|
||||
|
||||
XMLElement *uniforms = xmlDoc_->NewElement("uniforms");
|
||||
uniforms->SetAttribute("stipple", n.stipple);
|
||||
uniforms->SetAttribute("mask", n.mask);
|
||||
xmlCurrent_->InsertEndChild(uniforms);
|
||||
}
|
||||
|
||||
void SessionVisitor::visit(MaskShader &n)
|
||||
{
|
||||
// Shader of a mask type
|
||||
xmlCurrent_->SetAttribute("type", "MaskShader");
|
||||
xmlCurrent_->SetAttribute("id", n.id());
|
||||
xmlCurrent_->SetAttribute("mode", n.mode);
|
||||
xmlCurrent_->SetAttribute("shape", n.shape);
|
||||
|
||||
XMLElement *uniforms = xmlDoc_->NewElement("uniforms");
|
||||
uniforms->SetAttribute("blur", n.blur);
|
||||
uniforms->SetAttribute("option", n.option);
|
||||
XMLElement *size = xmlDoc_->NewElement("size");
|
||||
size->InsertEndChild( XMLElementFromGLM(xmlDoc_, n.size) );
|
||||
uniforms->InsertEndChild(size);
|
||||
xmlCurrent_->InsertEndChild(uniforms);
|
||||
}
|
||||
|
||||
void SessionVisitor::visit(ImageProcessingShader &n)
|
||||
@@ -343,14 +362,36 @@ void SessionVisitor::visit (Source& s)
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.groupNode(View::APPEARANCE)->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement("Crop");
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.renderingSurface()->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Blending" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.blendingShader()->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Mask" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.maskShader()->accept(*this);
|
||||
// if we are saving a pain mask
|
||||
if (s.maskShader()->mode == MaskShader::PAINT) {
|
||||
// get the mask previously stored
|
||||
FrameBufferImage *img = s.getMask();
|
||||
if (img != nullptr) {
|
||||
// get the jpeg encoded buffer
|
||||
FrameBufferImage::jpegBuffer jpgimg = img->getJpeg();
|
||||
if (jpgimg.buffer != nullptr) {
|
||||
// fill the xml array with jpeg buffer
|
||||
XMLElement *array = XMLElementEncodeArray(xmlDoc_, jpgimg.buffer, jpgimg.len);
|
||||
// free the buffer
|
||||
free(jpgimg.buffer);
|
||||
// if we could create the array
|
||||
if (array) {
|
||||
// create an Image node to store the mask image
|
||||
XMLElement *imageelement = xmlDoc_->NewElement("Image");
|
||||
imageelement->InsertEndChild(array);
|
||||
xmlCurrent_->InsertEndChild(imageelement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "ImageProcessing" );
|
||||
xmlCurrent_->SetAttribute("enabled", s.imageProcessingEnabled());
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
void visit(MediaPlayer& n) override;
|
||||
void visit(Shader& n) override;
|
||||
void visit(ImageShader& n) override;
|
||||
void visit(MaskShader& n) override;
|
||||
void visit(ImageProcessingShader& n) override;
|
||||
|
||||
// Sources
|
||||
|
||||
@@ -82,6 +82,7 @@ void Settings::Save()
|
||||
RenderNode->SetAttribute("vsync", application.render.vsync);
|
||||
RenderNode->SetAttribute("multisampling", application.render.multisampling);
|
||||
RenderNode->SetAttribute("blit", application.render.blit);
|
||||
RenderNode->SetAttribute("gpu_decoding", application.render.gpu_decoding);
|
||||
RenderNode->SetAttribute("ratio", application.render.ratio);
|
||||
RenderNode->SetAttribute("res", application.render.res);
|
||||
pRoot->InsertEndChild(RenderNode);
|
||||
@@ -127,8 +128,8 @@ void Settings::Save()
|
||||
// bloc views
|
||||
{
|
||||
XMLElement *viewsNode = xmlDoc.NewElement( "Views" );
|
||||
// save current view only if [mixing, geometry or layers]
|
||||
int v = application.current_view > 3 ? 1 : application.current_view;
|
||||
// save current view only if [mixing, geometry, layers, appearance]
|
||||
int v = application.current_view > 4 ? 1 : application.current_view;
|
||||
viewsNode->SetAttribute("current", v);
|
||||
|
||||
map<int, Settings::ViewConfig>::iterator iter;
|
||||
@@ -264,6 +265,7 @@ void Settings::Load()
|
||||
rendernode->QueryIntAttribute("vsync", &application.render.vsync);
|
||||
rendernode->QueryIntAttribute("multisampling", &application.render.multisampling);
|
||||
rendernode->QueryBoolAttribute("blit", &application.render.blit);
|
||||
rendernode->QueryBoolAttribute("gpu_decoding", &application.render.gpu_decoding);
|
||||
rendernode->QueryIntAttribute("ratio", &application.render.ratio);
|
||||
rendernode->QueryIntAttribute("res", &application.render.res);
|
||||
}
|
||||
|
||||
@@ -136,14 +136,16 @@ struct RenderConfig
|
||||
int ratio;
|
||||
int res;
|
||||
float fading;
|
||||
bool gpu_decoding;
|
||||
|
||||
RenderConfig() {
|
||||
blit = false;
|
||||
vsync = 1; // todo GUI selection
|
||||
multisampling = 2; // todo GUI selection
|
||||
vsync = 1;
|
||||
multisampling = 2;
|
||||
ratio = 3;
|
||||
res = 1;
|
||||
fading = 0.0;
|
||||
gpu_decoding = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
16
Shader.cpp
@@ -1,5 +1,6 @@
|
||||
#include "Shader.h"
|
||||
#include "Resource.h"
|
||||
#include "FrameBuffer.h"
|
||||
#include "Log.h"
|
||||
#include "Visitor.h"
|
||||
#include "RenderingManager.h"
|
||||
@@ -119,14 +120,20 @@ void ShadingProgram::setUniform<float>(const std::string& name, float val1, floa
|
||||
}
|
||||
|
||||
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));
|
||||
void ShadingProgram::setUniform<glm::vec2>(const std::string& name, glm::vec2 val) {
|
||||
glm::vec2 v(val);
|
||||
glUniform2fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
|
||||
}
|
||||
|
||||
template<>
|
||||
void ShadingProgram::setUniform<glm::vec3>(const std::string& name, glm::vec3 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));
|
||||
}
|
||||
|
||||
@@ -208,7 +215,7 @@ void Shader::use()
|
||||
program_->setUniform("iTransform", iTransform);
|
||||
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);
|
||||
|
||||
// Blending Function
|
||||
@@ -238,7 +245,6 @@ void Shader::reset()
|
||||
projection = glm::identity<glm::mat4>();
|
||||
modelview = 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);
|
||||
}
|
||||
|
||||
|
||||
16
Shader.h
@@ -7,6 +7,7 @@
|
||||
|
||||
// Forward declare classes referenced
|
||||
class Visitor;
|
||||
class FrameBuffer;
|
||||
|
||||
class ShadingProgram
|
||||
{
|
||||
@@ -22,13 +23,13 @@ public:
|
||||
static void enduse();
|
||||
|
||||
private:
|
||||
void checkCompileErr();
|
||||
void checkLinkingErr();
|
||||
void compile();
|
||||
void link();
|
||||
unsigned int vertex_id_, fragment_id_, id_;
|
||||
std::string vertex_code_;
|
||||
std::string fragment_code_;
|
||||
void checkCompileErr();
|
||||
void checkLinkingErr();
|
||||
void compile();
|
||||
void link();
|
||||
unsigned int vertex_id_, fragment_id_, id_;
|
||||
std::string vertex_code_;
|
||||
std::string fragment_code_;
|
||||
std::string vertex_file_;
|
||||
std::string fragment_file_;
|
||||
|
||||
@@ -71,7 +72,6 @@ public:
|
||||
|
||||
protected:
|
||||
ShadingProgram *program_;
|
||||
glm::vec3 iResolution;
|
||||
|
||||
};
|
||||
|
||||
|
||||
238
Source.cpp
@@ -1,5 +1,5 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <locale>
|
||||
#include <glm/gtc/matrix_access.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
#include "SearchVisitor.h"
|
||||
#include "ImageShader.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "SystemToolkit.h"
|
||||
#include "Log.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
Source::Source() : initialized_(false), active_(true), need_update_(true), symbol_(nullptr)
|
||||
Source::Source() : initialized_(false), active_(true), locked_(false), need_update_(true), symbol_(nullptr)
|
||||
{
|
||||
// create unique id
|
||||
id_ = GlmToolkit::uniqueId();
|
||||
@@ -92,11 +93,15 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo
|
||||
handles_[View::GEOMETRY][Handles::SCALE] = new Handles(Handles::SCALE);
|
||||
handles_[View::GEOMETRY][Handles::SCALE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::SCALE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::SCALE]);
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::SCALE]);
|
||||
handles_[View::GEOMETRY][Handles::MENU] = new Handles(Handles::MENU);
|
||||
handles_[View::GEOMETRY][Handles::MENU]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::MENU]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::MENU]);
|
||||
handles_[View::GEOMETRY][Handles::CROP] = new Handles(Handles::CROP);
|
||||
handles_[View::GEOMETRY][Handles::CROP]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::CROP]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::CROP]);
|
||||
|
||||
frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
|
||||
frame->translation_.z = 0.1;
|
||||
@@ -172,15 +177,41 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo
|
||||
// empty transition node
|
||||
groups_[View::TRANSITION] = new Group;
|
||||
|
||||
//
|
||||
// shared locker symbol
|
||||
//
|
||||
locker_ = new Symbol(Symbol::LOCK, glm::vec3(0.8f, -0.8f, 0.01f));
|
||||
locker_->color = glm::vec4(1.f, 1.f, 1.f, 0.6f);
|
||||
|
||||
// add semi transparent icon statically to mixing and layer views
|
||||
Group *lockgroup = new Group;
|
||||
lockgroup->translation_.z = 0.1;
|
||||
lockgroup->attach( locker_ );
|
||||
groups_[View::LAYER]->attach(lockgroup);
|
||||
groups_[View::MIXING]->attach(lockgroup);
|
||||
|
||||
// add semi transparent icon dynamically with overlay
|
||||
overlays_[View::LAYER]->attach( locker_ );
|
||||
overlays_[View::MIXING]->attach( locker_ );
|
||||
|
||||
// create objects
|
||||
stored_status_ = new Group;
|
||||
|
||||
// those will be associated to nodes later
|
||||
// simple image shader (with texturing) for blending
|
||||
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;
|
||||
// default to image processing enabled
|
||||
// default rendering with image processing enabled
|
||||
renderingshader_ = (Shader *) processingshader_;
|
||||
|
||||
// for drawing in mixing view
|
||||
mixingshader_ = new ImageShader;
|
||||
mixingshader_->stipple = 1.0;
|
||||
|
||||
// create media surface:
|
||||
// - textured with original texture from media player
|
||||
// - crop & repeat UV can be managed here
|
||||
@@ -190,7 +221,10 @@ Source::Source() : initialized_(false), active_(true), need_update_(true), symbo
|
||||
// will be created at init
|
||||
renderbuffer_ = nullptr;
|
||||
rendersurface_ = nullptr;
|
||||
|
||||
mixingsurface_ = nullptr;
|
||||
maskbuffer_ = nullptr;
|
||||
maskimage_ = nullptr;
|
||||
mask_need_update_ = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,6 +239,10 @@ Source::~Source()
|
||||
delete stored_status_;
|
||||
if (renderbuffer_)
|
||||
delete renderbuffer_;
|
||||
if (maskbuffer_)
|
||||
delete maskbuffer_;
|
||||
if (maskimage_)
|
||||
delete maskimage_;
|
||||
|
||||
// all groups and their children are deleted in the scene
|
||||
// this includes rendersurface_, overlays, blendingshader_ and rendershader_
|
||||
@@ -229,10 +267,10 @@ Source::~Source()
|
||||
|
||||
void Source::setName (const std::string &name)
|
||||
{
|
||||
name_ = name;
|
||||
name_ = SystemToolkit::transliterate(name);
|
||||
|
||||
initials_[0] = std::toupper( name_.front() );
|
||||
initials_[1] = std::toupper( name_.back() );
|
||||
initials_[0] = std::toupper( name_.front(), std::locale("C") );
|
||||
initials_[1] = std::toupper( name_.back(), std::locale("C") );
|
||||
}
|
||||
|
||||
void Source::accept(Visitor& v)
|
||||
@@ -253,13 +291,13 @@ void Source::setMode(Source::Mode m)
|
||||
(*g).second->visible_ = true;
|
||||
}
|
||||
|
||||
// choose frame if selected
|
||||
// choose frame 0 if visible, 1 if selected
|
||||
uint index_frame = m == Source::VISIBLE ? 0 : 1;
|
||||
for (auto f = frames_.begin(); f != frames_.end(); f++)
|
||||
(*f).second->setActive(index_frame);
|
||||
|
||||
// show overlay if current
|
||||
bool current = m == Source::CURRENT;
|
||||
bool current = m >= Source::CURRENT;
|
||||
for (auto o = overlays_.begin(); o != overlays_.end(); o++)
|
||||
(*o).second->visible_ = current;
|
||||
|
||||
@@ -323,7 +361,7 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
{
|
||||
renderbuffer_ = renderbuffer;
|
||||
|
||||
// if a symbol is available, add it to icons
|
||||
// if a symbol is available, add it to overlay
|
||||
if (symbol_) {
|
||||
overlays_[View::MIXING]->attach( symbol_ );
|
||||
overlays_[View::LAYER]->attach( symbol_ );
|
||||
@@ -333,27 +371,23 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
|
||||
groups_[View::RENDERING]->attach(rendersurface_);
|
||||
groups_[View::GEOMETRY]->attach(rendersurface_);
|
||||
groups_[View::MIXING]->attach(rendersurface_);
|
||||
// groups_[View::LAYER]->attach(rendersurface_);
|
||||
|
||||
// for mixing and layer views, add another surface to overlay
|
||||
// (stippled view on top with transparency)
|
||||
Surface *surfacemix = new FrameBufferSurface(renderbuffer_);
|
||||
ImageShader *is = static_cast<ImageShader *>(surfacemix->shader());
|
||||
if (is) is->stipple = 1.0;
|
||||
groups_[View::MIXING]->attach(surfacemix);
|
||||
groups_[View::LAYER]->attach(surfacemix);
|
||||
mixingsurface_ = new FrameBufferSurface(renderbuffer_, mixingshader_);
|
||||
groups_[View::MIXING]->attach(mixingsurface_);
|
||||
groups_[View::LAYER]->attach(mixingsurface_);
|
||||
|
||||
// for appearance view, a dedicated surface without blending
|
||||
// for views showing a scaled mixing surface, a dedicated transparent surface allows grabbing
|
||||
Surface *surfacetmp = new Surface();
|
||||
surfacetmp->setTextureIndex(Resource::getTextureTransparent());
|
||||
groups_[View::APPEARANCE]->attach(surfacetmp);
|
||||
groups_[View::MIXING]->attach(surfacetmp);
|
||||
groups_[View::LAYER]->attach(surfacetmp);
|
||||
|
||||
// Transition group node is optionnal
|
||||
if ( groups_[View::TRANSITION]->numChildren() > 0 ) {
|
||||
groups_[View::TRANSITION]->attach(rendersurface_);
|
||||
groups_[View::TRANSITION]->attach(surfacemix);
|
||||
}
|
||||
if (groups_[View::TRANSITION]->numChildren() > 0)
|
||||
groups_[View::TRANSITION]->attach(mixingsurface_);
|
||||
|
||||
// scale all icon nodes to match aspect ratio
|
||||
for (int v = View::MIXING; v < View::INVALID; v++) {
|
||||
@@ -364,11 +398,21 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
}
|
||||
}
|
||||
|
||||
// hack to place the symbols in the corner independently of aspect ratio
|
||||
symbol_->translation_.x += 0.1f * (renderbuffer_->aspectRatio()-1.f);
|
||||
locker_->translation_.x += 0.1f * (renderbuffer_->aspectRatio()-1.f);
|
||||
|
||||
// (re) create the masking buffer
|
||||
if (maskbuffer_)
|
||||
delete maskbuffer_;
|
||||
maskbuffer_ = new FrameBuffer( glm::vec3(0.5) * renderbuffer->resolution() );
|
||||
|
||||
// make the source visible
|
||||
if ( mode_ == UNINITIALIZED ) {
|
||||
if ( mode_ == UNINITIALIZED )
|
||||
setMode(VISIBLE);
|
||||
need_update_ = true;
|
||||
}
|
||||
|
||||
// request update
|
||||
need_update_ = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -376,16 +420,32 @@ void Source::setActive (bool on)
|
||||
{
|
||||
active_ = on;
|
||||
|
||||
// do not disactivate if a clone depends on it
|
||||
for(auto clone = clones_.begin(); clone != clones_.end(); clone++) {
|
||||
if ( (*clone)->active() )
|
||||
active_ = true;
|
||||
}
|
||||
|
||||
// an inactive source is visible only in the MIXING view
|
||||
groups_[View::RENDERING]->visible_ = active_;
|
||||
groups_[View::GEOMETRY]->visible_ = active_;
|
||||
groups_[View::LAYER]->visible_ = active_;
|
||||
|
||||
}
|
||||
|
||||
void Source::setLocked (bool on)
|
||||
{
|
||||
locked_ = on;
|
||||
|
||||
// the lock icon is visible when locked
|
||||
locker_->visible_ = on;
|
||||
|
||||
// a locked source is not visible in the GEOMETRY view (that's the whole point of it!)
|
||||
groups_[View::GEOMETRY]->visible_ = !locked_;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Transfer functions from coordinates to alpha (1 - transparency)
|
||||
float linear_(float x, float y) {
|
||||
return 1.f - CLAMP( sqrt( ( x * x ) + ( y * y ) ), 0.f, 1.f );
|
||||
@@ -396,7 +456,9 @@ float quad_(float x, float y) {
|
||||
}
|
||||
|
||||
float sin_quad(float x, float y) {
|
||||
return 0.5f + 0.5f * cos( M_PI * CLAMP( ( ( x * x ) + ( y * y ) ), 0.f, 1.f ) );
|
||||
float D = sqrt( ( x * x ) + ( y * y ) );
|
||||
return 0.5f + 0.5f * cos( M_PI * CLAMP( D * sqrt(D), 0.f, 1.f ) );
|
||||
// return 0.5f + 0.5f * cos( M_PI * CLAMP( ( ( x * x ) + ( y * y ) ), 0.f, 1.f ) );
|
||||
}
|
||||
|
||||
void Source::update(float dt)
|
||||
@@ -405,30 +467,56 @@ void Source::update(float dt)
|
||||
dt_ = dt;
|
||||
|
||||
// update nodes if needed
|
||||
if (need_update_)
|
||||
if (renderbuffer_ && mixingsurface_ && maskbuffer_ && need_update_)
|
||||
{
|
||||
// Log::Info("UPDATE %s %f", initials_, dt);
|
||||
|
||||
// ADJUST alpha based on MIXING node
|
||||
// read position of the mixing node and interpret this as transparency of render output
|
||||
glm::vec2 dist = glm::vec2(groups_[View::MIXING]->translation_);
|
||||
// use the prefered transfer function
|
||||
blendingshader_->color.a = sin_quad( dist.x, dist.y );
|
||||
// use the sinusoidal transfer function
|
||||
blendingshader_->color = glm::vec4(1.0, 1.0, 1.0, sin_quad( dist.x, dist.y ));
|
||||
mixingshader_->color = blendingshader_->color;
|
||||
|
||||
// CHANGE update status based on limbo
|
||||
bool a = glm::length(dist) < 1.3f;
|
||||
bool a = glm::length(dist) < MIXING_LIMBO_SCALE;
|
||||
setActive( a );
|
||||
// adjust scale of mixing icon : smaller if not active
|
||||
groups_[View::MIXING]->scale_ = glm::vec3(MIXING_ICON_SCALE) - ( a ? glm::vec3(0.f, 0.f, 0.f) : glm::vec3(0.03f, 0.03f, 0.f) );
|
||||
|
||||
// MODIFY geometry based on GEOMETRY node
|
||||
groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_;
|
||||
groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_;
|
||||
// avoid any null scale
|
||||
glm::vec3 s = groups_[View::GEOMETRY]->scale_;
|
||||
// avoid any null scale
|
||||
s.x = CLAMP_SCALE(s.x);
|
||||
s.y = CLAMP_SCALE(s.y);
|
||||
s.z = 1.f;
|
||||
groups_[View::GEOMETRY]->scale_ = s;
|
||||
groups_[View::RENDERING]->scale_ = s;
|
||||
|
||||
// MODIFY CROP projection based on GEOMETRY crop
|
||||
renderbuffer_->setProjectionArea( glm::vec2(groups_[View::GEOMETRY]->crop_) );
|
||||
|
||||
// Mixing and layer icons scaled based on GEOMETRY crop
|
||||
mixingsurface_->scale_ = groups_[View::GEOMETRY]->crop_;
|
||||
mixingsurface_->scale_.x *= renderbuffer_->aspectRatio();
|
||||
mixingsurface_->update(dt_);
|
||||
|
||||
// Layers icons are displayed in Perspective (diagonal)
|
||||
groups_[View::LAYER]->translation_.y = groups_[View::LAYER]->translation_.x / LAYER_PERSPECTIVE;
|
||||
|
||||
// CHANGE lock based on range of layers stage
|
||||
bool l = (groups_[View::LAYER]->translation_.x < -FOREGROUND_DEPTH)
|
||||
|| (groups_[View::LAYER]->translation_.x > -BACKGROUND_DEPTH);
|
||||
setLocked( l );
|
||||
|
||||
// adjust position of layer icon: step up when on stage
|
||||
if (groups_[View::LAYER]->translation_.x < -FOREGROUND_DEPTH)
|
||||
groups_[View::LAYER]->translation_.y -= 0.3f;
|
||||
else if (groups_[View::LAYER]->translation_.x < -BACKGROUND_DEPTH)
|
||||
groups_[View::LAYER]->translation_.y -= 0.15f;
|
||||
|
||||
// MODIFY depth based on LAYER node
|
||||
groups_[View::MIXING]->translation_.z = groups_[View::LAYER]->translation_.z;
|
||||
groups_[View::GEOMETRY]->translation_.z = groups_[View::LAYER]->translation_.z;
|
||||
@@ -437,19 +525,14 @@ void Source::update(float dt)
|
||||
// MODIFY texture projection based on APPEARANCE node
|
||||
// UV to node coordinates
|
||||
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));
|
||||
// make sure to update rendering texture surface node
|
||||
texturesurface_->update(dt);
|
||||
glm::vec3(0.f, 0.f, 0.f),
|
||||
glm::vec3(-2.f, 2.f, 1.f));
|
||||
// Aspect Ratio correction transform : coordinates of Appearance Frame are scaled by render buffer width
|
||||
glm::mat4 Ar = glm::identity<glm::mat4>();
|
||||
if (renderbuffer_)
|
||||
Ar = glm::scale(glm::identity<glm::mat4>(), glm::vec3(renderbuffer_->aspectRatio() * texturesurface_->scale_.x, texturesurface_->scale_.y, 1.f) );
|
||||
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)
|
||||
glm::mat4 Tra = glm::translate(glm::identity<glm::mat4>(), groups_[View::APPEARANCE]->translation_);
|
||||
// Scaling : inverse scaling (larger UV when smaller Appearance Frame)
|
||||
glm::mat4 Sca = glm::scale(glm::identity<glm::mat4>(), glm::vec3( texturesurface_->scale_.x / groups_[View::APPEARANCE]->scale_.x,
|
||||
texturesurface_->scale_.y / groups_[View::APPEARANCE]->scale_.y, 1.f));
|
||||
glm::mat4 Sca = glm::scale(glm::identity<glm::mat4>(), glm::vec3(groups_[View::APPEARANCE]->scale_.x,groups_[View::APPEARANCE]->scale_.y, 1.f));
|
||||
// Rotation : same angle than Appearance Frame, inverted axis
|
||||
glm::mat4 Rot = glm::rotate(glm::identity<glm::mat4>(), groups_[View::APPEARANCE]->rotation_.z, glm::vec3(0.f, 0.f, -1.f) );
|
||||
// Combine transformations (non transitive) in this order:
|
||||
@@ -460,11 +543,33 @@ 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) * Sca * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene;
|
||||
texturesurface_->shader()->iTransform = glm::inverse(UVtoScene) * glm::inverse(Sca) * glm::inverse(Ar) * Rot * Tra * Ar * UVtoScene;
|
||||
|
||||
// if a mask image was given to be updated
|
||||
if (mask_need_update_) {
|
||||
// fill the mask buffer (once)
|
||||
if (maskbuffer_->fill(maskimage_) )
|
||||
mask_need_update_ = false;
|
||||
}
|
||||
// otherwise, render the mask buffer
|
||||
else
|
||||
{
|
||||
// draw mask in mask frame buffer
|
||||
maskbuffer_->begin(false);
|
||||
// loopback maskbuffer texture for painting
|
||||
masksurface_->setTextureIndex(maskbuffer_->texture());
|
||||
// fill surface with mask texture
|
||||
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
|
||||
need_update_ = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FrameBuffer *Source::frame() const
|
||||
@@ -489,6 +594,49 @@ bool Source::contains(Node *node) const
|
||||
}
|
||||
|
||||
|
||||
void Source::storeMask(FrameBufferImage *img)
|
||||
{
|
||||
// free the output mask storage
|
||||
if (maskimage_ != nullptr) {
|
||||
delete maskimage_;
|
||||
maskimage_ = nullptr;
|
||||
}
|
||||
|
||||
// if no image is provided
|
||||
if (img == nullptr) {
|
||||
// if ready
|
||||
if (maskbuffer_!=nullptr) {
|
||||
// get & store image from mask buffer
|
||||
maskimage_ = maskbuffer_->image();
|
||||
}
|
||||
}
|
||||
else
|
||||
// store the given image
|
||||
maskimage_ = img;
|
||||
|
||||
// maskimage_ can now be accessed with Source::getStoredMask
|
||||
}
|
||||
|
||||
void Source::setMask(FrameBufferImage *img)
|
||||
{
|
||||
// if a valid image is given
|
||||
if (img != nullptr && img->width>0 && img->height>0) {
|
||||
|
||||
// remember this new image as the current mask
|
||||
// NB: will be freed when replaced
|
||||
storeMask(img);
|
||||
|
||||
// ask Source::update to use it at next update for filling mask buffer
|
||||
mask_need_update_ = true;
|
||||
|
||||
// ask to update the source
|
||||
touch();
|
||||
}
|
||||
else
|
||||
mask_need_update_ = false;
|
||||
}
|
||||
|
||||
|
||||
bool Source::hasNode::operator()(const Source* elem) const
|
||||
{
|
||||
if (_n && elem)
|
||||
@@ -560,9 +708,11 @@ void CloneSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// deep update to reorder
|
||||
View::need_deep_update_++;
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
|
||||
Log::Info("Source %s cloning source %s.", name().c_str(), origin_->name().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
35
Source.h
@@ -11,6 +11,7 @@
|
||||
#define DEFAULT_MIXING_TRANSLATION -1.f, 1.f
|
||||
|
||||
class ImageShader;
|
||||
class MaskShader;
|
||||
class ImageProcessingShader;
|
||||
class FrameBuffer;
|
||||
class FrameBufferSurface;
|
||||
@@ -66,12 +67,6 @@ public:
|
||||
// tests if a given node is part of the source
|
||||
bool contains (Node *node) const;
|
||||
|
||||
// a Source has a shader used to render in fbo
|
||||
inline Shader *renderingShader () const { return renderingshader_; }
|
||||
|
||||
// a Source has a surface used to draw images
|
||||
inline Surface *renderingSurface () const { return texturesurface_; }
|
||||
|
||||
// the rendering shader always have an image processing shader
|
||||
inline ImageProcessingShader *processingShader () const { return processingshader_; }
|
||||
|
||||
@@ -82,10 +77,15 @@ public:
|
||||
|
||||
// a Source has a shader to control mixing effects
|
||||
inline ImageShader *blendingShader () const { return blendingshader_; }
|
||||
// a Source has a shader used to render in fbo
|
||||
inline Shader *renderingShader () const { return renderingshader_; }
|
||||
|
||||
// every Source has a frame buffer from the renderbuffer
|
||||
virtual FrameBuffer *frame () const;
|
||||
|
||||
// a Source has a shader used to render mask
|
||||
inline MaskShader *maskShader () const { return maskshader_; }
|
||||
|
||||
// touch to request update
|
||||
inline void touch () { need_update_ = true; }
|
||||
|
||||
@@ -99,6 +99,10 @@ public:
|
||||
virtual void setActive (bool on);
|
||||
inline bool active () { return active_; }
|
||||
|
||||
// lock mode
|
||||
virtual void setLocked (bool on);
|
||||
inline bool locked () { return locked_; }
|
||||
|
||||
// a Source shall informs if the source failed (i.e. shall be deleted)
|
||||
virtual bool failed () const = 0;
|
||||
|
||||
@@ -111,6 +115,11 @@ public:
|
||||
// accept all kind of visitors
|
||||
virtual void accept (Visitor& v);
|
||||
|
||||
// operations on mask
|
||||
void storeMask(FrameBufferImage *img = nullptr);
|
||||
FrameBufferImage *getMask() const { return maskimage_; }
|
||||
void setMask(FrameBufferImage *img);
|
||||
|
||||
struct hasNode: public std::unary_function<Source*, bool>
|
||||
{
|
||||
bool operator()(const Source* elem) const;
|
||||
@@ -162,6 +171,7 @@ protected:
|
||||
// the rendersurface draws the renderbuffer in the scene
|
||||
// It is associated to the rendershader for mixing effects
|
||||
FrameBufferSurface *rendersurface_;
|
||||
FrameBufferSurface *mixingsurface_;
|
||||
|
||||
// image processing shaders
|
||||
ImageProcessingShader *processingshader_;
|
||||
@@ -171,6 +181,14 @@ protected:
|
||||
|
||||
// blendingshader provides mixing controls
|
||||
ImageShader *blendingshader_;
|
||||
ImageShader *mixingshader_;
|
||||
|
||||
// shader and buffer to draw mask
|
||||
MaskShader *maskshader_;
|
||||
FrameBuffer *maskbuffer_;
|
||||
Surface *masksurface_;
|
||||
bool mask_need_update_;
|
||||
FrameBufferImage *maskimage_;
|
||||
|
||||
// surface to draw on
|
||||
Surface *texturesurface_;
|
||||
@@ -181,11 +199,12 @@ protected:
|
||||
// overlays and frames to be displayed on top of source
|
||||
std::map<View::Mode, Group*> overlays_;
|
||||
std::map<View::Mode, Switch*> frames_;
|
||||
std::map<View::Mode, Handles*[6]> handles_;
|
||||
Symbol *symbol_;
|
||||
std::map<View::Mode, Handles*[7]> handles_;
|
||||
Symbol *symbol_, *locker_;
|
||||
|
||||
// update
|
||||
bool active_;
|
||||
bool locked_;
|
||||
bool need_update_;
|
||||
float dt_;
|
||||
Group *stored_status_;
|
||||
|
||||
@@ -80,13 +80,15 @@ void StreamSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source '%s' linked to Stream %s", name().c_str(), std::to_string(stream_->id()).c_str());
|
||||
// deep update to reorder
|
||||
View::need_deep_update_++;
|
||||
|
||||
// force update of activation mode
|
||||
active_ = true;
|
||||
touch();
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source '%s' linked to Stream %s", name().c_str(), std::to_string(stream_->id()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#include <ctime>
|
||||
#include <chrono>
|
||||
|
||||
#include <locale>
|
||||
#include <unicode/ustream.h>
|
||||
#include <unicode/translit.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -355,4 +359,23 @@ void SystemToolkit::execute(const string& command)
|
||||
// "gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,encoding-name=JPEG,payload=26 ! rtpjpegdepay ! jpegdec ! autovideosink").detach();;
|
||||
|
||||
|
||||
// Using ICU transliteration :
|
||||
// https://unicode-org.github.io/icu/userguide/transforms/general/#icu-transliterators
|
||||
|
||||
std::string SystemToolkit::transliterate(std::string input)
|
||||
{
|
||||
auto ucs = icu::UnicodeString::fromUTF8(input);
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
icu::Transliterator *firstTrans = icu::Transliterator::createInstance(
|
||||
"any-NFKD ; [:Nonspacing Mark:] Remove; NFKC; Latin", UTRANS_FORWARD, status);
|
||||
firstTrans->transliterate(ucs);
|
||||
|
||||
icu::Transliterator *secondTrans = icu::Transliterator::createInstance(
|
||||
"any-NFKD ; [:Nonspacing Mark:] Remove; [@!#$*%~] Remove; NFKC", UTRANS_FORWARD, status);
|
||||
secondTrans->transliterate(ucs);
|
||||
|
||||
std::ostringstream output;
|
||||
output << ucs;
|
||||
return output.str();
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace SystemToolkit
|
||||
|
||||
// try to open the file with system
|
||||
void open(const std::string& path);
|
||||
|
||||
// try to execute a command
|
||||
void execute(const std::string& command);
|
||||
|
||||
@@ -74,6 +75,9 @@ namespace SystemToolkit
|
||||
|
||||
// get a string to display memory size with unit KB, MB, GB, TB
|
||||
std::string byte_to_string(long b);
|
||||
|
||||
// get a transliteration to Latin of any string
|
||||
std::string transliterate(std::string input);
|
||||
}
|
||||
|
||||
#endif // SYSTEMTOOLKIT_H
|
||||
|
||||
@@ -15,7 +15,7 @@ using namespace std;
|
||||
#include "imgui_impl_opengl3.h"
|
||||
|
||||
// Desktop OpenGL function loader
|
||||
#include <glad/glad.h>
|
||||
#include <glad/glad.h>
|
||||
|
||||
// Include glfw3.h after our OpenGL definitions
|
||||
#include <GLFW/glfw3.h>
|
||||
@@ -158,7 +158,7 @@ UserInterface::UserInterface()
|
||||
ctrl_modifier_active = false;
|
||||
alt_modifier_active = false;
|
||||
shift_modifier_active = false;
|
||||
show_vimix_config = false;
|
||||
show_vimix_about = false;
|
||||
show_imgui_about = false;
|
||||
show_gst_about = false;
|
||||
show_opengl_about = false;
|
||||
@@ -178,9 +178,7 @@ bool UserInterface::Init()
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
io.MouseDrawCursor = true;
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.FontGlobalScale = Settings::application.scale;
|
||||
|
||||
// Setup Platform/Renderer bindings
|
||||
@@ -256,7 +254,7 @@ void UserInterface::handleKeyboard()
|
||||
}
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_O )) {
|
||||
// SHIFT + CTRL + O : reopen current session
|
||||
if (ctrl_modifier_active && !Mixer::manager().session()->filename().empty())
|
||||
if (shift_modifier_active && !Mixer::manager().session()->filename().empty())
|
||||
Mixer::manager().load( Mixer::manager().session()->filename() );
|
||||
// CTRL + O : Open session
|
||||
else
|
||||
@@ -384,8 +382,21 @@ void UserInterface::handleKeyboard()
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_INSERT ))
|
||||
navigator.togglePannelNew();
|
||||
// button tab to select next
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_TAB ))
|
||||
Mixer::manager().setCurrentNext();
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_TAB )) {
|
||||
if (shift_modifier_active)
|
||||
Mixer::manager().setCurrentPrevious();
|
||||
else
|
||||
Mixer::manager().setCurrentNext();
|
||||
}
|
||||
// arrow keys to act on current view
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_LEFT ))
|
||||
Mixer::manager().view()->arrow( glm::vec2(-1.f, 0.f) );
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_RIGHT ))
|
||||
Mixer::manager().view()->arrow( glm::vec2(+1.f, 0.f) );
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_UP ))
|
||||
Mixer::manager().view()->arrow( glm::vec2(0.f, -1.f) );
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_DOWN ))
|
||||
Mixer::manager().view()->arrow( glm::vec2(0.f, 1.f) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,6 +416,10 @@ void UserInterface::handleKeyboard()
|
||||
|
||||
void setMouseCursor(ImVec2 mousepos, View::Cursor c = View::Cursor())
|
||||
{
|
||||
// Hack if GLFW does not have all cursors, ask IMGUI to redraw cursor
|
||||
#if GLFW_HAS_NEW_CURSORS == 0
|
||||
ImGui::GetIO().MouseDrawCursor = (c.type > 0); // only redraw non-arrow cursor
|
||||
#endif
|
||||
ImGui::SetMouseCursor(c.type);
|
||||
|
||||
if ( !c.info.empty()) {
|
||||
@@ -444,10 +459,18 @@ void UserInterface::handleMouse()
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) /*|| ImGui::IsMouseClicked(ImGuiMouseButton_Middle)*/)
|
||||
ImGui::FocusWindow(NULL);
|
||||
|
||||
//
|
||||
// Mouse over
|
||||
//
|
||||
{
|
||||
View::Cursor c = Mixer::manager().view()->over(mousepos);
|
||||
if (c.type > 0)
|
||||
setMouseCursor(io.MousePos, c);
|
||||
}
|
||||
|
||||
// if not on any window
|
||||
if ( !ImGui::IsAnyWindowHovered() && !ImGui::IsAnyWindowFocused() )
|
||||
{
|
||||
|
||||
//
|
||||
// Mouse wheel over background
|
||||
//
|
||||
@@ -632,12 +655,13 @@ void UserInterface::handleMouse()
|
||||
}
|
||||
|
||||
|
||||
if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) )
|
||||
if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) || ImGui::IsMouseReleased(ImGuiMouseButton_Right) )
|
||||
{
|
||||
view_drag = nullptr;
|
||||
mousedown = false;
|
||||
picked = { nullptr, glm::vec2(0.f) };
|
||||
Mixer::manager().view()->terminate();
|
||||
setMouseCursor(io.MousePos);
|
||||
|
||||
// special case of one single source in selection : make current after release
|
||||
if (Mixer::selection().size() == 1)
|
||||
@@ -761,8 +785,8 @@ void UserInterface::Render()
|
||||
Log::ShowLogWindow(&Settings::application.widget.logs);
|
||||
|
||||
// about dialogs
|
||||
if (show_vimix_config)
|
||||
ShowConfig(&show_vimix_config);
|
||||
if (show_vimix_about)
|
||||
RenderAbout(&show_vimix_about);
|
||||
if (show_imgui_about)
|
||||
ImGui::ShowAboutWindow(&show_imgui_about);
|
||||
if (show_gst_about)
|
||||
@@ -807,10 +831,10 @@ void UserInterface::showMenuFile()
|
||||
Mixer::manager().close();
|
||||
navigator.hidePannel();
|
||||
}
|
||||
ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x );
|
||||
ImGui::Combo("##AR", &Settings::application.render.ratio, FrameBuffer::aspect_ratio_name, IM_ARRAYSIZE(FrameBuffer::aspect_ratio_name) );
|
||||
ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x );
|
||||
ImGui::Combo("##HEIGHT", &Settings::application.render.res, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) );
|
||||
ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.6f);
|
||||
ImGui::Combo("Ratio", &Settings::application.render.ratio, FrameBuffer::aspect_ratio_name, IM_ARRAYSIZE(FrameBuffer::aspect_ratio_name) );
|
||||
ImGui::SetNextItemWidth( ImGui::GetContentRegionAvail().x * 0.6f);
|
||||
ImGui::Combo("Height", &Settings::application.render.res, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) );
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
@@ -818,6 +842,8 @@ void UserInterface::showMenuFile()
|
||||
|
||||
if (ImGui::MenuItem( ICON_FA_FILE_UPLOAD " Open", CTRL_MOD "O"))
|
||||
selectOpenFilename();
|
||||
if (ImGui::MenuItem( ICON_FA_FILE_UPLOAD " Reload", CTRL_MOD "+Shift+O"))
|
||||
Mixer::manager().load( Mixer::manager().session()->filename() );
|
||||
|
||||
if (ImGui::MenuItem( ICON_FA_FILE_EXPORT " Import")) {
|
||||
// launch file dialog to open a session file
|
||||
@@ -997,7 +1023,7 @@ void ToolBox::Render()
|
||||
|
||||
// About and other utility windows
|
||||
if (show_icons_window)
|
||||
ImGuiToolkit::ShowIconsWindow(&show_icons_window);
|
||||
ImGuiToolkit::ShowIconsWindow(&show_icons_window);
|
||||
if (show_sandbox)
|
||||
ShowSandbox(&show_sandbox);
|
||||
if (show_demo_window)
|
||||
@@ -1011,7 +1037,7 @@ void UserInterface::RenderHistory()
|
||||
ImVec2 MinWindowSize = ImVec2(250.f, history_height);
|
||||
|
||||
ImGui::SetNextWindowPos(ImVec2(1180, 400), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSize(ImVec2(250, 400), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
|
||||
ImGui::SetNextWindowSizeConstraints(MinWindowSize, ImVec2(FLT_MAX, FLT_MAX));
|
||||
if ( !ImGui::Begin(IMGUI_TITLE_HISTORY, &Settings::application.widget.history, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse ))
|
||||
{
|
||||
@@ -1027,7 +1053,7 @@ void UserInterface::RenderHistory()
|
||||
{
|
||||
if ( ImGui::MenuItem( ICON_FA_UNDO " Undo", CTRL_MOD "Z") )
|
||||
Action::manager().undo();
|
||||
if ( ImGui::MenuItem( ICON_FA_REDO " Redo", CTRL_MOD "+Shift Z") )
|
||||
if ( ImGui::MenuItem( ICON_FA_REDO " Redo", CTRL_MOD "Shift+Z") )
|
||||
Action::manager().redo();
|
||||
|
||||
ImGui::MenuItem( ICON_FA_DIRECTIONS " Follow view", nullptr, &Settings::application.action_history_follow_view);
|
||||
@@ -1051,7 +1077,7 @@ void UserInterface::RenderHistory()
|
||||
|
||||
if (ImGui::ListBoxHeader("##History", ImGui::GetContentRegionAvail() ) )
|
||||
{
|
||||
for (int i = 1; i <= Action::manager().max(); i++) {
|
||||
for (int i = Action::manager().max(); i > 0; i--) {
|
||||
|
||||
std::string step_label_ = Action::manager().label(i);
|
||||
|
||||
@@ -1115,13 +1141,30 @@ void UserInterface::RenderPreview()
|
||||
{
|
||||
if (ImGui::BeginMenu(IMGUI_TITLE_PREVIEW))
|
||||
{
|
||||
glm::ivec2 p = FrameBuffer::getParametersFromResolution(output->resolution());
|
||||
std::ostringstream info;
|
||||
info << "Resolution " << output->width() << "x" << output->height();
|
||||
if (p.x > -1)
|
||||
info << " " << FrameBuffer::aspect_ratio_name[p.x] ;
|
||||
ImGui::MenuItem(info.str().c_str(), nullptr, false, false);
|
||||
// cannot change resolution when recording
|
||||
if (rec == nullptr && p.y > -1) {
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if (ImGui::Combo("Height", &p.y, FrameBuffer::resolution_name, IM_ARRAYSIZE(FrameBuffer::resolution_name) ) )
|
||||
{
|
||||
glm::vec3 res = FrameBuffer::getResolutionFromParameters(p.x, p.y);
|
||||
Mixer::manager().session()->setResolution(res);
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
|
||||
if ( ImGui::MenuItem( ICON_FA_WINDOW_RESTORE " Show output window") )
|
||||
Rendering::manager().outputWindow().show();
|
||||
|
||||
if ( ImGui::MenuItem( ICON_FA_SHARE_SQUARE " Create Source") )
|
||||
Mixer::manager().addSource( Mixer::manager().createSourceRender() );
|
||||
|
||||
if ( ImGui::MenuItem( ICON_FA_TIMES " Close") )
|
||||
if ( ImGui::MenuItem( ICON_FA_TIMES " Close", CTRL_MOD "D") )
|
||||
Settings::application.widget.preview = false;
|
||||
|
||||
ImGui::EndMenu();
|
||||
@@ -1153,7 +1196,7 @@ void UserInterface::RenderPreview()
|
||||
}
|
||||
ImGui::PopStyleColor(1);
|
||||
// select profile
|
||||
ImGui::SetNextItemWidth(300);
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
ImGui::Combo("Codec", &Settings::application.record.profile, VideoRecorder::profile_name, IM_ARRAYSIZE(VideoRecorder::profile_name) );
|
||||
}
|
||||
|
||||
@@ -1403,7 +1446,7 @@ void MediaController::Render()
|
||||
{
|
||||
ImGui::MenuItem( ICON_FA_EYE " Preview", nullptr, &Settings::application.widget.media_player_view);
|
||||
|
||||
if ( ImGui::MenuItem( ICON_FA_TIMES " Close") )
|
||||
if ( ImGui::MenuItem( ICON_FA_TIMES " Close", CTRL_MOD "P") )
|
||||
Settings::application.widget.media_player = false;
|
||||
|
||||
ImGui::EndMenu();
|
||||
@@ -1956,7 +1999,7 @@ void Navigator::Render()
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
about = "Mixing [F1]";
|
||||
about = "Mixing [ F1 ]";
|
||||
if (ImGui::Selectable( ICON_FA_OBJECT_UNGROUP , &selected_view[2], 0, iconsize))
|
||||
{
|
||||
if (ImGui::IsItemHovered())
|
||||
@@ -1964,21 +2007,21 @@ void Navigator::Render()
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
about = "Geometry [F2]";
|
||||
about = "Geometry [ F2 ]";
|
||||
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::IsItemHovered())
|
||||
about = "Layers [F3]";
|
||||
if (ImGui::Selectable( ICON_FA_SIGN, &selected_view[4], 0, iconsize))
|
||||
about = "Layers [ F3 ]";
|
||||
if (ImGui::Selectable( ICON_FA_CHESS_BOARD, &selected_view[4], 0, iconsize))
|
||||
{
|
||||
Mixer::manager().setView(View::APPEARANCE);
|
||||
view_pannel_visible = previous_view == Settings::application.current_view;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
about = "Source apppearance [F4]";
|
||||
about = "Texturing [ F4 ]";
|
||||
|
||||
|
||||
ImGui::End();
|
||||
@@ -2099,8 +2142,8 @@ void Navigator::RenderSourcePannel(Source *s)
|
||||
// Source pannel
|
||||
static ImGuiVisitor v;
|
||||
s->accept(v);
|
||||
// ensure change is applied
|
||||
s->touch();
|
||||
// ensure change is applied // TODO : touch() in visitor ? [avoid here as it forces useless update]
|
||||
// s->touch();
|
||||
// delete button
|
||||
ImGui::Text(" ");
|
||||
// Action on source
|
||||
@@ -2116,7 +2159,7 @@ void Navigator::RenderSourcePannel(Source *s)
|
||||
// ImGui::EndPopup();
|
||||
// }
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
@@ -2240,7 +2283,8 @@ void Navigator::RenderNewPannel()
|
||||
fileImportFileDialogs.pop_back();
|
||||
fileDialogPending_ = false;
|
||||
// create a source with this file
|
||||
std::string label = open_filename.substr( open_filename.size() - MIN( 35, open_filename.size()) );
|
||||
std::string label = SystemToolkit::transliterate( open_filename );
|
||||
label = label.substr( label.size() - MIN( 35, label.size()) );
|
||||
new_source_preview_.setSource( Mixer::manager().createSourceFile(open_filename), label);
|
||||
}
|
||||
}
|
||||
@@ -2254,7 +2298,8 @@ void Navigator::RenderNewPannel()
|
||||
{
|
||||
std::string recentpath(*path);
|
||||
if ( SystemToolkit::file_exists(recentpath)) {
|
||||
std::string label = SystemToolkit::trunc_filename(recentpath, 35);
|
||||
std::string label = SystemToolkit::transliterate( recentpath );
|
||||
label = SystemToolkit::trunc_filename(label, 35);
|
||||
if (ImGui::Selectable( label.c_str() )) {
|
||||
new_source_preview_.setSource( Mixer::manager().createSourceFile(recentpath.c_str()), label);
|
||||
}
|
||||
@@ -2657,49 +2702,55 @@ void Navigator::RenderMainPannel()
|
||||
ImGuiToolkit::ButtonSwitch( ICON_FA_HISTORY " History", &Settings::application.widget.history);
|
||||
ImGuiToolkit::ButtonSwitch( ICON_FA_TACHOMETER_ALT " Metrics", &Settings::application.widget.stats);
|
||||
|
||||
// Settings application appearance
|
||||
// Settings & application appearance
|
||||
static bool show_config = false;
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Appearance");
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if ( ImGui::DragFloat("Scale", &Settings::application.scale, 0.01, 0.5f, 2.0f, "%.1f"))
|
||||
ImGui::GetIO().FontGlobalScale = Settings::application.scale;
|
||||
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// if ( ImGui::Combo("Accent", &Settings::application.accent_color, "Blue\0Orange\0Grey\0\0"))
|
||||
// ImGuiToolkit::SetAccentColor(static_cast<ImGuiToolkit::accent_color>(Settings::application.accent_color));
|
||||
bool b = ImGui::RadioButton("Blue", &Settings::application.accent_color, 0); ImGui::SameLine();
|
||||
bool o = ImGui::RadioButton("Orange", &Settings::application.accent_color, 1); ImGui::SameLine();
|
||||
bool g = ImGui::RadioButton("Grey", &Settings::application.accent_color, 2);
|
||||
if (b || o || g)
|
||||
ImGuiToolkit::SetAccentColor(static_cast<ImGuiToolkit::accent_color>(Settings::application.accent_color));
|
||||
|
||||
static unsigned int vimixicon = Resource::getTextureImage("images/vimix_256x256.png");
|
||||
static float height_about = 3.f * ImGui::GetTextLineHeightWithSpacing();
|
||||
bool show_icon = ImGui::GetCursorPosY() + height_about + 128.f < height_ ;
|
||||
bool show_about = ImGui::GetCursorPosY() + height_about < height_ ;
|
||||
|
||||
// Bottom aligned About buttons
|
||||
if ( show_about) {
|
||||
// Bottom aligned Logo
|
||||
if ( show_icon ) {
|
||||
ImGui::SetCursorPos(ImVec2(pannel_width_ / 2.f - 64.f, height_ -height_about - 128.f));
|
||||
ImGui::Image((void*)(intptr_t)vimixicon, ImVec2(128, 128));
|
||||
}
|
||||
else {
|
||||
ImGui::SetCursorPosY(height_ -height_about);
|
||||
}
|
||||
if (show_config)
|
||||
{
|
||||
ImGui::Text("System");
|
||||
bool vsync = (Settings::application.render.vsync > 0);
|
||||
ImGuiToolkit::ButtonSwitch( "Vertical synchronization", &vsync);
|
||||
Settings::application.render.vsync = vsync ? 1 : 0;
|
||||
ImGuiToolkit::ButtonSwitch( "Blit framebuffer", &Settings::application.render.blit);
|
||||
bool multi = (Settings::application.render.multisampling > 0);
|
||||
ImGuiToolkit::ButtonSwitch( "Antialiasing framebuffer", &multi);
|
||||
Settings::application.render.multisampling = multi ? 3 : 0;
|
||||
ImGuiToolkit::ButtonSwitch( "Hardware video decoding", &Settings::application.render.gpu_decoding);
|
||||
ImGui::Spacing();
|
||||
if ( ImGui::Button( ICON_FA_CROW " vimix", ImVec2(ImGui::GetContentRegionAvail().x, 0)) )
|
||||
UserInterface::manager().show_vimix_config = true;
|
||||
if ( ImGui::Button(" ImGui "))
|
||||
UserInterface::manager().show_imgui_about = true;
|
||||
ImGui::SameLine();
|
||||
if ( ImGui::Button(" GStreamer "))
|
||||
UserInterface::manager().show_gst_about = true;
|
||||
ImGui::SameLine();
|
||||
if ( ImGui::Button("OpenGL", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
UserInterface::manager().show_opengl_about = true;
|
||||
if (ImGui::Button( ICON_FA_POWER_OFF " Restart to apply", ImVec2(ImGui::GetContentRegionAvail().x - 50, 0)))
|
||||
Rendering::manager().close();
|
||||
}
|
||||
else {
|
||||
ImGui::Text("Appearance");
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if ( ImGui::DragFloat("Scale", &Settings::application.scale, 0.01, 0.5f, 2.0f, "%.1f"))
|
||||
ImGui::GetIO().FontGlobalScale = Settings::application.scale;
|
||||
bool b = ImGui::RadioButton("Blue", &Settings::application.accent_color, 0); ImGui::SameLine();
|
||||
bool o = ImGui::RadioButton("Orange", &Settings::application.accent_color, 1); ImGui::SameLine();
|
||||
bool g = ImGui::RadioButton("Grey", &Settings::application.accent_color, 2);
|
||||
if (b || o || g)
|
||||
ImGuiToolkit::SetAccentColor(static_cast<ImGuiToolkit::accent_color>(Settings::application.accent_color));
|
||||
|
||||
}
|
||||
|
||||
// Bottom aligned Logo (if enougth room)
|
||||
static unsigned int vimixicon = Resource::getTextureImage("images/vimix_256x256.png");
|
||||
static float height_about = 1.6f * ImGui::GetTextLineHeightWithSpacing();
|
||||
bool show_icon = ImGui::GetCursorPosY() + height_about + 128.f < height_ ;
|
||||
if ( show_icon ) {
|
||||
ImGui::SetCursorPos(ImVec2(pannel_width_ / 2.f - 64.f, height_ -height_about - 128.f));
|
||||
ImGui::Image((void*)(intptr_t)vimixicon, ImVec2(128, 128));
|
||||
}
|
||||
else {
|
||||
ImGui::SetCursorPosY(height_ -height_about);
|
||||
}
|
||||
|
||||
// About & System config toggle
|
||||
if ( ImGui::Button( ICON_FA_CROW " About vimix", ImVec2(ImGui::GetContentRegionAvail().x - 50, 0)) )
|
||||
UserInterface::manager().show_vimix_about = true;
|
||||
ImGui::SameLine();
|
||||
ImGuiToolkit::IconToggle(13,5,12,5,&show_config);
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
@@ -2755,134 +2806,100 @@ void ShowSandbox(bool* p_open)
|
||||
|
||||
ImGui::Text("Testing sandox");
|
||||
|
||||
const guint64 duration = GST_SECOND * 6;
|
||||
const guint64 step = GST_MSECOND * 20;
|
||||
static guint64 t = 0;
|
||||
// const guint64 duration = GST_SECOND * 6;
|
||||
// const guint64 step = GST_MSECOND * 20;
|
||||
// static guint64 t = 0;
|
||||
|
||||
// bool slider_pressed = ImGuiToolkit::TimelineSlider("timeline", &t, duration, step);
|
||||
// static float *arr_lines = nullptr;
|
||||
// static float *arr_histo = nullptr;
|
||||
// static uint array_size = 200;
|
||||
|
||||
static float *arr_lines = nullptr;
|
||||
static float *arr_histo = nullptr;
|
||||
// static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f,
|
||||
// 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f, 0.f, 1.f, 0.4f };
|
||||
// if (arr_lines == nullptr) {
|
||||
|
||||
static uint array_size = 200;
|
||||
// arr_lines = (float *) malloc(array_size * sizeof(float));
|
||||
// arr_histo = (float *) malloc(array_size * sizeof(float));
|
||||
|
||||
// MediaPlayer *mp_ = nullptr;
|
||||
// auto po = MediaPlayer::begin();
|
||||
// if (po != MediaPlayer::end())
|
||||
// mp_ = *po;
|
||||
// if (mp_) {
|
||||
// }
|
||||
//// duration = mp_->duration();
|
||||
//// step = mp_->frameDuration();
|
||||
//// t = mp_->position();
|
||||
// for (int i = 0; i < array_size; ++i) {
|
||||
// arr_lines[i] = 1.f;
|
||||
// arr_histo[i] = 0.f;
|
||||
// }
|
||||
// }
|
||||
|
||||
//// arr = mp_->timelineArray();
|
||||
//// array_size = mp_->timelineArraySize();
|
||||
|
||||
if (arr_lines == nullptr) {
|
||||
|
||||
arr_lines = (float *) malloc(array_size * sizeof(float));
|
||||
arr_histo = (float *) malloc(array_size * sizeof(float));
|
||||
|
||||
for (int i = 0; i < array_size; ++i) {
|
||||
arr_lines[i] = 1.f;
|
||||
arr_histo[i] = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
// scrolling sub-window
|
||||
ImGui::BeginChild("##scrolling",
|
||||
ImVec2(ImGui::GetContentRegionAvail().x, 250),
|
||||
false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
// // scrolling sub-window
|
||||
// ImGui::BeginChild("##scrolling",
|
||||
// ImVec2(ImGui::GetContentRegionAvail().x, 250),
|
||||
// false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
|
||||
|
||||
if (arr_lines != nullptr)
|
||||
{
|
||||
// if (arr_lines != nullptr)
|
||||
// {
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(1, 1));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.f);
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(1, 1));
|
||||
// ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 1.f);
|
||||
|
||||
ImVec2 size = ImGui::CalcItemSize(ImVec2(-FLT_MIN, 0.0f), ImGui::CalcItemWidth(), 40);
|
||||
size.x *= 1.f;
|
||||
// ImVec2 size = ImGui::CalcItemSize(ImVec2(-FLT_MIN, 0.0f), ImGui::CalcItemWidth(), 40);
|
||||
// size.x *= 1.f;
|
||||
|
||||
// // draw position when entering
|
||||
// ImVec2 draw_pos = ImGui::GetCursorPos();
|
||||
//// // draw position when entering
|
||||
//// ImVec2 draw_pos = ImGui::GetCursorPos();
|
||||
|
||||
//// // capture user input
|
||||
//// uint press_index = array_size-1;
|
||||
//// float val = 0.f;
|
||||
//// bool pressed = false;
|
||||
////// // capture user input
|
||||
////// uint press_index = array_size-1;
|
||||
////// float val = 0.f;
|
||||
////// bool pressed = false;
|
||||
|
||||
//// uint starting_index = press_index;
|
||||
//// pressed = ImGuiToolkit::InvisibleDoubleSliderFloat("test", &press_index, &val, 0, array_size-1, size);
|
||||
//// if (pressed)
|
||||
//// {
|
||||
//// for (int i = MIN(starting_index, press_index); i < MAX(starting_index, press_index); ++i)
|
||||
//// arr[i] = val;
|
||||
////// uint starting_index = press_index;
|
||||
////// pressed = ImGuiToolkit::InvisibleDoubleSliderFloat("test", &press_index, &val, 0, array_size-1, size);
|
||||
////// if (pressed)
|
||||
////// {
|
||||
////// for (int i = MIN(starting_index, press_index); i < MAX(starting_index, press_index); ++i)
|
||||
////// arr[i] = val;
|
||||
|
||||
////// starting_index = press_index;
|
||||
//////// starting_index = press_index;
|
||||
////// }
|
||||
|
||||
//// float x = -1.f;
|
||||
//// float y = -1.f;
|
||||
//// bool clicked = ImGuiToolkit::InvisibleCoordinatesFloat("test", &x, &y, size);
|
||||
//// if (clicked) {
|
||||
//// Log::Info("clic %f %f in [%f %f]", x, y, size.x, size.y);
|
||||
//// }
|
||||
|
||||
// float x = -1.f;
|
||||
// float y = -1.f;
|
||||
// bool clicked = ImGuiToolkit::InvisibleCoordinatesFloat("test", &x, &y, size);
|
||||
// if (clicked) {
|
||||
// Log::Info("clic %f %f in [%f %f]", x, y, size.x, size.y);
|
||||
// }
|
||||
|
||||
//// // back to
|
||||
//// ImGui::SetCursorPos(draw_pos);
|
||||
//// // plot lines
|
||||
//// ImGui::PlotLines("Lines", arr, array_size-1, 0, NULL, 0.0f, 1.0f, size);
|
||||
|
||||
// // back to
|
||||
// ImGui::SetCursorPos(draw_pos);
|
||||
// // plot lines
|
||||
// ImGui::PlotLines("Lines", arr, array_size-1, 0, NULL, 0.0f, 1.0f, size);
|
||||
////// size.y = 20;
|
||||
////// ImGui::PlotHistogram("Hisfd", arr, array_size-1, 0, NULL, 0.0f, 1.0f, size);
|
||||
// bool r = false;
|
||||
// ImGuiToolkit::EditPlotHistoLines("Alpha", arr_histo, arr_lines, array_size, 0.f, 1.f, &r, size);
|
||||
|
||||
//// size.y = 20;
|
||||
//// ImGui::PlotHistogram("Hisfd", arr, array_size-1, 0, NULL, 0.0f, 1.0f, size);
|
||||
bool r = false;
|
||||
ImGuiToolkit::EditPlotHistoLines("Alpha", arr_histo, arr_lines, array_size, 0.f, 1.f, &r, size);
|
||||
// bool slider_pressed = ImGuiToolkit::TimelineSlider("timeline", &t, 0, duration, step, size.x);
|
||||
|
||||
bool slider_pressed = ImGuiToolkit::TimelineSlider("timeline", &t, 0, duration, step, size.x);
|
||||
// ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::PopStyleVar(2);
|
||||
// ImGui::Text("Timeline t %" GST_STIME_FORMAT "\n", GST_STIME_ARGS(t));
|
||||
// ImGui::Text("Timeline Pressed %s", slider_pressed ? "on" : "off");
|
||||
|
||||
ImGui::Text("Timeline t %" GST_STIME_FORMAT "\n", GST_STIME_ARGS(t));
|
||||
ImGui::Text("Timeline Pressed %s", slider_pressed ? "on" : "off");
|
||||
// static int w = 0;
|
||||
// ImGui::SetNextItemWidth(size.x);
|
||||
// ImGui::SliderInt("##int", &w, 0, array_size-1);
|
||||
|
||||
static int w = 0;
|
||||
ImGui::SetNextItemWidth(size.x);
|
||||
ImGui::SliderInt("##int", &w, 0, array_size-1);
|
||||
// }
|
||||
|
||||
}
|
||||
// ImGui::EndChild();
|
||||
|
||||
ImGui::EndChild();
|
||||
static char str0[128] = "àöäüèáû вторая строчка";
|
||||
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
|
||||
std::string tra = SystemToolkit::transliterate(std::string(str0));
|
||||
ImGui::Text("Transliteration: '%s'", tra.c_str());
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void ShowConfig(bool* p_open)
|
||||
void UserInterface::RenderAbout(bool* p_open)
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(1000, 20), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("About " APP_NAME APP_TITLE, p_open, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize))
|
||||
@@ -2897,27 +2914,41 @@ void ShowConfig(bool* p_open)
|
||||
ImGui::Separator();
|
||||
ImGui::Text("vimix performs graphical mixing and blending of\nseveral movie clips and computer generated graphics,\nwith image processing effects in real-time.");
|
||||
ImGui::Text("\nvimix is licensed under the GNU GPL version 3.\nCopyright 2019-2020 Bruno Herbelin.");
|
||||
ImGuiToolkit::ButtonOpenUrl("https://brunoherbelin.github.io/vimix/");
|
||||
ImGui::SameLine();
|
||||
|
||||
static bool show_config = false;
|
||||
ImGui::SetNextItemWidth(-100.f);
|
||||
ImGui::Text(" Details");
|
||||
ImGui::SameLine();
|
||||
ImGui::Spacing();
|
||||
ImGuiToolkit::ButtonOpenUrl("https://brunoherbelin.github.io/vimix/", ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("\nvimix is built using the following libraries:");
|
||||
|
||||
ImGui::Columns(3, "abouts");
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Text("Dear ImGui");
|
||||
ImGui::PushID("dearimguiabout");
|
||||
if ( ImGui::Button("More info", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
show_imgui_about = true;
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Text("GStreamer");
|
||||
ImGui::PushID("gstreamerabout");
|
||||
if ( ImGui::Button("More info", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
show_gst_about = true;
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::NextColumn();
|
||||
|
||||
ImGui::Text("OpenGL");
|
||||
ImGui::PushID("openglabout");
|
||||
if ( ImGui::Button("More info", ImVec2(ImGui::GetContentRegionAvail().x, 0)))
|
||||
show_opengl_about = true;
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::Columns(1);
|
||||
|
||||
ImGuiToolkit::IconToggle(10,0,11,0,&show_config);
|
||||
if (show_config)
|
||||
{
|
||||
ImGui::Text("\nOpenGL options (enable all for optimal performance).");
|
||||
ImGui::Checkbox("Blit framebuffer (fast draw to output)", &Settings::application.render.blit);
|
||||
bool multi = (Settings::application.render.multisampling > 0);
|
||||
ImGui::Checkbox("Antialiasing framebuffer (fast multisampling)", &multi);
|
||||
Settings::application.render.multisampling = multi ? 3 : 0;
|
||||
bool vsync = (Settings::application.render.vsync < 2);
|
||||
ImGui::Checkbox("Sync refresh with monitor (v-sync 60Hz)", &vsync);
|
||||
Settings::application.render.vsync = vsync ? 1 : 2;
|
||||
ImGui::Text( ICON_FA_EXCLAMATION " Restart the application for change to take effect.");
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class UserInterface
|
||||
bool ctrl_modifier_active;
|
||||
bool alt_modifier_active;
|
||||
bool shift_modifier_active;
|
||||
bool show_vimix_config;
|
||||
bool show_vimix_about;
|
||||
bool show_imgui_about;
|
||||
bool show_gst_about;
|
||||
bool show_opengl_about;
|
||||
@@ -168,6 +168,7 @@ protected:
|
||||
void handleKeyboard();
|
||||
void handleMouse();
|
||||
void handleScreenshot();
|
||||
void RenderAbout(bool* p_open);
|
||||
};
|
||||
|
||||
#endif /* #define __UI_MANAGER_H_ */
|
||||
|
||||
72
View.h
@@ -29,9 +29,9 @@ public:
|
||||
virtual void update (float dt);
|
||||
virtual void draw ();
|
||||
|
||||
virtual void zoom (float) {}
|
||||
virtual void zoom (float);
|
||||
virtual void resize (int) {}
|
||||
virtual int size () { return 0; }
|
||||
virtual int size () { return 50; }
|
||||
virtual void recenter();
|
||||
virtual void centerSource(Source *) {}
|
||||
|
||||
@@ -71,16 +71,19 @@ public:
|
||||
return Cursor();
|
||||
}
|
||||
|
||||
// // test mouse over provided a point in screen coordinates and the picking point
|
||||
// virtual Cursor over (Source*, glm::vec2, std::pair<Node *, glm::vec2>) {
|
||||
// return Cursor();
|
||||
// }
|
||||
// test mouse over provided a point in screen coordinates
|
||||
virtual Cursor over (glm::vec2) {
|
||||
return Cursor();
|
||||
}
|
||||
|
||||
// left-right [-1 1] and up-down [1 -1] action from arrow keys
|
||||
virtual void arrow (glm::vec2) {}
|
||||
|
||||
// accessible scene
|
||||
Scene scene;
|
||||
|
||||
// reordering scene when necessary
|
||||
static bool need_deep_update_;
|
||||
static uint need_deep_update_;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -100,15 +103,15 @@ public:
|
||||
|
||||
void draw () override;
|
||||
void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
int size () override;
|
||||
void centerSource(Source *) override;
|
||||
void select(glm::vec2, glm::vec2) override;
|
||||
void selectAll() override;
|
||||
|
||||
std::pair<Node *, glm::vec2> pick(glm::vec2) override;
|
||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>) override;
|
||||
Cursor drag (glm::vec2, glm::vec2) override;
|
||||
void arrow (glm::vec2) override;
|
||||
|
||||
void setAlpha (Source *s);
|
||||
inline float limboScale() { return limbo_scale_; }
|
||||
@@ -153,17 +156,16 @@ public:
|
||||
|
||||
void draw () override;
|
||||
void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
int size () override;
|
||||
|
||||
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
|
||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
||||
// Cursor over (Source *s, glm::vec2 pos, std::pair<Node *, glm::vec2> pick) override;
|
||||
Cursor drag (glm::vec2, glm::vec2) override;
|
||||
void terminate() override;
|
||||
void arrow (glm::vec2) override;
|
||||
|
||||
private:
|
||||
Surface *output_surface_;
|
||||
Node *overlay_position_;
|
||||
Node *overlay_position_cross_;
|
||||
Node *overlay_rotation_;
|
||||
@@ -173,6 +175,7 @@ private:
|
||||
Node *overlay_scaling_;
|
||||
Node *overlay_scaling_cross_;
|
||||
Node *overlay_scaling_grid_;
|
||||
Node *overlay_crop_;
|
||||
bool show_context_menu_;
|
||||
};
|
||||
|
||||
@@ -182,17 +185,19 @@ public:
|
||||
LayerView();
|
||||
|
||||
void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
int size () override;
|
||||
|
||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
||||
Cursor drag (glm::vec2, glm::vec2) override;
|
||||
void arrow (glm::vec2) override;
|
||||
|
||||
float setDepth (Source *, float d = -1.f);
|
||||
|
||||
private:
|
||||
float aspect_ratio;
|
||||
Mesh *persp_layer_;
|
||||
Mesh *persp_left_, *persp_right_;
|
||||
Group *frame_;
|
||||
};
|
||||
|
||||
class TransitionView : public View
|
||||
@@ -207,6 +212,7 @@ public:
|
||||
|
||||
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
|
||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
||||
void arrow (glm::vec2) override;
|
||||
Cursor drag (glm::vec2, glm::vec2) override;
|
||||
|
||||
void attach(SessionSource *ts);
|
||||
@@ -232,13 +238,15 @@ public:
|
||||
void draw () override;
|
||||
|
||||
void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
int size () override;
|
||||
|
||||
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
|
||||
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
|
||||
Cursor drag (glm::vec2, glm::vec2) override;
|
||||
Cursor over (glm::vec2) override;
|
||||
void arrow (glm::vec2) override;
|
||||
|
||||
void initiate() override;
|
||||
void terminate() override;
|
||||
|
||||
private:
|
||||
@@ -248,17 +256,21 @@ private:
|
||||
Source *getEditOrCurrentSource();
|
||||
void adjustBackground();
|
||||
|
||||
Surface *surfacepreview;
|
||||
Surface *backgroundchecker_;
|
||||
Frame *backgroundframe_;
|
||||
Mesh *horizontal_line_;
|
||||
Surface *preview_surface_;
|
||||
class ImageShader *preview_shader_;
|
||||
Surface *preview_checker_;
|
||||
Frame *preview_frame_;
|
||||
Surface *background_surface_;
|
||||
Frame *background_frame_;
|
||||
Mesh *horizontal_mark_;
|
||||
bool show_horizontal_scale_;
|
||||
Group *vertical_line_;
|
||||
Mesh *vertical_mark_;
|
||||
bool show_vertical_scale_;
|
||||
Symbol *crop_horizontal_;
|
||||
Symbol *crop_vertical_;
|
||||
bool show_scale_;
|
||||
Group *mask_node_;
|
||||
Frame *mask_square_;
|
||||
Mesh *mask_circle_;
|
||||
Mesh *mask_horizontal_;
|
||||
Group *mask_vertical_;
|
||||
|
||||
Symbol *overlay_position_;
|
||||
Symbol *overlay_position_cross_;
|
||||
Symbol *overlay_scaling_;
|
||||
@@ -269,6 +281,16 @@ private:
|
||||
Node *overlay_rotation_clock_;
|
||||
Symbol *overlay_rotation_clock_hand_;
|
||||
bool show_context_menu_;
|
||||
|
||||
// for mask shader draw: 0=cursor, 1=brush, 2=eraser, 3=crop_shape
|
||||
int mask_cursor_paint_;
|
||||
int mask_cursor_shape_;
|
||||
Mesh *mask_cursor_circle_;
|
||||
Mesh *mask_cursor_square_;
|
||||
Mesh *mask_cursor_crop_;
|
||||
glm::vec3 stored_mask_size_;
|
||||
bool show_cursor_forced_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ class Stream;
|
||||
class MediaPlayer;
|
||||
class Shader;
|
||||
class ImageShader;
|
||||
class MaskShader;
|
||||
class ImageProcessingShader;
|
||||
class Source;
|
||||
class MediaSource;
|
||||
@@ -64,6 +65,7 @@ public:
|
||||
virtual void visit (MediaPlayer&) {}
|
||||
virtual void visit (Shader&) {}
|
||||
virtual void visit (ImageShader&) {}
|
||||
virtual void visit (MaskShader&) {}
|
||||
virtual void visit (ImageProcessingShader&) {}
|
||||
|
||||
// utility
|
||||
|
||||
30
defines.h
@@ -5,9 +5,9 @@
|
||||
#define APP_TITLE " -- Video Live Mixer"
|
||||
#define APP_SETTINGS "vimix.xml"
|
||||
#define APP_VERSION_MAJOR 0
|
||||
#define APP_VERSION_MINOR 4
|
||||
#define APP_VERSION_MINOR 5
|
||||
#define XML_VERSION_MAJOR 0
|
||||
#define XML_VERSION_MINOR 1
|
||||
#define XML_VERSION_MINOR 2
|
||||
#define MAX_RECENT_HISTORY 20
|
||||
|
||||
#define MINI(a, b) (((a) < (b)) ? (a) : (b))
|
||||
@@ -24,27 +24,40 @@
|
||||
#define ROUND(val, factor) float( int( val * factor ) ) / factor;
|
||||
|
||||
#define SCENE_UNIT 5.f
|
||||
#define SCENE_DEPTH 12.f
|
||||
#define CIRCLE_SQUARE_DIST(x,y) ( (x*x + y*y) / (SCENE_UNIT * SCENE_UNIT * SCENE_UNIT * SCENE_UNIT) )
|
||||
#define MIN_SCALE 0.01f
|
||||
#define MAX_SCALE 10.f
|
||||
#define CLAMP_SCALE(x) SIGN(x) * CLAMP( ABS(x), MIN_SCALE, MAX_SCALE)
|
||||
#define SCENE_DEPTH 14.f
|
||||
#define MIN_DEPTH 0.f
|
||||
#define MAX_DEPTH 12.f
|
||||
#define BACKGROUND_DEPTH 2.f
|
||||
#define FOREGROUND_DEPTH 10.f
|
||||
#define MIXING_DEFAULT_SCALE 2.4f
|
||||
#define MIXING_MIN_SCALE 0.8f
|
||||
#define MIXING_MAX_SCALE 7.0f
|
||||
#define MIXING_LIMBO_SCALE 1.3f
|
||||
#define MIXING_ICON_SCALE 0.15f, 0.15f, 1.f
|
||||
#define GEOMETRY_DEFAULT_SCALE 1.2f
|
||||
#define GEOMETRY_DEFAULT_SCALE 1.4f
|
||||
#define GEOMETRY_MIN_SCALE 0.4f
|
||||
#define GEOMETRY_MAX_SCALE 10.0f
|
||||
#define LAYER_DEFAULT_SCALE 0.8f
|
||||
#define GEOMETRY_MAX_SCALE 7.0f
|
||||
#define LAYER_DEFAULT_SCALE 0.6f
|
||||
#define LAYER_MIN_SCALE 0.4f
|
||||
#define LAYER_MAX_SCALE 1.7f
|
||||
#define LAYER_PERSPECTIVE 2.0f
|
||||
#define APPEARANCE_DEFAULT_SCALE 2.f
|
||||
#define APPEARANCE_MIN_SCALE 0.4f
|
||||
#define APPEARANCE_MAX_SCALE 10.0f
|
||||
#define APPEARANCE_MAX_SCALE 7.0f
|
||||
#define BRUSH_MIN_SIZE 0.05f
|
||||
#define BRUSH_MAX_SIZE 2.f
|
||||
#define BRUSH_MIN_PRESS 0.005f
|
||||
#define BRUSH_MAX_PRESS 1.f
|
||||
#define SHAPE_MIN_BLUR 0.f
|
||||
#define SHAPE_MAX_BLUR 1.f
|
||||
#define TRANSITION_DEFAULT_SCALE 5.0f
|
||||
#define TRANSITION_MIN_DURATION 0.2f
|
||||
#define TRANSITION_MAX_DURATION 10.f
|
||||
#define ARROWS_MOVEMENT_FACTOR 5.f
|
||||
|
||||
#define IMGUI_TITLE_MAINWINDOW ICON_FA_CIRCLE_NOTCH " vimix"
|
||||
#define IMGUI_TITLE_MEDIAPLAYER ICON_FA_FILM " Player"
|
||||
@@ -72,7 +85,10 @@
|
||||
#define COLOR_TRANSITION_SOURCE 1.f, 0.5f, 1.f
|
||||
#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f
|
||||
#define COLOR_APPEARANCE_SOURCE 0.9f, 0.9f, 0.1f
|
||||
#define COLOR_APPEARANCE_MASK 0.1f, 0.9f, 0.9f
|
||||
#define COLOR_APPEARANCE_MASK_DISABLE 0.3f, 0.6f, 0.6f
|
||||
#define COLOR_FRAME 0.8f, 0.f, 0.8f
|
||||
#define COLOR_FRAME_LIGHT 0.95f, 0.3f, 0.95f
|
||||
#define COLOR_LIMBO_CIRCLE 0.16f, 0.16f, 0.16f
|
||||
#define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f
|
||||
#define COLOR_STASH_CIRCLE 0.06f, 0.06f, 0.06f
|
||||
|
||||
BIN
docs/images/manual_appearance_0.png
Normal file
|
After Width: | Height: | Size: 592 KiB |
BIN
docs/images/manual_appearance_1.png
Normal file
|
After Width: | Height: | Size: 772 KiB |
BIN
docs/images/manual_appearance_2.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
docs/images/manual_appearance_3.png
Normal file
|
After Width: | Height: | Size: 846 KiB |
BIN
docs/images/manual_appearance_4.png
Normal file
|
After Width: | Height: | Size: 404 KiB |
BIN
docs/images/manual_appearance_5.png
Normal file
|
After Width: | Height: | Size: 582 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -1,6 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
@@ -15,11 +13,11 @@
|
||||
height="64"
|
||||
id="svg3744"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
|
||||
inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"
|
||||
version="1.0"
|
||||
sodipodi:docname="v-mix.svg"
|
||||
sodipodi:docname="vimix.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
inkscape:export-filename="/home/bhbn/Developments/v-mix/rsc/images/v-mix_256x256.png"
|
||||
inkscape:export-filename="/home/bhbn/Developments/v-mix/rsc/images/vimix_256x256.png"
|
||||
inkscape:export-xdpi="405.16815"
|
||||
inkscape:export-ydpi="405.16815">
|
||||
<sodipodi:namedview
|
||||
@@ -29,9 +27,9 @@
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="24.671299"
|
||||
inkscape:cx="36.638352"
|
||||
inkscape:cy="31.887987"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="34.523709"
|
||||
inkscape:cy="21.609175"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:document-units="px"
|
||||
@@ -41,16 +39,17 @@
|
||||
showborder="true"
|
||||
objecttolerance="1"
|
||||
guidetolerance="10000"
|
||||
inkscape:window-width="2618"
|
||||
inkscape:window-width="2890"
|
||||
inkscape:window-height="1885"
|
||||
inkscape:window-x="920"
|
||||
inkscape:window-y="160"
|
||||
inkscape:window-x="982"
|
||||
inkscape:window-y="112"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:showpageshadow="false">
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:document-rotation="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3754"
|
||||
@@ -169,7 +168,7 @@
|
||||
xlink:href="#linearGradient3237-580"
|
||||
id="radialGradient855"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(4.0147937,-0.11912026,0.11328765,3.8182126,-0.22461479,-46.392657)"
|
||||
gradientTransform="matrix(4.0147937,-0.11912026,0.11328765,3.8182126,-1.0246148,2.407343)"
|
||||
cx="8"
|
||||
cy="8"
|
||||
fx="8"
|
||||
@@ -196,12 +195,26 @@
|
||||
<path
|
||||
id="path4090"
|
||||
d="m 32.8,-48.060406 c -17.255744,0 -31.2604062,14.004662 -31.2604062,31.260406 0,17.25574444 14.0046622,31.260406 31.2604062,31.260406 17.255744,0 31.260406,-14.00466156 31.260406,-31.260406 0,-17.255744 -14.004662,-31.260406 -31.260406,-31.260406 z m 0,3.907551 c 15.098776,0 27.352855,12.254079 27.352855,27.352855 0,15.0987764 -12.254079,27.352856 -27.352855,27.352856 -15.098776,0 -27.3528555,-12.2540796 -27.3528555,-27.352856 0,-15.098776 12.2540795,-27.352855 27.3528555,-27.352855 z"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0.2;fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.34172344;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.5999999;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0.2;fill:#848484;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.34172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:3.6;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;enable-background:accumulate"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0.80100002;fill:url(#radialGradient855);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.09425879;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.64077669;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:stroke fill markers;enable-background:accumulate"
|
||||
d="m 32.810524,-42.734828 -1.015246,0.02097 A 25.934385,25.934385 0 0 0 6.8756139,-16.048973 25.934385,25.934385 0 0 0 11.186212,-2.4795029 L 33.725083,-20.21064 v -1.535455 c 0,-3.229159 2.61689,-5.846052 5.846054,-5.846052 1.906945,0 3.585382,0.926722 4.652509,2.33884 h 1.19564 c 3.875281,0 7.016522,2.093915 7.016522,4.677681 l -7.016522,1.168373 v 5.848149 c 0,6.3779185 -4.259255,11.7523532 -10.085332,13.45829656 l 3.014273,8.15342884 c 0.05432,0.1490791 0.05251,0.2989217 0.02726,0.444695 A 25.934385,25.934385 0 0 0 58.732847,-17.043242 25.934385,25.934385 0 0 0 32.810524,-42.734828 Z m 6.760613,19.235127 c -0.968462,0 -1.753607,0.78442 -1.753607,1.753606 0,0.968457 0.785146,1.755704 1.753607,1.755704 0.96846,0 1.755703,-0.787247 1.755703,-1.755704 0,-0.969186 -0.787244,-1.753606 -1.755703,-1.753606 z M 31.799473,0.45296287 c -0.138877,0.004393 -0.273623,0.0209759 -0.413229,0.0209759 h -2.854855 l 2.800315,7.57868263 c 0.138751,0.3807921 -0.01302,0.7823496 -0.329324,1.0047577 a 25.934385,25.934385 0 0 0 2.294791,0.071319 25.934385,25.934385 0 0 0 1.675994,-0.090197 z M 17.737064,0.47393875 14.865429,1.9087078 A 25.934385,25.934385 0 0 0 27.807711,8.6336612 L 24.789245,0.47393875 Z"
|
||||
id="path4096"
|
||||
inkscape:connector-curvature="0" />
|
||||
style="display:inline;overflow:visible;visibility:visible;opacity:0.801;fill:url(#radialGradient855);fill-opacity:1;fill-rule:nonzero;stroke:#1a1a1a;stroke-width:2.09426;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none;paint-order:stroke fill markers;enable-background:accumulate"
|
||||
d="m 35.888672,6.359375 c -0.303933,2.1085366 -2.081796,3.675579 -4.183594,3.6875 -2.080492,0.0106 -3.863017,-1.5066505 -4.21289,-3.5859375 C 14.819383,8.697554 5.7033554,19.888693 6.0761719,32.751953 c 0.1430268,4.836335 1.636139,9.536221 4.3105471,13.568359 L 32.925781,28.589844 v -1.535156 c 0,-3.229159 2.616539,-5.847657 5.845703,-5.847657 1.906945,0 3.585217,0.927726 4.652344,2.339844 h 1.195313 c 3.875281,0 7.017578,2.093968 7.017578,4.677734 l -7.017578,1.167969 v 5.847656 c 0,6.377919 -4.259861,11.753041 -10.085938,13.458985 l 3.015625,8.154297 c 0.05432,0.149079 0.106204,0.243515 0.205076,0.378518 C 49.721772,54.597233 58.034322,44.009915 57.933594,31.755859 57.813463,19.027519 48.473702,8.2678032 35.888672,6.359375 Z m 2.882812,18.941406 c -0.968462,0 -1.753906,0.78472 -1.753906,1.753907 0,0.968457 0.785445,1.755859 1.753906,1.755859 0.96846,0 1.75586,-0.787402 1.75586,-1.755859 0,-0.969187 -0.787401,-1.753907 -1.75586,-1.753907 z M 31,49.253906 c -0.138877,0.0044 -0.274456,0.01953 -0.414062,0.01953 h -2.855469 l 2.800781,7.580078 c 0.138751,0.380792 0.336318,0.763068 0.493205,1.047905 0.763561,0.0573 0.707955,0.03676 1.473592,0.02631 0.559417,-0.01186 1.118303,-0.04182 1.675781,-0.08984 z m -14.0625,0.01953 -2.873047,1.435546 c 3.582287,3.433627 8.074429,5.76748 12.943359,6.72461 l -3.019531,-8.160156 z"
|
||||
transform="translate(0.8,-48.8)"
|
||||
sodipodi:nodetypes="ccccccsscsccscccccssssscsccccccccccc" />
|
||||
<path
|
||||
style="opacity:0.80908332;fill:#acacac;fill-opacity:1;stroke:#1c1c1c;stroke-width:1.12343;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
id="path859"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="32.47654"
|
||||
sodipodi:cy="-43.181934"
|
||||
sodipodi:rx="2.0615652"
|
||||
sodipodi:ry="2.0901108"
|
||||
sodipodi:start="0"
|
||||
sodipodi:end="6.2616827"
|
||||
sodipodi:arc-type="chord"
|
||||
d="m 34.538105,-43.181934 a 2.0615652,2.0901108 0 0 1 -2.050483,2.09008 2.0615652,2.0901108 0 0 1 -2.072528,-2.067609 2.0615652,2.0901108 0 0 1 2.0282,-2.11231 2.0615652,2.0901108 0 0 1 2.094334,2.044899 z"
|
||||
sodipodi:open="true" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 322 KiB After Width: | Height: | Size: 323 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 322 KiB |
|
Before Width: | Height: | Size: 19 KiB |
506
rsc/mesh/border_handles_crop.ply
Normal file
@@ -0,0 +1,506 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.91.0 - www.blender.org
|
||||
element vertex 250
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
element face 246
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-0.042157 0.063218 0.000000
|
||||
-0.041120 0.063272 0.000000
|
||||
-0.041354 0.063272 0.000000
|
||||
-0.040476 0.063272 0.000000
|
||||
-0.039503 0.063272 0.000000
|
||||
-0.038283 0.063272 0.000000
|
||||
-0.036898 0.063272 0.000000
|
||||
-0.035432 0.063272 0.000000
|
||||
-0.033965 0.063272 0.000000
|
||||
-0.032581 0.063272 0.000000
|
||||
-0.031361 0.063272 0.000000
|
||||
-0.030387 0.063272 0.000000
|
||||
-0.029743 0.063272 0.000000
|
||||
-0.029510 0.063272 0.000000
|
||||
-0.028707 0.063218 0.000000
|
||||
-0.042927 0.063061 0.000000
|
||||
-0.027936 0.063061 0.000000
|
||||
-0.043658 0.062807 0.000000
|
||||
-0.027206 0.062807 0.000000
|
||||
-0.044342 0.062464 0.000000
|
||||
-0.026522 0.062464 0.000000
|
||||
-0.044972 0.062039 0.000000
|
||||
-0.025892 0.062039 0.000000
|
||||
-0.045540 0.061539 0.000000
|
||||
-0.025323 0.061539 0.000000
|
||||
-0.046041 0.060970 0.000000
|
||||
-0.024823 0.060970 0.000000
|
||||
-0.046467 0.060341 0.000000
|
||||
-0.024397 0.060341 0.000000
|
||||
-0.046810 0.059657 0.000000
|
||||
-0.024054 0.059657 0.000000
|
||||
-0.047064 0.058926 0.000000
|
||||
-0.023800 0.058926 0.000000
|
||||
-0.047221 0.058155 0.000000
|
||||
-0.023642 0.058155 0.000000
|
||||
-0.047275 0.057352 0.000000
|
||||
-0.023588 0.057352 0.000000
|
||||
-0.047275 0.057158 0.000000
|
||||
-0.023588 0.055760 0.000000
|
||||
-0.047275 0.056621 0.000000
|
||||
-0.047275 0.055810 0.000000
|
||||
-0.047275 0.054794 0.000000
|
||||
-0.023588 0.051358 0.000000
|
||||
-0.047275 0.053640 0.000000
|
||||
-0.047275 0.052418 0.000000
|
||||
-0.047275 0.051196 0.000000
|
||||
-0.023588 0.044709 0.000000
|
||||
-0.047275 0.050043 0.000000
|
||||
-0.047275 0.049026 0.000000
|
||||
-0.047275 0.048215 0.000000
|
||||
-0.047275 0.047678 0.000000
|
||||
-0.047275 0.047484 0.000000
|
||||
-0.057948 0.047430 0.000000
|
||||
-0.057145 0.047484 0.000000
|
||||
-0.015693 0.023802 0.000000
|
||||
-0.014605 0.047484 0.000000
|
||||
-0.015693 0.047484 0.000000
|
||||
-0.011599 0.047484 0.000000
|
||||
-0.007057 0.047484 0.000000
|
||||
-0.001363 0.047484 0.000000
|
||||
0.005097 0.047484 0.000000
|
||||
0.011942 0.047484 0.000000
|
||||
0.018787 0.047484 0.000000
|
||||
0.025248 0.047484 0.000000
|
||||
0.030941 0.047484 0.000000
|
||||
0.035483 0.047484 0.000000
|
||||
0.038490 0.047484 0.000000
|
||||
0.039577 0.047484 0.000000
|
||||
0.040648 0.047412 0.000000
|
||||
-0.058719 0.047273 0.000000
|
||||
0.041676 0.047202 0.000000
|
||||
-0.059449 0.047019 0.000000
|
||||
0.042650 0.046864 0.000000
|
||||
-0.060133 0.046676 0.000000
|
||||
0.043562 0.046406 0.000000
|
||||
-0.060763 0.046251 0.000000
|
||||
0.044402 0.045839 0.000000
|
||||
-0.061332 0.045751 0.000000
|
||||
0.045160 0.045172 0.000000
|
||||
-0.061832 0.045182 0.000000
|
||||
-0.062258 0.044553 0.000000
|
||||
0.045827 0.044414 0.000000
|
||||
-0.023588 0.036374 0.000000
|
||||
-0.062601 0.043869 0.000000
|
||||
0.046395 0.043574 0.000000
|
||||
-0.062855 0.043138 0.000000
|
||||
0.046852 0.042663 0.000000
|
||||
-0.063013 0.042367 0.000000
|
||||
0.047191 0.041689 0.000000
|
||||
-0.063067 0.041564 0.000000
|
||||
0.047401 0.040661 0.000000
|
||||
-0.063067 0.041331 0.000000
|
||||
-0.063067 0.040687 0.000000
|
||||
-0.063067 0.039714 0.000000
|
||||
0.047473 0.039590 0.000000
|
||||
-0.063067 0.038494 0.000000
|
||||
0.023786 0.023802 0.000000
|
||||
0.047473 -0.023562 0.000000
|
||||
-0.063067 0.037110 0.000000
|
||||
-0.063067 0.035643 0.000000
|
||||
-0.023588 0.026916 0.000000
|
||||
-0.063067 0.034177 0.000000
|
||||
-0.063067 0.032793 0.000000
|
||||
-0.063067 0.031573 0.000000
|
||||
-0.063067 0.030600 0.000000
|
||||
-0.063067 0.029956 0.000000
|
||||
-0.063067 0.029723 0.000000
|
||||
-0.063013 0.028920 0.000000
|
||||
-0.062855 0.028149 0.000000
|
||||
-0.062601 0.027419 0.000000
|
||||
-0.062258 0.026735 0.000000
|
||||
-0.047275 0.023802 0.000000
|
||||
-0.023588 0.016895 0.000000
|
||||
-0.061832 0.026105 0.000000
|
||||
-0.061332 0.025537 0.000000
|
||||
-0.060763 0.025036 0.000000
|
||||
-0.060133 0.024611 0.000000
|
||||
-0.059449 0.024268 0.000000
|
||||
-0.058719 0.024014 0.000000
|
||||
-0.057948 0.023856 0.000000
|
||||
-0.057145 0.023802 0.000000
|
||||
-0.056951 0.023802 0.000000
|
||||
-0.056414 0.023802 0.000000
|
||||
-0.055603 0.023802 0.000000
|
||||
-0.054586 0.023802 0.000000
|
||||
-0.053432 0.023802 0.000000
|
||||
-0.052210 0.023802 0.000000
|
||||
-0.050988 0.023802 0.000000
|
||||
-0.049834 0.023802 0.000000
|
||||
-0.048817 0.023802 0.000000
|
||||
-0.048006 0.023802 0.000000
|
||||
-0.047469 0.023802 0.000000
|
||||
-0.047275 -0.039350 0.000000
|
||||
0.023786 -0.057111 0.000000
|
||||
-0.023588 0.006875 0.000000
|
||||
-0.023588 -0.002584 0.000000
|
||||
-0.023588 -0.010919 0.000000
|
||||
-0.023588 -0.017568 0.000000
|
||||
-0.023588 -0.021970 0.000000
|
||||
-0.023588 -0.023562 0.000000
|
||||
0.015890 -0.023562 0.000000
|
||||
0.015890 -0.047244 0.000000
|
||||
0.057342 -0.023562 0.000000
|
||||
0.058146 -0.023616 0.000000
|
||||
0.058916 -0.023773 0.000000
|
||||
0.059647 -0.024027 0.000000
|
||||
0.060331 -0.024370 0.000000
|
||||
0.060960 -0.024795 0.000000
|
||||
0.061529 -0.025295 0.000000
|
||||
0.062030 -0.025864 0.000000
|
||||
0.062455 -0.026493 0.000000
|
||||
0.062798 -0.027177 0.000000
|
||||
0.063052 -0.027908 0.000000
|
||||
0.063210 -0.028679 0.000000
|
||||
0.063264 -0.029482 0.000000
|
||||
0.063264 -0.029715 0.000000
|
||||
0.063264 -0.030359 0.000000
|
||||
0.063264 -0.031332 0.000000
|
||||
0.063264 -0.032552 0.000000
|
||||
0.063264 -0.033936 0.000000
|
||||
0.063264 -0.035403 0.000000
|
||||
0.063264 -0.036869 0.000000
|
||||
0.063264 -0.038253 0.000000
|
||||
0.063264 -0.039473 0.000000
|
||||
-0.047203 -0.040421 0.000000
|
||||
0.063264 -0.040446 0.000000
|
||||
-0.046993 -0.041448 0.000000
|
||||
0.047473 -0.047244 0.000000
|
||||
0.063264 -0.041090 0.000000
|
||||
0.063264 -0.041323 0.000000
|
||||
0.063210 -0.042126 0.000000
|
||||
-0.046655 -0.042422 0.000000
|
||||
0.063052 -0.042897 0.000000
|
||||
-0.046197 -0.043334 0.000000
|
||||
0.062798 -0.043627 0.000000
|
||||
-0.045630 -0.044173 0.000000
|
||||
0.062455 -0.044311 0.000000
|
||||
-0.044962 -0.044931 0.000000
|
||||
0.062030 -0.044940 0.000000
|
||||
-0.044204 -0.045599 0.000000
|
||||
0.061529 -0.045509 0.000000
|
||||
0.060960 -0.046010 0.000000
|
||||
-0.043364 -0.046166 0.000000
|
||||
0.060331 -0.046435 0.000000
|
||||
-0.042453 -0.046623 0.000000
|
||||
0.059647 -0.046778 0.000000
|
||||
-0.041478 -0.046962 0.000000
|
||||
0.058916 -0.047032 0.000000
|
||||
-0.040451 -0.047172 0.000000
|
||||
0.058146 -0.047190 0.000000
|
||||
-0.039380 -0.047244 0.000000
|
||||
0.057342 -0.047244 0.000000
|
||||
-0.038292 -0.047244 0.000000
|
||||
-0.035286 -0.047244 0.000000
|
||||
-0.030744 -0.047244 0.000000
|
||||
-0.025050 -0.047244 0.000000
|
||||
-0.018590 -0.047244 0.000000
|
||||
-0.011745 -0.047244 0.000000
|
||||
-0.004900 -0.047244 0.000000
|
||||
0.001561 -0.047244 0.000000
|
||||
0.007254 -0.047244 0.000000
|
||||
0.011796 -0.047244 0.000000
|
||||
0.014803 -0.047244 0.000000
|
||||
0.047473 -0.047438 0.000000
|
||||
0.047473 -0.047975 0.000000
|
||||
0.047473 -0.048785 0.000000
|
||||
0.047473 -0.049802 0.000000
|
||||
0.047473 -0.050955 0.000000
|
||||
0.047473 -0.052177 0.000000
|
||||
0.047473 -0.053399 0.000000
|
||||
0.047473 -0.054553 0.000000
|
||||
0.047473 -0.055569 0.000000
|
||||
0.047473 -0.056380 0.000000
|
||||
0.047473 -0.056917 0.000000
|
||||
0.047473 -0.057111 0.000000
|
||||
0.023840 -0.057914 0.000000
|
||||
0.047419 -0.057914 0.000000
|
||||
0.023997 -0.058685 0.000000
|
||||
0.047261 -0.058685 0.000000
|
||||
0.024251 -0.059415 0.000000
|
||||
0.047007 -0.059415 0.000000
|
||||
0.024594 -0.060099 0.000000
|
||||
0.046664 -0.060099 0.000000
|
||||
0.025020 -0.060728 0.000000
|
||||
0.046238 -0.060728 0.000000
|
||||
0.025521 -0.061297 0.000000
|
||||
0.045738 -0.061297 0.000000
|
||||
0.026089 -0.061798 0.000000
|
||||
0.045169 -0.061798 0.000000
|
||||
0.026719 -0.062223 0.000000
|
||||
0.044539 -0.062223 0.000000
|
||||
0.027403 -0.062566 0.000000
|
||||
0.043855 -0.062566 0.000000
|
||||
0.028134 -0.062820 0.000000
|
||||
0.043125 -0.062820 0.000000
|
||||
0.028904 -0.062978 0.000000
|
||||
0.042354 -0.062978 0.000000
|
||||
0.029707 -0.063032 0.000000
|
||||
0.041551 -0.063032 0.000000
|
||||
0.029940 -0.063032 0.000000
|
||||
0.030585 -0.063032 0.000000
|
||||
0.031558 -0.063032 0.000000
|
||||
0.032778 -0.063032 0.000000
|
||||
0.034162 -0.063032 0.000000
|
||||
0.035629 -0.063032 0.000000
|
||||
0.037096 -0.063032 0.000000
|
||||
0.038480 -0.063032 0.000000
|
||||
0.039700 -0.063032 0.000000
|
||||
0.040674 -0.063032 0.000000
|
||||
0.041318 -0.063032 0.000000
|
||||
3 0 1 2
|
||||
3 0 3 1
|
||||
3 0 4 3
|
||||
3 0 5 4
|
||||
3 0 6 5
|
||||
3 0 7 6
|
||||
3 0 8 7
|
||||
3 0 9 8
|
||||
3 0 10 9
|
||||
3 0 11 10
|
||||
3 0 12 11
|
||||
3 0 13 12
|
||||
3 0 14 13
|
||||
3 15 14 0
|
||||
3 15 16 14
|
||||
3 17 16 15
|
||||
3 17 18 16
|
||||
3 19 18 17
|
||||
3 19 20 18
|
||||
3 21 20 19
|
||||
3 21 22 20
|
||||
3 23 22 21
|
||||
3 23 24 22
|
||||
3 25 24 23
|
||||
3 25 26 24
|
||||
3 27 26 25
|
||||
3 27 28 26
|
||||
3 29 28 27
|
||||
3 29 30 28
|
||||
3 31 30 29
|
||||
3 31 32 30
|
||||
3 33 32 31
|
||||
3 33 34 32
|
||||
3 35 34 33
|
||||
3 35 36 34
|
||||
3 37 36 35
|
||||
3 37 38 36
|
||||
3 39 38 37
|
||||
3 40 38 39
|
||||
3 41 38 40
|
||||
3 41 42 38
|
||||
3 43 42 41
|
||||
3 44 42 43
|
||||
3 45 42 44
|
||||
3 45 46 42
|
||||
3 47 46 45
|
||||
3 48 46 47
|
||||
3 49 46 48
|
||||
3 50 46 49
|
||||
3 51 46 50
|
||||
3 52 51 53
|
||||
3 52 46 51
|
||||
3 54 55 56
|
||||
3 54 57 55
|
||||
3 54 58 57
|
||||
3 54 59 58
|
||||
3 54 60 59
|
||||
3 54 61 60
|
||||
3 54 62 61
|
||||
3 54 63 62
|
||||
3 54 64 63
|
||||
3 54 65 64
|
||||
3 54 66 65
|
||||
3 54 67 66
|
||||
3 54 68 67
|
||||
3 69 46 52
|
||||
3 54 70 68
|
||||
3 71 46 69
|
||||
3 54 72 70
|
||||
3 73 46 71
|
||||
3 54 74 72
|
||||
3 75 46 73
|
||||
3 54 76 74
|
||||
3 77 46 75
|
||||
3 54 78 76
|
||||
3 79 46 77
|
||||
3 80 46 79
|
||||
3 54 81 78
|
||||
3 80 82 46
|
||||
3 83 82 80
|
||||
3 54 84 81
|
||||
3 85 82 83
|
||||
3 54 86 84
|
||||
3 87 82 85
|
||||
3 54 88 86
|
||||
3 89 82 87
|
||||
3 54 90 88
|
||||
3 91 82 89
|
||||
3 92 82 91
|
||||
3 93 82 92
|
||||
3 54 94 90
|
||||
3 95 82 93
|
||||
3 54 96 94
|
||||
3 96 97 94
|
||||
3 98 82 95
|
||||
3 99 82 98
|
||||
3 99 100 82
|
||||
3 101 100 99
|
||||
3 102 100 101
|
||||
3 103 100 102
|
||||
3 104 100 103
|
||||
3 105 100 104
|
||||
3 106 100 105
|
||||
3 107 100 106
|
||||
3 108 100 107
|
||||
3 109 100 108
|
||||
3 110 100 109
|
||||
3 110 111 100
|
||||
3 111 112 100
|
||||
3 113 111 110
|
||||
3 114 111 113
|
||||
3 115 111 114
|
||||
3 116 111 115
|
||||
3 117 111 116
|
||||
3 118 111 117
|
||||
3 119 111 118
|
||||
3 120 111 119
|
||||
3 121 111 120
|
||||
3 122 111 121
|
||||
3 123 111 122
|
||||
3 124 111 123
|
||||
3 125 111 124
|
||||
3 126 111 125
|
||||
3 127 111 126
|
||||
3 128 111 127
|
||||
3 129 111 128
|
||||
3 130 111 129
|
||||
3 131 111 130
|
||||
3 132 112 111
|
||||
3 133 97 96
|
||||
3 132 134 112
|
||||
3 132 135 134
|
||||
3 132 136 135
|
||||
3 132 137 136
|
||||
3 132 138 137
|
||||
3 132 139 138
|
||||
3 132 140 139
|
||||
3 132 141 140
|
||||
3 133 142 97
|
||||
3 133 143 142
|
||||
3 133 144 143
|
||||
3 133 145 144
|
||||
3 133 146 145
|
||||
3 133 147 146
|
||||
3 133 148 147
|
||||
3 133 149 148
|
||||
3 133 150 149
|
||||
3 133 151 150
|
||||
3 133 152 151
|
||||
3 133 153 152
|
||||
3 133 154 153
|
||||
3 133 155 154
|
||||
3 133 156 155
|
||||
3 133 157 156
|
||||
3 133 158 157
|
||||
3 133 159 158
|
||||
3 133 160 159
|
||||
3 133 161 160
|
||||
3 133 162 161
|
||||
3 133 163 162
|
||||
3 164 141 132
|
||||
3 133 165 163
|
||||
3 166 141 164
|
||||
3 133 167 165
|
||||
3 167 168 165
|
||||
3 167 169 168
|
||||
3 167 170 169
|
||||
3 171 141 166
|
||||
3 167 172 170
|
||||
3 173 141 171
|
||||
3 167 174 172
|
||||
3 175 141 173
|
||||
3 167 176 174
|
||||
3 177 141 175
|
||||
3 167 178 176
|
||||
3 179 141 177
|
||||
3 167 180 178
|
||||
3 167 181 180
|
||||
3 182 141 179
|
||||
3 167 183 181
|
||||
3 184 141 182
|
||||
3 167 185 183
|
||||
3 186 141 184
|
||||
3 167 187 185
|
||||
3 188 141 186
|
||||
3 167 189 187
|
||||
3 190 141 188
|
||||
3 167 191 189
|
||||
3 192 141 190
|
||||
3 193 141 192
|
||||
3 194 141 193
|
||||
3 195 141 194
|
||||
3 196 141 195
|
||||
3 197 141 196
|
||||
3 198 141 197
|
||||
3 199 141 198
|
||||
3 200 141 199
|
||||
3 201 141 200
|
||||
3 202 141 201
|
||||
3 133 203 167
|
||||
3 133 204 203
|
||||
3 133 205 204
|
||||
3 133 206 205
|
||||
3 133 207 206
|
||||
3 133 208 207
|
||||
3 133 209 208
|
||||
3 133 210 209
|
||||
3 133 211 210
|
||||
3 133 212 211
|
||||
3 133 213 212
|
||||
3 133 214 213
|
||||
3 215 214 133
|
||||
3 215 216 214
|
||||
3 217 216 215
|
||||
3 217 218 216
|
||||
3 219 218 217
|
||||
3 219 220 218
|
||||
3 221 220 219
|
||||
3 221 222 220
|
||||
3 223 222 221
|
||||
3 223 224 222
|
||||
3 225 224 223
|
||||
3 225 226 224
|
||||
3 227 226 225
|
||||
3 227 228 226
|
||||
3 229 228 227
|
||||
3 229 230 228
|
||||
3 231 230 229
|
||||
3 231 232 230
|
||||
3 233 232 231
|
||||
3 233 234 232
|
||||
3 235 234 233
|
||||
3 235 236 234
|
||||
3 237 236 235
|
||||
3 237 238 236
|
||||
3 239 238 237
|
||||
3 240 238 239
|
||||
3 241 238 240
|
||||
3 242 238 241
|
||||
3 243 238 242
|
||||
3 244 238 243
|
||||
3 245 238 244
|
||||
3 246 238 245
|
||||
3 247 238 246
|
||||
3 248 238 247
|
||||
3 249 238 248
|
||||
59
rsc/mesh/corner.ply
Normal file
@@ -0,0 +1,59 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.91.0 - www.blender.org
|
||||
element vertex 21
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
element face 24
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-0.006000 0.200012 0.000000 255 255 255 255
|
||||
-0.002199 0.014730 0.000000 255 255 255 255
|
||||
-0.002199 0.200028 0.000000 255 255 255 255
|
||||
0.000000 0.019503 0.000000 255 255 255 255
|
||||
0.000000 0.200031 0.000000 255 255 255 255
|
||||
0.000000 0.011329 0.000000 255 255 255 255
|
||||
-0.001404 0.006999 0.000000 255 255 255 255
|
||||
0.000000 -0.000000 0.000000 255 255 255 255
|
||||
0.007305 -0.001503 0.000000 255 255 255 255
|
||||
-0.001032 -0.001167 0.000000 255 255 255 255
|
||||
0.014783 -0.002353 0.000000 255 255 255 255
|
||||
0.011630 -0.000000 0.000000 255 255 255 255
|
||||
0.004955 -0.006000 0.000000 255 255 255 255
|
||||
-0.004236 -0.006000 0.000000 255 255 255 255
|
||||
-0.006000 -0.006000 0.000000 255 255 255 255
|
||||
-0.006000 -0.000126 0.000000 255 255 255 255
|
||||
-0.006000 0.007802 0.000000 255 255 255 255
|
||||
0.199994 -0.006001 0.000000 255 255 255 255
|
||||
0.199997 -0.002353 0.000000 255 255 255 255
|
||||
0.019554 -0.000000 0.000000 255 255 255 255
|
||||
0.200000 0.000000 0.000000 255 255 255 255
|
||||
3 0 1 2
|
||||
3 2 3 4
|
||||
3 1 5 3
|
||||
3 6 7 5
|
||||
3 8 7 9
|
||||
3 10 11 8
|
||||
3 8 12 10
|
||||
3 13 9 14
|
||||
3 9 15 14
|
||||
3 6 16 15
|
||||
3 17 10 12
|
||||
3 18 19 10
|
||||
3 0 16 1
|
||||
3 2 1 3
|
||||
3 1 6 5
|
||||
3 6 9 7
|
||||
3 8 11 7
|
||||
3 10 19 11
|
||||
3 8 13 12
|
||||
3 13 8 9
|
||||
3 9 6 15
|
||||
3 6 1 16
|
||||
3 17 18 10
|
||||
3 18 20 19
|
||||
506
rsc/mesh/icon_crop.ply
Normal file
@@ -0,0 +1,506 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.91.0 - www.blender.org
|
||||
element vertex 250
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
element face 246
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-0.042157 0.063218 0.000000
|
||||
-0.041120 0.063272 0.000000
|
||||
-0.041354 0.063272 0.000000
|
||||
-0.040476 0.063272 0.000000
|
||||
-0.039503 0.063272 0.000000
|
||||
-0.038283 0.063272 0.000000
|
||||
-0.036898 0.063272 0.000000
|
||||
-0.035432 0.063272 0.000000
|
||||
-0.033965 0.063272 0.000000
|
||||
-0.032581 0.063272 0.000000
|
||||
-0.031361 0.063272 0.000000
|
||||
-0.030387 0.063272 0.000000
|
||||
-0.029743 0.063272 0.000000
|
||||
-0.029510 0.063272 0.000000
|
||||
-0.028707 0.063218 0.000000
|
||||
-0.042927 0.063061 0.000000
|
||||
-0.027936 0.063061 0.000000
|
||||
-0.043658 0.062807 0.000000
|
||||
-0.027206 0.062807 0.000000
|
||||
-0.044342 0.062464 0.000000
|
||||
-0.026522 0.062464 0.000000
|
||||
-0.044972 0.062039 0.000000
|
||||
-0.025892 0.062039 0.000000
|
||||
-0.045540 0.061539 0.000000
|
||||
-0.025323 0.061539 0.000000
|
||||
-0.046041 0.060970 0.000000
|
||||
-0.024823 0.060970 0.000000
|
||||
-0.046467 0.060341 0.000000
|
||||
-0.024397 0.060341 0.000000
|
||||
-0.046810 0.059657 0.000000
|
||||
-0.024054 0.059657 0.000000
|
||||
-0.047064 0.058926 0.000000
|
||||
-0.023800 0.058926 0.000000
|
||||
-0.047221 0.058155 0.000000
|
||||
-0.023642 0.058155 0.000000
|
||||
-0.047275 0.057352 0.000000
|
||||
-0.023588 0.057352 0.000000
|
||||
-0.047275 0.057158 0.000000
|
||||
-0.023588 0.055760 0.000000
|
||||
-0.047275 0.056621 0.000000
|
||||
-0.047275 0.055810 0.000000
|
||||
-0.047275 0.054794 0.000000
|
||||
-0.023588 0.051358 0.000000
|
||||
-0.047275 0.053640 0.000000
|
||||
-0.047275 0.052418 0.000000
|
||||
-0.047275 0.051196 0.000000
|
||||
-0.023588 0.044709 0.000000
|
||||
-0.047275 0.050043 0.000000
|
||||
-0.047275 0.049026 0.000000
|
||||
-0.047275 0.048215 0.000000
|
||||
-0.047275 0.047678 0.000000
|
||||
-0.047275 0.047484 0.000000
|
||||
-0.057948 0.047430 0.000000
|
||||
-0.057145 0.047484 0.000000
|
||||
-0.015693 0.023802 0.000000
|
||||
-0.014605 0.047484 0.000000
|
||||
-0.015693 0.047484 0.000000
|
||||
-0.011599 0.047484 0.000000
|
||||
-0.007057 0.047484 0.000000
|
||||
-0.001363 0.047484 0.000000
|
||||
0.005097 0.047484 0.000000
|
||||
0.011942 0.047484 0.000000
|
||||
0.018787 0.047484 0.000000
|
||||
0.025248 0.047484 0.000000
|
||||
0.030941 0.047484 0.000000
|
||||
0.035483 0.047484 0.000000
|
||||
0.038490 0.047484 0.000000
|
||||
0.039577 0.047484 0.000000
|
||||
0.040648 0.047412 0.000000
|
||||
-0.058719 0.047273 0.000000
|
||||
0.041676 0.047202 0.000000
|
||||
-0.059449 0.047019 0.000000
|
||||
0.042650 0.046864 0.000000
|
||||
-0.060133 0.046676 0.000000
|
||||
0.043562 0.046406 0.000000
|
||||
-0.060763 0.046251 0.000000
|
||||
0.044402 0.045839 0.000000
|
||||
-0.061332 0.045751 0.000000
|
||||
0.045160 0.045172 0.000000
|
||||
-0.061832 0.045182 0.000000
|
||||
-0.062258 0.044553 0.000000
|
||||
0.045827 0.044414 0.000000
|
||||
-0.023588 0.036374 0.000000
|
||||
-0.062601 0.043869 0.000000
|
||||
0.046395 0.043574 0.000000
|
||||
-0.062855 0.043138 0.000000
|
||||
0.046852 0.042663 0.000000
|
||||
-0.063013 0.042367 0.000000
|
||||
0.047191 0.041689 0.000000
|
||||
-0.063067 0.041564 0.000000
|
||||
0.047401 0.040661 0.000000
|
||||
-0.063067 0.041331 0.000000
|
||||
-0.063067 0.040687 0.000000
|
||||
-0.063067 0.039714 0.000000
|
||||
0.047473 0.039590 0.000000
|
||||
-0.063067 0.038494 0.000000
|
||||
0.023786 0.023802 0.000000
|
||||
0.047473 -0.023562 0.000000
|
||||
-0.063067 0.037110 0.000000
|
||||
-0.063067 0.035643 0.000000
|
||||
-0.023588 0.026916 0.000000
|
||||
-0.063067 0.034177 0.000000
|
||||
-0.063067 0.032793 0.000000
|
||||
-0.063067 0.031573 0.000000
|
||||
-0.063067 0.030600 0.000000
|
||||
-0.063067 0.029956 0.000000
|
||||
-0.063067 0.029723 0.000000
|
||||
-0.063013 0.028920 0.000000
|
||||
-0.062855 0.028149 0.000000
|
||||
-0.062601 0.027419 0.000000
|
||||
-0.062258 0.026735 0.000000
|
||||
-0.047275 0.023802 0.000000
|
||||
-0.023588 0.016895 0.000000
|
||||
-0.061832 0.026105 0.000000
|
||||
-0.061332 0.025537 0.000000
|
||||
-0.060763 0.025036 0.000000
|
||||
-0.060133 0.024611 0.000000
|
||||
-0.059449 0.024268 0.000000
|
||||
-0.058719 0.024014 0.000000
|
||||
-0.057948 0.023856 0.000000
|
||||
-0.057145 0.023802 0.000000
|
||||
-0.056951 0.023802 0.000000
|
||||
-0.056414 0.023802 0.000000
|
||||
-0.055603 0.023802 0.000000
|
||||
-0.054586 0.023802 0.000000
|
||||
-0.053432 0.023802 0.000000
|
||||
-0.052210 0.023802 0.000000
|
||||
-0.050988 0.023802 0.000000
|
||||
-0.049834 0.023802 0.000000
|
||||
-0.048817 0.023802 0.000000
|
||||
-0.048006 0.023802 0.000000
|
||||
-0.047469 0.023802 0.000000
|
||||
-0.047275 -0.039350 0.000000
|
||||
0.023786 -0.057111 0.000000
|
||||
-0.023588 0.006875 0.000000
|
||||
-0.023588 -0.002584 0.000000
|
||||
-0.023588 -0.010919 0.000000
|
||||
-0.023588 -0.017568 0.000000
|
||||
-0.023588 -0.021970 0.000000
|
||||
-0.023588 -0.023562 0.000000
|
||||
0.015890 -0.023562 0.000000
|
||||
0.015890 -0.047244 0.000000
|
||||
0.057342 -0.023562 0.000000
|
||||
0.058146 -0.023616 0.000000
|
||||
0.058916 -0.023773 0.000000
|
||||
0.059647 -0.024027 0.000000
|
||||
0.060331 -0.024370 0.000000
|
||||
0.060960 -0.024795 0.000000
|
||||
0.061529 -0.025295 0.000000
|
||||
0.062030 -0.025864 0.000000
|
||||
0.062455 -0.026493 0.000000
|
||||
0.062798 -0.027177 0.000000
|
||||
0.063052 -0.027908 0.000000
|
||||
0.063210 -0.028679 0.000000
|
||||
0.063264 -0.029482 0.000000
|
||||
0.063264 -0.029715 0.000000
|
||||
0.063264 -0.030359 0.000000
|
||||
0.063264 -0.031332 0.000000
|
||||
0.063264 -0.032552 0.000000
|
||||
0.063264 -0.033936 0.000000
|
||||
0.063264 -0.035403 0.000000
|
||||
0.063264 -0.036869 0.000000
|
||||
0.063264 -0.038253 0.000000
|
||||
0.063264 -0.039473 0.000000
|
||||
-0.047203 -0.040421 0.000000
|
||||
0.063264 -0.040446 0.000000
|
||||
-0.046993 -0.041448 0.000000
|
||||
0.047473 -0.047244 0.000000
|
||||
0.063264 -0.041090 0.000000
|
||||
0.063264 -0.041323 0.000000
|
||||
0.063210 -0.042126 0.000000
|
||||
-0.046655 -0.042422 0.000000
|
||||
0.063052 -0.042897 0.000000
|
||||
-0.046197 -0.043334 0.000000
|
||||
0.062798 -0.043627 0.000000
|
||||
-0.045630 -0.044173 0.000000
|
||||
0.062455 -0.044311 0.000000
|
||||
-0.044962 -0.044931 0.000000
|
||||
0.062030 -0.044940 0.000000
|
||||
-0.044204 -0.045599 0.000000
|
||||
0.061529 -0.045509 0.000000
|
||||
0.060960 -0.046010 0.000000
|
||||
-0.043364 -0.046166 0.000000
|
||||
0.060331 -0.046435 0.000000
|
||||
-0.042453 -0.046623 0.000000
|
||||
0.059647 -0.046778 0.000000
|
||||
-0.041478 -0.046962 0.000000
|
||||
0.058916 -0.047032 0.000000
|
||||
-0.040451 -0.047172 0.000000
|
||||
0.058146 -0.047190 0.000000
|
||||
-0.039380 -0.047244 0.000000
|
||||
0.057342 -0.047244 0.000000
|
||||
-0.038292 -0.047244 0.000000
|
||||
-0.035286 -0.047244 0.000000
|
||||
-0.030744 -0.047244 0.000000
|
||||
-0.025050 -0.047244 0.000000
|
||||
-0.018590 -0.047244 0.000000
|
||||
-0.011745 -0.047244 0.000000
|
||||
-0.004900 -0.047244 0.000000
|
||||
0.001561 -0.047244 0.000000
|
||||
0.007254 -0.047244 0.000000
|
||||
0.011796 -0.047244 0.000000
|
||||
0.014803 -0.047244 0.000000
|
||||
0.047473 -0.047438 0.000000
|
||||
0.047473 -0.047975 0.000000
|
||||
0.047473 -0.048785 0.000000
|
||||
0.047473 -0.049802 0.000000
|
||||
0.047473 -0.050955 0.000000
|
||||
0.047473 -0.052177 0.000000
|
||||
0.047473 -0.053399 0.000000
|
||||
0.047473 -0.054553 0.000000
|
||||
0.047473 -0.055569 0.000000
|
||||
0.047473 -0.056380 0.000000
|
||||
0.047473 -0.056917 0.000000
|
||||
0.047473 -0.057111 0.000000
|
||||
0.023840 -0.057914 0.000000
|
||||
0.047419 -0.057914 0.000000
|
||||
0.023997 -0.058685 0.000000
|
||||
0.047261 -0.058685 0.000000
|
||||
0.024251 -0.059415 0.000000
|
||||
0.047007 -0.059415 0.000000
|
||||
0.024594 -0.060099 0.000000
|
||||
0.046664 -0.060099 0.000000
|
||||
0.025020 -0.060728 0.000000
|
||||
0.046238 -0.060728 0.000000
|
||||
0.025521 -0.061297 0.000000
|
||||
0.045738 -0.061297 0.000000
|
||||
0.026089 -0.061798 0.000000
|
||||
0.045169 -0.061798 0.000000
|
||||
0.026719 -0.062223 0.000000
|
||||
0.044539 -0.062223 0.000000
|
||||
0.027403 -0.062566 0.000000
|
||||
0.043855 -0.062566 0.000000
|
||||
0.028134 -0.062820 0.000000
|
||||
0.043125 -0.062820 0.000000
|
||||
0.028904 -0.062978 0.000000
|
||||
0.042354 -0.062978 0.000000
|
||||
0.029707 -0.063032 0.000000
|
||||
0.041551 -0.063032 0.000000
|
||||
0.029940 -0.063032 0.000000
|
||||
0.030585 -0.063032 0.000000
|
||||
0.031558 -0.063032 0.000000
|
||||
0.032778 -0.063032 0.000000
|
||||
0.034162 -0.063032 0.000000
|
||||
0.035629 -0.063032 0.000000
|
||||
0.037096 -0.063032 0.000000
|
||||
0.038480 -0.063032 0.000000
|
||||
0.039700 -0.063032 0.000000
|
||||
0.040674 -0.063032 0.000000
|
||||
0.041318 -0.063032 0.000000
|
||||
3 0 1 2
|
||||
3 0 3 1
|
||||
3 0 4 3
|
||||
3 0 5 4
|
||||
3 0 6 5
|
||||
3 0 7 6
|
||||
3 0 8 7
|
||||
3 0 9 8
|
||||
3 0 10 9
|
||||
3 0 11 10
|
||||
3 0 12 11
|
||||
3 0 13 12
|
||||
3 0 14 13
|
||||
3 15 14 0
|
||||
3 15 16 14
|
||||
3 17 16 15
|
||||
3 17 18 16
|
||||
3 19 18 17
|
||||
3 19 20 18
|
||||
3 21 20 19
|
||||
3 21 22 20
|
||||
3 23 22 21
|
||||
3 23 24 22
|
||||
3 25 24 23
|
||||
3 25 26 24
|
||||
3 27 26 25
|
||||
3 27 28 26
|
||||
3 29 28 27
|
||||
3 29 30 28
|
||||
3 31 30 29
|
||||
3 31 32 30
|
||||
3 33 32 31
|
||||
3 33 34 32
|
||||
3 35 34 33
|
||||
3 35 36 34
|
||||
3 37 36 35
|
||||
3 37 38 36
|
||||
3 39 38 37
|
||||
3 40 38 39
|
||||
3 41 38 40
|
||||
3 41 42 38
|
||||
3 43 42 41
|
||||
3 44 42 43
|
||||
3 45 42 44
|
||||
3 45 46 42
|
||||
3 47 46 45
|
||||
3 48 46 47
|
||||
3 49 46 48
|
||||
3 50 46 49
|
||||
3 51 46 50
|
||||
3 52 51 53
|
||||
3 52 46 51
|
||||
3 54 55 56
|
||||
3 54 57 55
|
||||
3 54 58 57
|
||||
3 54 59 58
|
||||
3 54 60 59
|
||||
3 54 61 60
|
||||
3 54 62 61
|
||||
3 54 63 62
|
||||
3 54 64 63
|
||||
3 54 65 64
|
||||
3 54 66 65
|
||||
3 54 67 66
|
||||
3 54 68 67
|
||||
3 69 46 52
|
||||
3 54 70 68
|
||||
3 71 46 69
|
||||
3 54 72 70
|
||||
3 73 46 71
|
||||
3 54 74 72
|
||||
3 75 46 73
|
||||
3 54 76 74
|
||||
3 77 46 75
|
||||
3 54 78 76
|
||||
3 79 46 77
|
||||
3 80 46 79
|
||||
3 54 81 78
|
||||
3 80 82 46
|
||||
3 83 82 80
|
||||
3 54 84 81
|
||||
3 85 82 83
|
||||
3 54 86 84
|
||||
3 87 82 85
|
||||
3 54 88 86
|
||||
3 89 82 87
|
||||
3 54 90 88
|
||||
3 91 82 89
|
||||
3 92 82 91
|
||||
3 93 82 92
|
||||
3 54 94 90
|
||||
3 95 82 93
|
||||
3 54 96 94
|
||||
3 96 97 94
|
||||
3 98 82 95
|
||||
3 99 82 98
|
||||
3 99 100 82
|
||||
3 101 100 99
|
||||
3 102 100 101
|
||||
3 103 100 102
|
||||
3 104 100 103
|
||||
3 105 100 104
|
||||
3 106 100 105
|
||||
3 107 100 106
|
||||
3 108 100 107
|
||||
3 109 100 108
|
||||
3 110 100 109
|
||||
3 110 111 100
|
||||
3 111 112 100
|
||||
3 113 111 110
|
||||
3 114 111 113
|
||||
3 115 111 114
|
||||
3 116 111 115
|
||||
3 117 111 116
|
||||
3 118 111 117
|
||||
3 119 111 118
|
||||
3 120 111 119
|
||||
3 121 111 120
|
||||
3 122 111 121
|
||||
3 123 111 122
|
||||
3 124 111 123
|
||||
3 125 111 124
|
||||
3 126 111 125
|
||||
3 127 111 126
|
||||
3 128 111 127
|
||||
3 129 111 128
|
||||
3 130 111 129
|
||||
3 131 111 130
|
||||
3 132 112 111
|
||||
3 133 97 96
|
||||
3 132 134 112
|
||||
3 132 135 134
|
||||
3 132 136 135
|
||||
3 132 137 136
|
||||
3 132 138 137
|
||||
3 132 139 138
|
||||
3 132 140 139
|
||||
3 132 141 140
|
||||
3 133 142 97
|
||||
3 133 143 142
|
||||
3 133 144 143
|
||||
3 133 145 144
|
||||
3 133 146 145
|
||||
3 133 147 146
|
||||
3 133 148 147
|
||||
3 133 149 148
|
||||
3 133 150 149
|
||||
3 133 151 150
|
||||
3 133 152 151
|
||||
3 133 153 152
|
||||
3 133 154 153
|
||||
3 133 155 154
|
||||
3 133 156 155
|
||||
3 133 157 156
|
||||
3 133 158 157
|
||||
3 133 159 158
|
||||
3 133 160 159
|
||||
3 133 161 160
|
||||
3 133 162 161
|
||||
3 133 163 162
|
||||
3 164 141 132
|
||||
3 133 165 163
|
||||
3 166 141 164
|
||||
3 133 167 165
|
||||
3 167 168 165
|
||||
3 167 169 168
|
||||
3 167 170 169
|
||||
3 171 141 166
|
||||
3 167 172 170
|
||||
3 173 141 171
|
||||
3 167 174 172
|
||||
3 175 141 173
|
||||
3 167 176 174
|
||||
3 177 141 175
|
||||
3 167 178 176
|
||||
3 179 141 177
|
||||
3 167 180 178
|
||||
3 167 181 180
|
||||
3 182 141 179
|
||||
3 167 183 181
|
||||
3 184 141 182
|
||||
3 167 185 183
|
||||
3 186 141 184
|
||||
3 167 187 185
|
||||
3 188 141 186
|
||||
3 167 189 187
|
||||
3 190 141 188
|
||||
3 167 191 189
|
||||
3 192 141 190
|
||||
3 193 141 192
|
||||
3 194 141 193
|
||||
3 195 141 194
|
||||
3 196 141 195
|
||||
3 197 141 196
|
||||
3 198 141 197
|
||||
3 199 141 198
|
||||
3 200 141 199
|
||||
3 201 141 200
|
||||
3 202 141 201
|
||||
3 133 203 167
|
||||
3 133 204 203
|
||||
3 133 205 204
|
||||
3 133 206 205
|
||||
3 133 207 206
|
||||
3 133 208 207
|
||||
3 133 209 208
|
||||
3 133 210 209
|
||||
3 133 211 210
|
||||
3 133 212 211
|
||||
3 133 213 212
|
||||
3 133 214 213
|
||||
3 215 214 133
|
||||
3 215 216 214
|
||||
3 217 216 215
|
||||
3 217 218 216
|
||||
3 219 218 217
|
||||
3 219 220 218
|
||||
3 221 220 219
|
||||
3 221 222 220
|
||||
3 223 222 221
|
||||
3 223 224 222
|
||||
3 225 224 223
|
||||
3 225 226 224
|
||||
3 227 226 225
|
||||
3 227 228 226
|
||||
3 229 228 227
|
||||
3 229 230 228
|
||||
3 231 230 229
|
||||
3 231 232 230
|
||||
3 233 232 231
|
||||
3 233 234 232
|
||||
3 235 234 233
|
||||
3 235 236 234
|
||||
3 237 236 235
|
||||
3 237 238 236
|
||||
3 239 238 237
|
||||
3 240 238 239
|
||||
3 241 238 240
|
||||
3 242 238 241
|
||||
3 243 238 242
|
||||
3 244 238 243
|
||||
3 245 238 244
|
||||
3 246 238 245
|
||||
3 247 238 246
|
||||
3 248 238 247
|
||||
3 249 238 248
|
||||
192
rsc/mesh/perspective_axis_left.ply
Normal file
@@ -0,0 +1,192 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.91.0 - www.blender.org
|
||||
element vertex 81
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
element face 101
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-1.005000 -2.010402 0.000000
|
||||
-0.997299 -2.010402 0.000000
|
||||
-1.016821 -2.006961 0.000000
|
||||
-1.012701 -2.042907 0.000000
|
||||
-1.012701 -2.010402 0.000000
|
||||
-1.005000 -2.140421 0.000000
|
||||
-1.012701 -2.140421 0.000000
|
||||
-0.993243 -2.143901 0.000000
|
||||
-5.016935 -6.134262 0.000000
|
||||
-5.012702 -6.172815 0.000000
|
||||
-5.012702 -6.140421 0.000000
|
||||
-5.005000 -6.269996 0.000000
|
||||
-5.012702 -6.269996 0.000000
|
||||
-4.993124 -6.271469 0.000000
|
||||
-0.993107 -2.007656 0.000000
|
||||
-0.025000 -1.026536 0.000000
|
||||
-0.040402 -1.029598 0.000000
|
||||
-1.016843 -2.042907 0.000000
|
||||
-4.997299 -6.140421 0.000000
|
||||
-4.992839 -6.146410 0.000000
|
||||
-1.016888 -2.130304 0.000000
|
||||
-5.017002 -6.172815 0.000000
|
||||
-5.016947 -6.272215 0.000000
|
||||
-6.051421 -7.308137 0.000000
|
||||
-6.029597 -7.308137 0.000000
|
||||
-0.014928 -1.028372 0.000000
|
||||
-0.023242 -1.023197 0.000000
|
||||
-0.014320 -1.024299 0.000000
|
||||
-5.005000 -6.205208 0.000000
|
||||
-5.005000 -6.237602 0.000000
|
||||
-4.997299 -6.237602 0.000000
|
||||
-5.012702 -6.205208 0.000000
|
||||
-5.017002 -6.205208 0.000000
|
||||
-5.017002 -6.237602 0.000000
|
||||
-5.012702 -6.237602 0.000000
|
||||
-5.005000 -6.140421 0.000000
|
||||
-4.997299 -6.172815 0.000000
|
||||
-5.005000 -6.172815 0.000000
|
||||
-4.997299 -6.205208 0.000000
|
||||
-4.992999 -6.237602 0.000000
|
||||
-4.992999 -6.205208 0.000000
|
||||
-4.992999 -6.172815 0.000000
|
||||
-4.997299 -6.269996 0.000000
|
||||
-1.005000 -2.075412 0.000000
|
||||
-1.005000 -2.107916 0.000000
|
||||
-0.997299 -2.107916 0.000000
|
||||
-1.012701 -2.075412 0.000000
|
||||
-1.016843 -2.075412 0.000000
|
||||
-1.016843 -2.107916 0.000000
|
||||
-1.012701 -2.107916 0.000000
|
||||
-0.997299 -2.042907 0.000000
|
||||
-1.005000 -2.042907 0.000000
|
||||
-0.997299 -2.075412 0.000000
|
||||
-0.993157 -2.107916 0.000000
|
||||
-0.993157 -2.075412 0.000000
|
||||
-0.993157 -2.042907 0.000000
|
||||
-0.997299 -2.140421 0.000000
|
||||
-0.024245 -1.019051 0.000000
|
||||
-0.029970 -1.019912 0.000000
|
||||
-0.017730 -1.020603 0.000000
|
||||
-0.033926 -1.023085 0.000000
|
||||
-4.771169 -7.309363 0.000000
|
||||
-6.041811 -7.295620 0.000000
|
||||
-6.041811 -7.309363 0.000000
|
||||
-4.771169 -7.295620 0.000000
|
||||
-3.725413 -6.272977 0.000000
|
||||
-5.004570 -6.259233 0.000000
|
||||
-5.004570 -6.272977 0.000000
|
||||
-3.725413 -6.259233 0.000000
|
||||
-3.722498 -6.151754 0.000000
|
||||
-5.003956 -6.129984 0.000000
|
||||
-5.003956 -6.151754 0.000000
|
||||
-3.722498 -6.129984 0.000000
|
||||
0.262578 -2.147450 0.000000
|
||||
-1.004861 -2.126240 0.000000
|
||||
-1.004861 -2.147450 0.000000
|
||||
0.262578 -2.126240 0.000000
|
||||
0.268543 -2.021173 0.000000
|
||||
-1.004861 -2.007429 0.000000
|
||||
-1.004861 -2.021173 0.000000
|
||||
0.268543 -2.007429 0.000000
|
||||
3 0 1 2
|
||||
3 2 3 4
|
||||
3 5 6 7
|
||||
3 8 9 10
|
||||
3 11 12 13
|
||||
3 14 15 16
|
||||
3 2 17 3
|
||||
3 18 19 20
|
||||
3 8 21 9
|
||||
3 22 23 24
|
||||
3 25 26 15
|
||||
3 25 27 26
|
||||
3 28 29 30
|
||||
3 28 31 29
|
||||
3 32 33 34
|
||||
3 35 36 18
|
||||
3 35 37 36
|
||||
3 28 30 38
|
||||
3 38 39 40
|
||||
3 38 30 39
|
||||
3 30 13 39
|
||||
3 36 38 40
|
||||
3 36 37 38
|
||||
3 37 28 38
|
||||
3 18 41 19
|
||||
3 18 36 41
|
||||
3 36 40 41
|
||||
3 34 12 11
|
||||
3 34 33 12
|
||||
3 33 22 12
|
||||
3 29 34 11
|
||||
3 29 31 34
|
||||
3 31 32 34
|
||||
3 30 42 13
|
||||
3 30 29 42
|
||||
3 29 11 42
|
||||
3 9 31 28
|
||||
3 9 21 31
|
||||
3 21 32 31
|
||||
3 10 37 35
|
||||
3 10 9 37
|
||||
3 9 28 37
|
||||
3 43 44 45
|
||||
3 43 46 44
|
||||
3 47 48 49
|
||||
3 0 50 1
|
||||
3 0 51 50
|
||||
3 43 45 52
|
||||
3 52 53 54
|
||||
3 52 45 53
|
||||
3 45 7 53
|
||||
3 50 52 54
|
||||
3 50 51 52
|
||||
3 51 43 52
|
||||
3 1 55 14
|
||||
3 1 50 55
|
||||
3 50 54 55
|
||||
3 49 6 5
|
||||
3 49 48 6
|
||||
3 48 20 6
|
||||
3 44 49 5
|
||||
3 44 46 49
|
||||
3 46 47 49
|
||||
3 45 56 7
|
||||
3 45 44 56
|
||||
3 44 5 56
|
||||
3 3 46 43
|
||||
3 3 17 46
|
||||
3 17 47 46
|
||||
3 4 51 0
|
||||
3 4 3 51
|
||||
3 3 43 51
|
||||
3 1 14 16
|
||||
3 16 2 1
|
||||
3 2 4 0
|
||||
3 6 20 19
|
||||
3 19 7 6
|
||||
3 7 56 5
|
||||
3 12 22 24
|
||||
3 24 13 12
|
||||
3 13 42 11
|
||||
3 20 8 18
|
||||
3 8 10 35
|
||||
3 35 18 8
|
||||
3 26 57 58
|
||||
3 26 27 57
|
||||
3 27 59 57
|
||||
3 15 60 16
|
||||
3 15 26 60
|
||||
3 26 58 60
|
||||
3 14 25 15
|
||||
3 61 62 63
|
||||
3 61 64 62
|
||||
3 65 66 67
|
||||
3 65 68 66
|
||||
3 69 70 71
|
||||
3 69 72 70
|
||||
3 73 74 75
|
||||
3 73 76 74
|
||||
3 77 78 79
|
||||
3 77 80 78
|
||||
3022
rsc/mesh/perspective_axis_right.ply
Normal file
@@ -1,42 +1,40 @@
|
||||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'perspective_layer.blend'
|
||||
element vertex 16
|
||||
comment Created by Blender 2.91.0 - www.blender.org
|
||||
element vertex 20
|
||||
property float x
|
||||
property float y
|
||||
property float z
|
||||
property uchar red
|
||||
property uchar green
|
||||
property uchar blue
|
||||
property uchar alpha
|
||||
element face 12
|
||||
element face 10
|
||||
property list uchar uint vertex_indices
|
||||
end_header
|
||||
-6.690000 -6.700000 0.000000 255 0 255 100
|
||||
-1.010000 -1.000000 0.000000 255 0 255 100
|
||||
-6.710000 -6.700000 0.000000 255 0 255 100
|
||||
-0.990000 -1.000000 0.000000 255 0 255 100
|
||||
-6.610000 -6.710000 0.000000 255 0 255 100
|
||||
-6.500000 -6.700000 0.000000 255 0 255 100
|
||||
-6.705731 -6.710000 0.000000 255 0 255 100
|
||||
-6.510000 -6.710000 0.000000 255 0 255 100
|
||||
-4.690000 -6.700000 0.000000 255 0 255 100
|
||||
0.990000 -1.000000 0.000000 255 0 255 100
|
||||
-4.710000 -6.700000 0.000000 255 0 255 100
|
||||
1.010000 -1.000000 0.000000 255 0 255 100
|
||||
-4.706754 -6.710000 0.000000 255 0 255 100
|
||||
-4.910000 -6.710000 0.000000 255 0 255 100
|
||||
-4.810000 -6.710000 0.000000 255 0 255 100
|
||||
-4.900000 -6.700000 0.000000 255 0 255 100
|
||||
1.001107 -2.119227 0.000000
|
||||
-0.998893 -2.105483 0.000000
|
||||
-0.998893 -2.119227 0.000000
|
||||
1.001107 -2.105483 0.000000
|
||||
-2.998893 -6.127666 0.000000
|
||||
-4.998893 -6.113922 0.000000
|
||||
-4.998893 -6.127666 0.000000
|
||||
-2.998893 -6.113922 0.000000
|
||||
-2.998893 -6.247665 0.000000
|
||||
-4.998893 -6.233922 0.000000
|
||||
-4.998893 -6.247665 0.000000
|
||||
-2.998893 -6.233922 0.000000
|
||||
-4.028101 -7.298446 0.000000
|
||||
-6.029685 -7.284703 0.000000
|
||||
-6.029685 -7.298446 0.000000
|
||||
-4.028101 -7.284703 0.000000
|
||||
1.001107 -2.008962 0.000000
|
||||
-0.998893 -1.995219 0.000000
|
||||
-0.998893 -2.008962 0.000000
|
||||
1.001107 -1.995219 0.000000
|
||||
3 0 1 2
|
||||
3 0 3 1
|
||||
3 2 4 0
|
||||
3 4 5 0
|
||||
3 2 6 4
|
||||
3 4 5 6
|
||||
3 4 7 5
|
||||
3 8 9 10
|
||||
3 8 11 9
|
||||
3 10 12 8
|
||||
3 10 13 14
|
||||
3 10 14 12
|
||||
3 10 15 13
|
||||
3 12 13 14
|
||||
3 12 15 13
|
||||
3 16 17 18
|
||||
3 16 19 17
|
||||
|
||||
@@ -7,7 +7,7 @@ in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport image resolution (in pixels)
|
||||
uniform mat4 iTransform; // UV image transformation
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color;
|
||||
uniform vec4 uv;
|
||||
|
||||
@@ -25,13 +25,14 @@ void main()
|
||||
vec4 textureColor = texture(iChannel0, texcoord.xy);
|
||||
vec3 RGB = textureColor.rgb * vertexColor.rgb * color.rgb;
|
||||
|
||||
// alpha is a mix of texture alpha, vertex alpha, and uniform alpha affected by stippling
|
||||
vec4 maskColor = texture(iChannel1, vertexUV);
|
||||
float maskIntensity = (maskColor.r + maskColor.g + maskColor.b) / 3.0;
|
||||
// read mask intensity as average of RGB
|
||||
float maskIntensity = dot(texture(iChannel1, vertexUV).rgb, vec3(1.0/3.0));
|
||||
|
||||
// alpha is a mix of texture alpha, vertex alpha, and uniform alpha affected by stippling
|
||||
float A = textureColor.a * vertexColor.a * color.a * maskIntensity;
|
||||
A -= stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 > 0 ? 0.05 : 0.95 );
|
||||
A += textureColor.a * stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 );
|
||||
|
||||
// output RGBA
|
||||
FragColor = vec4(RGB, clamp(A, 0.0, 1.0) );
|
||||
// FragColor = texture(iChannel1, vertexUV);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,7 @@ void main()
|
||||
vec3 RGB = textureColor.rgb * vertexColor.rgb * color.rgb;
|
||||
|
||||
// alpha is a mix of texture alpha, vertex alpha, and uniform alpha affected by stippling
|
||||
vec4 maskColor = texture(iChannel1, vertexUV);
|
||||
float maskIntensity = (maskColor.r + maskColor.g + maskColor.b) / 3.0;
|
||||
float maskIntensity = dot(texture(iChannel1, vertexUV).rgb, vec3(1.0/3.0));
|
||||
|
||||
float A = textureColor.a * vertexColor.a * color.a * maskIntensity;
|
||||
A -= stipple * ( int(gl_FragCoord.x + gl_FragCoord.y) % 2 > 0 ? 0.05 : 0.95 );
|
||||
|
||||
35
rsc/shaders/mask_box.fs
Normal file
@@ -0,0 +1,35 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float sdRoundBox( in vec2 p, in vec2 b, in float r )
|
||||
{
|
||||
vec2 q = abs(p)-b+r;
|
||||
return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
float d = sdRoundBox( uv, vec2(size.x * iResolution.x/iResolution.y, size.y), blur * 0.5 );
|
||||
|
||||
vec3 col = vec3(1.0 - sign(d));
|
||||
col *= 1.0 - exp( -600.0/ (blur * 1000.f + 1.0) * abs(d));
|
||||
|
||||
FragColor = vec4( col, 1.0 );
|
||||
}
|
||||
111
rsc/shaders/mask_draw.fs
Normal file
@@ -0,0 +1,111 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform sampler2D iChannel0; // base texture
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
uniform vec4 cursor;
|
||||
uniform vec3 brush;
|
||||
uniform int option;
|
||||
uniform int effect;
|
||||
|
||||
float sdBox( in vec2 p, in float b)
|
||||
{
|
||||
vec2 q = abs(p) - vec2(b);
|
||||
float d = min( max(q.x, q.y), 0.0) + length(max(q,0.0));
|
||||
return 1.0 - abs(d) * step(d, 0.0);
|
||||
}
|
||||
|
||||
float sdCircle( in vec2 p, in float b)
|
||||
{
|
||||
return ( length( p ) / b );
|
||||
}
|
||||
|
||||
const mat3 KERNEL = mat3( 0.0625, 0.125, 0.0625,
|
||||
0.125, 0.25, 0.125,
|
||||
0.0625, 0.125, 0.0625);
|
||||
|
||||
vec3 gaussian()
|
||||
{
|
||||
vec2 filter_step = 1.f / textureSize(iChannel0, 0);
|
||||
int i = 0, j = 0;
|
||||
vec3 sum = vec3(0.0);
|
||||
|
||||
for (i = 0; i<3; ++i)
|
||||
for (j = 0; j<3; ++j)
|
||||
sum += texture(iChannel0, vertexUV.xy + filter_step * vec2 (i-1, j-1) ).rgb * KERNEL[i][j];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(iChannel0, vertexUV).rgb; // raw color
|
||||
|
||||
// clear
|
||||
color += mix(vec3(0), vec3(1) - color, int(effect == 1));
|
||||
// invert
|
||||
color = mix(color, vec3(1) - color, int(effect == 2));
|
||||
// step edge
|
||||
color = mix(color, vec3(1.0 - step(dot(color, vec3(1.0/3.0)), 0.6)), int(effect == 3));
|
||||
|
||||
if ( option > 0 ) {
|
||||
|
||||
// fragment coordinates
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
// adjust coordinates to match scaling area
|
||||
uv.x *= cursor.z ;
|
||||
uv.y *= cursor.w ;
|
||||
// cursor coordinates
|
||||
vec2 cursor = vec2(cursor.x, - cursor.y);
|
||||
// use distance function relative to length brush.x (size), depending on brush.z (shape):
|
||||
// - brush.z = 0 : circle shape
|
||||
// - brush.z = 1 : square shape
|
||||
float d = (1.0 -brush.z) * sdCircle(cursor-uv, brush.x) + brush.z * sdBox(uv-cursor, brush.x);
|
||||
|
||||
// modify only the pixels inside the brush
|
||||
if( d < 1.0 )
|
||||
{
|
||||
// blur the image incrementally each step
|
||||
color = gaussian();
|
||||
|
||||
// mask intensity
|
||||
float c = dot(color, vec3(1.0/3.0));
|
||||
|
||||
// depending on option:
|
||||
// - option 1 : paint (add color)
|
||||
// - option 2 : erase (substract color)
|
||||
float p = c + (option > 1 ? d - 1.0 : 1.0 - d );
|
||||
|
||||
// new intensity is a mix betwen current intensity and painted intensity
|
||||
c = (1.0 - brush.y) * c + (brush.y) * p;
|
||||
|
||||
// distribute value in RGB (will be averaged in image.fs)
|
||||
// NB : this encodes the mask intensity over 3*8 bits
|
||||
c *= 3.0;
|
||||
color.r = clamp(c, 0.0, 1.0);
|
||||
color.g = step(1.0, c) * (clamp(c, 1.0, 2.0) - 1.0);
|
||||
color.b = step(2.0, c) * (clamp(c, 2.0, 3.0) - 2.0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
FragColor = vec4( clamp(color, 0.0, 1.0), 1.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
63
rsc/shaders/mask_elipse.fs
Normal file
@@ -0,0 +1,63 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
// See: http://www.iquilezles.org/www/articles/ellipsoids/ellipsoids.htm
|
||||
float sdEllipsoid( in vec2 p, in vec2 r )
|
||||
{
|
||||
float k0 = length(p/r);
|
||||
float k1 = length(p/(r*r));
|
||||
return k0*(k0-1.0)/k1;
|
||||
}
|
||||
|
||||
float sdEllipse( in vec2 p, in vec2 e )
|
||||
{
|
||||
p = abs( p );
|
||||
|
||||
if( e.x<e.y ) { p = p.yx; e = e.yx; }
|
||||
|
||||
vec2 r = e*e;
|
||||
vec2 z = p/e;
|
||||
vec2 n = r*z;
|
||||
|
||||
float g = dot(z,z) - 1.0;
|
||||
float s0 = z.y - 1.0;
|
||||
float s1 = (g<0.0) ? 0.0 : length( n )/r.y - 1.0;
|
||||
float s = 0.0;
|
||||
for( int i=0; i<64; i++ )
|
||||
{
|
||||
s = 0.5*(s0+s1);
|
||||
vec2 ratio = n/(r.y*s+r);
|
||||
g = dot(ratio,ratio) - 1.0;
|
||||
if( g>0.0 ) s0=s; else s1=s;
|
||||
}
|
||||
|
||||
vec2 q = p*r/(r.y*s+r);
|
||||
return length( p-q ) * (((p.y-q.y)<0.0)?-1.0:1.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
float d = sdEllipse( uv, vec2(size.x * iResolution.x/iResolution.y, size.y) );
|
||||
|
||||
vec3 col = vec3(1.0- sign(d));
|
||||
col *= 1.0 - exp( -600.0/ (blur * 1000.f + 1.0) * abs(d));
|
||||
|
||||
FragColor = vec4( col, 1.0 );
|
||||
}
|
||||
32
rsc/shaders/mask_horizontal.fs
Normal file
@@ -0,0 +1,32 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float sdHorizontal( in vec2 p, in float y )
|
||||
{
|
||||
float d = step(0.0, y);
|
||||
d = d * smoothstep(0.0, 2.0 * blur, y + p.y) + (1.0-d)*smoothstep(-2.0 * blur, 0.0, (-2.0 * blur) - (y + p.y));
|
||||
return d;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
|
||||
float d = sdHorizontal( uv, size.y);
|
||||
|
||||
FragColor = vec4( vec3(d), 1.0 );
|
||||
}
|
||||
67
rsc/shaders/mask_lowleftcorner.fs
Normal file
@@ -0,0 +1,67 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float sdRoundSide( in vec2 p, in vec2 b, in float r )
|
||||
{
|
||||
vec2 q = vec2(-1.0, 1.0) * p - b + r;
|
||||
return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
|
||||
}
|
||||
|
||||
float sdHorizontal( in vec2 p, in float y )
|
||||
{
|
||||
float d = 0.0;
|
||||
|
||||
// if (y < 0.0) {
|
||||
|
||||
// d = smoothstep(-2.0 * blur, 0.0, (-2.0 * blur) - (y + p.y));
|
||||
//// d = smoothstep(-2.0 * blur, 0.0, -y -blur -p.y); // centered blur
|
||||
|
||||
|
||||
// }
|
||||
// else {
|
||||
|
||||
// d = smoothstep(0.0, 2.0 * blur, y + p.y);
|
||||
|
||||
//// d = smoothstep(0.0, 2.0 * blur, y +blur +p.y); // centered blur
|
||||
|
||||
// }
|
||||
d = step(0.0, y);
|
||||
d = d * smoothstep(0.0, 2.0 * blur, y + p.y) + (1.0-d)*smoothstep(-2.0 * blur, 0.0, (-2.0 * blur) - (y + p.y));
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
float d = sdHorizontal( uv, size.y);
|
||||
|
||||
vec3 col = vec3(d);
|
||||
|
||||
|
||||
// col = vec3(sign(d));
|
||||
// col *= 1.0 - exp( -600.0/ (blur * 1000.0 + 1.0) * abs(d));
|
||||
|
||||
// float d = sdRoundSide( uv, vec2(size.x * iResolution.x/iResolution.y, size.y), blur );
|
||||
// vec3 col = vec3(1.0 - sign(d));
|
||||
// float delta = 0.5 * length(min(size,1.0));
|
||||
// col *= 1.0 - exp( -300.0/ (blur * 1000.0 * delta + 1.0) * abs(d));
|
||||
|
||||
FragColor = vec4( col, 1.0 );
|
||||
}
|
||||
54
rsc/shaders/mask_round.fs
Normal file
@@ -0,0 +1,54 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float udSegment( in vec2 p, in vec2 a, in vec2 b )
|
||||
{
|
||||
vec2 ba = b-a;
|
||||
vec2 pa = p-a;
|
||||
float h =clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
|
||||
return length(pa-h*ba);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
float ar = iResolution.x / iResolution.y;
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
uv.x *= ar;
|
||||
|
||||
float th = 0.0;
|
||||
vec2 v1;
|
||||
vec2 v2;
|
||||
vec2 rect = size;
|
||||
rect.x *= ar;
|
||||
|
||||
if(rect.x < rect.y) {
|
||||
th = rect.x;
|
||||
v1 = vec2(0.0, -rect.y + th) ;
|
||||
v2 = vec2(0.0, rect.y - th) ;
|
||||
}
|
||||
else {
|
||||
th = rect.y;
|
||||
v1 = vec2(-rect.x + th, 0.0) ;
|
||||
v2 = vec2( rect.x - th, 0.0) ;
|
||||
}
|
||||
float d = udSegment( uv, v1, v2 )- th;
|
||||
|
||||
vec3 col = vec3(1.0- sign(d));
|
||||
col *= 1.0 - exp( -600.0/ (blur * 1000.0 + 1.0) * abs(d));
|
||||
|
||||
FragColor = vec4( col, 1.0 );
|
||||
}
|
||||
37
rsc/shaders/mask_uprightcorner.fs
Normal file
@@ -0,0 +1,37 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float sdRoundSide( in vec2 p, in vec2 b, in float r )
|
||||
{
|
||||
vec2 q = vec2(1.0, -1.0) * p - b + r;
|
||||
return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
uv.x *= iResolution.x / iResolution.y;
|
||||
|
||||
vec2 s = 2.0 - size;
|
||||
float d = sdRoundSide( uv, vec2(s.x * iResolution.x/iResolution.y, s.y), blur );
|
||||
|
||||
vec3 col = vec3(1.0 - sign(d));
|
||||
float delta = 0.5 * length(min(size, 1.0));
|
||||
col *= 1.0 - exp( -200.0/ (blur * 1000.0 * delta + 1.0) * abs(d) );
|
||||
|
||||
FragColor = vec4( col, 1.0 );
|
||||
}
|
||||
32
rsc/shaders/mask_vertical.fs
Normal file
@@ -0,0 +1,32 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec4 vertexColor;
|
||||
in vec2 vertexUV;
|
||||
|
||||
// from General Shader
|
||||
uniform vec3 iResolution; // viewport resolution (in pixels)
|
||||
uniform mat4 iTransform; // image transformation
|
||||
uniform vec4 color; // drawing color
|
||||
uniform vec4 uv;
|
||||
|
||||
// Mask Shader
|
||||
uniform vec2 size; // size of the mask area
|
||||
uniform float blur; // percent of blur
|
||||
|
||||
float sdVertical( in vec2 p, in float x )
|
||||
{
|
||||
float d = step(0.0, x);
|
||||
d = d * smoothstep(0.0, 2.0 * blur, x + p.x) + (1.0-d)*smoothstep(-2.0 * blur, 0.0, (-2.0 * blur) - (x + p.x));
|
||||
return d;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = -1.0 + 2.0 * gl_FragCoord.xy / iResolution.xy;
|
||||
|
||||
float d = sdVertical( uv, -size.x);
|
||||
|
||||
FragColor = vec4( vec3(d), 1.0 );
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
name: vimix
|
||||
base: core18
|
||||
version: '0.4'
|
||||
version: '0.5'
|
||||
summary: Live video mixing
|
||||
title: vimix
|
||||
description: |
|
||||
@@ -51,6 +51,7 @@ parts:
|
||||
- libglfw3-dev
|
||||
- libgstreamer1.0-dev
|
||||
- libgstreamer-plugins-base1.0-dev
|
||||
- libicu-dev
|
||||
stage-packages:
|
||||
- zenity
|
||||
- libpng16-16
|
||||
|
||||
@@ -22,6 +22,14 @@ XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::ivec2 vector)
|
||||
return newelement;
|
||||
}
|
||||
|
||||
XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::vec2 vector)
|
||||
{
|
||||
XMLElement *newelement = doc->NewElement( "vec2" );
|
||||
newelement->SetAttribute("x", vector.x);
|
||||
newelement->SetAttribute("y", vector.y);
|
||||
return newelement;
|
||||
}
|
||||
|
||||
XMLElement *tinyxml2::XMLElementFromGLM(XMLDocument *doc, glm::vec3 vector)
|
||||
{
|
||||
XMLElement *newelement = doc->NewElement( "vec3" );
|
||||
@@ -62,6 +70,14 @@ void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::ivec2 &vector)
|
||||
elem->QueryIntAttribute("y", &vector.y);
|
||||
}
|
||||
|
||||
void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::vec2 &vector)
|
||||
{
|
||||
if ( !elem || std::string(elem->Name()).find("vec2") == std::string::npos )
|
||||
return;
|
||||
elem->QueryFloatAttribute("x", &vector.x); // If this fails, original value is left as-is
|
||||
elem->QueryFloatAttribute("y", &vector.y);
|
||||
}
|
||||
|
||||
void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::vec3 &vector)
|
||||
{
|
||||
if ( !elem || std::string(elem->Name()).find("vec3") == std::string::npos )
|
||||
@@ -102,7 +118,7 @@ void tinyxml2::XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix)
|
||||
}
|
||||
|
||||
|
||||
XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, void *array, unsigned int arraysize)
|
||||
XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, const void *array, uint arraysize)
|
||||
{
|
||||
// create <array> node
|
||||
XMLElement *newelement = doc->NewElement( "array" );
|
||||
@@ -141,63 +157,68 @@ XMLElement *tinyxml2::XMLElementEncodeArray(XMLDocument *doc, void *array, unsig
|
||||
return newelement;
|
||||
}
|
||||
|
||||
bool tinyxml2::XMLElementDecodeArray(XMLElement *elem, void *array, unsigned int arraysize)
|
||||
bool tinyxml2::XMLElementDecodeArray(XMLElement *elem, void *array, uint arraysize)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
// sanity check
|
||||
if (array==nullptr || arraysize==0)
|
||||
return ret;
|
||||
|
||||
// make sure we have the good type of XML node
|
||||
if ( !elem || std::string(elem->Name()).compare("array") != 0 )
|
||||
return ret;
|
||||
|
||||
// make sure the stored array is of the requested array size
|
||||
unsigned int len = 0;
|
||||
uint len = 0;
|
||||
elem->QueryUnsignedAttribute("len", &len);
|
||||
if ( arraysize != len )
|
||||
return ret;
|
||||
if (len == arraysize)
|
||||
{
|
||||
// read and decode the text field in <array>
|
||||
gsize decoded_size = 0;
|
||||
guchar *decoded_array = g_base64_decode(elem->GetText(), &decoded_size);
|
||||
|
||||
// read and decode the text field in <array>
|
||||
gsize decoded_size = 0;
|
||||
guchar *decoded_array = g_base64_decode(elem->GetText(), &decoded_size);
|
||||
// if data is z-compressed (zbytes size is indicated)
|
||||
uint zbytes = 0;
|
||||
elem->QueryUnsignedAttribute("zbytes", &zbytes);
|
||||
if ( zbytes > 0) {
|
||||
// sanity check 1: decoded data size must match the buffer size
|
||||
if ( decoded_array && zbytes == (uint) decoded_size ) {
|
||||
|
||||
// if data is z-compressed (zbytes size is indicated)
|
||||
uint zbytes = 0;
|
||||
elem->QueryUnsignedAttribute("zbytes", &zbytes);
|
||||
if ( zbytes > 0) {
|
||||
// sanity check 1: decoded data size must match the buffer size
|
||||
if ( decoded_array && zbytes == (uint) decoded_size ) {
|
||||
// allocate a temporary array for decompressing data
|
||||
uLong uncompressed_size = len;
|
||||
gchar *uncompressed_array = g_new(gchar, uncompressed_size);
|
||||
|
||||
// allocate a temporary array for decompressing data
|
||||
uLong uncompressed_size = arraysize;
|
||||
gchar *uncompressed_array = g_new(gchar, uncompressed_size);
|
||||
// zlib uncompress ((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
|
||||
uncompress((Bytef *)uncompressed_array, &uncompressed_size,
|
||||
(Bytef *)decoded_array, (uLong) zbytes) ;
|
||||
|
||||
// zlib uncompress ((Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen));
|
||||
uncompress((Bytef *)uncompressed_array, &uncompressed_size,
|
||||
(Bytef *)decoded_array, (uLong) zbytes) ;
|
||||
|
||||
// sanity check 2: decompressed data size must match array size
|
||||
if ( uncompressed_array && arraysize == uncompressed_size ){
|
||||
// sanity check 2: decompressed data size must match array size
|
||||
if ( uncompressed_array && len == uncompressed_size ){
|
||||
// copy to target array
|
||||
memcpy(array, uncompressed_array, len);
|
||||
// success
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// free temp decompression buffer
|
||||
g_free(uncompressed_array);
|
||||
}
|
||||
}
|
||||
// data is not z-compressed
|
||||
else {
|
||||
// copy the decoded data
|
||||
if ( decoded_array && len == decoded_size ) {
|
||||
// copy to target array
|
||||
memcpy(array, uncompressed_array, arraysize);
|
||||
memcpy(array, decoded_array, len);
|
||||
// success
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// free temp decompression buffer
|
||||
g_free(uncompressed_array);
|
||||
}
|
||||
}
|
||||
// data is not z-compressed
|
||||
else {
|
||||
// copy the decoded data
|
||||
if ( decoded_array && arraysize == decoded_size )
|
||||
memcpy(array, decoded_array, arraysize);
|
||||
// success
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// free temporary array
|
||||
g_free(decoded_array);
|
||||
// free temporary array
|
||||
g_free(decoded_array);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#define TINYXML2TOOLKIT_H
|
||||
|
||||
#include <string>
|
||||
#ifdef __APPLE__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
namespace tinyxml2 {
|
||||
@@ -10,17 +14,19 @@ class XMLDocument;
|
||||
class XMLElement;
|
||||
|
||||
XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::ivec2 vector);
|
||||
XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::vec2 vector);
|
||||
XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::vec3 vector);
|
||||
XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::vec4 vector);
|
||||
XMLElement *XMLElementFromGLM(XMLDocument *doc, glm::mat4 matrix);
|
||||
|
||||
void XMLElementToGLM(XMLElement *elem, glm::ivec2 &vector);
|
||||
void XMLElementToGLM(XMLElement *elem, glm::vec2 &vector);
|
||||
void XMLElementToGLM(XMLElement *elem, glm::vec3 &vector);
|
||||
void XMLElementToGLM(XMLElement *elem, glm::vec4 &vector);
|
||||
void XMLElementToGLM(XMLElement *elem, glm::mat4 &matrix);
|
||||
|
||||
XMLElement *XMLElementEncodeArray(XMLDocument *doc, void *array, unsigned int arraysize);
|
||||
bool XMLElementDecodeArray(XMLElement *elem, void *array, unsigned int arraysize);
|
||||
XMLElement *XMLElementEncodeArray(XMLDocument *doc, const void *array, uint arraysize);
|
||||
bool XMLElementDecodeArray(XMLElement *elem, void *array, uint arraysize);
|
||||
|
||||
bool XMLSaveDoc(tinyxml2::XMLDocument * const doc, std::string filename);
|
||||
bool XMLResultError(int result);
|
||||
|
||||