Merge branch 'master' into cache-update
This commit is contained in:
@@ -90,11 +90,11 @@ void MatrixGenerator::Retranslate()
|
||||
void MatrixGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
{
|
||||
// Push matrix output
|
||||
QMatrix4x4 mat = GenerateMatrix(value, false, false, false);
|
||||
QMatrix4x4 mat = GenerateMatrix(value, false, false, false, QMatrix4x4());
|
||||
table->Push(NodeValue::kMatrix, mat, this);
|
||||
}
|
||||
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale) const
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale, const QMatrix4x4 &mat) const
|
||||
{
|
||||
QVector2D anchor;
|
||||
QVector2D position;
|
||||
@@ -116,17 +116,17 @@ QMatrix4x4 MatrixGenerator::GenerateMatrix(const NodeValueRow &value, bool ignor
|
||||
value[kRotationInput].toDouble(),
|
||||
scale,
|
||||
value[kUniformScaleInput].toBool(),
|
||||
anchor);
|
||||
anchor,
|
||||
mat);
|
||||
}
|
||||
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const QVector2D& pos,
|
||||
const float& rot,
|
||||
const QVector2D& scale,
|
||||
bool uniform_scale,
|
||||
const QVector2D& anchor)
|
||||
const QVector2D& anchor,
|
||||
QMatrix4x4 mat)
|
||||
{
|
||||
QMatrix4x4 mat;
|
||||
|
||||
// Position
|
||||
mat.translate(pos);
|
||||
|
||||
|
||||
@@ -53,12 +53,13 @@ public:
|
||||
static const QString kAnchorInput;
|
||||
|
||||
protected:
|
||||
QMatrix4x4 GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale) const;
|
||||
QMatrix4x4 GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale, const QMatrix4x4 &mat) const;
|
||||
static QMatrix4x4 GenerateMatrix(const QVector2D &pos,
|
||||
const float &rot,
|
||||
const QVector2D &scale,
|
||||
bool uniform_scale,
|
||||
const QVector2D &anchor);
|
||||
const QVector2D &anchor,
|
||||
QMatrix4x4 mat);
|
||||
|
||||
virtual void InputValueChangedEvent(const QString& input, int element) override;
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QVector2D>
|
||||
|
||||
#include "common/cpuoptimize.h"
|
||||
|
||||
namespace olive {
|
||||
|
||||
const QString PolygonGenerator::kPointsInput = QStringLiteral("points_in");
|
||||
@@ -89,20 +87,25 @@ void PolygonGenerator::Retranslate()
|
||||
SetInputName(kColorInput, tr("Color"));
|
||||
}
|
||||
|
||||
GenerateJob PolygonGenerator::GetGenerateJob(const NodeValueRow &value) const
|
||||
ShaderJob PolygonGenerator::GetGenerateJob(const NodeValueRow &value) const
|
||||
{
|
||||
GenerateJob job;
|
||||
|
||||
job.Insert(value);
|
||||
job.SetRequestedFormat(VideoParams::kFormatFloat32);
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetRequestedFormat(VideoParams::kFormatUnsigned8);
|
||||
|
||||
return job;
|
||||
// Conversion to RGB
|
||||
ShaderJob rgb;
|
||||
rgb.SetShaderID(QStringLiteral("rgb"));
|
||||
rgb.Insert(QStringLiteral("texture_in"), NodeValue(NodeValue::kTexture, job, this));
|
||||
rgb.Insert(QStringLiteral("color_in"), value[kColorInput]);
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
{
|
||||
GenerateJob job = GetGenerateJob(value);
|
||||
ShaderJob job = GetGenerateJob(value);
|
||||
|
||||
PushMergableJob(value, QVariant::fromValue(job), table);
|
||||
}
|
||||
@@ -113,7 +116,7 @@ void PolygonGenerator::GenerateFrame(FramePtr frame, const GenerateJob &job) con
|
||||
// QImages only support integer pixels and we use float pixels, so what we do here is draw onto
|
||||
// a single-channel QImage (alpha only) and then transplant that alpha channel to our float buffer
|
||||
// with correct float RGB.
|
||||
QImage img(frame->width(), frame->height(), QImage::Format_Grayscale8);
|
||||
QImage img((uchar *) frame->data(), frame->width(), frame->height(), frame->linesize_bytes(), QImage::Format_RGBA8888_Premultiplied);
|
||||
img.fill(Qt::transparent);
|
||||
|
||||
QVector<NodeValue> points = job.Get(kPointsInput).value< QVector<NodeValue> >();
|
||||
@@ -128,34 +131,6 @@ void PolygonGenerator::GenerateFrame(FramePtr frame, const GenerateJob &job) con
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
p.drawPath(path);
|
||||
|
||||
// Transplant alpha channel to frame
|
||||
Color rgba = job.Get(kColorInput).toColor();
|
||||
#if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM)
|
||||
__m128 sse_color = _mm_loadu_ps(rgba.data());
|
||||
#endif
|
||||
|
||||
float *frame_dst = reinterpret_cast<float*>(frame->data());
|
||||
for (int y=0; y<frame->height(); y++) {
|
||||
uchar *src_y = img.bits() + img.bytesPerLine() * y;
|
||||
float *dst_y = frame_dst + y*frame->linesize_pixels()*VideoParams::kRGBAChannelCount;
|
||||
|
||||
for (int x=0; x<frame->width(); x++) {
|
||||
float alpha = float(src_y[x]) / 255.0f;
|
||||
float *dst = dst_y + x*VideoParams::kRGBAChannelCount;
|
||||
|
||||
#if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM)
|
||||
__m128 sse_alpha = _mm_load1_ps(&alpha);
|
||||
__m128 sse_res = _mm_mul_ps(sse_color, sse_alpha);
|
||||
|
||||
_mm_store_ps(dst, sse_res);
|
||||
#else
|
||||
for (int i=0; i<VideoParams::kRGBAChannelCount; i++) {
|
||||
dst[i] = rgba.data()[i] * alpha;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -241,6 +216,15 @@ void PolygonGenerator::UpdateGizmoPositions(const NodeValueRow &row, const NodeG
|
||||
poly_gizmo_->SetPath(GeneratePath(points).translated(half_res));
|
||||
}
|
||||
|
||||
ShaderCode PolygonGenerator::GetShaderCode(const ShaderRequest &request) const
|
||||
{
|
||||
if (request.id == QStringLiteral("rgb")) {
|
||||
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/rgb.frag"));
|
||||
} else {
|
||||
return super::GetShaderCode(request);
|
||||
}
|
||||
}
|
||||
|
||||
void PolygonGenerator::GizmoDragMove(double x, double y, const Qt::KeyboardModifiers &modifiers)
|
||||
{
|
||||
DraggableGizmo *gizmo = static_cast<DraggableGizmo*>(sender());
|
||||
|
||||
@@ -54,11 +54,13 @@ public:
|
||||
|
||||
virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override;
|
||||
|
||||
virtual ShaderCode GetShaderCode(const ShaderRequest &request) const override;
|
||||
|
||||
static const QString kPointsInput;
|
||||
static const QString kColorInput;
|
||||
|
||||
protected:
|
||||
GenerateJob GetGenerateJob(const NodeValueRow &value) const;
|
||||
ShaderJob GetGenerateJob(const NodeValueRow &value) const;
|
||||
|
||||
protected slots:
|
||||
virtual void GizmoDragMove(double x, double y, const Qt::KeyboardModifiers &modifiers) override;
|
||||
|
||||
@@ -25,10 +25,14 @@ namespace olive {
|
||||
#define super ShapeNodeBase
|
||||
|
||||
QString ShapeNode::kTypeInput = QStringLiteral("type_in");
|
||||
QString ShapeNode::kRadiusInput = QStringLiteral("radius_in");
|
||||
|
||||
ShapeNode::ShapeNode()
|
||||
{
|
||||
PrependInput(kTypeInput, NodeValue::kCombo);
|
||||
|
||||
AddInput(kRadiusInput, NodeValue::kFloat, 20.0);
|
||||
SetInputProperty(kRadiusInput, QStringLiteral("min"), 0.0);
|
||||
}
|
||||
|
||||
QString ShapeNode::Name() const
|
||||
@@ -56,9 +60,10 @@ void ShapeNode::Retranslate()
|
||||
super::Retranslate();
|
||||
|
||||
SetInputName(kTypeInput, tr("Type"));
|
||||
SetInputName(kRadiusInput, tr("Radius"));
|
||||
|
||||
// Coordinate with Type enum
|
||||
SetComboBoxStrings(kTypeInput, {tr("Rectangle"), tr("Ellipse")});
|
||||
SetComboBoxStrings(kTypeInput, {tr("Rectangle"), tr("Ellipse"), tr("Rounded Rectangle")});
|
||||
}
|
||||
|
||||
ShaderCode ShapeNode::GetShaderCode(const ShaderRequest &request) const
|
||||
@@ -76,10 +81,23 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod
|
||||
|
||||
job.Insert(value);
|
||||
job.Insert(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this));
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetShaderID(QStringLiteral("shape"));
|
||||
|
||||
PushMergableJob(value, QVariant::fromValue(job), table);
|
||||
}
|
||||
|
||||
void ShapeNode::InputValueChangedEvent(const QString &input, int element)
|
||||
{
|
||||
if (input == kTypeInput) {
|
||||
InputFlags i = GetInputFlags(kRadiusInput);
|
||||
if (GetStandardValue(kTypeInput).toInt() == kRoundedRectangle) {
|
||||
i &= InputFlag(~kInputFlagHidden);
|
||||
} else {
|
||||
i |= kInputFlagHidden;
|
||||
}
|
||||
SetInputFlags(kRadiusInput, i);
|
||||
}
|
||||
super::InputValueChangedEvent(input, element);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ public:
|
||||
|
||||
enum Type {
|
||||
kRectangle,
|
||||
kEllipse
|
||||
kEllipse,
|
||||
kRoundedRectangle
|
||||
};
|
||||
|
||||
NODE_DEFAULT_FUNCTIONS(ShapeNode)
|
||||
@@ -49,6 +50,10 @@ public:
|
||||
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
|
||||
|
||||
static QString kTypeInput;
|
||||
static QString kRadiusInput;
|
||||
|
||||
protected:
|
||||
virtual void InputValueChangedEvent(const QString &input, int element) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ void TextGeneratorV1::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
{
|
||||
GenerateJob job;
|
||||
job.Insert(value);
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
|
||||
if (!job.Get(kTextInput).toString().isEmpty()) {
|
||||
table->Push(NodeValue::kTexture, QVariant::fromValue(job), this);
|
||||
|
||||
@@ -96,7 +96,6 @@ void TextGeneratorV2::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
{
|
||||
GenerateJob job;
|
||||
job.Insert(value);
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetRequestedFormat(VideoParams::kFormatFloat32);
|
||||
|
||||
if (!job.Get(kTextInput).toString().isEmpty()) {
|
||||
|
||||
@@ -38,6 +38,9 @@ enum TextVerticalAlign {
|
||||
};
|
||||
|
||||
const QString TextGeneratorV3::kTextInput = QStringLiteral("text_in");
|
||||
const QString TextGeneratorV3::kVerticalAlignmentInput = QStringLiteral("valign_in");
|
||||
const QString TextGeneratorV3::kUseArgsInput = QStringLiteral("use_args_in");
|
||||
const QString TextGeneratorV3::kArgsInput = QStringLiteral("args_in");
|
||||
|
||||
TextGeneratorV3::TextGeneratorV3() :
|
||||
ShapeNodeBase(false)
|
||||
@@ -47,8 +50,17 @@ TextGeneratorV3::TextGeneratorV3() :
|
||||
|
||||
SetStandardValue(kSizeInput, QVector2D(400, 300));
|
||||
|
||||
AddInput(kVerticalAlignmentInput, NodeValue::kCombo);
|
||||
|
||||
AddInput(kUseArgsInput, NodeValue::kBoolean, true, InputFlags(kInputFlagHidden | kInputFlagStatic));
|
||||
|
||||
AddInput(kArgsInput, NodeValue::kText, InputFlags(kInputFlagArray));
|
||||
SetInputProperty(kArgsInput, QStringLiteral("arraystart"), 1);
|
||||
|
||||
text_gizmo_ = new TextGizmo(this);
|
||||
text_gizmo_->SetInput(NodeInput(this, kTextInput));
|
||||
connect(text_gizmo_, &TextGizmo::Activated, this, &TextGeneratorV3::GizmoActivated);
|
||||
connect(text_gizmo_, &TextGizmo::Deactivated, this, &TextGeneratorV3::GizmoDeactivated);
|
||||
}
|
||||
|
||||
QString TextGeneratorV3::Name() const
|
||||
@@ -76,15 +88,32 @@ void TextGeneratorV3::Retranslate()
|
||||
super::Retranslate();
|
||||
|
||||
SetInputName(kTextInput, tr("Text"));
|
||||
SetInputName(kVerticalAlignmentInput, tr("Vertical Alignment"));
|
||||
SetComboBoxStrings(kVerticalAlignmentInput, {tr("Top"), tr("Middle"), tr("Bottom")});
|
||||
SetInputName(kArgsInput, tr("Arguments"));
|
||||
}
|
||||
|
||||
void TextGeneratorV3::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
{
|
||||
GenerateJob job;
|
||||
job.Insert(value);
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetRequestedFormat(VideoParams::kFormatUnsigned8);
|
||||
|
||||
if (value[kUseArgsInput].toBool()) {
|
||||
auto args = value[kArgsInput].toArray();
|
||||
if (!args.empty()) {
|
||||
QStringList list;
|
||||
list.reserve(args.size());
|
||||
for (int i=0; i<args.size(); i++) {
|
||||
list.append(args[i].toString());
|
||||
}
|
||||
|
||||
NodeValue v = job.Get(kTextInput);
|
||||
v.set_value(FormatString(v.toString(), list));
|
||||
job.Insert(kTextInput, v);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Provide user override for this
|
||||
job.SetColorspace(project()->color_manager()->GetDefaultInputColorSpace());
|
||||
|
||||
@@ -123,6 +152,18 @@ void TextGeneratorV3::GenerateFrame(FramePtr frame, const GenerateJob& job) cons
|
||||
p.translate(frame->video_params().width()/2, frame->video_params().height()/2);
|
||||
p.setClipRect(0, 0, size.x(), size.y());
|
||||
|
||||
switch (static_cast<VerticalAlignment>(job.Get(kVerticalAlignmentInput).toInt())) {
|
||||
case kVAlignTop:
|
||||
// Do nothing
|
||||
break;
|
||||
case kVAlignMiddle:
|
||||
p.translate(0, size.y()/2-text_doc.size().height()/2);
|
||||
break;
|
||||
case kVAlignBottom:
|
||||
p.translate(0, size.y()-text_doc.size().height());
|
||||
break;
|
||||
}
|
||||
|
||||
// Ensure default text color is white
|
||||
QAbstractTextDocumentLayout::PaintContext ctx;
|
||||
ctx.palette.setColor(QPalette::Text, Qt::white);
|
||||
@@ -139,4 +180,52 @@ void TextGeneratorV3::UpdateGizmoPositions(const NodeValueRow &row, const NodeGl
|
||||
text_gizmo_->SetHtml(row[kTextInput].toString());
|
||||
}
|
||||
|
||||
QString TextGeneratorV3::FormatString(const QString &input, const QStringList &args)
|
||||
{
|
||||
QString output;
|
||||
output.reserve(input.size());
|
||||
|
||||
for (int i=0; i<input.size(); i++) {
|
||||
const QChar &this_char = input.at(i);
|
||||
|
||||
if (i < input.size()-1 && this_char == '%') {
|
||||
const QChar &next_char = input.at(i+1);
|
||||
if (next_char == '%') {
|
||||
// Double percent, append a single percent
|
||||
output.append('%');
|
||||
i++;
|
||||
} else if (next_char.isDigit()) {
|
||||
// Find length of number
|
||||
QString num;
|
||||
i++;
|
||||
while (i < input.size() && input.at(i).isDigit()) {
|
||||
num.append(input.at(i));
|
||||
i++;
|
||||
}
|
||||
i--;
|
||||
int index = num.toInt()-1;
|
||||
if (index >= 0 && index < args.size()) {
|
||||
output.append(args.at(index));
|
||||
}
|
||||
} else {
|
||||
output.append(this_char);
|
||||
}
|
||||
} else {
|
||||
output.append(this_char);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void TextGeneratorV3::GizmoActivated()
|
||||
{
|
||||
SetStandardValue(kUseArgsInput, false);
|
||||
}
|
||||
|
||||
void TextGeneratorV3::GizmoDeactivated()
|
||||
{
|
||||
SetStandardValue(kUseArgsInput, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,11 +47,27 @@ public:
|
||||
|
||||
virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override;
|
||||
|
||||
enum VerticalAlignment
|
||||
{
|
||||
kVAlignTop,
|
||||
kVAlignMiddle,
|
||||
kVAlignBottom
|
||||
};
|
||||
|
||||
static const QString kTextInput;
|
||||
static const QString kVerticalAlignmentInput;
|
||||
static const QString kUseArgsInput;
|
||||
static const QString kArgsInput;
|
||||
|
||||
static QString FormatString(const QString &input, const QStringList &args);
|
||||
|
||||
private:
|
||||
TextGizmo *text_gizmo_;
|
||||
|
||||
private slots:
|
||||
void GizmoActivated();
|
||||
void GizmoDeactivated();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user