// ================================================================================================= // // Starling Framework // Copyright Gamua GmbH. 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.VertexBuffer3D; import flash.utils.Dictionary; import starling.core.Starling; import starling.utils.StringUtil; /** Describes the memory layout of VertexData instances, as used for every single vertex. * *

The format is set up via a simple String. Here is an example:

* * * format = VertexDataFormat.fromString("position:float2, color:bytes4"); * *

This String describes two attributes: "position" and "color". The keywords after * the colons depict the format and size of the data that each attribute uses; in this * case, we store two floats for the position (taking up the x- and y-coordinates) and four * bytes for the color. (The available formats are the same as those defined in the * Context3DVertexBufferFormat class: * float1, float2, float3, float4, bytes4.)

* *

You cannot create a VertexData instance with its constructor; instead, you must use the * static fromString-method. The reason for this behavior: the class maintains * a cache, and a call to fromString will return an existing instance if an * equivalent format has already been created in the past. That saves processing time and * memory.

* *

VertexDataFormat instances are immutable, i.e. they are solely defined by their format * string and cannot be changed later.

* * @see VertexData */ public class VertexDataFormat { private var _format:String; private var _vertexSize:int; private var _attributes:Vector.; // format cache private static var sFormats:Dictionary = new Dictionary(); /** Don't use the constructor, but call VertexDataFormat.fromString instead. * This allows for efficient format caching. */ public function VertexDataFormat() { _attributes = new Vector.(); } /** Creates a new VertexDataFormat instance from the given String, or returns one from * the cache (if an equivalent String has already been used before). * * @param format * * Describes the attributes of each vertex, consisting of a comma-separated * list of attribute names and their format, e.g.: * *
"position:float2, texCoords:float2, color:bytes4"
* *

This set of attributes will be allocated for each vertex, and they will be * stored in exactly the given order.

* * */ public static function fromString(format:String):VertexDataFormat { if (format in sFormats) return sFormats[format]; else { var instance:VertexDataFormat = new VertexDataFormat(); instance.parseFormat(format); var normalizedFormat:String = instance._format; if (normalizedFormat in sFormats) instance = sFormats[normalizedFormat]; sFormats[format] = instance; sFormats[normalizedFormat] = instance; return instance; } } /** Creates a new VertexDataFormat instance by appending the given format string * to the current instance's format. */ public function extend(format:String):VertexDataFormat { return fromString(_format + ", " + format); } // query methods /** Returns the size of a certain vertex attribute in bytes. */ public function getSize(attrName:String):int { return getAttribute(attrName).size; } /** Returns the size of a certain vertex attribute in 32 bit units. */ public function getSizeIn32Bits(attrName:String):int { return getAttribute(attrName).size / 4; } /** Returns the offset (in bytes) of an attribute within a vertex. */ public function getOffset(attrName:String):int { return getAttribute(attrName).offset; } /** Returns the offset (in 32 bit units) of an attribute within a vertex. */ public function getOffsetIn32Bits(attrName:String):int { return getAttribute(attrName).offset / 4; } /** Returns the format of a certain vertex attribute, identified by its name. * Typical values: float1, float2, float3, float4, bytes4. */ public function getFormat(attrName:String):String { return getAttribute(attrName).format; } /** Returns the name of the attribute at the given position within the vertex format. */ public function getName(attrIndex:int):String { return _attributes[attrIndex].name; } /** Indicates if the format contains an attribute with the given name. */ public function hasAttribute(attrName:String):Boolean { var numAttributes:int = _attributes.length; for (var i:int=0; iContext3D-method with the same name, * automatically replacing attrName with the corresponding values for * bufferOffset and format. */ public function setVertexBufferAt(index:int, buffer:VertexBuffer3D, attrName:String):void { var attribute:VertexDataAttribute = getAttribute(attrName); Starling.context.setVertexBufferAt(index, buffer, attribute.offset / 4, attribute.format); } // parsing private function parseFormat(format:String):void { if (format != null && format != "") { _attributes.length = 0; _format = ""; var parts:Array = format.split(","); var numParts:int = parts.length; var offset:int = 0; for (var i:int=0; i { return _attributes; } // properties /** Returns the normalized format string. */ public function get formatString():String { return _format; } /** The size (in bytes) of each vertex. */ public function get vertexSize():int { return _vertexSize; } /** The size (in 32 bit units) of each vertex. */ public function get vertexSizeIn32Bits():int { return _vertexSize / 4; } /** The number of attributes per vertex. */ public function get numAttributes():int { return _attributes.length; } } }