Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

simplified matrix calculations of filters

  • Loading branch information...
commit d5c4b37cc9e020803962bce880ce335db3ef88a1 1 parent 2e6a19f
Daniel Sperl PrimaryFeather authored
19 starling/src/starling/core/RenderSupport.as
@@ -58,7 +58,7 @@ package starling.core
58 58 mQuadBatches = new <QuadBatch>[new QuadBatch()];
59 59
60 60 loadIdentity();
61   - setOrthographicProjection(400, 300);
  61 + setOrthographicProjection(0, 0, 400, 300);
62 62 }
63 63
64 64 /** Disposes all quad batches. */
@@ -71,9 +71,10 @@ package starling.core
71 71 // matrix manipulation
72 72
73 73 /** Sets up the projection matrix for ortographic 2D rendering. */
74   - public function setOrthographicProjection(width:Number, height:Number):void
  74 + public function setOrthographicProjection(x:Number, y:Number, width:Number, height:Number):void
75 75 {
76   - mProjectionMatrix.setTo(2.0/width, 0, 0, -2.0/height, -1.0, 1.0);
  76 + mProjectionMatrix.setTo(2.0/width, 0, 0, -2.0/height,
  77 + -(2*x + width) / width, (2*y + height) / height);
77 78 }
78 79
79 80 /** Changes the modelview matrix to the identity matrix. */
@@ -170,7 +171,8 @@ package starling.core
170 171 setBlendFactors(premultipliedAlpha, mBlendMode);
171 172 }
172 173
173   - /** The blend mode to be used on rendering. */
  174 + /** The blend mode to be used on rendering. To apply the factor, you have to manually call
  175 + * 'applyBlendMode' (because the actual blend factors depend on the PMA mode). */
174 176 public function get blendMode():String { return mBlendMode; }
175 177 public function set blendMode(value:String):void
176 178 {
@@ -179,18 +181,17 @@ package starling.core
179 181
180 182 // render targets
181 183
182   - /** The texture that is currently being rendered into,
183   - * or 'null' to render into the back buffer. */
  184 + /** The texture that is currently being rendered into, or 'null' to render into the
  185 + * back buffer. If you set a new target, it is immediately activated. */
  186 + public function get renderTarget():Texture { return mRenderTarget; }
184 187 public function set renderTarget(target:Texture):void
185   - {
  188 + {
186 189 mRenderTarget = target;
187 190
188 191 if (target) Starling.context.setRenderToTexture(target.base);
189 192 else Starling.context.setRenderToBackBuffer();
190 193 }
191 194
192   - public function get renderTarget():Texture { return mRenderTarget; }
193   -
194 195 // optimized quad rendering
195 196
196 197 /** Adds a quad to the current batch of unrendered quads. If there is a state change,
2  starling/src/starling/core/Starling.as
@@ -354,7 +354,7 @@ package starling.core
354 354 if (!mShareContext)
355 355 RenderSupport.clear(mStage.color, 1.0);
356 356
357   - mSupport.setOrthographicProjection(mStage.stageWidth, mStage.stageHeight);
  357 + mSupport.setOrthographicProjection(0, 0, mStage.stageWidth, mStage.stageHeight);
358 358 mSupport.renderTarget = null; // back buffer
359 359
360 360 mStage.render(mSupport, 1.0);
89 starling/src/starling/filters/FragmentFilter.as
@@ -27,7 +27,6 @@ package starling.filters
27 27 import starling.core.RenderSupport;
28 28 import starling.core.Starling;
29 29 import starling.display.DisplayObject;
30   - import starling.display.Image;
31 30 import starling.display.Stage;
32 31 import starling.errors.AbstractClassError;
33 32 import starling.errors.MissingContextError;
@@ -126,14 +125,29 @@ package starling.filters
126 125
127 126 public function render(object:DisplayObject, support:RenderSupport, parentAlpha:Number):void
128 127 {
  128 + if (mode == FragmentFilterMode.ABOVE)
  129 + object.render(support, parentAlpha);
  130 +
  131 + renderPasses(object, support, parentAlpha);
  132 +
  133 + if (mode == FragmentFilterMode.BELOW)
  134 + object.render(support, parentAlpha);
  135 + }
  136 +
  137 + // helper methods
  138 +
  139 + private function renderPasses(object:DisplayObject, support:RenderSupport,
  140 + parentAlpha:Number):void
  141 + {
129 142 var stage:Stage = object.stage;
130 143 if (stage == null) return;
131 144
132 145 var context:Context3D = Starling.context;
133 146 if (context == null) throw new MissingContextError();
134 147
135   - if (mode == FragmentFilterMode.ABOVE)
136   - object.render(support, parentAlpha);
  148 + support.finishQuadBatch();
  149 + support.raiseDrawCount(mNumPasses);
  150 + support.pushMatrix();
137 151
138 152 // save original projection matrix and render target
139 153 mProjMatrix.copyFrom(support.projectionMatrix);
@@ -145,52 +159,42 @@ package starling.filters
145 159 "This limitation will be removed in a future Stage3D version.");
146 160
147 161 // get bounds in stage coordinates
148   - // can be expensive, so we optimize at least for full-screen effects
  162 + // optimize for full-screen effects
149 163 if (object == stage || object == Starling.current.root)
150 164 mBounds.setTo(0, 0, stage.stageWidth, stage.stageHeight);
151 165 else
152 166 object.getBounds(stage, mBounds);
153 167
  168 + // the bounds are a rectangle around the object, in stage coordinates,
  169 + // and with an optional margin. To fit into a POT-texture, it will grow towards
  170 + // the right and bottom.
154 171 var deltaMargin:Number = mResolution == 1.0 ? 0.0 : 1.0 / mResolution; // to avoid hard edges
155 172 mBounds.x -= mMarginX + deltaMargin;
156 173 mBounds.y -= mMarginY + deltaMargin;
157 174 mBounds.width += 2 * (mMarginX + deltaMargin);
158 175 mBounds.height += 2 * (mMarginY + deltaMargin);
159 176
160   - mBounds.width = getNextPowerOfTwo(mBounds.width * mResolution);
161   - mBounds.height = getNextPowerOfTwo(mBounds.height * mResolution);
  177 + var textureWidth:int = getNextPowerOfTwo(mBounds.width * mResolution);
  178 + var textureHeight:int = getNextPowerOfTwo(mBounds.height * mResolution);
162 179
163   - updatePassTextures(mBounds.width, mBounds.height);
  180 + mBounds.width = textureWidth / mResolution;
  181 + mBounds.height = textureHeight / mResolution;
164 182
165   - // update the vertices that span up the filter rectangle
166   - updateBuffers(context, mBounds.width, mBounds.height);
167   -
168   - // now prepare filter passes
169   - support.finishQuadBatch();
170   - support.raiseDrawCount(mNumPasses);
171   -
172   - support.pushMatrix();
173   - support.loadIdentity();
174   - support.setOrthographicProjection(mBounds.width, mBounds.height);
175   -
176   - // draw the original object into a render texture
177   - var matrix:Matrix = support.modelViewMatrix;
178   - object.getTransformationMatrix(stage, matrix);
179   - matrix.translate(-mBounds.x, -mBounds.y);
180   - matrix.scale(mResolution, mResolution);
  183 + // prepare the textures we will render into, and the quad that spans up the filter
  184 + updatePassTextures(textureWidth, textureHeight);
  185 + updateBuffers(context, mBounds);
181 186
  187 + // draw the original object into a texture
182 188 support.renderTarget = mPassTextures[0];
183 189 support.clear();
184   -
  190 + support.setOrthographicProjection(mBounds.x, mBounds.y, mBounds.width, mBounds.height);
185 191 object.render(support, parentAlpha);
186   -
187 192 support.finishQuadBatch();
188   - support.loadIdentity();
189 193
190   - // force blend mode "normal" for render passes
191   - RenderSupport.setBlendFactors(PMA);
  194 + // prepare drawing of actual filter passes
  195 + RenderSupport.setBlendFactors(PMA); // force blend mode "normal" for filter passes
  196 + support.loadIdentity(); // now we'll draw in stage coordinates!
192 197
193   - // set shader attributes
194 198 context.setVertexBufferAt(0, mVertexBuffer, VertexData.POSITION_OFFSET, Context3DVertexBufferFormat.FLOAT_2);
195 199 context.setVertexBufferAt(1, mVertexBuffer, VertexData.TEXCOORD_OFFSET, Context3DVertexBufferFormat.FLOAT_2);
196 200
@@ -206,8 +210,7 @@ package starling.filters
206 210 {
207 211 support.renderTarget = previousRenderTarget;
208 212 support.projectionMatrix.copyFrom(mProjMatrix); // restore projection matrix
209   - support.translateMatrix(mBounds.x + mOffsetX, mBounds.y + mOffsetY);
210   - support.scaleMatrix(1.0/mResolution, 1.0/mResolution);
  213 + support.translateMatrix(mOffsetX, mOffsetY);
211 214 }
212 215
213 216 var passTexture:Texture = getPassTexture(i);
@@ -226,18 +229,14 @@ package starling.filters
226 229 context.setTextureAt(0, null);
227 230
228 231 support.popMatrix();
229   -
230   - if (mode == FragmentFilterMode.BELOW)
231   - object.render(support, parentAlpha);
232 232 }
233 233
234   - // helper methods
235   -
236   - private function updateBuffers(context:Context3D, width:Number, height:Number):void
  234 + private function updateBuffers(context:Context3D, bounds:Rectangle):void
237 235 {
238   - mVertexData.setPosition(1, width, 0);
239   - mVertexData.setPosition(2, 0, height);
240   - mVertexData.setPosition(3, width, height);
  236 + mVertexData.setPosition(0, bounds.x, bounds.y);
  237 + mVertexData.setPosition(1, bounds.right, bounds.y);
  238 + mVertexData.setPosition(2, bounds.x, bounds.bottom);
  239 + mVertexData.setPosition(3, bounds.right, bounds.bottom);
241 240
242 241 if (mVertexBuffer == null)
243 242 {
@@ -261,7 +260,9 @@ package starling.filters
261 260 {
262 261 if (mPassTextures)
263 262 {
264   - for each (var texture:Texture in mPassTextures) texture.dispose();
  263 + for each (var texture:Texture in mPassTextures)
  264 + texture.dispose();
  265 +
265 266 mPassTextures.length = numPassTextures;
266 267 }
267 268 else
@@ -316,7 +317,11 @@ package starling.filters
316 317 // properties
317 318
318 319 public function get resolution():Number { return mResolution; }
319   - public function set resolution(value:Number):void { mResolution = value; }
  320 + public function set resolution(value:Number):void
  321 + {
  322 + if (value <= 0) throw new ArgumentError("Resolution must be > 0");
  323 + else mResolution = value;
  324 + }
320 325
321 326 public function get mode():String { return mMode; }
322 327 public function set mode(value:String):void { mMode = value; }
2  starling/src/starling/textures/RenderTexture.as
@@ -86,7 +86,7 @@ package starling.textures
86 86 mActiveTexture = Texture.empty(width, height, PMA, true, scale);
87 87
88 88 mSupport = new RenderSupport();
89   - mSupport.setOrthographicProjection(mNativeWidth/scale, mNativeHeight/scale);
  89 + mSupport.setOrthographicProjection(0, 0, mNativeWidth/scale, mNativeHeight/scale);
90 90
91 91 if (persistent)
92 92 {

0 comments on commit d5c4b37

Please sign in to comment.
Something went wrong with that request. Please try again.