Esempio n. 1
0
        private void BeforeDraw()
        {
            m_bNoDrawChildren = false;

            if (m_childClippingMode == CCClipMode.Bounds)
            {
                // We always clip to the bounding box
                var rect   = new CCRect(0, 0, m_obContentSize.Width, m_obContentSize.Height);
                var bounds = CCAffineTransform.Transform(rect, NodeToWorldTransform());

                var winSize = CCDirector.SharedDirector.WinSize;

                CCRect prevScissorRect;
                if (CCDrawManager.ScissorRectEnabled)
                {
                    prevScissorRect = CCDrawManager.ScissorRect;
                }
                else
                {
                    prevScissorRect = new CCRect(0, 0, winSize.Width, winSize.Height);
                }

                if (!bounds.IntersectsRect(prevScissorRect))
                {
                    m_bNoDrawChildren = true;
                    return;
                }

                float minX = Math.Max(bounds.MinX, prevScissorRect.MinX);
                float minY = Math.Max(bounds.MinY, prevScissorRect.MinY);
                float maxX = Math.Min(bounds.MaxX, prevScissorRect.MaxX);
                float maxY = Math.Min(bounds.MaxY, prevScissorRect.MaxY);

                if (CCDrawManager.ScissorRectEnabled)
                {
                    m_bRestoreScissor = true;
                }
                else
                {
                    CCDrawManager.ScissorRectEnabled = true;
                }

                m_tSaveScissorRect = prevScissorRect;

                CCDrawManager.SetScissorInPoints(minX, minY, maxX - minX, maxY - minY);
            }
            else if (m_childClippingMode == CCClipMode.BoundsWithRenderTarget)
            {
                m_tSaveScissorRect = CCDrawManager.ScissorRect;
                m_bRestoreScissor  = CCDrawManager.ScissorRectEnabled;

                CCDrawManager.ScissorRectEnabled = false;

                CCDrawManager.PushMatrix();
                CCDrawManager.SetIdentityMatrix();

                m_pRenderTexture.BeginWithClear(0, 0, 0, 0);
            }
        }
Esempio n. 2
0
        public override void Visit()
        {
            if (m_pStencil == null || !m_pStencil.Visible)
            {
                if (m_bInverted)
                {
                    // draw everything
                    base.Visit();
                }
                return;
            }

            if (_layer + 1 == 8) //DepthFormat.Depth24Stencil8
            {
                if (_once)
                {
                    CCLog.Log(
                        "Nesting more than 8 stencils is not supported. Everything will be drawn without stencil for this node and its childs."
                        );
                    _once = false;
                }
                base.Visit();
                return;
            }

            _layer++;

            int maskLayer   = 1 << _layer;
            int maskLayerL  = maskLayer - 1;
            int maskLayerLe = maskLayer | maskLayerL;

            var saveDepthStencilState = CCDrawManager.DepthStencilState;

            ///////////////////////////////////
            // CLEAR STENCIL BUFFER

            var stencilState = new DepthStencilState()
            {
                DepthBufferEnable = false,

                StencilEnable = true,

                StencilFunction = CompareFunction.Never,

                StencilMask      = maskLayer,
                StencilWriteMask = maskLayer,
                ReferenceStencil = maskLayer,

                StencilFail = !m_bInverted ? StencilOperation.Zero : StencilOperation.Replace
            };

            CCDrawManager.DepthStencilState = stencilState;

            // draw a fullscreen solid rectangle to clear the stencil buffer
            var size = CCDirector.SharedDirector.WinSize;

            CCDrawManager.PushMatrix();
            CCDrawManager.SetIdentityMatrix();

            CCDrawingPrimitives.Begin();
            CCDrawingPrimitives.DrawSolidRect(CCPoint.Zero, new CCPoint(size.Width, size.Height), new CCColor4B(255, 255, 255, 255));
            CCDrawingPrimitives.End();

            CCDrawManager.PopMatrix();

            ///////////////////////////////////
            // DRAW CLIPPING STENCIL

            stencilState = new DepthStencilState()
            {
                DepthBufferEnable = false,

                StencilEnable = true,

                StencilFunction = CompareFunction.Never,

                StencilMask      = maskLayer,
                StencilWriteMask = maskLayer,
                ReferenceStencil = maskLayer,

                StencilFail = !m_bInverted ? StencilOperation.Replace : StencilOperation.Zero,
            };
            CCDrawManager.DepthStencilState = stencilState;

            if (m_fAlphaThreshold < 1)
            {
                if (_alphaTest == null)
                {
                    _alphaTest = new AlphaTestEffect(CCDrawManager.GraphicsDevice);
                    _alphaTest.AlphaFunction = CompareFunction.Greater;
                }

                _alphaTest.ReferenceAlpha = (byte)(255 * m_fAlphaThreshold);

                CCDrawManager.PushEffect(_alphaTest);
            }

            CCDrawManager.PushMatrix();
            Transform();
            m_pStencil.Visit();
            CCDrawManager.PopMatrix();

            if (m_fAlphaThreshold < 1)
            {
                CCDrawManager.PopEffect();
            }

            ///////////////////////////////////
            // DRAW CONTENT

            stencilState = new DepthStencilState()
            {
                DepthBufferEnable = saveDepthStencilState.DepthBufferEnable,

                StencilEnable = true,

                StencilMask      = maskLayerLe,
                StencilWriteMask = 0,
                ReferenceStencil = maskLayerLe,

                StencilFunction = CompareFunction.Equal,

                StencilPass = StencilOperation.Keep,
                StencilFail = StencilOperation.Keep,
            };
            CCDrawManager.DepthStencilState = stencilState;


            base.Visit();

            //Restore DepthStencilState
            CCDrawManager.DepthStencilState = saveDepthStencilState;

            _layer--;
        }