Last active
April 23, 2025 17:13
-
-
Save joshtynjala/974f6f3f49bad9a788e8a7f252d77e5f to your computer and use it in GitHub Desktop.
The revised ColorOffsetFilter of the tutorial from the Starling Manual for OpenFL; now with fixed PMA handling.
This file contains hidden or 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 openfl.Vector; | |
import openfl.display3D.Context3D; | |
import openfl.display3D.Context3DProgramType; | |
import starling.filters.FragmentFilter; | |
import starling.rendering.FilterEffect; | |
import starling.rendering.Program; | |
class ColorOffsetFilter extends FragmentFilter | |
{ | |
public function new(redOffset:Float=0.0, greenOffset:Float=0.0, | |
blueOffset:Float=0.0, alphaOffset:Float=0.0) | |
{ | |
super(); | |
colorOffsetEffect.redOffset = redOffset; | |
colorOffsetEffect.greenOffset = greenOffset; | |
colorOffsetEffect.blueOffset = blueOffset; | |
colorOffsetEffect.alphaOffset = alphaOffset; | |
} | |
override private function createEffect():FilterEffect | |
{ | |
return new ColorOffsetEffect(); | |
} | |
private var colorOffsetEffect(get, never):ColorOffsetEffect; | |
private function get_colorOffsetEffect():ColorOffsetEffect | |
{ | |
return cast(effect, ColorOffsetEffect); | |
} | |
public var redOffset(get, set):Float; | |
private function get_redOffset():Float { return colorOffsetEffect.redOffset; } | |
private function set_redOffset(value:Float):Float | |
{ | |
colorOffsetEffect.redOffset = value; | |
setRequiresRedraw(); | |
return value; | |
} | |
public var greenOffset(get, set):Float; | |
private function get_greenOffset():Float { return colorOffsetEffect.greenOffset; } | |
private function set_greenOffset(value:Float):Float | |
{ | |
colorOffsetEffect.greenOffset = value; | |
setRequiresRedraw(); | |
return value; | |
} | |
public var blueOffset(get, set):Float; | |
private function get_blueOffset():Float { return colorOffsetEffect.blueOffset; } | |
private function set_blueOffset(value:Float):Float | |
{ | |
colorOffsetEffect.blueOffset = value; | |
setRequiresRedraw(); | |
return value; | |
} | |
public var alphaOffset(get, set):Float; | |
private function get_alphaOffset():Float { return colorOffsetEffect.alphaOffset; } | |
private function set_alphaOffset(value:Float):Float | |
{ | |
colorOffsetEffect.alphaOffset = value; | |
setRequiresRedraw(); | |
return value; | |
} | |
} | |
private class ColorOffsetEffect extends FilterEffect | |
{ | |
private var _offsets:Vector<Float>; | |
private static final MIN_COLOR:Vector<Float> = Vector.ofArray([0, 0, 0, 0.001]); | |
public function new() | |
{ | |
super(); | |
_offsets = new Vector(4, true); | |
} | |
override private function createProgram():Program | |
{ | |
var vertexShader:String = FilterEffect.STD_VERTEX_SHADER; | |
var fragmentShader:String = [ | |
FilterEffect.tex("ft0", "v0", 0, texture), // get color from texture | |
"mov ft1, fc0", // copy complete offset to ft1 | |
"mul ft1.xyz, fc0.xyz, ft0.www", // multiply offset.rgb with alpha (pma!) | |
"add oc, ft0, ft1 " // add offset, copy to output | |
].join("\n"); | |
return Program.fromSource(vertexShader, fragmentShader); | |
} | |
override private function beforeDraw(context:Context3D):Void | |
{ | |
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 0, _offsets); | |
context.setProgramConstantsFromVector(Context3DProgramType.FRAGMENT, 1, MIN_COLOR); | |
super.beforeDraw(context); | |
} | |
public var redOffset(get, set):Float; | |
private function get_redOffset():Float { return _offsets[0]; } | |
private function set_redOffset(value:Float):Float { return _offsets[0] = value; } | |
public var greenOffset(get, set):Float; | |
private function get_greenOffset():Float { return _offsets[1]; } | |
private function set_greenOffset(value:Float):Float { return _offsets[1] = value; } | |
public var blueOffset(get, set):Float; | |
private function get_blueOffset():Float { return _offsets[2]; } | |
private function set_blueOffset(value:Float):Float { return _offsets[2] = value; } | |
public var alphaOffset(get, set):Float; | |
private function get_alphaOffset():Float { return _offsets[3]; } | |
private function set_alphaOffset(value:Float):Float { return _offsets[3] = value; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See Starling Manual for OpenFL: Custom Filters for details.