All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scaffold.libs_as.starling.rendering.RenderState.as Maven / Gradle / Ivy

// =================================================================================================
//
//	Starling Framework
//	Copyright 2011-2015 Gamua. All Rights Reserved.
//
//	This program is free software. You can redistribute and/or modify it
//	in accordance with the terms of the accompanying license agreement.
//
// =================================================================================================

package starling.rendering
{
    import flash.display3D.Context3DTriangleFace;
    import flash.display3D.textures.TextureBase;
    import flash.geom.Matrix;
    import flash.geom.Matrix3D;
    import flash.geom.Rectangle;
    import flash.geom.Vector3D;

    import starling.display.BlendMode;
    import starling.textures.Texture;
    import starling.utils.MatrixUtil;
    import starling.utils.Pool;
    import starling.utils.RectangleUtil;

    /** The RenderState stores a combination of settings that are currently used for rendering.
     *  This includes modelview and transformation matrices as well as context3D related settings.
     *
     *  

Starling's Painter instance stores a reference to the current RenderState. * Via a stack mechanism, you can always save a specific state and restore it later. * That makes it easy to write rendering code that doesn't have any side effects.

* *

Beware that any context-related settings are not applied on the context * right away, but only after calling painter.prepareToDraw(). * However, the Painter recognizes changes to those settings and will finish the current * batch right away if necessary.

* * Matrix Magic * *

On rendering, Starling traverses the display tree, constantly moving from one * coordinate system to the next. Each display object stores its vertex coordinates * in its local coordinate system; on rendering, they must be moved to a global, * 2D coordinate space (the so-called "clip-space"). To handle these calculations, * the RenderState contains a set of matrices.

* *

By multiplying vertex coordinates with the modelviewMatrix, you'll get the * coordinates in "screen-space", or in other words: in stage coordinates. (Optionally, * there's also a 3D version of this matrix. It comes into play when you're working with * Sprite3D containers.)

* *

By feeding the result of the previous transformation into the * projectionMatrix, you'll end up with so-called "clipping coordinates", * which are in the range [-1, 1] (just as needed by the graphics pipeline). * If you've got vertices in the 3D space, this matrix will also execute a perspective * projection.

* *

Finally, there's the mvpMatrix, which is short for * "modelviewProjectionMatrix". This is simply a combination of modelview- and * projectionMatrix, combining the effects of both. Pass this matrix * to the vertex shader and all your vertices will automatically end up at the right * position.

* * @see Painter * @see starling.display.Sprite3D */ public class RenderState { private var _alpha:Number; private var _blendMode:String; private var _renderTarget:Texture; private var _renderTargetOptions:uint; private var _culling:String; private var _clipRect:Rectangle; private var _onDrawRequired:Function; private var _modelviewMatrix:Matrix; private var _modelviewMatrix3D:Matrix3D; private var _projectionMatrix3D:Matrix3D; private var _mvpMatrix3D:Matrix3D; // helper objects private static var sMatrix3D:Matrix3D = new Matrix3D(); /** Creates a new render state with the default settings. */ public function RenderState() { reset(); } /** Duplicates all properties of another instance on the current instance. */ public function copyFrom(renderState:RenderState):void { if (_onDrawRequired != null) { var currentTarget:TextureBase = _renderTarget ? _renderTarget.base : null; var nextTarget:TextureBase = renderState._renderTarget ? renderState._renderTarget.base : null; var clipRectChanges:Boolean = _clipRect || renderState._clipRect ? !RectangleUtil.compare(_clipRect, renderState._clipRect) : false; if (_blendMode != renderState._blendMode || _culling != renderState._culling || currentTarget != nextTarget || clipRectChanges) { _onDrawRequired(); } } _alpha = renderState._alpha; _blendMode = renderState._blendMode; _renderTarget = renderState._renderTarget; _renderTargetOptions = renderState._renderTargetOptions; _culling = renderState._culling; _modelviewMatrix.copyFrom(renderState._modelviewMatrix); _projectionMatrix3D.copyFrom(renderState._projectionMatrix3D); if (_modelviewMatrix3D || renderState._modelviewMatrix3D) this.modelviewMatrix3D = renderState._modelviewMatrix3D; if (_clipRect || renderState._clipRect) this.clipRect = renderState._clipRect; } /** Resets the RenderState to the default settings. * (Check each property documentation for its default value.) */ public function reset():void { this.alpha = 1.0; this.blendMode = BlendMode.NORMAL; this.culling = Context3DTriangleFace.NONE; this.modelviewMatrix3D = null; this.renderTarget = null; this.clipRect = null; if (_modelviewMatrix) _modelviewMatrix.identity(); else _modelviewMatrix = new Matrix(); if (_projectionMatrix3D) _projectionMatrix3D.identity(); else _projectionMatrix3D = new Matrix3D(); if (_mvpMatrix3D == null) _mvpMatrix3D = new Matrix3D(); } // matrix methods / properties /** Prepends the given matrix to the 2D modelview matrix. */ public function transformModelviewMatrix(matrix:Matrix):void { MatrixUtil.prependMatrix(_modelviewMatrix, matrix); } /** Prepends the given matrix to the 3D modelview matrix. * The current contents of the 2D modelview matrix is stored in the 3D modelview matrix * before doing so; the 2D modelview matrix is then reset to the identity matrix. */ public function transformModelviewMatrix3D(matrix:Matrix3D):void { if (_modelviewMatrix3D == null) _modelviewMatrix3D = Pool.getMatrix3D(); _modelviewMatrix3D.prepend(MatrixUtil.convertTo3D(_modelviewMatrix, sMatrix3D)); _modelviewMatrix3D.prepend(matrix); _modelviewMatrix.identity(); } /** Creates a perspective projection matrix suitable for 2D and 3D rendering. * *

The first 4 parameters define which area of the stage you want to view (the camera * will 'zoom' to exactly this region). The final 3 parameters determine the perspective * in which you're looking at the stage.

* *

The stage is always on the rectangle that is spawned up between x- and y-axis (with * the given size). All objects that are exactly on that rectangle (z equals zero) will be * rendered in their true size, without any distortion.

* *

If you pass only the first 4 parameters, the camera will be set up above the center * of the stage, with a field of view of 1.0 rad.

*/ public function setProjectionMatrix(x:Number, y:Number, width:Number, height:Number, stageWidth:Number=0, stageHeight:Number=0, cameraPos:Vector3D=null):void { MatrixUtil.createPerspectiveProjectionMatrix( x, y, width, height, stageWidth, stageHeight, cameraPos, _projectionMatrix3D); } /** Changes the modelview matrices (2D and, if available, 3D) to identity matrices. * An object transformed an identity matrix performs no transformation. */ public function setModelviewMatricesToIdentity():void { _modelviewMatrix.identity(); if (_modelviewMatrix3D) _modelviewMatrix3D.identity(); } /** Returns the current 2D modelview matrix. * CAUTION: Use with care! Each call returns the same instance. * @default identity matrix */ public function get modelviewMatrix():Matrix { return _modelviewMatrix; } public function set modelviewMatrix(value:Matrix):void { _modelviewMatrix.copyFrom(value); } /** Returns the current 3D modelview matrix, if there have been 3D transformations. * CAUTION: Use with care! Each call returns the same instance. * @default null */ public function get modelviewMatrix3D():Matrix3D { return _modelviewMatrix3D; } public function set modelviewMatrix3D(value:Matrix3D):void { if (value) { if (_modelviewMatrix3D == null) _modelviewMatrix3D = Pool.getMatrix3D(false); _modelviewMatrix3D.copyFrom(value); } else if (_modelviewMatrix3D) { Pool.putMatrix3D(_modelviewMatrix3D); _modelviewMatrix3D = null; } } /** Returns the current projection matrix. You can use the method 'setProjectionMatrix3D' * to set it up in an intuitive way. * CAUTION: Use with care! Each call returns the same instance. * @default identity matrix */ public function get projectionMatrix3D():Matrix3D { return _projectionMatrix3D; } public function set projectionMatrix3D(value:Matrix3D):void { _projectionMatrix3D.copyFrom(value); } /** Calculates the product of modelview and projection matrix and stores it in a 3D matrix. * CAUTION: Use with care! Each call returns the same instance. */ public function get mvpMatrix3D():Matrix3D { _mvpMatrix3D.copyFrom(_projectionMatrix3D); if (_modelviewMatrix3D) _mvpMatrix3D.prepend(_modelviewMatrix3D); _mvpMatrix3D.prepend(MatrixUtil.convertTo3D(_modelviewMatrix, sMatrix3D)); return _mvpMatrix3D; } // other methods /** Changes the the current render target. * * @param target Either a texture or null to render into the back buffer. * @param enableDepthAndStencil Indicates if depth and stencil testing will be available. * This parameter affects only texture targets. * @param antiAlias The anti-aliasing quality (0 meaning: no anti-aliasing). * This parameter affects only texture targets. Note that at the time * of this writing, AIR supports anti-aliasing only on Desktop. */ public function setRenderTarget(target:Texture, enableDepthAndStencil:Boolean=true, antiAlias:int=0):void { var currentTarget:TextureBase = _renderTarget ? _renderTarget.base : null; var newTarget:TextureBase = target ? target.base : null; var newOptions:uint = uint(enableDepthAndStencil) | antiAlias << 4; if (currentTarget != newTarget || _renderTargetOptions != newOptions) { if (_onDrawRequired != null) _onDrawRequired(); _renderTarget = target; _renderTargetOptions = newOptions; } } // other properties /** The current, cumulated alpha value. Beware that, in a standard 'render' method, * this already includes the current object! The value is the product of current object's * alpha value and all its parents. @default 1.0 */ public function get alpha():Number { return _alpha; } public function set alpha(value:Number):void { _alpha = value; } /** The blend mode to be used on rendering. A value of "auto" is ignored, since it * means that the mode should remain unchanged. * * @default BlendMode.NORMAL * @see starling.display.BlendMode */ public function get blendMode():String { return _blendMode; } public function set blendMode(value:String):void { if (value != BlendMode.AUTO && _blendMode != value) { if (_onDrawRequired != null) _onDrawRequired(); _blendMode = value; } } /** The texture that is currently being rendered into, or null * to render into the back buffer. On assignment, calls setRenderTarget * with its default parameters. */ public function get renderTarget():Texture { return _renderTarget; } public function set renderTarget(value:Texture):void { setRenderTarget(value); } /** @private */ internal function get renderTargetBase():TextureBase { return _renderTarget ? _renderTarget.base : null; } /** Sets the triangle culling mode. Allows to exclude triangles from rendering based on * their orientation relative to the view plane. * @default Context3DTriangleFace.NONE */ public function get culling():String { return _culling; } public function set culling(value:String):void { if (_culling != value) { if (_onDrawRequired != null) _onDrawRequired(); _culling = value; } } /** The clipping rectangle can be used to limit rendering in the current render target to * a certain area. This method expects the rectangle in stage coordinates. To prevent * any clipping, assign null. * * @default null */ public function get clipRect():Rectangle { return _clipRect; } public function set clipRect(value:Rectangle):void { if (!RectangleUtil.compare(_clipRect, value)) { if (_onDrawRequired != null) _onDrawRequired(); if (value) { if (_clipRect == null) _clipRect = Pool.getRectangle(); _clipRect.copyFrom(value); } else if (_clipRect) { Pool.putRectangle(_clipRect); _clipRect = null; } } } /** The anti-alias setting used when setting the current render target * via setRenderTarget. */ public function get renderTargetAntiAlias():int { return _renderTargetOptions >> 4; } /** Indicates if the render target (set via setRenderTarget) * has its depth and stencil buffers enabled. */ public function get renderTargetSupportsDepthAndStencil():Boolean { return (_renderTargetOptions & 0xf) != 0; } /** Indicates if there have been any 3D transformations. * Returns true if the 3D modelview matrix contains a value. */ public function get is3D():Boolean { return _modelviewMatrix3D != null; } /** @private * * This callback is executed whenever a state change requires a draw operation. * This is the case if blend mode, render target, culling or clipping rectangle * are changing. */ internal function get onDrawRequired():Function { return _onDrawRequired; } internal function set onDrawRequired(value:Function):void { _onDrawRequired = value; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy