diff --git a/Extensions/PrimitiveDrawing/Extension.cpp b/Extensions/PrimitiveDrawing/Extension.cpp index 56b7529949..4f537dd768 100644 --- a/Extensions/PrimitiveDrawing/Extension.cpp +++ b/Extensions/PrimitiveDrawing/Extension.cpp @@ -28,7 +28,8 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) { .AddObject( "Drawer", //"Drawer" is kept for compatibility with GD<=3.6.76 _("Shape painter"), - _("Allows you to draw simple shapes on the screen using the events."), + _("Allows you to draw simple shapes on the screen using the " + "events."), "CppPlatform/Extensions/primitivedrawingicon.png") .SetCategoryFullName(_("Advanced")); @@ -783,5 +784,36 @@ void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension) { .AddParameter("expression", _("X drawing position")) .AddParameter("expression", _("Y drawing position")); + obj.AddAction("SetAntialiasing", + _("Anti-aliasing"), + _("Anti-aliasing"), + _("Set anti-aliasing of _PARAM0_ to _PARAM1_"), + _("Setup"), + "res/actions/antialiasing24.png", + "res/actions/antialiasing.png") + .AddParameter("object", _("Object"), "Drawer") + .AddParameter("stringWithSelector", + _("Anti-aliasing quality level"), + "[\"none\",\"low\",\"medium\",\"high\"]"); + + obj.AddCondition("CheckAntialiasing", + _("Anti-aliasing type"), + _("Checks the selected type of anti-aliasing"), + _("The anti-aliasing of _PARAM0_ is set to _PARAM1_"), + _("Setup"), + "res/actions/antialiasing24.png", + "res/actions/antialiasing.png") + .AddParameter("object", _("Object"), "Drawer") + .AddParameter("stringWithSelector", + _("Type of anti-aliasing to check the object against"), + "[\"none\",\"low\",\"medium\",\"high\"]"); + + obj.AddStrExpression("Antialiasing", + _("Type of anti-aliasing used by a shape painter"), + _("Returns the type of anti-aliasing in use: none, low, " + "medium, or high."), + _("Setup"), + "res/actions/antialiasing.png") + .AddParameter("object", _("Object"), "Drawer"); #endif } diff --git a/Extensions/PrimitiveDrawing/JsExtension.cpp b/Extensions/PrimitiveDrawing/JsExtension.cpp index f5e0a04e9f..bed83e9c57 100644 --- a/Extensions/PrimitiveDrawing/JsExtension.cpp +++ b/Extensions/PrimitiveDrawing/JsExtension.cpp @@ -4,12 +4,11 @@ GDevelop - Primitive Drawing Extension Copyright (c) 2008-2016 Florian Rival (Florian.Rival@gmail.com) This project is released under the MIT License. */ -#if defined(GD_IDE_ONLY) +#include + #include "GDCore/Extensions/PlatformExtension.h" #include "GDCore/Tools/Localization.h" -#include - void DeclarePrimitiveDrawingExtension(gd::PlatformExtension& extension); /** @@ -26,7 +25,9 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension { GetObjectMetadata("PrimitiveDrawing::Drawer") .SetIncludeFile( "Extensions/PrimitiveDrawing/shapepainterruntimeobject.js") - .AddIncludeFile("Extensions/PrimitiveDrawing/pixi-graphics-extras/graphics-extras.min.js") + .AddIncludeFile( + "Extensions/PrimitiveDrawing/pixi-graphics-extras/" + "graphics-extras.min.js") .AddIncludeFile( "Extensions/PrimitiveDrawing/" "shapepainterruntimeobject-pixi-renderer.js"); @@ -37,8 +38,7 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension { GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Circle"] .SetFunctionName("drawCircle"); - GetAllActionsForObject( - "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Line"] + GetAllActionsForObject("PrimitiveDrawing::Drawer")["PrimitiveDrawing::Line"] .SetFunctionName("drawLine"); GetAllActionsForObject( @@ -50,11 +50,9 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension { GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::RoundedRectangle"] .SetFunctionName("drawRoundedRectangle"); - GetAllActionsForObject( - "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Star"] + GetAllActionsForObject("PrimitiveDrawing::Drawer")["PrimitiveDrawing::Star"] .SetFunctionName("drawStar"); - GetAllActionsForObject( - "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Arc"] + GetAllActionsForObject("PrimitiveDrawing::Drawer")["PrimitiveDrawing::Arc"] .SetFunctionName("drawArc"); GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::BezierCurve"] @@ -93,10 +91,10 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension { GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::RoundedRectangle"] .SetFunctionName("drawRoundedRectangle"); - GetAllActionsForObject( - "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Star"] + GetAllActionsForObject("PrimitiveDrawing::Drawer")["PrimitiveDrawing::Star"] .SetFunctionName("drawStar"); - // These actions are not exposed yet as the way they work is unsure. See https://github.com/4ian/GDevelop/pull/1256 + // These actions are not exposed yet as the way they work is unsure. See + // https://github.com/4ian/GDevelop/pull/1256 /*GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::Arc"] .SetFunctionName("drawArc"); @@ -220,23 +218,27 @@ class PrimitiveDrawingJsExtension : public gd::PlatformExtension { GetAllActionsForObject( "PrimitiveDrawing::Drawer")["PrimitiveDrawing::SetRotationCenter"] .SetFunctionName("setRotationCenter"); - GetAllActionsForObject( - "PrimitiveDrawing::Drawer")["PrimitiveDrawing::SetRectangularCollisionMask"] - .SetFunctionName("setRectangularCollisionMask"); + GetAllActionsForObject("PrimitiveDrawing::Drawer") + ["PrimitiveDrawing::SetRectangularCollisionMask"] + .SetFunctionName("setRectangularCollisionMask"); - GetAllExpressionsForObject( - "PrimitiveDrawing::Drawer")["ToDrawingX"] + GetAllExpressionsForObject("PrimitiveDrawing::Drawer")["ToDrawingX"] .SetFunctionName("transformToDrawingX"); - GetAllExpressionsForObject( - "PrimitiveDrawing::Drawer")["ToDrawingY"] + GetAllExpressionsForObject("PrimitiveDrawing::Drawer")["ToDrawingY"] .SetFunctionName("transformToDrawingY"); - GetAllExpressionsForObject( - "PrimitiveDrawing::Drawer")["ToSceneX"] + GetAllExpressionsForObject("PrimitiveDrawing::Drawer")["ToSceneX"] .SetFunctionName("transformToSceneX"); - GetAllExpressionsForObject( - "PrimitiveDrawing::Drawer")["ToSceneY"] + GetAllExpressionsForObject("PrimitiveDrawing::Drawer")["ToSceneY"] .SetFunctionName("transformToSceneX"); + GetAllActionsForObject( + "PrimitiveDrawing::Drawer")["PrimitiveDrawing::SetAntialiasing"] + .SetFunctionName("setAntialiasing"); + GetAllStrExpressionsForObject("PrimitiveDrawing::Drawer")["Antialiasing"] + .SetFunctionName("getAntialiasing"); + GetAllConditionsForObject( + "PrimitiveDrawing::Drawer")["PrimitiveDrawing::CheckAntialiasing"] + .SetFunctionName("checkAntialiasing"); GD_COMPLETE_EXTENSION_COMPILATION_INFORMATION(); }; }; @@ -254,4 +256,3 @@ extern "C" gd::PlatformExtension* GD_EXTENSION_API CreateGDJSExtension() { return new PrimitiveDrawingJsExtension; } #endif -#endif diff --git a/Extensions/PrimitiveDrawing/ShapePainterObject.cpp b/Extensions/PrimitiveDrawing/ShapePainterObject.cpp index 95b1704cb5..2462d6ebca 100644 --- a/Extensions/PrimitiveDrawing/ShapePainterObject.cpp +++ b/Extensions/PrimitiveDrawing/ShapePainterObject.cpp @@ -14,10 +14,6 @@ This project is released under the MIT License. #include "GDCore/Serialization/SerializerElement.h" #include "GDCore/Tools/Localization.h" -#if defined(GD_IDE_ONLY) -#include "GDCore/CommonTools.h" -#endif - using namespace std; ShapePainterObjectBase::ShapePainterObjectBase() @@ -31,7 +27,8 @@ ShapePainterObjectBase::ShapePainterObjectBase() outlineColorB(0), outlineOpacity(255), clearBetweenFrames(true), - absoluteCoordinates(false) {} + absoluteCoordinates(false), + antialiasing("none") {} ShapePainterObject::ShapePainterObject() {} @@ -67,6 +64,10 @@ void ShapePainterObjectBase::DoUnserializeFrom( element.HasChild("clearBetweenFrames") ? element.GetChild("clearBetweenFrames").GetValue().GetBool() : true; + + antialiasing = element.HasChild("antialiasing") + ? element.GetChild("antialiasing").GetValue().GetString() + : "none"; } void ShapePainterObject::DoUnserializeFrom( @@ -74,7 +75,6 @@ void ShapePainterObject::DoUnserializeFrom( ShapePainterObjectBase::DoUnserializeFrom(project, element); } -#if defined(GD_IDE_ONLY) void ShapePainterObjectBase::DoSerializeTo( gd::SerializerElement& element) const { element.AddChild("fillOpacity").SetValue(fillOpacity); @@ -90,12 +90,12 @@ void ShapePainterObjectBase::DoSerializeTo( .SetAttribute("b", (int)outlineColorB); element.AddChild("absoluteCoordinates").SetValue(absoluteCoordinates); element.AddChild("clearBetweenFrames").SetValue(clearBetweenFrames); + element.AddChild("antialiasing").SetValue(antialiasing); } void ShapePainterObject::DoSerializeTo(gd::SerializerElement& element) const { ShapePainterObjectBase::DoSerializeTo(element); } -#endif /** * Change the color filter of the sprite object diff --git a/Extensions/PrimitiveDrawing/ShapePainterObject.h b/Extensions/PrimitiveDrawing/ShapePainterObject.h index aa842835bf..4f937357a8 100644 --- a/Extensions/PrimitiveDrawing/ShapePainterObject.h +++ b/Extensions/PrimitiveDrawing/ShapePainterObject.h @@ -60,12 +60,13 @@ class GD_EXTENSION_API ShapePainterObjectBase { inline void SetClearBetweenFrames(bool value) { clearBetweenFrames = value; } inline bool IsClearedBetweenFrames() { return clearBetweenFrames; } + inline gd::String GetAntialiasing() { return antialiasing; } + inline void SetAntialiasing(const gd::String& value) { antialiasing = value; } + protected: virtual void DoUnserializeFrom(gd::Project& project, const gd::SerializerElement& element); -#if defined(GD_IDE_ONLY) virtual void DoSerializeTo(gd::SerializerElement& element) const; -#endif private: // Fill color @@ -83,6 +84,9 @@ class GD_EXTENSION_API ShapePainterObjectBase { bool absoluteCoordinates; bool clearBetweenFrames; + + // Antialiasing + gd::String antialiasing; }; /** @@ -100,10 +104,7 @@ class GD_EXTENSION_API ShapePainterObject : public gd::ObjectConfiguration, private: virtual void DoUnserializeFrom(gd::Project& project, const gd::SerializerElement& element); -#if defined(GD_IDE_ONLY) virtual void DoSerializeTo(gd::SerializerElement& element) const; - -#endif }; #endif // SHAPEPAINTEROBJECT_H diff --git a/Extensions/PrimitiveDrawing/shapepainterruntimeobject-pixi-renderer.ts b/Extensions/PrimitiveDrawing/shapepainterruntimeobject-pixi-renderer.ts index 690a996d1f..00da25624e 100644 --- a/Extensions/PrimitiveDrawing/shapepainterruntimeobject-pixi-renderer.ts +++ b/Extensions/PrimitiveDrawing/shapepainterruntimeobject-pixi-renderer.ts @@ -20,6 +20,8 @@ namespace gdjs { */ _transformationIsUpToDate = false; + _antialiasingFilter: null | PIXI.Filter = null; + private static readonly _positionForTransformation: PIXI.IPointData = { x: 0, y: 0, @@ -35,6 +37,7 @@ namespace gdjs { .getLayer('') .getRenderer() .addRendererObject(this._graphics, runtimeObject.getZOrder()); + this.updateAntialiasing(); } getRendererObject() { @@ -485,6 +488,39 @@ namespace gdjs { point[1] = position.y; return point; } + + updateAntialiasing(): void { + if (this._object.getAntialiasing() !== 'none') { + if (!this._antialiasingFilter) { + this._antialiasingFilter = new PIXI.filters.FXAAFilter(); + } + + const antialiasingFilter = this._antialiasingFilter; + antialiasingFilter.enabled = true; + antialiasingFilter.multisample = + PIXI.MSAA_QUALITY[this._object.getAntialiasing().toUpperCase()] || + PIXI.MSAA_QUALITY.LOW; + + if (!this._graphics.filters) { + this._graphics.filters = []; + } + // Do not apply the filter if it is already present on the object. + if (this._graphics.filters.indexOf(antialiasingFilter) === -1) { + this._graphics.filters.push(antialiasingFilter); + } + } else if (this._antialiasingFilter !== null) { + if (!this._graphics.filters) { + return; + } + const antialiasingFilterIndex = this._graphics.filters.indexOf( + this._antialiasingFilter + ); + + if (antialiasingFilterIndex !== -1) { + this._graphics.filters.splice(antialiasingFilterIndex, 1); + } + } + } } export const ShapePainterRuntimeObjectRenderer = ShapePainterRuntimeObjectPixiRenderer; diff --git a/Extensions/PrimitiveDrawing/shapepainterruntimeobject.ts b/Extensions/PrimitiveDrawing/shapepainterruntimeobject.ts index ef0b168b08..308f62f6bd 100644 --- a/Extensions/PrimitiveDrawing/shapepainterruntimeobject.ts +++ b/Extensions/PrimitiveDrawing/shapepainterruntimeobject.ts @@ -13,6 +13,8 @@ namespace gdjs { b: integer; }; + export type Antialiasing = 'none' | 'low' | 'medium' | 'high'; + /** Initial properties for a for {@link gdjs.ShapePainterRuntimeObject}. */ export type ShapePainterObjectDataType = { /** The color (in RGB format) of the inner part of the painted shape */ @@ -29,6 +31,8 @@ namespace gdjs { absoluteCoordinates: boolean; /** Clear the previous render before the next draw? */ clearBetweenFrames: boolean; + /** The type of anti-aliasing to apply at rendering. */ + antialiasing: Antialiasing; }; export type ShapePainterObjectData = ObjectData & ShapePainterObjectDataType; @@ -52,6 +56,7 @@ namespace gdjs { _outlineSize: float; _useAbsoluteCoordinates: boolean; _clearBetweenFrames: boolean; + _antialiasing: Antialiasing; _renderer: gdjs.ShapePainterRuntimeObjectRenderer; private static readonly _pointForTransformation: FloatPoint = [0, 0]; @@ -86,6 +91,7 @@ namespace gdjs { this._outlineSize = shapePainterObjectData.outlineSize; this._useAbsoluteCoordinates = shapePainterObjectData.absoluteCoordinates; this._clearBetweenFrames = shapePainterObjectData.clearBetweenFrames; + this._antialiasing = shapePainterObjectData.antialiasing; this._renderer = new gdjs.ShapePainterRuntimeObjectRenderer( this, instanceContainer @@ -337,6 +343,19 @@ namespace gdjs { return this._clearBetweenFrames; } + setAntialiasing(value: Antialiasing): void { + this._antialiasing = value; + this._renderer.updateAntialiasing(); + } + + getAntialiasing(): Antialiasing { + return this._antialiasing; + } + + checkAntialiasing(valueToCompare: Antialiasing): boolean { + return this._antialiasing === valueToCompare; + } + setCoordinatesRelative(value: boolean): void { this._useAbsoluteCoordinates = !value; } diff --git a/Extensions/PrimitiveDrawing/tests/shapepainterruntimeobject.pixiruntimegamewithassets.spec.js b/Extensions/PrimitiveDrawing/tests/shapepainterruntimeobject.pixiruntimegamewithassets.spec.js index b994c5a012..6cc9a911b3 100644 --- a/Extensions/PrimitiveDrawing/tests/shapepainterruntimeobject.pixiruntimegamewithassets.spec.js +++ b/Extensions/PrimitiveDrawing/tests/shapepainterruntimeobject.pixiruntimegamewithassets.spec.js @@ -18,6 +18,7 @@ describe('gdjs.ShapePainterRuntimeObject (using a PixiJS RuntimeGame with assets outlineSize: 1, absoluteCoordinates: false, clearBetweenFrames: false, + antialiasing: 'low', }); /** @param {gdjs.RuntimeScene} runtimeScene */ diff --git a/GDevelop.js/Bindings/Bindings.idl b/GDevelop.js/Bindings/Bindings.idl index 87af573ec5..aff565307f 100644 --- a/GDevelop.js/Bindings/Bindings.idl +++ b/GDevelop.js/Bindings/Bindings.idl @@ -3071,6 +3071,9 @@ interface ShapePainterObject { unsigned long GetFillColorR(); unsigned long GetFillColorG(); unsigned long GetFillColorB(); + [Const, Value] DOMString GetAntialiasing(); + void SetAntialiasing([Const] DOMString value); + }; ShapePainterObject implements ObjectConfiguration; diff --git a/GDevelop.js/types/gdshapepainterobject.js b/GDevelop.js/types/gdshapepainterobject.js index 131df9ccc3..c4f7af1799 100644 --- a/GDevelop.js/types/gdshapepainterobject.js +++ b/GDevelop.js/types/gdshapepainterobject.js @@ -20,6 +20,8 @@ declare class gdShapePainterObject extends gdObjectConfiguration { getFillColorR(): number; getFillColorG(): number; getFillColorB(): number; + getAntialiasing(): string; + setAntialiasing(value: string): void; delete(): void; ptr: number; }; \ No newline at end of file diff --git a/newIDE/app/public/res/actions/antialiasing.png b/newIDE/app/public/res/actions/antialiasing.png new file mode 100644 index 0000000000..82cf5c66e7 Binary files /dev/null and b/newIDE/app/public/res/actions/antialiasing.png differ diff --git a/newIDE/app/public/res/actions/antialiasing24.png b/newIDE/app/public/res/actions/antialiasing24.png new file mode 100644 index 0000000000..e2d3c9007d Binary files /dev/null and b/newIDE/app/public/res/actions/antialiasing24.png differ diff --git a/newIDE/app/public/res/antialiasing.png b/newIDE/app/public/res/antialiasing.png new file mode 100644 index 0000000000..82cf5c66e7 Binary files /dev/null and b/newIDE/app/public/res/antialiasing.png differ diff --git a/newIDE/app/public/res/antialiasing24.png b/newIDE/app/public/res/antialiasing24.png new file mode 100644 index 0000000000..e2d3c9007d Binary files /dev/null and b/newIDE/app/public/res/antialiasing24.png differ diff --git a/newIDE/app/src/ObjectEditor/Editors/ShapePainterEditor.js b/newIDE/app/src/ObjectEditor/Editors/ShapePainterEditor.js index 82d20cd2e5..76e41862c1 100644 --- a/newIDE/app/src/ObjectEditor/Editors/ShapePainterEditor.js +++ b/newIDE/app/src/ObjectEditor/Editors/ShapePainterEditor.js @@ -1,5 +1,5 @@ // @flow -import { Trans } from '@lingui/macro'; +import { t, Trans } from '@lingui/macro'; import * as React from 'react'; import Checkbox from '../../UI/Checkbox'; @@ -11,6 +11,8 @@ import { import { type EditorProps } from './EditorProps.flow'; import SemiControlledTextField from '../../UI/SemiControlledTextField'; import { ResponsiveLineStackLayout, ColumnStackLayout } from '../../UI/Layout'; +import SelectField from '../../UI/SelectField'; +import SelectOption from '../../UI/SelectOption'; const gd = global.gd; export default class PanelSpriteEditor extends React.Component< @@ -133,6 +135,29 @@ export default class PanelSpriteEditor extends React.Component< }} /> + + Anti-aliasing} + value={shapePainterConfiguration.getAntialiasing()} + onChange={(e, i, valueString: string) => { + shapePainterConfiguration.setAntialiasing(valueString); + this.forceUpdate(); + }} + > + + + + + + ); }