half way through keyframes data
This commit is contained in:
@@ -24,12 +24,12 @@ void PanEffect::refresh() {}
|
||||
|
||||
Effect* PanEffect::copy(Clip* c) {
|
||||
PanEffect* p = new PanEffect(c);
|
||||
p->pan_val->set_double_value(pan_val->get_double_value());
|
||||
copy_field_keyframes(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
void PanEffect::process_audio(quint8 *samples, int nb_bytes) {
|
||||
double pval = pan_val->get_double_value();
|
||||
double pval = pan_val->get_double_value(-1);
|
||||
if (pval != 0) {
|
||||
for (int i=0;i<nb_bytes;i+=4) {
|
||||
qint16 left_sample = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
|
||||
@@ -25,12 +25,12 @@ void VolumeEffect::refresh() {}
|
||||
|
||||
Effect* VolumeEffect::copy(Clip* c) {
|
||||
VolumeEffect* v = new VolumeEffect(c);
|
||||
v->volume_val->set_double_value(volume_val->get_double_value());
|
||||
copy_field_keyframes(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void VolumeEffect::process_audio(quint8* samples, int nb_bytes) {
|
||||
double vol_val = volume_val->get_double_value();
|
||||
double vol_val = volume_val->get_double_value(-1);
|
||||
if (vol_val != 100) {
|
||||
for (int i=0;i<nb_bytes;i+=2) {
|
||||
qint32 samp = (qint16) (((samples[i+1] & 0xFF) << 8) | (samples[i] & 0xFF));
|
||||
|
||||
+101
-31
@@ -12,6 +12,7 @@
|
||||
#include "ui/fontcombobox.h"
|
||||
#include "ui/checkboxex.h"
|
||||
#include "project/clip.h"
|
||||
#include "panels/timeline.h"
|
||||
|
||||
#include "effects/video/transformeffect.h"
|
||||
#include "effects/video/inverteffect.h"
|
||||
@@ -92,6 +93,16 @@ Effect::~Effect() {
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::copy_field_keyframes(Effect* e) {
|
||||
for (int i=0;i<rows.size();i++) {
|
||||
EffectRow* row = rows.at(i);
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
EffectField* field = row->field(j);
|
||||
e->rows.at(i)->field(j)->keyframes = field->keyframes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EffectRow* Effect::add_row(const QString& name) {
|
||||
EffectRow* row = new EffectRow(this, ui_layout, name, rows.size());
|
||||
rows.append(row);
|
||||
@@ -165,34 +176,31 @@ void Effect::save(QXmlStreamWriter* stream) {
|
||||
stream->writeStartElement("row");
|
||||
for (int j=0;j<row->fieldCount();j++) {
|
||||
EffectField* field = row->field(j);
|
||||
switch (field->type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
stream->writeTextElement("field", QString::number(field->get_double_value()));
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
stream->writeTextElement("field", field->get_color_value().name());
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
stream->writeTextElement("field", field->get_string_value());
|
||||
break;
|
||||
case EFFECT_FIELD_BOOL:
|
||||
stream->writeTextElement("field", QString::number(field->get_bool_value()));
|
||||
break;
|
||||
case EFFECT_FIELD_COMBO:
|
||||
stream->writeTextElement("field", field->get_combo_string());
|
||||
break;
|
||||
case EFFECT_FIELD_FONT:
|
||||
stream->writeTextElement("field", field->get_font_name());
|
||||
break;
|
||||
stream->writeStartElement("field");
|
||||
for (int k=0;k<field->keyframes.size();k++) {
|
||||
const EffectKeyframe& key = field->keyframes.at(i);
|
||||
stream->writeStartElement("key");
|
||||
stream->writeAttribute("frame", QString::number(key.frame));
|
||||
stream->writeAttribute("type", QString::number(key.type));
|
||||
switch (field->type) {
|
||||
case EFFECT_FIELD_DOUBLE: stream->writeAttribute("value", QString::number(key.data.toDouble())); break;
|
||||
case EFFECT_FIELD_COLOR: stream->writeAttribute("value", key.data.value<QColor>().name()); break;
|
||||
case EFFECT_FIELD_STRING: stream->writeAttribute("value", key.data.toString()); break;
|
||||
case EFFECT_FIELD_BOOL: stream->writeAttribute("value", QString::number(key.data.toBool())); break;
|
||||
case EFFECT_FIELD_COMBO: stream->writeAttribute("value", key.data.toString()); break;
|
||||
case EFFECT_FIELD_FONT: stream->writeAttribute("value", key.data.toString()); break;
|
||||
}
|
||||
stream->writeEndElement();
|
||||
}
|
||||
stream->writeEndElement(); // field
|
||||
}
|
||||
stream->writeEndElement(); // row
|
||||
}
|
||||
}
|
||||
|
||||
Effect* Effect::copy(Clip*) {return NULL;}
|
||||
void Effect::process_image(QImage&) {}
|
||||
void Effect::process_gl(QOpenGLShaderProgram&, int*, int*) {}
|
||||
void Effect::process_image(long, QImage&) {}
|
||||
void Effect::process_gl(long, QOpenGLShaderProgram&, int*, int*) {}
|
||||
void Effect::process_audio(uint8_t*, int) {}
|
||||
|
||||
/* Effect Row Definitions */
|
||||
@@ -231,6 +239,11 @@ int EffectRow::fieldCount() {
|
||||
/* Effect Field Definitions */
|
||||
|
||||
EffectField::EffectField(int t) : type(t) {
|
||||
// DEFAULT KEYFRAME
|
||||
EffectKeyframe key;
|
||||
key.frame = -1;
|
||||
keyframes.append(key);
|
||||
|
||||
switch (t) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
{
|
||||
@@ -279,6 +292,62 @@ EffectField::EffectField(int t) : type(t) {
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectField::is_keyframed(long p) {
|
||||
return keyframes.size() == 0 || p < 0;
|
||||
}
|
||||
|
||||
QVariant EffectField::get_keyframe_data(long p) {
|
||||
if (keyframes.size() == 1) {
|
||||
return keyframes.at(0).data;
|
||||
}
|
||||
|
||||
EffectKeyframe* before = NULL;
|
||||
EffectKeyframe* after = NULL;
|
||||
for (int i=1;i<keyframes.size();i++) {
|
||||
if (keyframes.at(i).frame == p) {
|
||||
return keyframes.at(i).data;
|
||||
} else if (keyframes.at(i).frame < p && !(before != NULL && keyframes.at(i).frame <= before->frame)) {
|
||||
before = &keyframes[i];
|
||||
} else if (keyframes.at(i).frame > p && !(after != NULL && keyframes.at(i).frame >= after->frame)) {
|
||||
after = &keyframes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// interpolate data
|
||||
if (before != NULL && after != NULL) {
|
||||
double progress = (p - before->frame)/(after->frame - before->frame);
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE:
|
||||
{
|
||||
return lerp(before->data.toDouble(), after->data.toDouble(), progress);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_COLOR:
|
||||
{
|
||||
QColor before_color = before->data.value<QColor>();
|
||||
QColor after_color = after->data.value<QColor>();
|
||||
QColor interval_color = QColor(
|
||||
lerp(before_color.red(), after_color.red(), progress),
|
||||
lerp(before_color.green(), after_color.green(), progress),
|
||||
lerp(before_color.blue(), after_color.blue(), progress)
|
||||
);
|
||||
return QVariant(interval_color);
|
||||
}
|
||||
break;
|
||||
case EFFECT_FIELD_STRING:
|
||||
case EFFECT_FIELD_BOOL:
|
||||
case EFFECT_FIELD_COMBO:
|
||||
case EFFECT_FIELD_FONT:
|
||||
return before->data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// return pre or post data
|
||||
if (before != NULL) return before->data;
|
||||
if (after != NULL) return after->data;
|
||||
}
|
||||
|
||||
QWidget* EffectField::get_ui_element() {
|
||||
return ui_element;
|
||||
}
|
||||
@@ -287,11 +356,12 @@ void EffectField::set_enabled(bool e) {
|
||||
ui_element->setEnabled(e);
|
||||
}
|
||||
|
||||
double EffectField::get_double_value() {
|
||||
return static_cast<LabelSlider*>(ui_element)->value();
|
||||
double EffectField::get_double_value(long p) {
|
||||
return get_keyframe_data(p).toDouble();
|
||||
}
|
||||
|
||||
void EffectField::set_double_value(double v) {
|
||||
|
||||
static_cast<LabelSlider*>(ui_element)->set_value(v, false);
|
||||
}
|
||||
|
||||
@@ -311,16 +381,16 @@ void EffectField::add_combo_item(const QString& name, const QVariant& data) {
|
||||
static_cast<ComboBoxEx*>(ui_element)->addItem(name, data);
|
||||
}
|
||||
|
||||
int EffectField::get_combo_index() {
|
||||
int EffectField::get_combo_index(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentIndex();
|
||||
}
|
||||
|
||||
const QVariant EffectField::get_combo_data() {
|
||||
const QVariant EffectField::get_combo_data(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentData();
|
||||
}
|
||||
|
||||
const QString EffectField::get_combo_string() {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->currentText();
|
||||
const QString EffectField::get_combo_string(long p) {
|
||||
return static_cast<ComboBoxEx*>(ui_element)->itemText(get_keyframe_data(p).toInt());
|
||||
}
|
||||
|
||||
void EffectField::set_combo_index(int index) {
|
||||
@@ -331,7 +401,7 @@ void EffectField::set_combo_string(const QString& s) {
|
||||
static_cast<ComboBoxEx*>(ui_element)->setCurrentTextEx(s);
|
||||
}
|
||||
|
||||
bool EffectField::get_bool_value() {
|
||||
bool EffectField::get_bool_value(long p) {
|
||||
return static_cast<QCheckBox*>(ui_element)->isChecked();
|
||||
}
|
||||
|
||||
@@ -339,7 +409,7 @@ void EffectField::set_bool_value(bool b) {
|
||||
return static_cast<QCheckBox*>(ui_element)->setChecked(b);
|
||||
}
|
||||
|
||||
const QString EffectField::get_string_value() {
|
||||
const QString EffectField::get_string_value(long p) {
|
||||
return static_cast<QTextEdit*>(ui_element)->toPlainText();
|
||||
}
|
||||
|
||||
@@ -347,7 +417,7 @@ void EffectField::set_string_value(const QString& s) {
|
||||
static_cast<QTextEdit*>(ui_element)->setText(s);
|
||||
}
|
||||
|
||||
const QString EffectField::get_font_name() {
|
||||
const QString EffectField::get_font_name(long p) {
|
||||
return static_cast<FontCombobox*>(ui_element)->currentText();
|
||||
}
|
||||
|
||||
@@ -355,7 +425,7 @@ void EffectField::set_font_name(const QString& s) {
|
||||
static_cast<FontCombobox*>(ui_element)->setCurrentText(s);
|
||||
}
|
||||
|
||||
QColor EffectField::get_color_value() {
|
||||
QColor EffectField::get_color_value(long p) {
|
||||
return static_cast<ColorButton*>(ui_element)->get_color();
|
||||
}
|
||||
|
||||
|
||||
+21
-23
@@ -52,17 +52,10 @@ Effect* create_effect(int effect_id, Clip* c);
|
||||
#define EFFECT_KEYFRAME_HOLD 1
|
||||
#define EFFECT_KEYFRAME_BEZIER 2
|
||||
|
||||
union KeyframeValue {
|
||||
double d;
|
||||
QColor c;
|
||||
bool b;
|
||||
};
|
||||
|
||||
class EffectKeyframe {
|
||||
public:
|
||||
struct EffectKeyframe {
|
||||
long frame;
|
||||
int type;
|
||||
KeyframeValue value;
|
||||
QVariant data;
|
||||
};
|
||||
|
||||
class EffectField : public QObject {
|
||||
@@ -71,33 +64,37 @@ public:
|
||||
EffectField(int t);
|
||||
int type;
|
||||
|
||||
double get_double_value();
|
||||
QVariant get_keyframe_data(long p);
|
||||
bool is_keyframed(long p);
|
||||
|
||||
double get_double_value(long p);
|
||||
void set_double_value(double v);
|
||||
void set_double_default_value(double v);
|
||||
void set_double_minimum_value(double v);
|
||||
void set_double_maximum_value(double v);
|
||||
|
||||
const QString get_string_value();
|
||||
const QString get_string_value(long p);
|
||||
void set_string_value(const QString &s);
|
||||
|
||||
void add_combo_item(const QString& name, const QVariant &data);
|
||||
int get_combo_index();
|
||||
const QVariant get_combo_data();
|
||||
const QString get_combo_string();
|
||||
int get_combo_index(long p);
|
||||
const QVariant get_combo_data(long p);
|
||||
const QString get_combo_string(long p);
|
||||
void set_combo_index(int index);
|
||||
void set_combo_string(const QString& s);
|
||||
|
||||
bool get_bool_value();
|
||||
bool get_bool_value(long p);
|
||||
void set_bool_value(bool b);
|
||||
|
||||
const QString get_font_name();
|
||||
const QString get_font_name(long p);
|
||||
void set_font_name(const QString& s);
|
||||
|
||||
QColor get_color_value();
|
||||
QColor get_color_value(long p);
|
||||
void set_color_value(QColor color);
|
||||
|
||||
QWidget* get_ui_element();
|
||||
void set_enabled(bool e);
|
||||
QVector<EffectKeyframe> keyframes;
|
||||
signals:
|
||||
void changed();
|
||||
void toggled(bool);
|
||||
@@ -112,12 +109,12 @@ public:
|
||||
EffectField* add_field(int type, int colspan = 1);
|
||||
EffectField* field(int i);
|
||||
int fieldCount();
|
||||
void set_keyframe(int field, long time);
|
||||
void move_keyframe(int field, long from, long to);
|
||||
void delete_keyframe(int field, long time);
|
||||
void set_keyframe(long time);
|
||||
void move_keyframe(long from, long to);
|
||||
void delete_keyframe(long time);
|
||||
QLabel* label;
|
||||
private:
|
||||
Effect* parent_effect;
|
||||
private:
|
||||
QGridLayout* ui;
|
||||
QString name;
|
||||
int ui_row;
|
||||
@@ -146,6 +143,7 @@ public:
|
||||
virtual void refresh();
|
||||
|
||||
virtual Effect* copy(Clip* c);
|
||||
void copy_field_keyframes(Effect *e);
|
||||
|
||||
void load(QXmlStreamReader* stream);
|
||||
void save(QXmlStreamWriter* stream);
|
||||
@@ -155,8 +153,8 @@ public:
|
||||
|
||||
const char* ffmpeg_filter;
|
||||
|
||||
virtual void process_image(QImage& img);
|
||||
virtual void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
virtual void process_image(long frame, QImage& img);
|
||||
virtual void process_gl(long frame, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
virtual void process_audio(quint8* samples, int nb_bytes);
|
||||
public slots:
|
||||
void field_changed();
|
||||
|
||||
@@ -19,25 +19,20 @@ InvertEffect::InvertEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_INVERT_
|
||||
// set defaults
|
||||
amount_val->set_double_default_value(100);
|
||||
|
||||
connect(amount_val, SIGNAL(changed()), this, SLOT(compile()));
|
||||
|
||||
compile();
|
||||
}
|
||||
|
||||
void InvertEffect::compile() {
|
||||
double value = amount_val->get_double_value()*0.01;
|
||||
vert_shader.compileSourceCode("varying vec2 vTexCoord; void main() { vTexCoord = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
frag_shader.compileSourceCode("uniform sampler2D myTexture; varying vec2 vTexCoord; void main(void) { vec4 textureColor = texture2D(myTexture, vTexCoord); gl_FragColor = vec4(textureColor.r+((1.0-textureColor.r-textureColor.r)*" + QString::number(value) + "), textureColor.g+((1.0-textureColor.g-textureColor.g)*" + QString::number(value) + "), textureColor.b+((1.0-textureColor.b-textureColor.b)*" + QString::number(value) + "), 1); }");
|
||||
field_changed();
|
||||
connect(amount_val, SIGNAL(changed()), this, SLOT(field_changed()));
|
||||
}
|
||||
|
||||
Effect* InvertEffect::copy(Clip* c) {
|
||||
InvertEffect* i = new InvertEffect(c);
|
||||
i->amount_val->set_double_value(amount_val->get_double_value());
|
||||
copy_field_keyframes(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
void InvertEffect::process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y) {
|
||||
void InvertEffect::process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y) {
|
||||
double value = amount_val->get_double_value(p)*0.01;
|
||||
vert_shader.compileSourceCode("varying vec2 vTexCoord; void main() { vTexCoord = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; }");
|
||||
frag_shader.compileSourceCode("uniform sampler2D myTexture; varying vec2 vTexCoord; void main(void) { vec4 textureColor = texture2D(myTexture, vTexCoord); gl_FragColor = vec4(textureColor.r+((1.0-textureColor.r-textureColor.r)*" + QString::number(value) + "), textureColor.g+((1.0-textureColor.g-textureColor.g)*" + QString::number(value) + "), textureColor.b+((1.0-textureColor.b-textureColor.b)*" + QString::number(value) + "), 1); }");
|
||||
|
||||
shader_prog.addShader(&vert_shader);
|
||||
shader_prog.addShader(&frag_shader);
|
||||
}
|
||||
|
||||
@@ -9,12 +9,10 @@ class InvertEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
InvertEffect(Clip* c);
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int *anchor_x, int *anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int *anchor_x, int *anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* amount_val;
|
||||
private slots:
|
||||
void compile();
|
||||
private:
|
||||
QOpenGLShader vert_shader;
|
||||
QOpenGLShader frag_shader;
|
||||
|
||||
@@ -41,7 +41,7 @@ ShakeEffect::ShakeEffect(Clip *c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SHAKE_EFF
|
||||
|
||||
void ShakeEffect::refresh() {
|
||||
if (parent_clip->sequence != NULL) {
|
||||
shake_limit = qRound(parent_clip->sequence->frame_rate / frequency_val->get_double_value());
|
||||
shake_limit = qRound(parent_clip->sequence->frame_rate / frequency_val->get_double_value(-1));
|
||||
shake_progress = shake_limit;
|
||||
next_x = 0;
|
||||
next_y = 0;
|
||||
@@ -51,15 +51,13 @@ void ShakeEffect::refresh() {
|
||||
|
||||
Effect* ShakeEffect::copy(Clip* c) {
|
||||
ShakeEffect* e = new ShakeEffect(c);
|
||||
e->intensity_val->set_double_value(intensity_val->get_double_value());
|
||||
e->rotation_val->set_double_value(rotation_val->get_double_value());
|
||||
e->frequency_val->set_double_value(frequency_val->get_double_value());
|
||||
copy_field_keyframes(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
void ShakeEffect::process_gl(QOpenGLShaderProgram&, int*, int*) {
|
||||
void ShakeEffect::process_gl(long p, QOpenGLShaderProgram&, int*, int*) {
|
||||
if (shake_progress > shake_limit) {
|
||||
double ival = intensity_val->get_double_value();
|
||||
double ival = intensity_val->get_double_value(p);
|
||||
if ((int)ival > 0) {
|
||||
prev_x = next_x;
|
||||
prev_y = next_y;
|
||||
@@ -89,7 +87,7 @@ void ShakeEffect::process_gl(QOpenGLShaderProgram&, int*, int*) {
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
}
|
||||
double rot_val = rotation_val->get_double_value();
|
||||
double rot_val = rotation_val->get_double_value(p);
|
||||
if ((int)rot_val > 0) {
|
||||
prev_rot = next_rot;
|
||||
next_rot = (qrand() % (int) (rot_val * 2)) - rot_val;
|
||||
|
||||
@@ -7,7 +7,7 @@ class ShakeEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShakeEffect(Clip* c);
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* intensity_val;
|
||||
|
||||
@@ -37,19 +37,19 @@ SolidEffect::SolidEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_SOLID_EFF
|
||||
}
|
||||
|
||||
void SolidEffect::enable_color() {
|
||||
solid_color_field->set_enabled(solid_type->get_combo_data() == SOLID_TYPE_COLOR);
|
||||
solid_color_field->set_enabled(solid_type->get_combo_data(-1) == SOLID_TYPE_COLOR);
|
||||
}
|
||||
|
||||
void SolidEffect::process_image(QImage& img) {
|
||||
void SolidEffect::process_image(long frame, QImage& img) {
|
||||
QPainter p(&img);
|
||||
int width = img.width();
|
||||
int height = img.height();
|
||||
|
||||
switch (solid_type->get_combo_data().toInt()) {
|
||||
switch (solid_type->get_combo_data(frame).toInt()) {
|
||||
case SOLID_TYPE_COLOR:
|
||||
{
|
||||
QColor brush = solid_color_field->get_color_value();
|
||||
p.fillRect(0, 0, width, height, QColor(brush.red(), brush.green(), brush.blue(), opacity_field->get_double_value()*2.55));
|
||||
QColor brush = solid_color_field->get_color_value(frame);
|
||||
p.fillRect(0, 0, width, height, QColor(brush.red(), brush.green(), brush.blue(), opacity_field->get_double_value(frame)*2.55));
|
||||
}
|
||||
break;
|
||||
case SOLID_TYPE_BARS:
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
EffectField* solid_type;
|
||||
EffectField* solid_color_field;
|
||||
EffectField* opacity_field;
|
||||
void process_image(QImage &img);
|
||||
void process_image(long p, QImage &img);
|
||||
private slots:
|
||||
void enable_color();
|
||||
};
|
||||
|
||||
@@ -242,7 +242,7 @@ void blurred2(QImage& result, const QRect& rect, int radius, bool alphaOnly = fa
|
||||
}
|
||||
}
|
||||
|
||||
void TextEffect::process_image(QImage& img) {
|
||||
void TextEffect::process_image(long frame, QImage& img) {
|
||||
QPainter p(&img);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
int width = img.width();
|
||||
@@ -250,15 +250,15 @@ void TextEffect::process_image(QImage& img) {
|
||||
|
||||
// set font
|
||||
font.setStyleHint(QFont::Helvetica, QFont::PreferAntialias);
|
||||
font.setFamily(set_font_combobox->get_font_name());
|
||||
font.setPointSize(size_val->get_double_value());
|
||||
font.setFamily(set_font_combobox->get_font_name(frame));
|
||||
font.setPointSize(size_val->get_double_value(frame));
|
||||
p.setFont(font);
|
||||
QFontMetrics fm(font);
|
||||
|
||||
QStringList lines = text_val->get_string_value().split('\n');
|
||||
QStringList lines = text_val->get_string_value(frame).split('\n');
|
||||
|
||||
// word wrap function
|
||||
if (word_wrap_field->get_bool_value()) {
|
||||
if (word_wrap_field->get_bool_value(frame)) {
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
const QString& s = lines.at(i);
|
||||
if (fm.width(s) > width) {
|
||||
@@ -287,7 +287,7 @@ void TextEffect::process_image(QImage& img) {
|
||||
for (int i=0;i<lines.size();i++) {
|
||||
int text_x, text_y;
|
||||
|
||||
switch (halign_field->get_combo_data().toInt()) {
|
||||
switch (halign_field->get_combo_data(frame).toInt()) {
|
||||
case Qt::AlignLeft: text_x = 0; break;
|
||||
case Qt::AlignHCenter: text_x = (width/2) - (fm.width(lines.at(i))/2); break;
|
||||
case Qt::AlignRight: text_x = width - fm.width(lines.at(i)); break;
|
||||
@@ -316,7 +316,7 @@ void TextEffect::process_image(QImage& img) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (valign_field->get_combo_data().toInt()) {
|
||||
switch (valign_field->get_combo_data(frame).toInt()) {
|
||||
case Qt::AlignTop: text_y = (fm.height()*i)+fm.ascent(); break;
|
||||
case Qt::AlignVCenter: text_y = ((height/2) - (text_height/2) - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
case Qt::AlignBottom: text_y = (height - text_height - fm.descent()) + (fm.height()*(i+1)); break;
|
||||
@@ -328,43 +328,38 @@ void TextEffect::process_image(QImage& img) {
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
// draw shadow
|
||||
if (shadow_bool->get_bool_value()) {
|
||||
if (shadow_bool->get_bool_value(frame)) {
|
||||
QImage shadow(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||
shadow.fill(Qt::transparent);
|
||||
QPainter spaint(&shadow);
|
||||
|
||||
int shadow_offset = shadow_distance->get_double_value();
|
||||
QColor col = shadow_color->get_color_value();
|
||||
col.setAlphaF(shadow_opacity->get_double_value()*0.01);
|
||||
int shadow_offset = shadow_distance->get_double_value(frame);
|
||||
QColor col = shadow_color->get_color_value(frame);
|
||||
col.setAlphaF(shadow_opacity->get_double_value(frame)*0.01);
|
||||
spaint.setBrush(col);
|
||||
spaint.drawPath(path);
|
||||
|
||||
blurred2(shadow, shadow.rect(), shadow_softness->get_double_value(), false);
|
||||
blurred2(shadow, shadow.rect(), shadow_softness->get_double_value(frame), false);
|
||||
p.drawImage(shadow_offset, shadow_offset, shadow);
|
||||
|
||||
spaint.end();
|
||||
}
|
||||
|
||||
// draw outline
|
||||
int outline_width_val = outline_width->get_double_value();
|
||||
if (outline_bool->get_bool_value() && outline_width_val > 0) {
|
||||
QPen outline(outline_color->get_color_value());
|
||||
int outline_width_val = outline_width->get_double_value(frame);
|
||||
if (outline_bool->get_bool_value(frame) && outline_width_val > 0) {
|
||||
QPen outline(outline_color->get_color_value(frame));
|
||||
outline.setWidth(outline_width_val);
|
||||
p.setPen(outline);
|
||||
}
|
||||
|
||||
// draw "master" text
|
||||
p.setBrush(set_color_button->get_color_value());
|
||||
p.setBrush(set_color_button->get_color_value(frame));
|
||||
p.drawPath(path);
|
||||
}
|
||||
|
||||
Effect* TextEffect::copy(Clip* c) {
|
||||
TextEffect* e = new TextEffect(c);
|
||||
e->text_val->set_string_value(text_val->get_string_value());
|
||||
e->size_val->set_double_value(size_val->get_double_value());
|
||||
e->set_color_button->set_color_value(set_color_button->get_color_value());
|
||||
e->set_font_combobox->set_font_name(set_font_combobox->get_font_name());
|
||||
e->halign_field->set_combo_index(halign_field->get_combo_index());
|
||||
e->valign_field->set_combo_index(valign_field->get_combo_index());
|
||||
copy_field_keyframes(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class TextEffect : public Effect {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TextEffect(Clip* c);
|
||||
void process_image(QImage& img);
|
||||
void process_image(long frame, QImage& img);
|
||||
Effect* copy(Clip* c);
|
||||
|
||||
EffectField* text_val;
|
||||
|
||||
@@ -80,16 +80,7 @@ TransformEffect::TransformEffect(Clip* c) : Effect(c, EFFECT_TYPE_VIDEO, VIDEO_T
|
||||
|
||||
Effect* TransformEffect::copy(Clip* c) {
|
||||
TransformEffect* t = new TransformEffect(c);
|
||||
t->position_x->set_double_value(position_x->get_double_value());
|
||||
t->position_y->set_double_value(position_y->get_double_value());
|
||||
t->scale_x->set_double_value(scale_x->get_double_value());
|
||||
t->scale_y->set_double_value(scale_y->get_double_value());
|
||||
t->uniform_scale_field->set_bool_value(uniform_scale_field->get_bool_value());
|
||||
t->rotation->set_double_value(rotation->get_double_value());
|
||||
t->anchor_x_box->set_double_value(anchor_x_box->get_double_value());
|
||||
t->anchor_y_box->set_double_value(anchor_y_box->get_double_value());
|
||||
t->opacity->set_double_value(opacity->get_double_value());
|
||||
t->blend_mode_box->set_combo_index(blend_mode_box->get_combo_index());
|
||||
copy_field_keyframes(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -136,24 +127,24 @@ void TransformEffect::toggle_uniform_scale(bool enabled) {
|
||||
scale_y->set_enabled(!enabled);
|
||||
}
|
||||
|
||||
void TransformEffect::process_gl(QOpenGLShaderProgram&, int* anchor_x, int* anchor_y) {
|
||||
void TransformEffect::process_gl(long frame, QOpenGLShaderProgram&, int* anchor_x, int* anchor_y) {
|
||||
// position
|
||||
glTranslatef(position_x->get_double_value()-(parent_clip->sequence->width/2), position_y->get_double_value()-(parent_clip->sequence->height/2), 0);
|
||||
glTranslatef(position_x->get_double_value(frame)-(parent_clip->sequence->width/2), position_y->get_double_value(frame)-(parent_clip->sequence->height/2), 0);
|
||||
|
||||
// anchor point
|
||||
*anchor_x += (anchor_x_box->get_double_value()-default_anchor_x);
|
||||
*anchor_y += (anchor_y_box->get_double_value()-default_anchor_y);
|
||||
*anchor_x += (anchor_x_box->get_double_value(frame)-default_anchor_x);
|
||||
*anchor_y += (anchor_y_box->get_double_value(frame)-default_anchor_y);
|
||||
|
||||
// rotation
|
||||
glRotatef(rotation->get_double_value(), 0, 0, 1);
|
||||
glRotatef(rotation->get_double_value(frame), 0, 0, 1);
|
||||
|
||||
// scale
|
||||
float sx = scale_x->get_double_value()*0.01;
|
||||
float sy = (uniform_scale_field->get_bool_value()) ? sx : scale_y->get_double_value()*0.01;
|
||||
float sx = scale_x->get_double_value(frame)*0.01;
|
||||
float sy = (uniform_scale_field->get_bool_value(frame)) ? sx : scale_y->get_double_value(frame)*0.01;
|
||||
glScalef(sx, sy, 1);
|
||||
|
||||
// blend mode
|
||||
switch (blend_mode_box->get_combo_data().toInt()) {
|
||||
switch (blend_mode_box->get_combo_data(frame).toInt()) {
|
||||
case BLEND_MODE_NORMAL:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
@@ -173,5 +164,5 @@ void TransformEffect::process_gl(QOpenGLShaderProgram&, int* anchor_x, int* anch
|
||||
// opacity
|
||||
float color[4];
|
||||
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||
glColor4f(1.0, 1.0, 1.0, color[3]*(opacity->get_double_value()*0.01));
|
||||
glColor4f(1.0, 1.0, 1.0, color[3]*(opacity->get_double_value(frame)*0.01));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ class TransformEffect : public Effect {
|
||||
public:
|
||||
TransformEffect(Clip* c);
|
||||
void refresh();
|
||||
void process_gl(QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
void process_gl(long p, QOpenGLShaderProgram& shader_prog, int* anchor_x, int* anchor_y);
|
||||
Effect* copy(Clip *c);
|
||||
|
||||
EffectField* position_x;
|
||||
|
||||
Reference in New Issue
Block a user