shape: add rounded rectangle

This commit is contained in:
itsmattkc
2022-08-09 11:49:11 -07:00
parent cc7893e7bc
commit 920a294387
3 changed files with 82 additions and 17 deletions
+20 -1
View File
@@ -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
@@ -81,4 +86,18 @@ void ShapeNode::Value(const NodeValueRow &value, const NodeGlobals &globals, Nod
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);
}
}
+6 -1
View File
@@ -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;
};
+56 -15
View File
@@ -3,14 +3,35 @@ in vec2 ove_texcoord;
out vec4 frag_color;
// Match with ShapeNode::Type
#define SHAPE_RECTANGLE 0
#define SHAPE_ELLIPSE 1
const int SHAPE_RECTANGLE = 0;
const int SHAPE_ELLIPSE = 1;
const int SHAPE_ROUNDEDRECT = 2;
uniform vec2 pos_in;
uniform vec2 size_in;
uniform int type_in;
uniform vec2 resolution_in;
uniform vec4 color_in;
uniform float radius_in;
vec4 draw_rect(vec2 real_position, vec2 real_size)
{
if (ove_texcoord.x >= real_position.x && ove_texcoord.y >= real_position.y
&& ove_texcoord.x < real_position.x+real_size.x && ove_texcoord.y < real_position.y+real_size.y) {
return color_in;
} else {
return vec4(0.0, 0.0, 0.0, 0.0);
}
}
vec4 draw_ellipse(vec2 center, float radius, float aspect_ratio) {
vec2 offset = ove_texcoord*resolution_in - center;
offset.x /= aspect_ratio;
float d = length(offset)-radius;
float t = clamp(d, 0.0, 1.0);
return color_in * (1.0-t);
}
void main() {
vec2 p = pos_in + resolution_in*0.5 - size_in*0.5;
@@ -20,22 +41,42 @@ void main() {
vec4 col = vec4(0.0);
if (type_in == SHAPE_RECTANGLE) {
if (ove_texcoord.x >= real_position.x && ove_texcoord.y >= real_position.y
&& ove_texcoord.x < real_position.x+real_size.x && ove_texcoord.y < real_position.y+real_size.y) {
col = color_in;
}
} else if (type_in == SHAPE_ELLIPSE) {
switch (type_in) {
case SHAPE_RECTANGLE:
{
col = draw_rect(real_position, real_size);
break;
}
case SHAPE_ELLIPSE:
{
vec2 center = p+size_in*0.5;
float radius = size_in.y*0.5;
float aspect_ratio = size_in.x/size_in.y;
vec2 offset = ove_texcoord*resolution_in - center;
offset.x /= aspect_ratio;
float d = length(offset)-radius;
float t = clamp(d, 0.0, 1.0);
col = color_in * (1.0-t);
col = draw_ellipse(center, radius, aspect_ratio);
break;
}
case SHAPE_ROUNDEDRECT:
{
// Limit radius so it is never larger than half the shortest size
float r = min(radius_in, min(size_in.y*0.5, size_in.x*0.5));
vec2 real_rad = vec2(r / resolution_in.x, r / resolution_in.y);
if (ove_texcoord.x < real_position.x + real_rad.x && ove_texcoord.y < real_position.y + real_rad.y) {
// Top-left
col = draw_ellipse(p + r, r, 1.0);
} else if (ove_texcoord.x > real_position.x+real_size.x - real_rad.x && ove_texcoord.y < real_position.y + real_rad.y) {
// Top-right
col = draw_ellipse(vec2(p.x + size_in.x - r, p.y + r), r, 1.0);
} else if (ove_texcoord.x < real_position.x + real_rad.x && ove_texcoord.y > real_position.y + real_size.y - real_rad.y) {
// Bottom-left
col = draw_ellipse(vec2(p.x + r, p.y + size_in.y - r), r, 1.0);
} else if (ove_texcoord.x > real_position.x+real_size.x - real_rad.x && ove_texcoord.y > real_position.y + real_size.y - real_rad.y) {
// Bottom-right
col = draw_ellipse(vec2(p.x + size_in.x - r, p.y + size_in.y - r), r, 1.0);
} else {
col = draw_rect(real_position, real_size);
}
break;
}
}
frag_color = col;