improved solid effect
This commit is contained in:
+12
-2
@@ -17,7 +17,16 @@
|
||||
#include <QGridLayout>
|
||||
#include <QTextEdit>
|
||||
|
||||
Effect::Effect(Clip* c, int t, int i) : parent_clip(c), type(t), id(i) {
|
||||
Effect::Effect(Clip* c, int t, int i) :
|
||||
parent_clip(c),
|
||||
type(t),
|
||||
id(i),
|
||||
enable_ffmpeg(false),
|
||||
enable_qimage(false),
|
||||
enable_pre_gl(false),
|
||||
enable_post_gl(false)
|
||||
|
||||
{
|
||||
container = new CollapsibleWidget();
|
||||
if (type == EFFECT_TYPE_VIDEO) {
|
||||
container->setText(video_effect_names[i]);
|
||||
@@ -195,7 +204,8 @@ EffectField::EffectField(int t) : type(t) {
|
||||
{
|
||||
CheckboxEx* cb = new CheckboxEx();
|
||||
ui_element = cb;
|
||||
connect(cb, SIGNAL(toggled(bool)), this, SIGNAL(changed()));
|
||||
connect(cb, SIGNAL(clicked(bool)), this, SIGNAL(changed()));
|
||||
connect(cb, SIGNAL(toggled(bool)), this, SIGNAL(toggled(bool)));
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COMBO:
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <QColor>
|
||||
class QWidget;
|
||||
class CollapsibleWidget;
|
||||
class QGridLayout;
|
||||
@@ -28,9 +29,17 @@ class Effect;
|
||||
#define EFFECT_KEYFRAME_HOLD 1
|
||||
#define EFFECT_KEYFRAME_BEZIER 2
|
||||
|
||||
union KeyframeValue {
|
||||
double d;
|
||||
QColor c;
|
||||
bool b;
|
||||
};
|
||||
|
||||
class EffectKeyframe {
|
||||
public:
|
||||
long frame;
|
||||
int type;
|
||||
KeyframeValue value;
|
||||
};
|
||||
|
||||
class EffectField : public QObject {
|
||||
@@ -68,6 +77,7 @@ public:
|
||||
void set_enabled(bool e);
|
||||
signals:
|
||||
void changed();
|
||||
void toggled(bool);
|
||||
private:
|
||||
QWidget* ui_element;
|
||||
};
|
||||
@@ -113,6 +123,11 @@ public:
|
||||
void load(QXmlStreamReader* stream);
|
||||
void save(QXmlStreamWriter* stream);
|
||||
|
||||
bool enable_ffmpeg;
|
||||
bool enable_qimage;
|
||||
bool enable_pre_gl;
|
||||
bool enable_post_gl;
|
||||
|
||||
virtual void process_gl(int* anchor_x, int* anchor_y);
|
||||
virtual void post_gl();
|
||||
virtual void process_audio(quint8* samples, int nb_bytes);
|
||||
|
||||
@@ -121,6 +121,8 @@ public:
|
||||
EffectField* shadow_opacity;
|
||||
private slots:
|
||||
void update_texture();
|
||||
void outline_enable(bool);
|
||||
void shadow_enable(bool);
|
||||
private:
|
||||
void destroy_texture();
|
||||
QOpenGLTexture* texture;
|
||||
@@ -133,7 +135,11 @@ class SolidEffect : public Effect {
|
||||
public:
|
||||
SolidEffect(Clip* c);
|
||||
void post_gl();
|
||||
EffectField* solid_type;
|
||||
EffectField* solid_color_field;
|
||||
EffectField* opacity_field;
|
||||
private slots:
|
||||
void enable_color();
|
||||
void update_texture();
|
||||
private:
|
||||
QOpenGLTexture* texture;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <QXmlStreamAttributes>
|
||||
|
||||
InvertEffect::InvertEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_INVERT_EFFECT) {
|
||||
|
||||
EffectRow* amount_row = add_row("Amount:");
|
||||
amount_val = amount_row->add_field(EFFECT_FIELD_DOUBLE);
|
||||
amount_val->set_double_minimum_value(0);
|
||||
|
||||
+116
-74
@@ -3,97 +3,133 @@
|
||||
#include <QOpenGLTexture>
|
||||
#include <QPainter>
|
||||
#include <QtMath>
|
||||
#include <QVariant>
|
||||
|
||||
#include "project/clip.h"
|
||||
#include "project/sequence.h"
|
||||
|
||||
#define SOLID_TYPE_COLOR 0
|
||||
#define SOLID_TYPE_BARS 1
|
||||
|
||||
#define SMPTE_BARS 7
|
||||
#define SMPTE_STRIP_COUNT 3
|
||||
#define SMPTE_LOWER_BARS 4
|
||||
|
||||
bool solid = false;
|
||||
|
||||
SolidEffect::SolidEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SOLID_EFFECT), texture(NULL) {
|
||||
enable_post_gl = true;
|
||||
|
||||
solid_type = add_row("Type:")->add_field(EFFECT_FIELD_COMBO);
|
||||
solid_type->add_combo_item("Solid Color", SOLID_TYPE_COLOR);
|
||||
solid_type->add_combo_item("SMPTE Bars", SOLID_TYPE_BARS);
|
||||
|
||||
solid_color_field = add_row("Color:")->add_field(EFFECT_FIELD_COLOR);
|
||||
solid_color_field->set_color_value(Qt::red);
|
||||
|
||||
opacity_field = add_row("Opacity:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
opacity_field->set_double_minimum_value(0);
|
||||
opacity_field->set_double_maximum_value(100);
|
||||
opacity_field->set_double_default_value(100);
|
||||
|
||||
connect(solid_type, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
connect(solid_type, SIGNAL(changed()), this, SLOT(enable_color()));
|
||||
connect(solid_color_field, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
connect(opacity_field, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
|
||||
update_texture();
|
||||
}
|
||||
|
||||
void SolidEffect::enable_color() {
|
||||
solid_color_field->set_enabled(solid_type->get_combo_data() == SOLID_TYPE_COLOR);
|
||||
}
|
||||
|
||||
void SolidEffect::update_texture() {
|
||||
QImage img(parent_clip->sequence->width, parent_clip->sequence->height, QImage::Format_RGB888);
|
||||
|
||||
if (solid) {
|
||||
img.fill(Qt::red);
|
||||
} else {
|
||||
// draw smpte bars
|
||||
img.fill(Qt::black);
|
||||
switch (solid_type->get_combo_data().toInt()) {
|
||||
case SOLID_TYPE_COLOR:
|
||||
img.fill(solid_color_field->get_color_value());
|
||||
break;
|
||||
case SOLID_TYPE_BARS:
|
||||
// draw smpte bars
|
||||
img.fill(Qt::black);
|
||||
|
||||
QPainter p(&img);
|
||||
int bar_width = qCeil((double) parent_clip->sequence->width / 7.0);
|
||||
int first_bar_height = qCeil((double) parent_clip->sequence->height / 3.0 * 2.0);
|
||||
int second_bar_height = qCeil((double) parent_clip->sequence->height / 12.5);
|
||||
int third_bar_y = first_bar_height + second_bar_height;
|
||||
int third_bar_height = parent_clip->sequence->height - third_bar_y;
|
||||
int third_bar_width = 0;
|
||||
int bar_x, strip_width;
|
||||
QColor first_color, second_color, third_color;
|
||||
for (int i=0;i<SMPTE_BARS;i++) {
|
||||
bar_x = bar_width*i;
|
||||
switch (i) {
|
||||
case 0:
|
||||
first_color = QColor(192, 192, 192);
|
||||
second_color = QColor(0, 0, 192);
|
||||
break;
|
||||
case 1:
|
||||
first_color = QColor(192, 192, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
break;
|
||||
case 2:
|
||||
first_color = QColor(0, 192, 192);
|
||||
second_color = QColor(192, 0, 192);
|
||||
break;
|
||||
case 3:
|
||||
first_color = QColor(0, 192, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
break;
|
||||
case 4:
|
||||
first_color = QColor(192, 0, 192);
|
||||
second_color = QColor(0, 192, 192);
|
||||
break;
|
||||
case 5:
|
||||
third_bar_width = bar_x / SMPTE_LOWER_BARS;
|
||||
QPainter p(&img);
|
||||
int bar_width = qCeil((double) parent_clip->sequence->width / 7.0);
|
||||
int first_bar_height = qCeil((double) parent_clip->sequence->height / 3.0 * 2.0);
|
||||
int second_bar_height = qCeil((double) parent_clip->sequence->height / 12.5);
|
||||
int third_bar_y = first_bar_height + second_bar_height;
|
||||
int third_bar_height = parent_clip->sequence->height - third_bar_y;
|
||||
int third_bar_width = 0;
|
||||
int bar_x, strip_width;
|
||||
QColor first_color, second_color, third_color;
|
||||
for (int i=0;i<SMPTE_BARS;i++) {
|
||||
bar_x = bar_width*i;
|
||||
switch (i) {
|
||||
case 0:
|
||||
first_color = QColor(192, 192, 192);
|
||||
second_color = QColor(0, 0, 192);
|
||||
break;
|
||||
case 1:
|
||||
first_color = QColor(192, 192, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
break;
|
||||
case 2:
|
||||
first_color = QColor(0, 192, 192);
|
||||
second_color = QColor(192, 0, 192);
|
||||
break;
|
||||
case 3:
|
||||
first_color = QColor(0, 192, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
break;
|
||||
case 4:
|
||||
first_color = QColor(192, 0, 192);
|
||||
second_color = QColor(0, 192, 192);
|
||||
break;
|
||||
case 5:
|
||||
third_bar_width = bar_x / SMPTE_LOWER_BARS;
|
||||
|
||||
first_color = QColor(192, 0, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
first_color = QColor(192, 0, 0);
|
||||
second_color = QColor(19, 19, 19);
|
||||
|
||||
strip_width = qCeil(bar_width/SMPTE_STRIP_COUNT);
|
||||
for (int j=0;j<SMPTE_STRIP_COUNT;j++) {
|
||||
switch (j) {
|
||||
case 0: third_color = QColor(9, 9, 9); break;
|
||||
case 1: third_color = QColor(19, 19, 19); break;
|
||||
case 2: third_color = QColor(29, 29, 29); break;
|
||||
}
|
||||
p.fillRect(QRect(bar_x + (strip_width*j), third_bar_y, strip_width, third_bar_height), third_color);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
first_color = QColor(0, 0, 192);
|
||||
second_color = QColor(192, 192, 192);
|
||||
p.fillRect(QRect(bar_x, third_bar_y, bar_width, third_bar_height), QColor(19, 19, 19));
|
||||
break;
|
||||
}
|
||||
p.fillRect(QRect(bar_x, 0, bar_width, first_bar_height), first_color);
|
||||
p.fillRect(QRect(bar_x, first_bar_height, bar_width, second_bar_height), second_color);
|
||||
}
|
||||
for (int i=0;i<SMPTE_LOWER_BARS;i++) {
|
||||
bar_x = third_bar_width*i;
|
||||
switch (i) {
|
||||
case 0: third_color = QColor(0, 33, 76); break;
|
||||
case 1: third_color = QColor(255, 255, 255); break;
|
||||
case 2: third_color = QColor(50, 0, 106); break;
|
||||
case 3: third_color = QColor(19, 19, 19); break;
|
||||
}
|
||||
p.fillRect(QRect(bar_x, third_bar_y, third_bar_width, third_bar_height), third_color);
|
||||
}
|
||||
}
|
||||
strip_width = qCeil(bar_width/SMPTE_STRIP_COUNT);
|
||||
for (int j=0;j<SMPTE_STRIP_COUNT;j++) {
|
||||
switch (j) {
|
||||
case 0:
|
||||
third_color = QColor(29, 29, 29);
|
||||
p.fillRect(QRect(bar_x, third_bar_y, bar_width, third_bar_height), third_color);
|
||||
break;
|
||||
case 1:
|
||||
third_color = QColor(19, 19, 19);
|
||||
p.fillRect(QRect(bar_x + strip_width, third_bar_y, strip_width, third_bar_height), third_color);
|
||||
break;
|
||||
case 2:
|
||||
third_color = QColor(9, 9, 9);
|
||||
p.fillRect(QRect(bar_x, third_bar_y, strip_width, third_bar_height), third_color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
first_color = QColor(0, 0, 192);
|
||||
second_color = QColor(192, 192, 192);
|
||||
p.fillRect(QRect(bar_x, third_bar_y, bar_width, third_bar_height), QColor(19, 19, 19));
|
||||
break;
|
||||
}
|
||||
p.fillRect(QRect(bar_x, 0, bar_width, first_bar_height), first_color);
|
||||
p.fillRect(QRect(bar_x, first_bar_height, bar_width, second_bar_height), second_color);
|
||||
}
|
||||
for (int i=0;i<SMPTE_LOWER_BARS;i++) {
|
||||
bar_x = third_bar_width*i;
|
||||
switch (i) {
|
||||
case 0: third_color = QColor(0, 33, 76); break;
|
||||
case 1: third_color = QColor(255, 255, 255); break;
|
||||
case 2: third_color = QColor(50, 0, 106); break;
|
||||
case 3: third_color = QColor(19, 19, 19); break;
|
||||
}
|
||||
p.fillRect(QRect(bar_x, third_bar_y, third_bar_width, third_bar_height), third_color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (texture == NULL) {
|
||||
texture = new QOpenGLTexture(img);
|
||||
@@ -107,6 +143,10 @@ void SolidEffect::update_texture() {
|
||||
|
||||
void SolidEffect::post_gl() {
|
||||
if (texture != NULL) {
|
||||
float color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
glColor4f(1.0, 1.0, 1.0, color[3]*(opacity_field->get_double_value()*0.01));
|
||||
|
||||
texture->bind();
|
||||
|
||||
int half_width = parent_clip->sequence->width/2;
|
||||
@@ -123,6 +163,8 @@ void SolidEffect::post_gl() {
|
||||
glVertex2f(-half_width, half_height);
|
||||
glEnd();
|
||||
|
||||
texture->release();
|
||||
texture->release();
|
||||
|
||||
glColor4f(color[0], color[1], color[2], color[3]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ TextEffect::TextEffect(Clip *c) :
|
||||
Effect(c, EFFECT_TYPE_VIDEO, VIDEO_TEXT_EFFECT),
|
||||
texture(NULL)
|
||||
{
|
||||
enable_post_gl = true;
|
||||
|
||||
text_val = add_row("Text:")->add_field(EFFECT_FIELD_STRING, 2);
|
||||
|
||||
set_font_combobox = add_row("Font:")->add_field(EFFECT_FIELD_FONT, 2);
|
||||
@@ -74,6 +76,9 @@ TextEffect::TextEffect(Clip *c) :
|
||||
shadow_opacity->set_double_default_value(80);
|
||||
outline_width->set_double_default_value(2);
|
||||
|
||||
outline_enable(false);
|
||||
shadow_enable(false);
|
||||
|
||||
connect(text_val, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
connect(size_val, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
connect(set_color_button, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
@@ -90,6 +95,9 @@ TextEffect::TextEffect(Clip *c) :
|
||||
connect(shadow_softness, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
connect(shadow_opacity, SIGNAL(changed()), this, SLOT(update_texture()));
|
||||
|
||||
connect(shadow_bool, SIGNAL(toggled(bool)), this, SLOT(shadow_enable(bool)));
|
||||
connect(outline_bool, SIGNAL(toggled(bool)), this, SLOT(outline_enable(bool)));
|
||||
|
||||
update_texture();
|
||||
}
|
||||
|
||||
@@ -105,6 +113,18 @@ void TextEffect::destroy_texture() {
|
||||
texture->destroy();
|
||||
}
|
||||
|
||||
void TextEffect::shadow_enable(bool e) {
|
||||
shadow_color->set_enabled(e);
|
||||
shadow_distance->set_enabled(e);
|
||||
shadow_softness->set_enabled(e);
|
||||
shadow_opacity->set_enabled(e);
|
||||
}
|
||||
|
||||
void TextEffect::outline_enable(bool e) {
|
||||
outline_color->set_enabled(e);
|
||||
outline_width->set_enabled(e);
|
||||
}
|
||||
|
||||
QImage blurred(const QImage& image, const QRect& rect, int radius, bool alphaOnly = false)
|
||||
{
|
||||
int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#define BLEND_MODE_OVERLAY 3
|
||||
|
||||
TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_TRANSFORM_EFFECT) {
|
||||
enable_pre_gl = true;
|
||||
|
||||
EffectRow* position_row = add_row("Position:");
|
||||
position_x = position_row->add_field(EFFECT_FIELD_DOUBLE); // position X
|
||||
position_y = position_row->add_field(EFFECT_FIELD_DOUBLE); // position Y
|
||||
@@ -58,7 +60,6 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_T
|
||||
blend_mode_box->add_combo_item("Multiply", BLEND_MODE_MULTIPLY);
|
||||
|
||||
// set defaults
|
||||
QCheckBox* uniform_scale_box = static_cast<QCheckBox*>(uniform_scale_field->get_ui_element());
|
||||
scale_y->set_enabled(false);
|
||||
uniform_scale_field->set_bool_value(true);
|
||||
blend_mode_box->set_combo_index(0);
|
||||
@@ -74,7 +75,7 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_T
|
||||
connect(anchor_y_box, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(opacity, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(blend_mode_box, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
connect(uniform_scale_box, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool)));
|
||||
connect(uniform_scale_field, SIGNAL(toggled(bool)), this, SLOT(toggle_uniform_scale(bool)));
|
||||
}
|
||||
|
||||
Effect* TransformEffect::copy(Clip* c) {
|
||||
|
||||
@@ -676,11 +676,17 @@
|
||||
<property name="text">
|
||||
<string>Delete In/Out</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>;</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRipple_Delete_In_Out">
|
||||
<property name="text">
|
||||
<string>Ripple Delete In/Out</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>'</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRectified_Waveforms">
|
||||
<property name="checkable">
|
||||
|
||||
+2
-2
@@ -122,7 +122,7 @@ void Clip::refresh() {
|
||||
|
||||
void Clip::run_video_pre_effect_stack(long playhead, int* anchor_x, int* anchor_y) {
|
||||
for (int j=0;j<effects.size();j++) {
|
||||
if (effects.at(j)->is_enabled()) effects.at(j)->process_gl(anchor_x, anchor_y);
|
||||
if (effects.at(j)->enable_pre_gl && effects.at(j)->is_enabled()) effects.at(j)->process_gl(anchor_x, anchor_y);
|
||||
}
|
||||
|
||||
if (opening_transition != NULL) {
|
||||
@@ -142,7 +142,7 @@ void Clip::run_video_pre_effect_stack(long playhead, int* anchor_x, int* anchor_
|
||||
|
||||
void Clip::run_video_post_effect_stack() {
|
||||
for (int j=0;j<effects.size();j++) {
|
||||
if (effects.at(j)->is_enabled()) effects.at(j)->post_gl();
|
||||
if (effects.at(j)->enable_post_gl && effects.at(j)->is_enabled()) effects.at(j)->post_gl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user