diff --git a/app/node/generator/polygon/polygon.cpp b/app/node/generator/polygon/polygon.cpp index c246b6f94..0ebdd826e 100644 --- a/app/node/generator/polygon/polygon.cpp +++ b/app/node/generator/polygon/polygon.cpp @@ -21,8 +21,11 @@ #include "polygon.h" #include +#include #include +#include "common/cpuoptimize.h" + namespace olive { const QString PolygonGenerator::kPointsInput = QStringLiteral("points_in"); @@ -36,16 +39,16 @@ PolygonGenerator::PolygonGenerator() // The Default Pentagon(tm) InputArrayResize(kPointsInput, 5); - SetSplitStandardValueOnTrack(kPointsInput, 0, 960, 0); - SetSplitStandardValueOnTrack(kPointsInput, 1, 240, 0); - SetSplitStandardValueOnTrack(kPointsInput, 0, 640, 1); - SetSplitStandardValueOnTrack(kPointsInput, 1, 480, 1); - SetSplitStandardValueOnTrack(kPointsInput, 0, 760, 2); - SetSplitStandardValueOnTrack(kPointsInput, 1, 800, 2); - SetSplitStandardValueOnTrack(kPointsInput, 0, 1100, 3); - SetSplitStandardValueOnTrack(kPointsInput, 1, 800, 3); - SetSplitStandardValueOnTrack(kPointsInput, 0, 1200, 4); - SetSplitStandardValueOnTrack(kPointsInput, 1, 480, 4); + SetSplitStandardValueOnTrack(kPointsInput, 0, 0, 0); + SetSplitStandardValueOnTrack(kPointsInput, 1, -146, 0); + SetSplitStandardValueOnTrack(kPointsInput, 0, -142, 1); + SetSplitStandardValueOnTrack(kPointsInput, 1, -45, 1); + SetSplitStandardValueOnTrack(kPointsInput, 0, -87, 2); + SetSplitStandardValueOnTrack(kPointsInput, 1, 123, 2); + SetSplitStandardValueOnTrack(kPointsInput, 0, 87, 3); + SetSplitStandardValueOnTrack(kPointsInput, 1, 123, 3); + SetSplitStandardValueOnTrack(kPointsInput, 0, 142, 4); + SetSplitStandardValueOnTrack(kPointsInput, 1, -44, 4); } Node *PolygonGenerator::copy() const @@ -79,22 +82,75 @@ void PolygonGenerator::Retranslate() SetInputName(kColorInput, tr("Color")); } -ShaderCode PolygonGenerator::GetShaderCode(const QString &shader_id) const -{ - Q_UNUSED(shader_id) - - return ShaderCode(FileFunctions::ReadFileAsString(QStringLiteral(":/shaders/polygon.frag"))); -} - void PolygonGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const { - ShaderJob job; + GenerateJob job; job.InsertValue(value); - job.InsertValue(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this)); + job.SetRequestedFormat(VideoParams::kFormatFloat32); job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn); - table->Push(NodeValue::kShaderJob, QVariant::fromValue(job), this); + table->Push(NodeValue::kGenerateJob, QVariant::fromValue(job), this); +} + +void PolygonGenerator::GenerateFrame(FramePtr frame, const GenerateJob &job) const +{ + // This could probably be more optimized, but for now we use Qt to draw to a QImage. + // 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); + img.fill(Qt::transparent); + + QPainterPath path; + + QVector points = job.GetValue(kPointsInput).data().value< QVector >(); + + if (!points.isEmpty()) { + path.moveTo(points.first().data().value().toPointF()); + + // TODO: Implement bezier + for (int i=1; i().toPointF()); + } + } + + QPainter p(&img); + double par = frame->video_params().pixel_aspect_ratio().toDouble(); + p.scale(1.0 / frame->video_params().divider() / par, 1.0 / frame->video_params().divider()); + p.translate(frame->video_params().width()/2 * par, frame->video_params().height()/2); + p.setBrush(Qt::white); + p.setPen(Qt::NoPen); + + p.drawPath(path); + + // Transplant alpha channel to frame + Color rgba = job.GetValue(kColorInput).data().value(); +#if defined(Q_PROCESSOR_X86) || defined(Q_PROCESSOR_ARM) + __m128 sse_color = _mm_loadu_ps(rgba.data()); +#endif + + float *frame_dst = reinterpret_cast(frame->data()); + for (int y=0; yheight(); y++) { + uchar *src_y = img.bits() + img.bytesPerLine() * y; + float *dst_y = frame_dst + y*frame->linesize_pixels()*VideoParams::kRGBAChannelCount; + + for (int x=0; xwidth(); 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 0 && pnpoly(ove_texcoord * resolution_in)) { - gl_FragColor = color_in; - } else { - gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); - } -}