Inheritance: DisplayObject
Beispiel #1
0
        /// <summary>
        /// Adds another quad batch to this batch, using custom alpha and blend mode values (ignoring the
        /// batch's original values) and transforming each vertex by a certain transformation matrix. Just
        /// like the 'AddQuad' method, you have to make sure that you only add batches with an equal state.
        /// </summary>
        public void AddQuadBatch(QuadBatch quadBatch, float alpha, uint blendMode, Matrix matrix = null)
        {
            int vertexID    = _numQuads * 4;
            int numQuads    = quadBatch.NumQuads;
            int numVertices = numQuads * 4;

            if (matrix == null)
            {
                matrix = quadBatch.TransformationMatrix;
            }
            if (_numQuads + numQuads > _capacity)
            {
                Capacity = _numQuads + numQuads;
            }
            if (_numQuads == 0)
            {
                _texture            = quadBatch.QuadTexture;
                _premultipliedAlpha = quadBatch.PremultipliedAlpha;
                BlendMode           = blendMode;
                _vertexData.SetPremultipliedAlpha(_premultipliedAlpha, false);
            }

            _tinted = alpha != 1.0f || quadBatch.Tinted;

            quadBatch.VertexData.CopyToVertexData(_vertexData, _tinted, vertexID, numVertices);
            _vertexData.TransformVertices(matrix, vertexID, numVertices);

            if (alpha != 1.0f)
            {
                _vertexData.ScaleAlphaBy(alpha, vertexID, numVertices);
            }

            _syncRequired = true;
            _numQuads    += numQuads;
        }
Beispiel #2
0
        override public void Render(RenderSupport support)
        {
            if (ClipRect != null)
            {
                Rectangle stageClipRect = support.PushClipRect(ClipRectInSpace(Stage));
                if (stageClipRect != null || stageClipRect.IsEmpty())
                {
                    // empty clipping bounds - no need to render children
                    support.PopClipRect();
                    return;
                }
            }

            if (_flattenRequested)
            {
                _flattenedContents = QuadBatch.Compile(this, _flattenedContents);
                _flattenRequested  = false;
            }

            if (_flattenedContents.Count > 0)
            {
                support.FinishQuadBatch();
                support.AddDrawCalls(_flattenedContents.Count);

                Matrix mvpMatrix        = support.MvpMatrix;
                float  alpha            = support.Alpha;
                uint   supportBlendMode = support.BlendMode;

                foreach (QuadBatch quadBatch in _flattenedContents)
                {
                    uint blendMode = quadBatch.BlendMode;
                    if (blendMode == Sparrow.Display.BlendMode.AUTO)
                    {
                        blendMode = supportBlendMode;
                    }

                    quadBatch.Render(mvpMatrix, alpha, blendMode);
                }
            }
            else
            {
                base.Render(support);
            }

            if (ClipRect != null)
            {
                support.PopClipRect();
            }
        }
Beispiel #3
0
        public TextField(float width, float height, string text = "", string fontName = "mini", float fontSize = 14, uint color = 0x0)
        {
            _text = text;
            _fontSize = fontSize;
            _color = color;
            _hAlign = HAlign.Center;
            _vAlign = VAlign.Center;
            _autoScale = false;
            _kerning = true;
            _requiresRedraw = true;
            FontName = fontName;

            _hitArea = new Quad(width, height);
            _hitArea.Alpha = 0.0f;
            AddChild(_hitArea);

            _contents = new QuadBatch();
            _contents.Touchable = false;
            AddChild(_contents);

            //[self addEventListener:@selector(onFlatten:) atObject:self forType:SPEventTypeFlatten];
        }
Beispiel #4
0
 /// <summary>
 /// Adds another quad batch to this batch.
 /// </summary>
 public void AddQuadBatch(QuadBatch quadBatch)
 {
     AddQuadBatch(quadBatch, quadBatch.Alpha, quadBatch.BlendMode);
 }
        private QuadBatch RenderPasses(DisplayObject obj, RenderSupport support, bool intoCache)
        {
            Texture cacheTexture = null;
            Stage stage = obj.Stage;
            float scale = Resolution;

            if (stage == null)
            {
                throw new InvalidOperationException("Filtered object must be on the stage.");
            }
            // the bounds of the object in stage coordinates
            Rectangle boundsPOT;
            Rectangle bounds;
            CalcBounds(obj, stage, scale, !intoCache, out bounds, out boundsPOT);

            if (bounds.IsEmpty())
            {
                DisposePassTextures();
                return intoCache ? new QuadBatch() : null;
            }

            UpdateBuffers(boundsPOT);
            UpdatePassTextures((int)boundsPOT.Width, (int)boundsPOT.Height, scale);

            support.FinishQuadBatch();
            support.AddDrawCalls(NumPasses);
            support.PushState(Matrix.Create(), 1.0f, BlendMode.AUTO);

            // save original projection matrix and render target
            _projMatrix.CopyFromMatrix(support.ProjectionMatrix);
            Texture previousRenderTarget = support.RenderTarget;

            // use cache?
            if (intoCache)
            {
                cacheTexture = CreateTexture((int)boundsPOT.Width, (int)boundsPOT.Height, scale);
            }

            // draw the original object into a texture
            support.RenderTarget = _passTextures[0];
            SparrowSharpApp.Context.ScissorBox = null; // we want the entire texture cleared
            support.Clear();
            support.BlendMode = BlendMode.NORMAL;
            support.SetupOrthographicProjection(boundsPOT.Left, boundsPOT.Right, boundsPOT.Bottom, boundsPOT.Top);
            obj.Render(support);
            support.FinishQuadBatch();

            // prepare drawing of actual filter passes
            support.ApplyBlendMode(true);
            support.ModelViewMatrix.Identity();
            support.PushClipRect(bounds);

            GL.BindBuffer (BufferTarget.ArrayBuffer, _vertexBufferName);
            GL.BindBuffer (BufferTarget.ElementArrayBuffer, _indexBufferName);

            GL.EnableVertexAttribArray (VertexPosID);
            GL.VertexAttribPointer (VertexPosID, 2, VertexAttribPointerType.Float, false, Vertex.SIZE, (IntPtr)Vertex.POSITION_OFFSET);

            GL.EnableVertexAttribArray (TexCoordsID);
            GL.VertexAttribPointer (TexCoordsID, 2, VertexAttribPointerType.Float, false, Vertex.SIZE, (IntPtr)Vertex.TEXTURE_OFFSET);

            // draw all passes
            for (int i = 0; i < NumPasses; ++i)
            {
                if (i < NumPasses - 1)
                { // intermediate pass
                    // draw into pass texture
                    support.RenderTarget = PassTextureForPass(i + 1);
                    support.Clear();
                }
                else
                { // final pass
                    if (intoCache)
                    {
                        // draw into cache texture
                        support.RenderTarget = cacheTexture;
                        support.Clear();
                    }
                    else
                    {
                        // draw into back buffer, at original (stage) coordinates
                        support.RenderTarget = previousRenderTarget;
                        support.ProjectionMatrix = _projMatrix;
                        support.ModelViewMatrix.Translate(OffsetX, OffsetY);
                        support.BlendMode = obj.BlendMode;
                        support.ApplyBlendMode(true);
                    }
                }

                Texture passTexture = PassTextureForPass(i);

                GL.ActiveTexture (TextureUnit.Texture0);
                GL.BindTexture (TextureTarget.Texture2D, passTexture.Name);

                ActivateWithPass (i, passTexture, support.MvpMatrix);
                GL.DrawElements (BeginMode.Triangles, 6, DrawElementsType.UnsignedShort, IntPtr.Zero);
                
                DeactivateWithPass(i, passTexture);
            }

            GL.DisableVertexAttribArray(VertexPosID);
            GL.DisableVertexAttribArray(TexCoordsID);

            support.PopState();
            support.PopClipRect();

            QuadBatch cache = null;
            if (intoCache)
            {
                // restore support settings
                support.RenderTarget = previousRenderTarget;
                support.ProjectionMatrix = _projMatrix;

                // Create an image containing the cache. To have a display object that contains
                // the filter output in object coordinates, we wrap it in a QuadBatch: that way,
                // we can modify it with a transformation matrix.
                cache = new QuadBatch();
                Image image = new Image(cacheTexture);

                Matrix matrix = stage.TransformationMatrixToSpace(obj);
                // Note: the next line was originally:
                // matrix.Translate (bounds.X + OffsetX, bounds.Y + OffsetY);
                // this seems like a sparrow-s bug; fix is from Starling
                matrix.PrependTranslation(bounds.X + OffsetX, bounds.Top + OffsetY);
                cache.AddQuad(image, 1.0f, BlendMode.AUTO, matrix);
            }

            return cache;
        }
 private void DisposeCache()
 {
     _cache = null;
 }
        /// <summary>
        /// Applies the filter on a certain display object, rendering the output into the current render
        /// target. This method is called automatically by Sparrow's rendering system for the object the
        /// filter is attached to.
        /// </summary>
        public void RenderObject(DisplayObject obj, RenderSupport support)
        {
            // bottom layer
            if (Mode == FragmentFilterMode.Above)
            {
                obj.Render(support);
            }
                
            // center layer
            if (_cacheRequested)
            {
                _cacheRequested = false;
                _cache = RenderPasses(obj, support, true);
                DisposePassTextures();
            }

            if (_cache != null)
            {
                _cache.Render(support);
            }
            else
            {
                RenderPasses(obj, support, false);
            }

            // top layer
            if (Mode == FragmentFilterMode.Below)
            {
                obj.Render(support);
            }
        }
        /// <summary>
        ///  Draws text into a quad batch.
        /// </summary>
        public void FillQuadBatch(QuadBatch quadBatch, float width, float height, string text, float size, uint color, HAlign hAlign, VAlign vAlign, bool autoScale, bool kerning)
        {
            List<CharLocation> charLocations = ArrangeCharsInArea(width, height, text, size, hAlign, vAlign, autoScale, kerning);
            _helperImage.Color = color;

            if (charLocations.Count > MAX_TEXT_CHAR_COUNT)
            {
                throw new InvalidDataException(string.Format("Bitmap font text is limited to {0} characters", MAX_TEXT_CHAR_COUNT));
            }

            CharLocation charLocation;
            for (int i = 0; i < charLocations.Count; i++)
            {
                charLocation = charLocations[i];
                _helperImage.Texture = charLocation.BitmapChar.Texture;
                _helperImage.X = charLocation.X;
                _helperImage.Y = charLocation.Y;
                _helperImage.ScaleX = _helperImage.ScaleY = charLocation.Scale;
                _helperImage.ReadjustSize();
                quadBatch.AddQuad(_helperImage);
            }

        }
Beispiel #9
0
 /// <summary>
 /// Adds another quad batch to this batch.
 /// </summary>
 public void AddQuadBatch(QuadBatch quadBatch)
 {
     AddQuadBatch(quadBatch, quadBatch.Alpha, quadBatch.BlendMode);
 }
 /// <summary>
 /// Resets the render state stack to the default.
 /// </summary>
 public void NextFrame()
 {
     _clipRectStackSize = 0;
     _stateStackIndex = 0;
     _quadBatchIndex = 0;
     _numDrawCalls = 0;
     _quadBatchTop = _quadBatches[0];
     _stateStackTop = _stateStack[0];
 }
        /// <summary>
        /// Clears all vertex and index buffers, releasing the associated memory. Useful in low-memory
        /// situations. Don't call from within a render method!
        /// </summary>
        public void PurgeBuffers()
        {
            _quadBatches.Clear();
            _quadBatchTop = new QuadBatch();
            _quadBatches.Add(_quadBatchTop);

            _quadBatchIndex = 0;
            _quadBatchSize = 1;
        }
        public RenderSupport()
        {
            _projectionMatrix = Matrix.Create();
            _mvpMatrix = Matrix.Create();

            _stateStack = new List<RenderState> { new RenderState() };
            _stateStackIndex = 0;
            _stateStackSize = 1;
            _stateStackTop = _stateStack[0];

            _quadBatches = new List<QuadBatch> { new QuadBatch() };
            _quadBatchIndex = 0;
            _quadBatchSize = 1;
            _quadBatchTop = _quadBatches[0];

            _clipRectStack = new List<Rectangle>();
            _clipRectStackSize = 0;

            SetupOrthographicProjection(0, 320, 0, 480);
        }
Beispiel #13
0
        public static int Compile(DisplayObject displayObject, List <QuadBatch> quadBatches, int quadBatchID,
                                  Matrix transformationMatrix, float alpha, uint blendMode)
        {
            bool  isRootObject = false;
            float objectAlpha  = displayObject.Alpha;

            Quad      quad  = displayObject is Quad ? (Quad)displayObject : null;
            QuadBatch batch = displayObject is QuadBatch ? (QuadBatch)displayObject : null;
            DisplayObjectContainer container = displayObject is DisplayObjectContainer ? (DisplayObjectContainer)displayObject : null;

            if (quadBatchID == -1)
            {
                isRootObject = true;
                quadBatchID  = 0;
                objectAlpha  = 1.0f;
                blendMode    = displayObject.BlendMode;

                if (quadBatches.Count == 0)
                {
                    quadBatches.Add(new QuadBatch());
                }
                else
                {
                    quadBatches[0].Reset();
                }
            }

            if (container != null)
            {
                Matrix childMatrix = Matrix.Create();
                childMatrix.Identity();
                int numChildren = container.NumChildren;
                for (int i = 0; i < numChildren; i++)
                {
                    DisplayObject child = container.GetChild(i);
                    if (child.HasVisibleArea)
                    {
                        uint childBlendMode = child.BlendMode;
                        if (childBlendMode == Sparrow.Display.BlendMode.AUTO)
                        {
                            childBlendMode = blendMode;
                        }

                        childMatrix.CopyFromMatrix(transformationMatrix);
                        childMatrix.PrependMatrix(child.TransformationMatrix);

                        quadBatchID = Compile(child, quadBatches, quadBatchID, childMatrix, alpha * objectAlpha, childBlendMode);
                    }
                }
            }
            else if (quad != null)
            {
                Texture texture = quad.Texture;
                bool    tinted  = quad.Tinted;
                bool    pma     = quad.PremultipliedAlpha;

                QuadBatch currentBatch = quadBatches[quadBatchID];
                if (currentBatch.IsStateChange(tinted, texture, alpha * objectAlpha, pma, blendMode, 1))
                {
                    quadBatchID++;

                    if (quadBatches.Count <= quadBatchID)
                    {
                        quadBatches.Add(new QuadBatch());
                    }

                    currentBatch = quadBatches[quadBatchID];
                    currentBatch.Reset();
                }

                currentBatch.AddQuad(quad, alpha * objectAlpha, blendMode, transformationMatrix);
            }
            else if (batch != null)
            {
                Texture texture  = quad.Texture;
                bool    tinted   = quad.Tinted;
                bool    pma      = quad.PremultipliedAlpha;
                int     numQuads = batch.NumQuads;

                QuadBatch currentBatch = quadBatches[quadBatchID];
                if (currentBatch.IsStateChange(tinted, texture, alpha * objectAlpha, pma, blendMode, numQuads))
                {
                    quadBatchID++;

                    if (quadBatches.Count <= quadBatchID)
                    {
                        quadBatches.Add(new QuadBatch());
                    }

                    currentBatch = quadBatches[quadBatchID];
                    currentBatch.Reset();
                }

                currentBatch.AddQuadBatch(batch, alpha * objectAlpha, blendMode, transformationMatrix);
            }
            else
            {
                throw new InvalidOperationException("Unsupported display object");
            }

            if (!isRootObject)
            {
                return(quadBatchID);
            }

            // remove unused batches
            for (int i = quadBatches.Count - 1; i > quadBatchID; --i)
            {
                quadBatches.RemoveAt(quadBatches.Count - 1);
            }
            return(quadBatchID);
        }
Beispiel #14
0
 /// <summary>
 /// Adds another quad batch to this batch, using a custom alpha value (ignoring the batch's
 /// original alpha).
 /// </summary>
 public void AddQuadBatch(QuadBatch quadBatch, float alpha)
 {
     AddQuadBatch(quadBatch, alpha, quadBatch.BlendMode);
 }
Beispiel #15
0
 /// <summary>
 /// Adds another quad batch to this batch, using a custom alpha value (ignoring the batch's
 /// original alpha).
 /// </summary>
 public void AddQuadBatch(QuadBatch quadBatch, float alpha)
 {
     AddQuadBatch(quadBatch, alpha, quadBatch.BlendMode);
 }
Beispiel #16
0
        /// <summary>
        /// Adds another quad batch to this batch, using custom alpha and blend mode values (ignoring the
        /// batch's original values) and transforming each vertex by a certain transformation matrix. Just
        /// like the 'AddQuad' method, you have to make sure that you only add batches with an equal state.
        /// </summary>
        public void AddQuadBatch(QuadBatch quadBatch, float alpha, uint blendMode, Matrix matrix = null)
        {
            int vertexID = _numQuads * 4;
            int numQuads = quadBatch.NumQuads;
            int numVertices = numQuads * 4;

            if (matrix == null)
            {
                matrix = quadBatch.TransformationMatrix;
            }
            if (_numQuads + numQuads > _capacity)
            {
                Capacity = _numQuads + numQuads;
            }
            if (_numQuads == 0)
            {
                _texture = quadBatch.QuadTexture;
                _premultipliedAlpha = quadBatch.PremultipliedAlpha;
                BlendMode = blendMode;
                _vertexData.SetPremultipliedAlpha(_premultipliedAlpha, false);
            }
                
            _tinted = alpha != 1.0f || quadBatch.Tinted;

            quadBatch.VertexData.CopyToVertexData(_vertexData, _tinted, vertexID, numVertices);
            _vertexData.TransformVertices(matrix, vertexID, numVertices);

            if (alpha != 1.0f)
            {
                _vertexData.ScaleAlphaBy(alpha, vertexID, numVertices);
            }

            _syncRequired = true;
            _numQuads += numQuads;
        }
        /// <summary>
        /// Renders the current quad batch and resets it.
        /// </summary>
        public void FinishQuadBatch()
        {
            if (_quadBatchTop.NumQuads != 0)
            {
                _quadBatchTop.Render(_projectionMatrix);
                _quadBatchTop.Reset();

                if (_quadBatchSize == _quadBatchIndex + 1)
                {
                    _quadBatches.Add(new QuadBatch());
                    _quadBatchSize++;
                }

                _numDrawCalls++;
                _quadBatchTop = _quadBatches[++_quadBatchIndex];
            }
        }