Last active
February 16, 2018 08:18
A MeshStyle for Starling 2 that allows to add an offset to each color channel of a mesh, as described in the Starling manual.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ================================================================================================= | |
// | |
// 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.extensions | |
{ | |
import starling.display.Mesh; | |
import starling.rendering.MeshEffect; | |
import starling.rendering.VertexDataFormat; | |
import starling.styles.MeshStyle; | |
public class ColorOffsetStyle extends MeshStyle | |
{ | |
public static const VERTEX_FORMAT:VertexDataFormat = | |
MeshStyle.VERTEX_FORMAT.extend("offset:float4"); | |
private var _offsets:Vector.<Number>; | |
public function ColorOffsetStyle(redOffset:Number=0, greenOffset:Number=0, | |
blueOffset:Number=0, alphaOffset:Number=0):void | |
{ | |
_offsets = new Vector.<Number>(4, true); | |
setTo(redOffset, greenOffset, blueOffset, alphaOffset); | |
} | |
public function setTo(redOffset:Number=0, greenOffset:Number=0, | |
blueOffset:Number=0, alphaOffset:Number=0):void | |
{ | |
_offsets[0] = redOffset; | |
_offsets[1] = greenOffset; | |
_offsets[2] = blueOffset; | |
_offsets[3] = alphaOffset; | |
updateVertices(); | |
} | |
override public function copyFrom(meshStyle:MeshStyle):void | |
{ | |
var colorOffsetStyle:ColorOffsetStyle = meshStyle as ColorOffsetStyle; | |
if (colorOffsetStyle) | |
{ | |
for (var i:int=0; i<4; ++i) | |
_offsets[i] = colorOffsetStyle._offsets[i]; | |
} | |
super.copyFrom(meshStyle); | |
} | |
override public function createEffect():MeshEffect | |
{ | |
return new ColorOffsetEffect(); | |
} | |
override protected function onTargetAssigned(target:Mesh):void | |
{ | |
updateVertices(); | |
} | |
override public function get vertexFormat():VertexDataFormat | |
{ | |
return VERTEX_FORMAT; | |
} | |
private function updateVertices():void | |
{ | |
if (target) | |
{ | |
var numVertices:int = vertexData.numVertices; | |
for (var i:int=0; i<numVertices; ++i) | |
vertexData.setPoint4D(i, "offset", | |
_offsets[0], _offsets[1], _offsets[2], _offsets[3]); | |
setRequiresRedraw(); | |
} | |
} | |
public function get redOffset():Number { return _offsets[0]; } | |
public function set redOffset(value:Number):void | |
{ | |
_offsets[0] = value; | |
updateVertices(); | |
} | |
public function get greenOffset():Number { return _offsets[1]; } | |
public function set greenOffset(value:Number):void | |
{ | |
_offsets[1] = value; | |
updateVertices(); | |
} | |
public function get blueOffset():Number { return _offsets[2]; } | |
public function set blueOffset(value:Number):void | |
{ | |
_offsets[2] = value; | |
updateVertices(); | |
} | |
public function get alphaOffset():Number { return _offsets[3]; } | |
public function set alphaOffset(value:Number):void | |
{ | |
_offsets[3] = value; | |
updateVertices(); | |
} | |
} | |
} | |
import flash.display3D.Context3D; | |
import starling.extensions.ColorOffsetStyle; | |
import starling.rendering.MeshEffect; | |
import starling.rendering.Program; | |
import starling.rendering.VertexDataFormat; | |
import starling.utils.RenderUtil; | |
class ColorOffsetEffect extends MeshEffect | |
{ | |
public static const VERTEX_FORMAT:VertexDataFormat = ColorOffsetStyle.VERTEX_FORMAT; | |
public function ColorOffsetEffect() | |
{ } | |
override protected function createProgram():Program | |
{ | |
var vertexShader:String, fragmentShader:String; | |
var addOffset:String = [ | |
"mov ft1, v2", // copy complete offset to ft1 | |
"mul ft1.xyz, v2.xyz, ft0.www", // multiply offset.rgb with alpha (pma!) | |
"add oc, ft0, ft1" // add offset, copy to output | |
].join("\n"); | |
if (texture) | |
{ | |
vertexShader = [ | |
"m44 op, va0, vc0", // 4x4 matrix transform to output clip-space | |
"mov v0, va1 ", // pass texture coordinates to fragment program | |
"mul v1, va2, vc4", // multiply alpha (vc4) with color (va2), pass to fp | |
"mov v2, va3 " // pass offset to fp | |
].join("\n"); | |
fragmentShader = [ | |
tex("ft0", "v0", 0, texture) + | |
"mul ft0, ft0, v1", // multiply color with texel color | |
addOffset | |
].join("\n"); | |
} | |
else | |
{ | |
vertexShader = [ | |
"m44 op, va0, vc0", // 4x4 matrix transform to output clipspace | |
"mul v0, va2, vc4", // multiply alpha (vc4) with color (va2) | |
"mov v2, va3 " // pass offset to fp | |
].join("\n"); | |
fragmentShader = [ | |
"mov ft0, v0", addOffset | |
].join("\n"); | |
} | |
return Program.fromSource(vertexShader, fragmentShader); | |
} | |
override public function get vertexFormat():VertexDataFormat | |
{ | |
return VERTEX_FORMAT; | |
} | |
override protected function beforeDraw(context:Context3D):void | |
{ | |
super.beforeDraw(context); | |
vertexFormat.setVertexBufferAt(3, vertexBuffer, "offset"); | |
} | |
override protected function afterDraw(context:Context3D):void | |
{ | |
context.setVertexBufferAt(3, null); | |
super.afterDraw(context); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment