reimplemented polygon node on cpu
This is still incomplete, it's a little slow (like text is), gizmos aren't functional, and still no beziers, but hey it works again now
This commit is contained in:
@@ -21,8 +21,11 @@
|
||||
#include "polygon.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QPainterPath>
|
||||
#include <QVector2D>
|
||||
|
||||
#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<NodeValue> points = job.GetValue(kPointsInput).data().value< QVector<NodeValue> >();
|
||||
|
||||
if (!points.isEmpty()) {
|
||||
path.moveTo(points.first().data().value<QVector2D>().toPointF());
|
||||
|
||||
// TODO: Implement bezier
|
||||
for (int i=1; i<points.size(); i++) {
|
||||
path.lineTo(points.at(i).data().value<QVector2D>().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<Color>();
|
||||
#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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PolygonGenerator::HasGizmos() const
|
||||
|
||||
@@ -43,9 +43,10 @@ public:
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
virtual ShaderCode GetShaderCode(const QString& shader_id) const override;
|
||||
virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
|
||||
|
||||
virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const override;
|
||||
|
||||
virtual bool HasGizmos() const override;
|
||||
//virtual void DrawGizmos(NodeValueDatabase& db, QPainter *p) const override;
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
uniform vec2[256] points_in;
|
||||
uniform int points_in_count;
|
||||
uniform vec4 color_in;
|
||||
|
||||
uniform vec2 resolution_in;
|
||||
|
||||
varying vec2 ove_texcoord;
|
||||
|
||||
/*
|
||||
int pnpoly(int npol, float *xp, float *yp, float x, float y) {
|
||||
int i, j, c = 0;
|
||||
for (i = 0, j = npol-1; i < npol; j = i++) {
|
||||
if ((((yp[i] <= y) && (y < yp[j])) ||
|
||||
((yp[j] <= y) && (y < yp[i]))) &&
|
||||
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
|
||||
c = !c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
*/
|
||||
|
||||
bool pnpoly(vec2 p) {
|
||||
bool c = false;
|
||||
int i, j;
|
||||
for (i = 0, j = points_in_count-1; i < points_in_count; j = i++) {
|
||||
if ((((points_in[i].y <= p.y) && (p.y < points_in[j].y)) ||
|
||||
((points_in[j].y <= p.y) && (p.y < points_in[i].y))) &&
|
||||
(p.x < (points_in[j].x - points_in[i].x) * (p.y - points_in[i].y) / (points_in[j].y - points_in[i].y) + points_in[i].x))
|
||||
c = !c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
if (points_in_count > 0 && pnpoly(ove_texcoord * resolution_in)) {
|
||||
gl_FragColor = color_in;
|
||||
} else {
|
||||
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user