PushClipRect() 공개 메소드

The clipping rectangle can be used to limit rendering in the current render target to a certain area. This method expects the rectangle in stage coordinates. Internally, it uses the 'glScissor' command of OpenGL, which works with pixel coordinates. Any pushed rectangle is intersected with the previous rectangle; the method returns that intersection.
public PushClipRect ( Rectangle clipRect ) : Rectangle
clipRect Sparrow.Geom.Rectangle
리턴 Sparrow.Geom.Rectangle
예제 #1
0
        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;
        }
예제 #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();
            }
        }