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

scaffold.libs_as.starling.rendering.MeshStyle.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.geom.Matrix;
    import flash.geom.Point;

    import starling.core.starling_internal;
    import starling.display.Mesh;
    import starling.events.Event;
    import starling.events.EventDispatcher;
    import starling.textures.Texture;
    import starling.textures.TextureSmoothing;

    /** Dispatched every frame on styles assigned to display objects connected to the stage. */
    [Event(name="enterFrame", type="starling.events.EnterFrameEvent")]

    /** MeshStyles provide a means to completely modify the way a mesh is rendered.
     *  The base class provides Starling's standard mesh rendering functionality: colored and
     *  (optionally) textured meshes. Subclasses may add support for additional features like
     *  color transformations, normal mapping, etc.
     *
     *  

Using styles

* *

First, create an instance of the desired style. Configure the style by updating its * properties, then assign it to the mesh. Here is an example that uses a fictitious * ColorStyle:

* * * var image:Image = new Image(heroTexture); * var colorStyle:ColorStyle = new ColorStyle(); * colorStyle.redOffset = 0.5; * colorStyle.redMultiplier = 2.0; * image.style = colorStyle; * *

Beware:

* *
    *
  • A style instance may only be used on one object at a time.
  • *
  • A style might require the use of a specific vertex format; * when the style is assigned, the mesh is converted to that format.
  • *
* *

Creating your own styles

* *

To create custom rendering code in Starling, you need to extend two classes: * MeshStyle and MeshEffect. While the effect class contains * the actual AGAL rendering code, the style provides the API that other developers will * interact with.

* *

Subclasses of MeshStyle will add specific properties that configure the * style's outcome, like the redOffset and redMultiplier properties * in the sample above. Here's how to properly create such a class:

* *
    *
  • Always provide a constructor that can be called without any arguments.
  • *
  • Override copyFrom — that's necessary for batching.
  • *
  • Override createEffect — this method must return the * MeshEffect that will do the actual Stage3D rendering.
  • *
  • Override updateEffect — this configures the effect created above * right before rendering.
  • *
  • Override canBatchWith if necessary — this method figures out if one * instance of the style can be batched with another. If they all can, you can leave * this out.
  • *
* *

If the style requires a custom vertex format, you must also:

* *
    *
  • add a static constant called VERTEX_FORMAT to the class and
  • *
  • override get vertexFormat and let it return exactly that format.
  • *
* *

When that's done, you can turn to the implementation of your MeshEffect; * the createEffect-override will return an instance of this class. * Directly before rendering begins, Starling will then call updateEffect * to set it up.

* * @see MeshEffect * @see VertexDataFormat * @see starling.display.Mesh */ public class MeshStyle extends EventDispatcher { /** The vertex format expected by this style (the same as found in the MeshEffect-class). */ public static const VERTEX_FORMAT:VertexDataFormat = MeshEffect.VERTEX_FORMAT; private var _type:Class; private var _target:Mesh; private var _texture:Texture; private var _textureSmoothing:String; private var _vertexData:VertexData; // just a reference to the target's vertex data private var _indexData:IndexData; // just a reference to the target's index data // helper objects private static var sPoint:Point = new Point(); /** Creates a new MeshStyle instance. * Subclasses must provide a constructor that can be called without any arguments. */ public function MeshStyle() { _textureSmoothing = TextureSmoothing.BILINEAR; _type = Object(this).constructor as Class; } /** Copies all properties of the given style to the current instance (or a subset, if the * classes don't match). Must be overridden by all subclasses! */ public function copyFrom(meshStyle:MeshStyle):void { _texture = meshStyle._texture; _textureSmoothing = meshStyle._textureSmoothing; } /** Creates a clone of this instance. The method will work for subclasses automatically, * no need to override it. */ public function clone():MeshStyle { var clone:MeshStyle = new _type(); clone.copyFrom(this); return clone; } /** Creates the effect that does the actual, low-level rendering. * Must be overridden by all subclasses! */ public function createEffect():MeshEffect { return new MeshEffect(); } /** Updates the settings of the given effect to match the current style. * The given effect will always match the class returned by * createEffect. * *

Must be overridden by all subclasses!

*/ public function updateEffect(effect:MeshEffect, state:RenderState):void { effect.texture = _texture; effect.textureSmoothing = _textureSmoothing; effect.mvpMatrix3D = state.mvpMatrix3D; effect.alpha = state.alpha; } /** Indicates if the current instance can be batched with the given style. * To be overridden by subclasses if default behavior is not sufficient. * The base implementation just checks if the styles are of the same type * and if the textures are compatible. */ public function canBatchWith(meshStyle:MeshStyle):Boolean { if (_type == meshStyle._type) { var newTexture:Texture = meshStyle._texture; if (_texture == null && newTexture == null) return true; else if (_texture && newTexture) return _texture.base == newTexture.base && _textureSmoothing == meshStyle._textureSmoothing; else return false; } else return false; } /** Copies the raw vertex data of the target mesh to the given VertexData instance. * If you pass a matrix, all vertices will be transformed during the process. * *

This method is called on batching. Subclasses may override it if they need to modify * the vertex data in that process. Per default, just the "position" attribute is * transformed.

*/ public function copyVertexDataTo(target:VertexData, targetVertexID:int=0, matrix:Matrix=null, vertexID:int=0, numVertices:int=-1):void { _vertexData.copyTo(target, targetVertexID, matrix, vertexID, numVertices); } /** Copies the raw index data to the given IndexData instance. * The given offset value will be added to all indices during the process. * *

This method is called on batching. Subclasses may override it if they need to modify * the index data in that process.

*/ public function copyIndexDataTo(target:IndexData, targetIndexID:int=0, offset:int=0, indexID:int=0, numIndices:int=-1):void { _indexData.copyTo(target, targetIndexID, offset, indexID, numIndices); } /** Call this method if the target needs to be redrawn. * The call is simply forwarded to the mesh. */ protected function setRequiresRedraw():void { if (_target) _target.setRequiresRedraw(); } /** Called when assigning a target mesh. Override to plug in class-specific logic. */ protected function onTargetAssigned(target:Mesh):void { } // enter frame event override public function addEventListener(type:String, listener:Function):void { if (type == Event.ENTER_FRAME && _target) _target.addEventListener(Event.ENTER_FRAME, onEnterFrame); super.addEventListener(type, listener); } override public function removeEventListener(type:String, listener:Function):void { if (type == Event.ENTER_FRAME && _target) _target.removeEventListener(type, onEnterFrame); super.removeEventListener(type, listener); } private function onEnterFrame(event:Event):void { dispatchEvent(event); } // internal methods /** @private */ starling_internal function setTarget(target:Mesh=null, vertexData:VertexData=null, indexData:IndexData=null):void { if (_target != target) { if (_target) _target.removeEventListener(Event.ENTER_FRAME, onEnterFrame); if (vertexData) vertexData.format = vertexFormat; _target = target; _vertexData = vertexData; _indexData = indexData; if (target) { if (hasEventListener(Event.ENTER_FRAME)) target.addEventListener(Event.ENTER_FRAME, onEnterFrame); onTargetAssigned(target); } } } // vertex manipulation /** Returns the alpha value of the vertex at the specified index. */ public function getVertexAlpha(vertexID:int):Number { return _vertexData.getAlpha(vertexID); } /** Sets the alpha value of the vertex at the specified index to a certain value. */ public function setVertexAlpha(vertexID:int, alpha:Number):void { _vertexData.setAlpha(vertexID, "color", alpha); setRequiresRedraw(); } /** Returns the RGB color of the vertex at the specified index. */ public function getVertexColor(vertexID:int):uint { return _vertexData.getColor(vertexID); } /** Sets the RGB color of the vertex at the specified index to a certain value. */ public function setVertexColor(vertexID:int, color:uint):void { _vertexData.setColor(vertexID, "color", color); setRequiresRedraw(); } /** Returns the texture coordinates of the vertex at the specified index. */ public function getTexCoords(vertexID:int, out:Point = null):Point { if (_texture) return _texture.getTexCoords(_vertexData, vertexID, "texCoords", out); else return _vertexData.getPoint(vertexID, "texCoords", out); } /** Sets the texture coordinates of the vertex at the specified index to the given values. */ public function setTexCoords(vertexID:int, u:Number, v:Number):void { if (_texture) _texture.setTexCoords(_vertexData, vertexID, "texCoords", u, v); else _vertexData.setPoint(vertexID, "texCoords", u, v); setRequiresRedraw(); } // properties /** Returns a reference to the vertex data of the assigned target (or null * if there is no target). Beware: the style itself does not own any vertices; * it is limited to manipulating those of the target mesh. */ protected function get vertexData():VertexData { return _vertexData; } /** Returns a reference to the index data of the assigned target (or null * if there is no target). Beware: the style itself does not own any indices; * it is limited to manipulating those of the target mesh. */ protected function get indexData():IndexData { return _indexData; } /** The actual class of this style. */ public function get type():Class { return _type; } /** Changes the color of all vertices to the same value. * The getter simply returns the color of the first vertex. */ public function get color():uint { if (_vertexData.numVertices > 0) return _vertexData.getColor(0); else return 0x0; } public function set color(value:uint):void { var i:int; var numVertices:int = _vertexData.numVertices; for (i=0; inull
, if there is none). */ public function get texture():Texture { return _texture; } public function set texture(value:Texture):void { if (value != _texture) { if (value) { var i:int; var numVertices:int = _vertexData ? _vertexData.numVertices : 0; for (i = 0; i < numVertices; ++i) { getTexCoords(i, sPoint); value.setTexCoords(_vertexData, i, "texCoords", sPoint.x, sPoint.y); } } _texture = value; setRequiresRedraw(); } } /** The smoothing filter that is used for the texture. @default bilinear */ public function get textureSmoothing():String { return _textureSmoothing; } public function set textureSmoothing(value:String):void { if (value != _textureSmoothing) { _textureSmoothing = value; setRequiresRedraw(); } } /** The target the style is currently assigned to. */ public function get target():Mesh { return _target; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy