/**************************************************************************************/ /* */ /* Visualization Library */ /* http://visualizationlibrary.org */ /* */ /* Copyright (c) 2005-2020, Michele Bosi */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, this */ /* list of conditions and the following disclaimer. */ /* */ /* - Redistributions in binary form must reproduce the above copyright notice, this */ /* list of conditions and the following disclaimer in the documentation and/or */ /* other materials provided with the distribution. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /**************************************************************************************/ #ifndef VectorGraphics_INCLUDE_ONCE #define VectorGraphics_INCLUDE_ONCE #include #include #include #include #include #include #include #include #include #include #include #include namespace vl { //! Defines how the texture is applied to the rendering primitive typedef enum { //! The texture is stretched over the primitive TextureMode_Clamp, //! The texture is repeated over the primitive TextureMode_Repeat } ETextureMode; //! Poligon stipple patterns typedef enum { //! The poligon is completely filled (default) PolygonStipple_Solid, PolygonStipple_Dot, PolygonStipple_Chain, PolygonStipple_HLine, PolygonStipple_VLine } EPolygonStipple; //! Line stipple patterns typedef enum { //! The line is completely filled (default) LineStipple_Solid, LineStipple_Dot, LineStipple_Dash, LineStipple_Dash4, LineStipple_Dash8, LineStipple_DashDot, LineStipple_DashDotDot } ELineStipple; //------------------------------------------------------------------------------------------------------------------------------------------- // VectorGraphics //------------------------------------------------------------------------------------------------------------------------------------------- /** * The VectorGraphics class is used in conjuction with SceneManagerVectorGraphics to generate and render 2D vector graphics. * The VectorGraphics object is basically nothing more than an container of Actor[s] generated by functions like * drawLines(), fillTriangles() etc. The Actor[s] are rendered in the order in which they are generated. * * The VectorGraphics class features a set of advanced capabilites: * - Matrix transformations and matrix stack * - State stack * - All the blending operations supported by OpenGL * - All the stencil operations supported by OpenGL * - Texture mapping on all the primitives with automatic texture coordinate generation * - Several primitives like lines, points, quads, triangles, line strips, triangle strips, ellipses etc. * - Polygon and line stipple * - Text rendering * - Scissor test to clip the objects against a rectangular region * - Line and point smoothing * - Color logic operations * * For more information please refer to the \ref pagGuideVectorGraphics "2D Vector Graphics" page. */ class VLVG_EXPORT VectorGraphics: public Object { VL_INSTRUMENT_CLASS(vl::VectorGraphics, Object) private: //------------------------------------------------------------------------- start internal //! \internal class ImageState { public: ImageState(const Image* img, ETextureMode mode): mImage(img), mTextureMode(mode) {} bool operator<(const ImageState& other) const { if (mImage != other.mImage) return mImage < other.mImage; else if (mTextureMode != other.mTextureMode) return mTextureMode < other.mTextureMode; else return false; } protected: const Image* mImage; ETextureMode mTextureMode; }; //------------------------------------------------------------------------- start internal //! \internal class State { public: State() { mColor = white; mPointSize = 5; mImage = NULL; mTextureMode = TextureMode_Clamp; mLogicOp = LO_COPY; mPointSmoothing= true; mLineSmoothing = true; mPolygonSmoothing = false; mLineWidth = 1.0; mLineStipple = 0xFFFF; memset(mPolyStipple, 0xFF, 32*32/8); // blend equation mBlendEquationRGB = BE_FUNC_ADD; mBlendEquationAlpha = BE_FUNC_ADD; // blend factor mBlendFactorSrcRGB = BF_SRC_ALPHA; mBlendFactorDstRGB = BF_ONE_MINUS_SRC_ALPHA; mBlendFactorSrcAlpha = BF_SRC_ALPHA; mBlendFactorDstAlpha = BF_ONE_MINUS_SRC_ALPHA; // alpha func mAlphaFuncRefValue = 0.0f; mAlphaFunc = FU_ALWAYS; // font mFont = defFontManager()->acquireFont("/font/bitstream-vera/VeraMono.ttf", 10, false); // masks /*mDepthMask = true;*/ mColorMask = ivec4(1,1,1,1); // stencil mStencilMask = 0xFFFFFFFF; mStencilTestEnabled = false; mStencil_SFail = SO_KEEP; mStencil_SFail = SO_KEEP; mStencil_DpFail = SO_KEEP; mStencil_Function = FU_ALWAYS; mStencil_RefValue = 0; mStencil_FunctionMask = ~(unsigned int)0; } fvec4 mColor; int mPointSize; ref mImage; ETextureMode mTextureMode; ELogicOp mLogicOp; float mLineWidth; bool mPointSmoothing; bool mLineSmoothing; bool mPolygonSmoothing; unsigned short mLineStipple; unsigned char mPolyStipple[32*32/8]; EBlendEquation mBlendEquationRGB; EBlendEquation mBlendEquationAlpha; EBlendFactor mBlendFactorSrcRGB; EBlendFactor mBlendFactorDstRGB; EBlendFactor mBlendFactorSrcAlpha; EBlendFactor mBlendFactorDstAlpha; float mAlphaFuncRefValue; EFunction mAlphaFunc; ref mFont; /*bool mDepthMask;*/ ivec4 mColorMask; // stencil bool mStencilTestEnabled; unsigned int mStencilMask; EStencilOp mStencil_SFail; EStencilOp mStencil_DpFail; EStencilOp mStencil_DpPass; EFunction mStencil_Function; int mStencil_RefValue; unsigned int mStencil_FunctionMask; bool operator<(const State& other) const { // lexicographic sorting if (mColor.r() != other.mColor.r()) return mColor.r() < other.mColor.r(); else if (mColor.g() != other.mColor.g()) return mColor.g() < other.mColor.g(); else if (mColor.b() != other.mColor.b()) return mColor.b() < other.mColor.b(); else if (mColor.a() != other.mColor.a()) return mColor.a() < other.mColor.a(); else if(mPointSize != other.mPointSize) return mPointSize < other.mPointSize; else if(mImage != other.mImage) return mImage < other.mImage; else if (mTextureMode != other.mTextureMode) return mTextureMode < other.mTextureMode; else if (mPolygonSmoothing != other.mPolygonSmoothing) return mPolygonSmoothing < other.mPolygonSmoothing; else if (mPointSmoothing!= other.mPointSmoothing) return mPointSmoothing < other.mPointSmoothing; else if (mLineSmoothing!= other.mLineSmoothing) return mLineSmoothing < other.mLineSmoothing; else if (mLineWidth != other.mLineWidth) return mLineWidth < other.mLineWidth; else if (mLineStipple != other.mLineStipple) return mLineStipple < other.mLineStipple; else if (mLogicOp != other.mLogicOp) return mLogicOp < other.mLogicOp; else if ( memcmp(mPolyStipple, other.mPolyStipple, 32*32/8) != 0 ) return memcmp(mPolyStipple, other.mPolyStipple, 32*32/8) < 0; else if ( mBlendEquationRGB != other.mBlendEquationRGB) return mBlendEquationRGB < other.mBlendEquationRGB; else if ( mBlendEquationAlpha != other.mBlendEquationAlpha) return mBlendEquationAlpha < other.mBlendEquationAlpha; else if ( mBlendFactorSrcRGB != other.mBlendFactorSrcRGB) return mBlendFactorSrcRGB < other.mBlendFactorSrcRGB; else if ( mBlendFactorDstRGB != other.mBlendFactorDstRGB) return mBlendFactorDstRGB < other.mBlendFactorDstRGB; else if ( mBlendFactorSrcAlpha != other.mBlendFactorSrcAlpha) return mBlendFactorSrcAlpha < other.mBlendFactorSrcAlpha; else if ( mBlendFactorDstAlpha != other.mBlendFactorDstAlpha) return mBlendFactorDstAlpha < other.mBlendFactorDstAlpha; else if ( mAlphaFuncRefValue != other.mAlphaFuncRefValue) return mAlphaFuncRefValue < other.mAlphaFuncRefValue; else if ( mAlphaFunc != other.mAlphaFunc) return mAlphaFunc < other.mAlphaFunc; else if ( mFont != other.mFont) return mFont < other.mFont; else /*if ( mDepthMask != other.mDepthMask) return mDepthMask < other.mDepthMask; else*/ if ( mColorMask.r() != other.mColorMask.r()) return mColorMask.r() < other.mColorMask.r(); else if ( mColorMask.g() != other.mColorMask.g()) return mColorMask.g() < other.mColorMask.g(); else if ( mColorMask.b() != other.mColorMask.b()) return mColorMask.b() < other.mColorMask.b(); else if ( mColorMask.a() != other.mColorMask.a()) return mColorMask.a() < other.mColorMask.a(); else if ( mStencilMask != other.mStencilMask) return mStencilMask < other.mStencilMask; else if ( mStencilTestEnabled != other.mStencilTestEnabled) return mStencilTestEnabled < other.mStencilTestEnabled; else if ( mStencil_SFail != other.mStencil_SFail ) return mStencil_SFail < other.mStencil_SFail; else if ( mStencil_DpFail != other.mStencil_DpFail ) return mStencil_DpFail < other.mStencil_DpFail; else if ( mStencil_DpPass != other.mStencil_DpPass ) return mStencil_DpPass < other.mStencil_DpPass; else if ( mStencil_Function != other.mStencil_Function ) return mStencil_Function < other.mStencil_Function; else if ( mStencil_RefValue != other.mStencil_RefValue ) return mStencil_RefValue < other.mStencil_RefValue; else if ( mStencil_FunctionMask != other.mStencil_FunctionMask ) return mStencil_FunctionMask < other.mStencil_FunctionMask; else return false; } }; //------------------------------------------------------------------------- end internal public: VectorGraphics(); //! Returns the list of Actor[s] generated by a VectorGraphics object. const ActorCollection* actors() const { return &mActors; } //! Returns the list of Actor[s] generated by a VectorGraphics object. ActorCollection* actors() { return &mActors; } //! Renders a line starting a point and ending at point Actor* drawLine(double x1, double y1, double x2, double y2); //! Renders a set of lines. The 'ln' parameter shoud contain N pairs of dvec2. Each pair defines a line segment. Actor* drawLines(const std::vector& ln); //! Renders a line passing through the points defined by 'ln'. Actor* drawLineStrip(const std::vector& ln); //! Renders a closed line passing through the points defined by 'ln'. Actor* drawLineLoop(const std::vector& ln); //! Renders a convex polygon whose corners are defined by 'poly' Actor* fillPolygon(const std::vector& poly); //! Renders a set of triangles. The 'triangles' parameters must contain N triplets of dvec2. Each triplet defines a triangle. Actor* fillTriangles(const std::vector& triangles); //! Renders a triangle fan. Actor* fillTriangleFan(const std::vector& fan); //! Renders a strip of triangles as defined by the OpenGL primitive GL_TRIANGLE_STRIP. Actor* fillTriangleStrip(const std::vector& strip); //! Renders a set of rectangles as defined by the OpenGL primitive GL_QUADS Actor* fillQuads(const std::vector& quads); //! Renders a set of rectangles as defined by the OpenGL primitive GL_QUAD_STRIP Actor* fillQuadStrip(const std::vector& quad_strip); //! Renders a single point. This is only an utility function. If you want to draw many points use drawPoints(const std::vector& pt) instead. Actor* drawPoint(double x, double y); //! Renders a set of points using the currently set pointSize(), color() and image(). Actor* drawPoints(const std::vector& pt); //! Renders the outline of an ellipse. Actor* drawEllipse(double origx, double origy, double xaxis, double yaxis, int segments = 64); //! Renders an ellipse. Actor* fillEllipse(double origx, double origy, double xaxis, double yaxis, int segments = 64); //! Utility function that renders the outline of a quad. Actor* drawQuad(double left, double bottom, double right, double top); //! Utility function that renders a single quad. Actor* fillQuad(double left, double bottom, double right, double top); /** Starts the drawing process. You have to call this function before calling any of the fill* and draw* functions. * This function will erase all the previously generated content of the VectorGraphics. */ void startDrawing() { clear(); } /** Continues the rendering on a VectorGraphics object. This function will reset the VectorGraphics state and matrix but will not * erase the previously generated graphics. */ void continueDrawing(); //! Ends the rendering on a VectorGraphics and releases the resources used during the Actor generation process. //! If you intend to continue the rendering or to add new graphics objects later set 'release_cache' to false. void endDrawing(bool release_cache=true); //! Resets the VectorGraphics removing all the graphics objects and resetting its internal state. void clear(); //! The current color. Note that the current color also modulates the currently active image. void setColor(const fvec4& color) { mState.mColor = color; } //! The current color. Note that the current color also modulates the currently active image. const fvec4& color() const { return mState.mColor; } //! The current point size void setPointSize(int size) { mState.mPointSize = size; } //! The current point size int pointSize() const { return mState.mPointSize; } //! The current image used to texture the rendered objects. Note that the current color also modulates the currently active image. void setImage(Image* image) { mState.mImage = image; } //! The current image used to texture the rendered objects. Note that the current color also modulates the currently active image. const Image* image() const { return mState.mImage.get(); } //! The current image used to texture the rendered objects. Note that the current color also modulates the currently active image. Image* image() { return mState.mImage.get(); } //! Utility function equivalent to 'setImage(image); setPointSize(image->width());' void setPoint(Image* image) { setImage(image); setPointSize(image->width()); } //! The current texture mode void setTextureMode(ETextureMode mode) { mState.mTextureMode = mode; } //! The current texture mode ETextureMode textureMode() const { return mState.mTextureMode; } //! The current logic operation, see also http://www.opengl.org/sdk/docs/man/xhtml/glLogicOp.xml for more information. void setLogicOp(ELogicOp op) { mState.mLogicOp = op; } //! The current logic operation ELogicOp logicOp() const { return mState.mLogicOp; } //! The current line width, see also http://www.opengl.org/sdk/docs/man/xhtml/glLineWidth.xml for more information. void setLineWidth(float width) { mState.mLineWidth = width; } //! The current line width float lineWidth() const { return mState.mLineWidth; } //! The current point smoothing mode void setPointSmoothing(bool smooth) { mState.mPointSmoothing = smooth; } //! The current point smoothing mode bool pointSmoothing() const { return mState.mPointSmoothing; } //! The current line smoothing mode void setLineSmoothing(bool smooth) { mState.mLineSmoothing = smooth; } //! The current line smoothing mode bool lineSmoothing() const { return mState.mLineSmoothing; } //! The current polygon smoothing mode void setPolygonSmoothing(bool smooth) { mState.mPolygonSmoothing = smooth; } //! The current polygon smoothing mode bool polygonSmoothing() const { return mState.mPolygonSmoothing; } //! The current line stipple, see also http://www.opengl.org/sdk/docs/man/xhtml/glLineStipple.xml for more information. void setLineStipple(ELineStipple stipple) ; //! The current line stipple void setLineStipple(unsigned short stipple) { mState.mLineStipple = stipple; } //! The current line stipple unsigned short lineStipple() const { return mState.mLineStipple; } //! The current polygon stipple, see also http://www.opengl.org/sdk/docs/man/xhtml/glPolygonStipple.xml for more information. void setPolygonStipple(EPolygonStipple stipple); //! The current polygon stipple void setPolygonStipple(unsigned char* stipple) { memcpy(mState.mPolyStipple, stipple, 32*32/8); } //! The current polygon stipple const unsigned char* polygonStipple() const { return mState.mPolyStipple; } //! The current polygon stipple unsigned char* polygonStipple() { return mState.mPolyStipple; } //! The current alpha function, see also http://www.opengl.org/sdk/docs/man/xhtml/glAlphaFunc.xml for more information. void setAlphaFunc(EFunction func, float ref_value) { mState.mAlphaFuncRefValue=ref_value; mState.mAlphaFunc=func; } //! The current alpha function void getAlphaFunc(EFunction& func, float& ref_value) const { ref_value=mState.mAlphaFuncRefValue; func=mState.mAlphaFunc; } //! The current blending factor, see also http://www.opengl.org/sdk/docs/man/xhtml/glBlendFunc.xml for more information. void setBlendFunc(EBlendFactor src_rgb, EBlendFactor dst_rgb, EBlendFactor src_alpha, EBlendFactor dst_alpha); //! The current blending factor void getBlendFunc(EBlendFactor& src_rgb, EBlendFactor& dst_rgb, EBlendFactor& src_alpha, EBlendFactor& dst_alpha) const; //! The current blend equation, see also http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquation.xml for more information. void setBlendEquation( EBlendEquation rgb_eq, EBlendEquation alpha_eq ); //! The current blend equation. void getBlendEquation( EBlendEquation& rgb_eq, EBlendEquation& alpha_eq ) const; //! The current color mask, see also http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml for more information. void setColorMask(bool r, bool g, bool b, bool a) { mState.mColorMask = ivec4(r?1:0,g?1:0,b?1:0,a?1:0); } //! The current color mask. const ivec4& colorMask() const { return mState.mColorMask; } /*void setDetphMask(bool mask) { mState.mDepthMask = mask; } bool depthMask() const { return mState.mDepthMask; }*/ //! If set to 'true' the stencil test and operations will be enabled void setStencilTestEnabled(bool enabled) { mState.mStencilTestEnabled = enabled; } //! If set to 'true' the stencil test and operations will be enabled bool stencilTestEnabled() const { return mState.mStencilTestEnabled; } //! Current stencil mask, see also http://www.opengl.org/sdk/docs/man/xhtml/glStencilMask.xml for more information. void setStencilMask(unsigned int mask) { mState.mStencilMask = mask; } //! Current stencil mask. unsigned int stencilMask() const { return mState.mStencilMask; } //! Current stencil operation, see also http://www.opengl.org/sdk/docs/man/xhtml/glStencilOp.xml for more information. void setStencilOp(EStencilOp sfail, EStencilOp dpfail, EStencilOp dppass); //! Current stencil operation. void getStencilOp(EStencilOp& sfail, EStencilOp& dpfail, EStencilOp& dppass); //! The current stencil function, see also http://www.opengl.org/sdk/docs/man/xhtml/glStencilFunc.xml for more information. void setStencilFunc(EFunction func, int refval, unsigned int mask); //! The current stencil function. void getStencilFunc(EFunction& func, int& refval, unsigned int& mask); //! Sets the current Font void setFont(const String& name, int size, bool smooth=false) { mState.mFont = defFontManager()->acquireFont(name,size,smooth); } //! Sets the current Font void setFont(const Font* font) { setFont(font->filePath(),font->size(),font->smooth()); } //! Sets the default Font void setDefaultFont() { setFont(defFontManager()->acquireFont("/font/bitstream-vera/VeraMono.ttf", 10, false)); } //! Returns the current Font const Font* font() const { return mState.mFont.get(); } /** Defines the scissor box and enables the scissor test. * The parameters are considered in windows coordinates. * The Scissor is used to clip the rendering against a specific rectangular area. * See also http://www.opengl.org/sdk/docs/man/xhtml/glScissor.xml for more information. */ void setScissor(int x, int y, int width, int height) { mScissor = resolveScissor(x,y,width,height); } /** Returns the currently active Scissor */ const Scissor* scissor() const { return mScissor.get(); } /** Disables the Scissor test and clipping. */ void removeScissor() { mScissor = NULL; } /** Clears the specific area of the viewport. * The parameters x y w h define a rectangular area in viewport coordinates that is clipped against the viewport itself. * * \note The specified rectangular area is not affected by the current matrix transform. */ Actor* clearColor(const fvec4& color, int x=0, int y=0, int w=-1, int h=-1); /** Clears the specific area of the viewport. * The parameters x y w h define a rectangular area in viewport coordinates that is clipped against the viewport itself. * * \note The specified rectangular area is not affected by the current matrix transform. */ Actor* clearStencil(int clear_val, int x=0, int y=0, int w=-1, int h=-1); //! Draw the specified Text object Actor* drawText(Text* text); /** Draws the specified text at the specified position. * Note that the current matrix transform affect the final position, rotation and scaling of the text. */ Actor* drawText(int x, int y, const String& text, int alignment = AlignBottom|AlignLeft); //! Draws the specified text Actor* drawText(const String& text, int alignment = AlignBottom|AlignLeft); /** Draws the specified Actor with the specified Transform. * If keep_effect is set to 'false' or the Actor's Effect is NULL a default Effect is automatically generated. * If 'transform' is non NULL it is bound to the Actor. */ Actor* drawActor(Actor* actor, Transform* transform=NULL, bool keep_effect=false); /** Like drawActor() but instead of drawing the given actor creates a copy of it and draws that. * This function is useful when you want to crate multiple instances of the same geometry. */ Actor* drawActorCopy(Actor* actor, Transform* transform=NULL); //! Returns the current transform matrix const dmat4& matrix() const { return mMatrix; } //! Sets the current transform matrix void setMatrix(const dmat4& matrix) { mMatrix = matrix; } //! Resets the current transform matrix. void resetMatrix() { mMatrix.setIdentity(); } //! Performs a rotation of 'deg' degrees around the z axis. void rotate(double deg); //! Translates the current transform matrix void translate(double x, double y, double z=0.0); //! Scales the current transform matrix void scale(double x, double y, double z=1.0); //! Pushes the current matrix in the matrix stack in order to restore it later with popMatrix(). void pushMatrix() { mMatrixStack.push_back(matrix()); } //! Pops the top most matrix in the matrix stack and sets it as the current matrix. void popMatrix(); //! Returns the matrix stack. const std::vector& matrixStack() const { return mMatrixStack; } //! Pushes the current VectorGraphics state (including the matrix state) in the state stack in order to restore it later with popState(). void pushState(); //! Pops the top most state in the state stack and sets it as the current state. void popState(); /*const std::vector& stateStack() const { return mStateStack; }*/ /** Pushes the current scissor in the scissor stack in order to restore it later with popScissor() and activates a new one. * The 'x', 'y', 'w' and 'h' parameters define the new scissor rectangle. * Note that such rectangle is clipped against the currently active one. */ void pushScissor(int x, int y, int w, int h); //! Pops the top most scissor in the scissor stack and sets it as the current scissor. void popScissor(); //! Returns the scissor stack. const std::vector< ref >& scissorStack() const { return mScissorStack; } //! Binds the given Transform to all the Actor[s] that have been generated so far. void setTransform(Transform* transform) { for(int i=0; isize(); ++i) actors()->at(i)->setTransform(transform); } //! Returns the Effect representing the current VectorGraphic's state. Effect* currentEffect() { return currentEffect(mState); } private: void generateQuadsTexCoords(Geometry* geom, const std::vector& points); void generatePlanarTexCoords(Geometry* geom, const std::vector& points); void generateLinearTexCoords(Geometry* geom); ref prepareGeometry(const std::vector& ln); ref prepareGeometryPolyToTriangles(const std::vector& ln); Scissor* resolveScissor(int x, int y, int width, int height); Texture* resolveTexture(const Image* image); Effect* currentEffect(const State& vgs); Actor* addActor(Actor* actor) ; private: // state-machine state variables State mState; dmat4 mMatrix; ref mScissor; std::vector mStateStack; std::vector mMatrixStack; std::vector< ref > mScissorStack; // state-machine state map std::map > mVGToEffectMap; std::map > mImageToTextureMap; std::map > mRectToScissorMap; ref mDefaultEffect; ActorCollection mActors; }; //------------------------------------------------------------------------------------------------------------------------------------------- } #endif