public AsFragmentFilter(int numPasses, float resolution)
 {
     if (AsCapabilities.getIsDebugger() && AsGlobal.getQualifiedClassName(this) == "starling.filters::FragmentFilter")
     {
         throw new AsAbstractClassError();
     }
     if (numPasses < 1)
     {
         throw new AsArgumentError("At least one pass is required.");
     }
     mNumPasses  = numPasses;
     mMarginX    = mMarginY = 0.0f;
     mOffsetX    = mOffsetY = 0;
     mResolution = resolution;
     mMode       = AsFragmentFilterMode.REPLACE;
     mVertexData = new AsVertexData(4);
     mVertexData.setTexCoords(0, 0, 0);
     mVertexData.setTexCoords(1, 1, 0);
     mVertexData.setTexCoords(2, 0, 1);
     mVertexData.setTexCoords(3, 1, 1);
     mIndexData = new AsVector <uint>();
     mIndexData.setOwnProperty("_fixed", true);
     createPrograms();
     AsStarling.getCurrent().getStage3D().addEventListener(AsEvent.CONTEXT3D_CREATE, onContextCreated, false, 0, true);
 }
        public static AsTexture empty(int width, int height, bool premultipliedAlpha, bool optimizeForRenderTexture, float scale)
        {
            if (scale <= 0)
            {
                scale = AsStarling.getContentScaleFactor();
            }
            int         origWidth   = (int)(width * scale);
            int         origHeight  = (int)(height * scale);
            int         legalWidth  = AsGlobal.getNextPowerOfTwo(origWidth);
            int         legalHeight = AsGlobal.getNextPowerOfTwo(origHeight);
            String      format      = AsContext3DTextureFormat.BGRA;
            AsContext3D context     = AsStarling.getContext();

            if (context == null)
            {
                throw new AsMissingContextError();
            }
            bc.flash.display3D.textures.AsTexture nativeTexture = context.createTexture(legalWidth, legalHeight, AsContext3DTextureFormat.BGRA, optimizeForRenderTexture);
            AsConcreteTexture concreteTexture = new AsConcreteTexture(nativeTexture, format, legalWidth, legalHeight, false, premultipliedAlpha, optimizeForRenderTexture, scale);

            if (origWidth == legalWidth && origHeight == legalHeight)
            {
                return(concreteTexture);
            }
            else
            {
                return(new AsSubTexture(concreteTexture, new AsRectangle(0, 0, width, height), true));
            }
        }
        private void createBuffers()
        {
            int         numVertices = mVertexData.getNumVertices();
            int         numIndices  = (int)(mIndexData.getLength());
            AsContext3D context     = AsStarling.getContext();

            if (mVertexBuffer != null)
            {
                mVertexBuffer.dispose();
            }
            if (mIndexBuffer != null)
            {
                mIndexBuffer.dispose();
            }
            if (numVertices == 0)
            {
                return;
            }
            if (context == null)
            {
                throw new AsMissingContextError();
            }
            mVertexBuffer = context.createVertexBuffer(numVertices, AsVertexData.ELEMENTS_PER_VERTEX);
            mVertexBuffer.uploadFromVector(mVertexData.getRawData(), 0, numVertices);
            mIndexBuffer = context.createIndexBuffer(numIndices);
            mIndexBuffer.uploadFromVector(mIndexData, 0, numIndices);
            mSyncRequired = false;
        }
 public AsQuadBatch()
 {
     mVertexData   = new AsVertexData(0, true);
     mIndexData    = new AsVector <uint>();
     mNumQuads     = 0;
     mTinted       = false;
     mSyncRequired = false;
     AsStarling.getCurrent().getStage3D().addEventListener(AsEvent.CONTEXT3D_CREATE, onContextCreated, false, 0, true);
 }
        private static AsDictionary getBitmapFonts()
        {
            AsDictionary fonts = AsStarling.getCurrent().getCustomData()[BITMAP_FONT_DATA_NAME] as AsDictionary;

            if (fonts == null)
            {
                fonts = new AsDictionary();
                AsStarling.getCurrent().getCustomData()[BITMAP_FONT_DATA_NAME] = fonts;
            }
            return(fonts);
        }
        public virtual void clear()
        {
            AsContext3D context = AsStarling.getContext();

            if (context == null)
            {
                throw new AsMissingContextError();
            }
            mSupport.setRenderTarget(mActiveTexture);
            mSupport.clear();
            mSupport.setRenderTarget(null);
        }
 public virtual void restoreOnLostContext(Object data)
 {
     if (mData == null && data != null)
     {
         AsStarling.getCurrent().addEventListener(AsEvent.CONTEXT3D_CREATE, onContextCreated);
     }
     if (data == null)
     {
         AsStarling.getCurrent().removeEventListener(AsEvent.CONTEXT3D_CREATE, onContextCreated);
     }
     mData = data;
 }
 public override void dispose()
 {
     AsStarling.getCurrent().getStage3D().removeEventListener(AsEvent.CONTEXT3D_CREATE, onContextCreated);
     if (mVertexBuffer != null)
     {
         mVertexBuffer.dispose();
     }
     if (mIndexBuffer != null)
     {
         mIndexBuffer.dispose();
     }
     base.dispose();
 }
        public static AsTexture fromColor(int width, int height, uint color, bool optimizeForRenderTexture, float scale)
        {
            if (scale <= 0)
            {
                scale = AsStarling.getContentScaleFactor();
            }
            AsBitmapData bitmapData = new AsBitmapData(width * scale, height * scale, true, color);
            AsTexture    texture    = fromBitmapData(bitmapData, false, optimizeForRenderTexture, scale);

            if (!AsStarling.getHandleLostContext())
            {
                bitmapData.dispose();
            }
            return(texture);
        }
        public virtual void drawBundled(AsDrawingBlockCallback drawingBlock, int antiAliasing)
        {
            float       scale   = mActiveTexture.getScale();
            AsContext3D context = AsStarling.getContext();

            if (context == null)
            {
                throw new AsMissingContextError();
            }
            sScissorRect.setTo(0, 0, mActiveTexture.getWidth() * scale, mActiveTexture.getHeight() * scale);
            context.setScissorRectangle(sScissorRect);
            if (getIsPersistent())
            {
                AsTexture tmpTexture = mActiveTexture;
                mActiveTexture = mBufferTexture;
                mBufferTexture = tmpTexture;
                mHelperImage.setTexture(mBufferTexture);
            }
            mSupport.setRenderTarget(mActiveTexture);
            mSupport.clear();
            if (getIsPersistent() && mBufferReady)
            {
                mHelperImage.render(mSupport, 1.0f);
            }
            else
            {
                mBufferReady = true;
            }
            try
            {
                mDrawing = true;
                if (drawingBlock != null)
                {
                    drawingBlock();
                }
            }
            finally
            {
                mDrawing = false;
                mSupport.finishQuadBatch();
                mSupport.nextFrame();
                mSupport.setRenderTarget(null);
                context.setScissorRectangle(null);
            }
        }
        public static AsTexture fromBitmapData(AsBitmapData data, bool generateMipMaps, bool optimizeForRenderTexture, float scale)
        {
            int          origWidth   = data.getWidth();
            int          origHeight  = data.getHeight();
            int          legalWidth  = AsGlobal.getNextPowerOfTwo(origWidth);
            int          legalHeight = AsGlobal.getNextPowerOfTwo(origHeight);
            AsContext3D  context     = AsStarling.getContext();
            AsBitmapData potData     = null;

            if (context == null)
            {
                throw new AsMissingContextError();
            }
            bc.flash.display3D.textures.AsTexture nativeTexture = context.createTexture(legalWidth, legalHeight, AsContext3DTextureFormat.BGRA, optimizeForRenderTexture);
            if (legalWidth > origWidth || legalHeight > origHeight)
            {
                potData = new AsBitmapData(legalWidth, legalHeight, true, 0);
                potData.copyPixels(data, data.getRect(), sOrigin);
                data = potData;
            }
            uploadBitmapData(nativeTexture, data, generateMipMaps);
            AsConcreteTexture concreteTexture = new AsConcreteTexture(nativeTexture, AsContext3DTextureFormat.BGRA, legalWidth, legalHeight, generateMipMaps, true, optimizeForRenderTexture, scale);

            if (AsStarling.getHandleLostContext())
            {
                concreteTexture.restoreOnLostContext(data);
            }
            else
            {
                if (potData != null)
                {
                    potData.dispose();
                }
            }
            if (origWidth == legalWidth && origHeight == legalHeight)
            {
                return(concreteTexture);
            }
            else
            {
                return(new AsSubTexture(concreteTexture, new AsRectangle(0, 0, origWidth / scale, origHeight / scale), true));
            }
        }
        private void calculateBounds(AsDisplayObject _object, AsStage stage, AsRectangle resultRect)
        {
            if (_object == stage || _object == AsStarling.getCurrent().getRoot())
            {
                resultRect.setTo(0, 0, stage.getStageWidth(), stage.getStageHeight());
            }
            else
            {
                _object.getBounds(stage, resultRect);
            }
            float deltaMargin = mResolution == 1.0f ? 0.0f : 1.0f / mResolution;

            resultRect.x      = resultRect.x - mMarginX + deltaMargin;
            resultRect.y      = resultRect.y - mMarginY + deltaMargin;
            resultRect.width  = resultRect.width + 2 * (mMarginX + deltaMargin);
            resultRect.height = resultRect.height + 2 * (mMarginY + deltaMargin);
            resultRect.width  = AsGlobal.getNextPowerOfTwo((int)(resultRect.width * mResolution)) / mResolution;
            resultRect.height = AsGlobal.getNextPowerOfTwo((int)(resultRect.height * mResolution)) / mResolution;
        }
        public static AsTexture fromAtfData(AsByteArray data, float scale)
        {
            AsContext3D context = AsStarling.getContext();

            if (context == null)
            {
                throw new AsMissingContextError();
            }
            AsAtfData atfData = new AsAtfData(data);

            bc.flash.display3D.textures.AsTexture nativeTexture = context.createTexture(atfData.getWidth(), atfData.getHeight(), atfData.getFormat(), false);
            uploadAtfData(nativeTexture, data);
            AsConcreteTexture concreteTexture = new AsConcreteTexture(nativeTexture, atfData.getFormat(), atfData.getWidth(), atfData.getHeight(), atfData.getNumTextures() > 1, false, false, scale);

            if (AsStarling.getHandleLostContext())
            {
                concreteTexture.restoreOnLostContext(atfData);
            }
            return(concreteTexture);
        }
        public virtual void renderCustom(AsMatrix mvpMatrix, float parentAlpha, String blendMode)
        {
            if (mNumQuads == 0)
            {
                return;
            }
            if (mSyncRequired)
            {
                syncBuffers();
            }
            bool        pma         = mVertexData.getPremultipliedAlpha();
            AsContext3D context     = AsStarling.getContext();
            bool        tinted      = mTinted || (parentAlpha != 1.0f);
            String      programName = mTexture != null?getImageProgramName(tinted, mTexture.getMipMapping(), mTexture.getRepeat(), mTexture.getFormat(), mSmoothing) : QUAD_PROGRAM_NAME;

            sRenderAlpha[0] = sRenderAlpha[1] = sRenderAlpha[2] = pma ? parentAlpha : 1.0f;
            sRenderAlpha[3] = parentAlpha;
            AsMatrixUtil.convertTo3D(mvpMatrix, sRenderMatrix);
            AsRenderSupport.setBlendFactors(pma, blendMode != null ? blendMode : this.getBlendMode());
            context.setProgram(AsStarling.getCurrent().getProgram(programName));
            context.setProgramConstantsFromVector(AsContext3DProgramType.VERTEX, 0, sRenderAlpha, 1);
            context.setProgramConstantsFromMatrix(AsContext3DProgramType.VERTEX, 1, sRenderMatrix, true);
            context.setVertexBufferAt(0, mVertexBuffer, AsVertexData.POSITION_OFFSET, AsContext3DVertexBufferFormat.FLOAT_2);
            if (mTexture == null || tinted)
            {
                context.setVertexBufferAt(1, mVertexBuffer, AsVertexData.COLOR_OFFSET, AsContext3DVertexBufferFormat.FLOAT_4);
            }
            if (mTexture != null)
            {
                context.setTextureAt(0, mTexture.get_base());
                context.setVertexBufferAt(2, mVertexBuffer, AsVertexData.TEXCOORD_OFFSET, AsContext3DVertexBufferFormat.FLOAT_2);
            }
            context.drawTriangles(mIndexBuffer, 0, mNumQuads * 2);
            if (mTexture != null)
            {
                context.setTextureAt(0, null);
                context.setVertexBufferAt(2, null);
            }
            context.setVertexBufferAt(1, null);
            context.setVertexBufferAt(0, null);
        }
        private void onContextCreated(AsEvent _event)
        {
            AsContext3D  context    = AsStarling.getContext();
            AsBitmapData bitmapData = mData as AsBitmapData;
            AsAtfData    atfData    = mData as AsAtfData;

            bc.flash.display3D.textures.AsTexture nativeTexture = null;
            if (bitmapData != null)
            {
                nativeTexture = context.createTexture(mWidth, mHeight, AsContext3DTextureFormat.BGRA, mOptimizedForRenderTexture);
                AsTexture.uploadBitmapData(nativeTexture, bitmapData, mMipMapping);
            }
            else
            {
                if (atfData != null)
                {
                    nativeTexture = context.createTexture(atfData.getWidth(), atfData.getHeight(), atfData.getFormat(), mOptimizedForRenderTexture);
                    AsTexture.uploadAtfData(nativeTexture, atfData.getData());
                }
            }
            mBase = nativeTexture;
        }
        private AsQuadBatch renderPasses(AsDisplayObject _object, AsRenderSupport support, float parentAlpha, bool intoCache)
        {
            AsTexture   cacheTexture = null;
            AsStage     stage        = _object.getStage();
            AsContext3D context      = AsStarling.getContext();
            float       scale        = AsStarling.getCurrent().getContentScaleFactor();

            if (stage == null)
            {
                throw new AsError("Filtered object must be on the stage.");
            }
            if (context == null)
            {
                throw new AsMissingContextError();
            }
            support.finishQuadBatch();
            support.raiseDrawCount((uint)(mNumPasses));
            support.pushMatrix();
            support.setBlendMode(AsBlendMode.NORMAL);
            AsRenderSupport.setBlendFactors(PMA);
            mProjMatrix.copyFrom(support.getProjectionMatrix());
            AsTexture previousRenderTarget = support.getRenderTarget();

            if (previousRenderTarget != null)
            {
                throw new AsIllegalOperationError("It's currently not possible to stack filters! " + "This limitation will be removed in a future Stage3D version.");
            }
            calculateBounds(_object, stage, sBounds);
            updateBuffers(context, sBounds);
            updatePassTextures((int)(sBounds.width), (int)(sBounds.height), mResolution * scale);
            if (intoCache)
            {
                cacheTexture = AsTexture.empty((int)(sBounds.width), (int)(sBounds.height), PMA, true, mResolution * scale);
            }
            support.setRenderTarget(mPassTextures[0]);
            support.clear();
            support.setOrthographicProjection(sBounds.x, sBounds.y, sBounds.width, sBounds.height);
            _object.render(support, parentAlpha);
            support.finishQuadBatch();
            AsRenderSupport.setBlendFactors(PMA);
            support.loadIdentity();
            context.setVertexBufferAt(0, mVertexBuffer, AsVertexData.POSITION_OFFSET, AsContext3DVertexBufferFormat.FLOAT_2);
            context.setVertexBufferAt(1, mVertexBuffer, AsVertexData.TEXCOORD_OFFSET, AsContext3DVertexBufferFormat.FLOAT_2);
            int i = 0;

            for (; i < mNumPasses; ++i)
            {
                if (i < mNumPasses - 1)
                {
                    support.setRenderTarget(getPassTexture(i + 1));
                    support.clear();
                }
                else
                {
                    if (intoCache)
                    {
                        support.setRenderTarget(cacheTexture);
                        support.clear();
                    }
                    else
                    {
                        support.setRenderTarget(previousRenderTarget);
                        support.getProjectionMatrix().copyFrom(mProjMatrix);
                        support.translateMatrix(mOffsetX, mOffsetY);
                        support.setBlendMode(_object.getBlendMode());
                        support.applyBlendMode(PMA);
                    }
                }
                AsTexture passTexture = getPassTexture(i);
                context.setProgramConstantsFromMatrix(AsContext3DProgramType.VERTEX, 0, support.getMvpMatrix3D(), true);
                context.setTextureAt(0, passTexture.get_base());
                activate(i, context, passTexture);
                context.drawTriangles(mIndexBuffer, 0, 2);
                deactivate(i, context, passTexture);
            }
            context.setVertexBufferAt(0, null);
            context.setVertexBufferAt(1, null);
            context.setTextureAt(0, null);
            support.popMatrix();
            if (intoCache)
            {
                support.setRenderTarget(previousRenderTarget);
                support.getProjectionMatrix().copyFrom(mProjMatrix);
                AsQuadBatch quadBatch = new AsQuadBatch();
                AsImage     image     = new AsImage(cacheTexture);
                stage.getTransformationMatrix(_object, sTransformationMatrix);
                AsMatrixUtil.prependTranslation(sTransformationMatrix, sBounds.x + mOffsetX, sBounds.y + mOffsetY);
                quadBatch.addImage(image, 1.0f, sTransformationMatrix);
                return(quadBatch);
            }
            else
            {
                return(null);
            }
        }
        private void createRenderedContents()
        {
            if (mQuadBatch != null)
            {
                mQuadBatch.removeFromParent(true);
                mQuadBatch = null;
            }
            float        scale      = AsStarling.getContentScaleFactor();
            float        width      = mHitArea.getWidth() * scale;
            float        height     = mHitArea.getHeight() * scale;
            AsTextFormat textFormat = new AsTextFormat(mFontName, mFontSize * scale, mColor, mBold, mItalic, mUnderline, null, null, mHAlign);

            textFormat.setKerning(mKerning);
            sNativeTextField.setDefaultTextFormat(textFormat);
            sNativeTextField.setWidth(width);
            sNativeTextField.setHeight(height);
            sNativeTextField.setAntiAliasType(AsAntiAliasType.ADVANCED);
            sNativeTextField.setSelectable(false);
            sNativeTextField.setMultiline(true);
            sNativeTextField.setWordWrap(true);
            sNativeTextField.setText(mText);
            sNativeTextField.setEmbedFonts(true);
            sNativeTextField.setOwnProperty("filters", mNativeFilters);
            if (sNativeTextField.getTextWidth() == 0.0f || sNativeTextField.getTextHeight() == 0.0f)
            {
                sNativeTextField.setEmbedFonts(false);
            }
            if (mAutoScale)
            {
                autoScaleNativeTextField(sNativeTextField);
            }
            float textWidth  = sNativeTextField.getTextWidth();
            float textHeight = sNativeTextField.getTextHeight();
            float xOffset    = 0.0f;

            if (mHAlign == AsHAlign.LEFT)
            {
                xOffset = 2;
            }
            else
            {
                if (mHAlign == AsHAlign.CENTER)
                {
                    xOffset = (width - textWidth) / 2.0f;
                }
                else
                {
                    if (mHAlign == AsHAlign.RIGHT)
                    {
                        xOffset = width - textWidth - 2;
                    }
                }
            }
            float yOffset = 0.0f;

            if (mVAlign == AsVAlign.TOP)
            {
                yOffset = 2;
            }
            else
            {
                if (mVAlign == AsVAlign.CENTER)
                {
                    yOffset = (height - textHeight) / 2.0f;
                }
                else
                {
                    if (mVAlign == AsVAlign.BOTTOM)
                    {
                        yOffset = height - textHeight - 2;
                    }
                }
            }
            AsBitmapData bitmapData = new AsBitmapData(width, height, true, 0x0);

            bitmapData.draw(sNativeTextField, new AsMatrix(1, 0, 0, 1, 0, ((int)(yOffset)) - 2));
            sNativeTextField.setText("");
            if (mTextBounds == null)
            {
                mTextBounds = new AsRectangle();
            }
            mTextBounds.setTo(xOffset / scale, yOffset / scale, textWidth / scale, textHeight / scale);
            AsTexture texture = AsTexture.fromBitmapData(bitmapData, false, false, scale);

            if (mImage == null)
            {
                mImage = new AsImage(texture);
                mImage.setTouchable(false);
                addChild(mImage);
            }
            else
            {
                mImage.getTexture().dispose();
                mImage.setTexture(texture);
                mImage.readjustSize();
            }
        }
        public AsRenderTexture(int width, int height, bool persistent, float scale)
            : base(mActiveTexture = AsTexture.empty(width, height, PMA, true, scale = scale <= 0 ? AsStarling.getContentScaleFactor() : scale), new AsRectangle(0, 0, width, height), true)
        {
            int nativeWidth  = AsGlobal.getNextPowerOfTwo((int)(width * scale));
            int nativeHeight = AsGlobal.getNextPowerOfTwo((int)(height * scale));

            mSupport = new AsRenderSupport();
            mSupport.setOrthographicProjection(0, 0, nativeWidth / scale, nativeHeight / scale);
            if (persistent)
            {
                mBufferTexture = AsTexture.empty(width, height, PMA, true, scale);
                mHelperImage   = new AsImage(mBufferTexture);
                mHelperImage.setSmoothing(AsTextureSmoothing.NONE);
            }
        }