windows frei0r support done

This commit is contained in:
itsmattkc
2019-01-20 21:06:21 +11:00
parent 80b77a382b
commit d5eab3673c
15 changed files with 305 additions and 136 deletions
+108 -10
View File
@@ -1,6 +1,7 @@
#include "frei0reffect.h"
#include <QMessageBox>
#include <QDir>
#include <Windows.h>
@@ -10,15 +11,15 @@ typedef void (*f0rDeinitFunc) ();
typedef void (*f0rUpdateFunc) (f0r_instance_t instance,
double time, const uint32_t* inframe, uint32_t* outframe);
typedef void (*f0rDestructFunc)(f0r_instance_t instance);
typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info);
typedef void (*f0rSetParamValue) (f0r_instance_t instance,
f0r_param_t param, int param_index);
Frei0rEffect::Frei0rEffect(Clip *c, const EffectMeta *em) : Effect(c, em) {
enable_image = true;
add_row("Heck");
// Windows DLL loading routine
QString dll_fn = "E:/invert0r.dll";
QString dll_fn = QDir(em->path).filePath(em->filename);
LPCWSTR dll_fn_w = reinterpret_cast<const wchar_t*>(dll_fn.utf16());
modulePtr = LoadLibrary(dll_fn_w);
@@ -37,28 +38,125 @@ Frei0rEffect::Frei0rEffect(Clip *c, const EffectMeta *em) : Effect(c, em) {
return;
}
f0rConstructFunc construct = reinterpret_cast<f0rConstructFunc>(GetProcAddress(modulePtr, "f0r_construct"));
f0rInitFunc init = reinterpret_cast<f0rInitFunc>(GetProcAddress(modulePtr, "f0r_init"));
init();
f0rConstructFunc construct = reinterpret_cast<f0rConstructFunc>(GetProcAddress(modulePtr, "f0r_construct"));
instance = construct(1920, 1080);
f0r_plugin_info_t info;
f0rGetPluginInfo info_func = reinterpret_cast<f0rGetPluginInfo>(GetProcAddress(modulePtr, "f0r_get_plugin_info"));
info_func(&info);
param_count = info.num_params;
qDebug() << "Frei0r Name:" << info.name;
qDebug() << "Frei0r Param Count:" << info.num_params;
qDebug() << "Frei0r Explanation:" << info.explanation;
get_param_info = reinterpret_cast<f0rGetParamInfo>(GetProcAddress(modulePtr, "f0r_get_param_info"));
for (int i=0;i<param_count;i++) {
f0r_param_info_t param_info;
get_param_info(&param_info, i);
if (param_info.type >= 0 && param_info.type <= F0R_PARAM_STRING) {
EffectRow* row = add_row(param_info.name);
switch (param_info.type) {
case F0R_PARAM_BOOL:
row->add_field(EFFECT_FIELD_BOOL, QString::number(i));
break;
case F0R_PARAM_DOUBLE:
{
EffectField* f = row->add_field(EFFECT_FIELD_DOUBLE, QString::number(i));
f->set_double_minimum_value(0);
f->set_double_maximum_value(100);
}
break;
case F0R_PARAM_COLOR:
row->add_field(EFFECT_FIELD_COLOR, QString::number(i));
break;
case F0R_PARAM_POSITION:
{
EffectField* fx = row->add_field(EFFECT_FIELD_DOUBLE, QString("%1X").arg(QString::number(i)));
fx->set_double_minimum_value(0);
fx->set_double_maximum_value(100);
EffectField* fy = row->add_field(EFFECT_FIELD_DOUBLE, QString("%1Y").arg(QString::number(i)));
fy->set_double_minimum_value(0);
fy->set_double_maximum_value(100);
}
break;
case F0R_PARAM_STRING:
row->add_field(EFFECT_FIELD_STRING, QString::number(i));
break;
}
}
}
}
Frei0rEffect::~Frei0rEffect() {
if (modulePtr != nullptr) {
FreeModule(modulePtr);
f0rDestructFunc destruct = reinterpret_cast<f0rDestructFunc>(GetProcAddress(modulePtr, "f0r_destruct"));
destruct(instance);
f0rDeinitFunc deinit = reinterpret_cast<f0rDeinitFunc>(GetProcAddress(modulePtr, "f0r_deinit"));
deinit();
FreeModule(modulePtr);
}
}
void Frei0rEffect::process_image(double timecode, uint8_t *input, uint8_t *output, int size) {
void Frei0rEffect::process_image(double timecode, uint8_t *input, uint8_t *output, int) {
f0rUpdateFunc update_func = reinterpret_cast<f0rUpdateFunc>(GetProcAddress(modulePtr, "f0r_update"));
for (int i=0;i<param_count;i++) {
EffectRow* param_row = row(i);
f0r_param_info_t param_info;
get_param_info(&param_info, i);
f0rSetParamValue set_param = reinterpret_cast<f0rSetParamValue>(GetProcAddress(modulePtr, "f0r_set_param_value"));
switch (param_info.type) {
case F0R_PARAM_BOOL:
{
double b = param_row->field(0)->get_bool_value(timecode);
set_param(instance, &b, i);
}
break;
case F0R_PARAM_DOUBLE:
{
double d = param_row->field(0)->get_double_value(timecode)*0.01;
set_param(instance, &d, i);
}
break;
case F0R_PARAM_COLOR:
{
QColor qcolor = param_row->field(0)->get_color_value(timecode);;
f0r_param_color fcolor;
fcolor.r = float(qcolor.redF());
fcolor.g = float(qcolor.greenF());
fcolor.b = float(qcolor.blueF());
set_param(instance, &fcolor, i);
}
break;
case F0R_PARAM_POSITION:
{
f0r_param_position pos;
pos.x = param_row->field(0)->get_double_value(timecode);
pos.y = param_row->field(1)->get_double_value(timecode);
set_param(instance, &pos, i);
}
break;
case F0R_PARAM_STRING:
{
QByteArray bytes = param_row->field(0)->get_string_value(timecode).toUtf8();
char* byte_data = bytes.data();
set_param(instance, &byte_data, i);
}
break;
}
}
update_func(instance, timecode, reinterpret_cast<uint32_t*>(input), reinterpret_cast<uint32_t*>(output));
}
+5
View File
@@ -5,6 +5,9 @@
#include <frei0r/frei0r.h>
typedef void (*f0rGetParamInfo)(f0r_param_info_t * info,
int param_index );
class Frei0rEffect : public Effect {
Q_OBJECT
public:
@@ -15,6 +18,8 @@ public:
private:
HMODULE modulePtr;
f0r_instance_t instance;
int param_count;
f0rGetParamInfo get_param_info;
};
#endif // FREI0REFFECT_H
+4 -4
View File
@@ -5,15 +5,15 @@ extern "C" {
}
enum QOpenGLTexture::PixelFormat get_gl_pix_fmt_from_av(int format) {
switch (format) {
/*switch (format) {
case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB;
}
}*/
return QOpenGLTexture::RGBA;
}
enum QOpenGLTexture::TextureFormat get_gl_tex_fmt_from_av(int format) {
switch (format) {
/*switch (format) {
case AV_PIX_FMT_RGB24: return QOpenGLTexture::RGB8_UNorm;
}
}*/
return QOpenGLTexture::RGBA8_UNorm;
}
+2 -2
View File
@@ -3,7 +3,7 @@
#include <QString>
#define SAVE_VERSION 190104 // YYMMDD
#define SAVE_VERSION 190120 // YYMMDD
#define MIN_SAVE_VERSION 190104 // lowest compatible project version
#define TIMECODE_DROP 0
@@ -63,7 +63,7 @@ struct Config {
bool seek_also_selects;
QString css_path;
int effect_textbox_lines;
bool use_software_fallback;
bool use_software_fallback;
void load(QString path);
void save(QString path);
+14 -2
View File
@@ -37,9 +37,21 @@ LoadThread::LoadThread(LoadDialog* l, bool a) : ld(l), autorecovery(a), cancelle
connect(this, SIGNAL(start_create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)), this, SLOT(create_effect_ui(QXmlStreamReader*, Clip*, int, const QString*, const EffectMeta*, long, bool)));
}
const EffectMeta* get_meta_from_name(const QString& name) {
const EffectMeta* get_meta_from_name(const QString& input) {
int split_index = input.indexOf('/');
QString category;
if (split_index > -1) {
category = input.left(split_index);
}
QString name = input.mid(split_index + 1);
qDebug() << "CAT:" << category;
qDebug() << "NAM:" << name;
for (int j=0;j<effects.size();j++) {
if (effects.at(j).name == name) {
if (effects.at(j).name == name
&& (effects.at(j).category == category
|| category.isEmpty())) {
return &effects.at(j);
}
}
+6 -6
View File
@@ -59,13 +59,13 @@ GraphEditor::GraphEditor(QWidget* parent) : QDockWidget(parent), row(nullptr) {
left_tool_layout->addStretch();
linear_button = new QPushButton(tr("Linear"));
linear_button->setProperty("type", KEYFRAME_TYPE_LINEAR);
linear_button->setProperty("type", EFFECT_KEYFRAME_LINEAR);
linear_button->setCheckable(true);
bezier_button = new QPushButton(tr("Bezier"));
bezier_button->setProperty("type", KEYFRAME_TYPE_BEZIER);
bezier_button->setProperty("type", EFFECT_KEYFRAME_BEZIER);
bezier_button->setCheckable(true);
hold_button = new QPushButton(tr("Hold"));
hold_button->setProperty("type", KEYFRAME_TYPE_HOLD);
hold_button->setProperty("type", EFFECT_KEYFRAME_HOLD);
hold_button->setCheckable(true);
center_tool_layout->addStretch();
@@ -216,11 +216,11 @@ void GraphEditor::select_all() {
void GraphEditor::set_key_button_enabled(bool e, int type) {
linear_button->setEnabled(e);
linear_button->setChecked(type == KEYFRAME_TYPE_LINEAR);
linear_button->setChecked(type == EFFECT_KEYFRAME_LINEAR);
bezier_button->setEnabled(e);
bezier_button->setChecked(type == KEYFRAME_TYPE_BEZIER);
bezier_button->setChecked(type == EFFECT_KEYFRAME_BEZIER);
hold_button->setEnabled(e);
hold_button->setChecked(type == KEYFRAME_TYPE_HOLD);
hold_button->setChecked(type == EFFECT_KEYFRAME_HOLD);
}
void GraphEditor::passthrough_slider_value() {
+1 -1
View File
@@ -767,7 +767,7 @@ void open_clip_worker(Clip* clip) {
}*/
enum AVPixelFormat valid_pix_fmts[] = {
AV_PIX_FMT_RGB24,
// AV_PIX_FMT_RGB24,
AV_PIX_FMT_RGBA,
AV_PIX_FMT_NONE
};
+6 -6
View File
@@ -50,10 +50,7 @@ bool shaders_are_enabled = true;
QVector<EffectMeta> effects;
Effect* create_effect(Clip* c, const EffectMeta* em) {
if (!em->filename.isEmpty()) {
// load effect from file
return new Effect(c, em);
} else if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
// must be an internal effect
switch (em->internal) {
case EFFECT_INTERNAL_TRANSFORM: return new TransformEffect(c, em);
@@ -72,6 +69,9 @@ Effect* create_effect(Clip* c, const EffectMeta* em) {
#endif
case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em);
}
} else if (!em->filename.isEmpty()) {
// load effect from file
return new Effect(c, em);
} else {
qCritical() << "Invalid effect data";
QMessageBox::critical(mainWindow,
@@ -118,7 +118,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
// set up UI from effect file
container->setText(em->name);
if (!em->filename.isEmpty()) {
if (!em->filename.isEmpty() && em->internal == -1) {
QFile effect_file(em->filename);
if (effect_file.open(QFile::ReadOnly)) {
QXmlStreamReader reader(&effect_file);
@@ -563,7 +563,7 @@ void Effect::load(QXmlStreamReader& stream) {
void Effect::custom_load(QXmlStreamReader &) {}
void Effect::save(QXmlStreamWriter& stream) {
stream.writeAttribute("name", meta->name);
stream.writeAttribute("name", meta->category + "/" + meta->name);
stream.writeAttribute("enabled", QString::number(is_enabled()));
for (int i=0;i<rows.size();i++) {
+29 -27
View File
@@ -41,35 +41,37 @@ double log_volume(double linear);
Effect* create_effect(Clip* c, const EffectMeta *em);
const EffectMeta* get_internal_meta(int internal_id, int type);
#define EFFECT_TYPE_INVALID 0
#define EFFECT_TYPE_VIDEO 1
#define EFFECT_TYPE_AUDIO 2
#define EFFECT_TYPE_EFFECT 3
#define EFFECT_TYPE_TRANSITION 4
enum EffectType {
EFFECT_TYPE_INVALID,
EFFECT_TYPE_VIDEO,
EFFECT_TYPE_AUDIO,
EFFECT_TYPE_EFFECT,
EFFECT_TYPE_TRANSITION
};
#define EFFECT_KEYFRAME_LINEAR 0
#define EFFECT_KEYFRAME_HOLD 1
#define EFFECT_KEYFRAME_BEZIER 2
enum EffectKeyframeType {
EFFECT_KEYFRAME_LINEAR,
EFFECT_KEYFRAME_BEZIER,
EFFECT_KEYFRAME_HOLD
};
#define EFFECT_INTERNAL_TRANSFORM 0
#define EFFECT_INTERNAL_TEXT 1
#define EFFECT_INTERNAL_SOLID 2
#define EFFECT_INTERNAL_NOISE 3
#define EFFECT_INTERNAL_VOLUME 4
#define EFFECT_INTERNAL_PAN 5
#define EFFECT_INTERNAL_TONE 6
#define EFFECT_INTERNAL_SHAKE 7
#define EFFECT_INTERNAL_TIMECODE 8
#define EFFECT_INTERNAL_MASK 9
#define EFFECT_INTERNAL_FILLLEFTRIGHT 10
#define EFFECT_INTERNAL_VST 11
#define EFFECT_INTERNAL_CORNERPIN 12
#define EFFECT_INTERNAL_FREI0R 13
#define EFFECT_INTERNAL_COUNT 14
#define KEYFRAME_TYPE_LINEAR 0
#define KEYFRAME_TYPE_BEZIER 1
#define KEYFRAME_TYPE_HOLD 2
enum EffectInternal {
EFFECT_INTERNAL_TRANSFORM,
EFFECT_INTERNAL_TEXT,
EFFECT_INTERNAL_SOLID,
EFFECT_INTERNAL_NOISE,
EFFECT_INTERNAL_VOLUME,
EFFECT_INTERNAL_PAN,
EFFECT_INTERNAL_TONE,
EFFECT_INTERNAL_SHAKE,
EFFECT_INTERNAL_TIMECODE,
EFFECT_INTERNAL_MASK,
EFFECT_INTERNAL_FILLLEFTRIGHT,
EFFECT_INTERNAL_VST,
EFFECT_INTERNAL_CORNERPIN,
EFFECT_INTERNAL_FREI0R,
EFFECT_INTERNAL_COUNT
};
struct GLTextureCoords {
int grid_size;
+44 -44
View File
@@ -86,53 +86,53 @@ EffectField::EffectField(EffectRow *parent, int t, const QString &i) :
connect(efc, SIGNAL(changed()), this, SLOT(ui_element_change()));
}
break;
}
}
}
double EffectField::get_validated_keyframe_handle(int key, bool post) {
int comp_key = -1;
int comp_key = -1;
// find keyframe before or after this one
for (int i=0;i<keyframes.size();i++) {
if (i != key
&& ((keyframes.at(i).time > keyframes.at(key).time) == post)
&& (comp_key == -1
|| ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) {
// compare with next keyframe for post or previous frame for pre
comp_key = i;
}
}
// find keyframe before or after this one
for (int i=0;i<keyframes.size();i++) {
if (i != key
&& ((keyframes.at(i).time > keyframes.at(key).time) == post)
&& (comp_key == -1
|| ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) {
// compare with next keyframe for post or previous frame for pre
comp_key = i;
}
}
double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x;
double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x;
// if this is the earliest/latest keyframe, no validation is required
if (comp_key == -1) {
return adjusted_key;
}
// if this is the earliest/latest keyframe, no validation is required
if (comp_key == -1) {
return adjusted_key;
}
double comp = keyframes.at(comp_key).time - keyframes.at(key).time;
double comp = keyframes.at(comp_key).time - keyframes.at(key).time;
// if comp keyframe is bezier, validate with its accompanying handle
if (keyframes.at(comp_key).type == KEYFRAME_TYPE_BEZIER) {
double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x);
// return an average
if ((post && keyframes.at(key).post_handle_x > relative_comp_handle)
|| (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) {
adjusted_key = (adjusted_key + relative_comp_handle)*0.5;
}
}
// if comp keyframe is bezier, validate with its accompanying handle
if (keyframes.at(comp_key).type == EFFECT_KEYFRAME_BEZIER) {
double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x);
// return an average
if ((post && keyframes.at(key).post_handle_x > relative_comp_handle)
|| (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) {
adjusted_key = (adjusted_key + relative_comp_handle)*0.5;
}
}
// don't let handle go beyond the compare keyframe's time
if (post == (adjusted_key > comp)) {
return comp;
}
// don't let handle go beyond the compare keyframe's time
if (post == (adjusted_key > comp)) {
return comp;
}
if (post == (adjusted_key < 0)) {
return 0;
}
if (post == (adjusted_key < 0)) {
return 0;
}
// original value is valid
return adjusted_key;
// original value is valid
return adjusted_key;
}
QVariant EffectField::get_previous_data() {
@@ -162,7 +162,7 @@ QVariant EffectField::get_current_data() {
}
double EffectField::frameToTimecode(long frame) {
return ((double) frame / parent_row->parent_effect->parent_clip->sequence->frame_rate);
return (double(frame) / parent_row->parent_effect->parent_clip->sequence->frame_rate);
}
long EffectField::timecodeToFrame(double timecode) {
@@ -242,22 +242,22 @@ QVariant EffectField::validate_keyframe_data(double timecode, bool async) {
double before_dbl = before_key.data.toDouble();
double after_dbl = after_key.data.toDouble();
if (before_key.type == KEYFRAME_TYPE_HOLD) {
if (before_key.type == EFFECT_KEYFRAME_HOLD) {
// hold
value = before_dbl;
} else if (before_key.type == KEYFRAME_TYPE_BEZIER || after_key.type == KEYFRAME_TYPE_BEZIER) {
} else if (before_key.type == EFFECT_KEYFRAME_BEZIER || after_key.type == EFFECT_KEYFRAME_BEZIER) {
// bezier interpolation
if (before_key.type == KEYFRAME_TYPE_BEZIER && after_key.type == KEYFRAME_TYPE_BEZIER) {
if (before_key.type == EFFECT_KEYFRAME_BEZIER && after_key.type == EFFECT_KEYFRAME_BEZIER) {
// cubic bezier
double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
value = cubic_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl+after_key.pre_handle_y, after_dbl, t);
} else if (after_key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier
} else if (after_key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier
// last keyframe is the bezier one
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time);
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time);
value = quad_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl, t);
} else {
// this keyframe is the bezier one
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
value = quad_from_t(before_dbl, after_dbl+after_key.pre_handle_y, after_dbl, t);
}
} else {
+58 -6
View File
@@ -11,6 +11,9 @@
#include <QDebug>
#include <frei0r/frei0r.h>
typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info);
void load_internal_effects() {
if (!shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional";
@@ -48,12 +51,6 @@ void load_internal_effects() {
em.subtype = EFFECT_TYPE_VIDEO;
// TEMPORARY begin
em.name = "Frei0r Plugin";
em.internal = EFFECT_INTERNAL_FREI0R;
effects.append(em);
// TEMPORARY end
em.name = "Transform";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_TRANSFORM;
@@ -165,6 +162,60 @@ void init_effects() {
init_thread->start();
}
void load_frei0r_effects() {
QList<QString> effect_dirs = get_effects_paths();
int lim = effect_dirs.size();
// add extra search paths for frei0r effects
for (int i=0;i<lim;i++) {
effect_dirs.append(QDir(effect_dirs.at(i)).filePath("frei0r"));
}
// add defined paths for frei0r plugins on unix
#if defined(__APPLE__) || defined(__linux__)
#endif
// search for paths
EffectMeta em;
em.category = "Frei0r";
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_VIDEO;
em.internal = EFFECT_INTERNAL_FREI0R;
for (int i=0;i<effect_dirs.size();i++) {
QDir search_dir(effect_dirs.at(i));
if (search_dir.exists()) {
QList<QString> entry_list = search_dir.entryList(QStringList("*.dll"));
for (int j=0;j<entry_list.size();j++) {
HMODULE effect = LoadLibrary(reinterpret_cast<const wchar_t*>(search_dir.filePath(entry_list.at(j)).utf16()));
if (effect != nullptr) {
f0rGetPluginInfo get_info_func = reinterpret_cast<f0rGetPluginInfo>(GetProcAddress(effect, "f0r_get_plugin_info"));
if (get_info_func != nullptr) {
f0r_plugin_info_t info;
get_info_func(&info);
if (info.plugin_type == F0R_PLUGIN_TYPE_FILTER
&& info.color_model == F0R_COLOR_MODEL_RGBA8888) {
em.name = info.name;
em.path = effect_dirs.at(i);
em.filename = entry_list.at(j);
effects.append(em);
}
// qDebug() << "Found:" << info.name << "by" << info.author;
}
FreeLibrary(effect);
}
// qDebug() << search_dir.filePath(entry_list.at(j));
}
}
}
}
EffectInit::EffectInit() {
panel_effect_controls->effects_loaded.lock();
}
@@ -173,6 +224,7 @@ void EffectInit::run() {
qInfo() << "Initializing effects...";
load_internal_effects();
load_shader_effects();
load_frei0r_effects();
panel_effect_controls->effects_loaded.unlock();
qInfo() << "Finished initializing effects";
}
+1 -1
View File
@@ -197,7 +197,7 @@ void EffectRow::set_keyframe_now(ComboAction* ca) {
}
}
if (exist_key == -1) {
key.type = (f->keyframes.size() == 0) ? KEYFRAME_TYPE_LINEAR : f->keyframes.at(closest_key).type;
key.type = (f->keyframes.size() == 0) ? EFFECT_KEYFRAME_LINEAR : f->keyframes.at(closest_key).type;
key.data = f->get_current_data();//f->keyframes.at(closest_key).data;
unsafe_keys[i] = f->keyframes.size();
f->keyframes.append(key);
+15 -15
View File
@@ -238,33 +238,33 @@ void GraphView::paintEvent(QPaintEvent *) {
} else {
const EffectKeyframe& last_key = field->keyframes.at(sorted_keys.at(j-1));
double pre_handle = field->get_validated_keyframe_handle(sorted_keys.at(j), false);
double last_post_handle = field->get_validated_keyframe_handle(sorted_keys.at(j-1), true);
double pre_handle = field->get_validated_keyframe_handle(sorted_keys.at(j), false);
double last_post_handle = field->get_validated_keyframe_handle(sorted_keys.at(j-1), true);
if (last_key.type == KEYFRAME_TYPE_HOLD) {
if (last_key.type == EFFECT_KEYFRAME_HOLD) {
// hold
p.drawLine(last_key_x, last_key_y, key_x, last_key_y);
p.drawLine(key_x, last_key_y, key_x, key_y);
} else if (last_key.type == KEYFRAME_TYPE_BEZIER || key.type == KEYFRAME_TYPE_BEZIER) {
} else if (last_key.type == EFFECT_KEYFRAME_BEZIER || key.type == EFFECT_KEYFRAME_BEZIER) {
QPainterPath bezier_path;
bezier_path.moveTo(last_key_x, last_key_y);
if (last_key.type == KEYFRAME_TYPE_BEZIER && key.type == KEYFRAME_TYPE_BEZIER) {
if (last_key.type == EFFECT_KEYFRAME_BEZIER && key.type == EFFECT_KEYFRAME_BEZIER) {
// cubic bezier
bezier_path.cubicTo(
QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom),
QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom),
QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom),
QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom),
QPointF(key_x, key_y)
);
} else if (key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier
} else if (key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier
// last keyframe is the bezier one
bezier_path.quadTo(
QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom),
QPointF(last_key_x+last_post_handle*zoom, last_key_y-last_key.post_handle_y*zoom),
QPointF(key_x, key_y)
);
} else {
// this keyframe is the bezier one
bezier_path.quadTo(
QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom),
QPointF(key_x+pre_handle*zoom, key_y-key.pre_handle_y*zoom),
QPointF(key_x, key_y)
);
}
@@ -286,7 +286,7 @@ void GraphView::paintEvent(QPaintEvent *) {
int key_x = get_screen_x(key.time);
int key_y = get_screen_y(key.data.toDouble());
if (key.type == KEYFRAME_TYPE_BEZIER) {
if (key.type == EFFECT_KEYFRAME_BEZIER) {
p.setPen(Qt::gray);
// pre handle line
@@ -612,24 +612,24 @@ void GraphView::mouseMoveEvent(QMouseEvent *event) {
&& event->pos().x() <= key_x) {
QRect mouse_rect(event->pos().x()-BEZIER_LINE_SIZE, event->pos().y()-BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE, BEZIER_LINE_SIZE+BEZIER_LINE_SIZE);
// NOTE: FILTHY copy/paste from paintEvent
if (last_key.type == KEYFRAME_TYPE_HOLD) {
if (last_key.type == EFFECT_KEYFRAME_HOLD) {
// hold
if (event->pos().y() >= last_key_y-BEZIER_LINE_SIZE
&& event->pos().y() <= last_key_y+BEZIER_LINE_SIZE) {
// dout << "make an HOLD key on field" << i << "after key" << j;
click_add = true;
}
} else if (last_key.type == KEYFRAME_TYPE_BEZIER || key.type == KEYFRAME_TYPE_BEZIER) {
} else if (last_key.type == EFFECT_KEYFRAME_BEZIER || key.type == EFFECT_KEYFRAME_BEZIER) {
QPainterPath bezier_path;
bezier_path.moveTo(last_key_x, last_key_y);
if (last_key.type == KEYFRAME_TYPE_BEZIER && key.type == KEYFRAME_TYPE_BEZIER) {
if (last_key.type == EFFECT_KEYFRAME_BEZIER && key.type == EFFECT_KEYFRAME_BEZIER) {
// cubic bezier
bezier_path.cubicTo(
QPointF(last_key_x+last_key.post_handle_x*zoom, last_key_y-last_key.post_handle_y*zoom),
QPointF(key_x+key.pre_handle_x*zoom, key_y-key.pre_handle_y*zoom),
QPointF(key_x, key_y)
);
} else if (key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier
} else if (key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier
// last keyframe is the bezier one
bezier_path.quadTo(
QPointF(last_key_x+last_key.post_handle_x*zoom, last_key_y-last_key.post_handle_y*zoom),
+3 -3
View File
@@ -14,16 +14,16 @@ void draw_keyframe(QPainter &p, int type, int x, int y, bool darker, int r, int
p.setBrush(QColor(r, g, b));
switch (type) {
case KEYFRAME_TYPE_LINEAR:
case EFFECT_KEYFRAME_LINEAR:
{
QPoint points[KEYFRAME_POINT_COUNT] = {QPoint(x-KEYFRAME_SIZE, y), QPoint(x, y-KEYFRAME_SIZE), QPoint(x+KEYFRAME_SIZE, y), QPoint(x, y+KEYFRAME_SIZE)};
p.drawPolygon(points, KEYFRAME_POINT_COUNT);
}
break;
case KEYFRAME_TYPE_BEZIER:
case EFFECT_KEYFRAME_BEZIER:
p.drawEllipse(QPoint(x, y), KEYFRAME_SIZE, KEYFRAME_SIZE);
break;
case KEYFRAME_TYPE_HOLD:
case EFFECT_KEYFRAME_HOLD:
p.drawRect(QRect(x - KEYFRAME_SIZE, y - KEYFRAME_SIZE, KEYFRAME_SIZE*2, KEYFRAME_SIZE*2));
break;
}
+9 -9
View File
@@ -50,12 +50,12 @@ void KeyframeView::show_context_menu(const QPoint& pos) {
if (selected_fields.size() > 0) {
QMenu menu(this);
QAction* linear = menu.addAction(tr("Linear"));
linear->setData(KEYFRAME_TYPE_LINEAR);
QAction* bezier = menu.addAction(tr("Bezier"));
bezier->setData(KEYFRAME_TYPE_BEZIER);
QAction* hold = menu.addAction(tr("Hold"));
hold->setData(KEYFRAME_TYPE_HOLD);
QAction* linear = menu.addAction(tr("Linear"));
linear->setData(EFFECT_KEYFRAME_LINEAR);
QAction* bezier = menu.addAction(tr("Bezier"));
bezier->setData(EFFECT_KEYFRAME_BEZIER);
QAction* hold = menu.addAction(tr("Hold"));
hold->setData(EFFECT_KEYFRAME_HOLD);
menu.addSeparator();
menu.addAction("Graph Editor");
@@ -199,9 +199,9 @@ void KeyframeView::set_y_scroll(int s) {
}
void KeyframeView::resize_move(double d) {
panel_effect_controls->zoom *= d;
header->update_zoom(panel_effect_controls->zoom);
update();
panel_effect_controls->zoom *= d;
header->update_zoom(panel_effect_controls->zoom);
update();
}
void KeyframeView::mousePressEvent(QMouseEvent *event) {