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); } }
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--; }