Exemple #1
0
        private void Draw(DrawState state, Vector2 scale, byte clipDepth)
        {
            Element parent = this.parent;


            Matrix         matrix;
            GraphicsDevice device = null;

            if (parent == null)
            {
                if (state.DrawTarget.MultiSampleType != MultiSampleType.None)
                {
                    device = state.BeginGetGraphicsDevice(StateFlag.None);
                    device.RenderState.MultiSampleAntiAlias = false;
                }

                this.clipTestActive = false;

                DeviceRenderState rstate = new DeviceRenderState();
                rstate.DepthColourCull.DepthWriteEnabled = false;
                rstate.DepthColourCull.DepthTestEnabled  = false;

                state.PushRenderState(ref rstate);

                if (camera == null)
                {
                    camera = state.UserValues[cameraID] as Xen.Camera.Camera2D;
                    if (camera == null)
                    {
                        camera = new Xen.Camera.Camera2D(true);
                        state.UserValues[cameraID] = camera;
                    }
                }

                state.PushCamera(camera);
            }
            else
            {
                this.clipTestActive = parent.clipTestActive | parent.ClipsChildren;
            }

            StencilTestState stencilState = new StencilTestState();

            if (clipTestActive)
            {
                stencilState.Enabled              = true;
                stencilState.ReferenceValue       = clipDepth;
                stencilState.StencilFunction      = CompareFunction.Equal;
                stencilState.StencilPassOperation = StencilOperation.Keep;
            }

            bool clearStencil = false;

            if (this.ClipsChildren)
            {
                clearStencil = clipDepth == 255;
                clipDepth--;

                if (!clipTestActive)
                {
                    //check there actually is a stencil buffer
#if DEBUG
                    DepthFormat format = state.DrawTarget.SurfaceDepthFormat ?? DepthFormat.Unknown;

                    if (format != DepthFormat.Depth24Stencil8)
                    {
                        throw new InvalidOperationException("ElementRect.ClipChildren requires the DrawTarget has a valid Depth Buffer with an 8bit Stencil Buffer");
                    }
#endif

                    stencilState.Enabled              = true;
                    stencilState.ReferenceValue       = clipDepth;
                    stencilState.StencilPassOperation = StencilOperation.Replace;
                }
                else
                {
                    stencilState.StencilPassOperation = StencilOperation.Decrement;
                }
            }

            if ((scale.X != 0 && scale.Y != 0))
            {
                Vector2 size = ElementSize;
                GetDisplayMatrix(out matrix, scale, ref size);

                state.PushWorldMatrixMultiply(ref matrix);

                BindShader(state, false);

                state.RenderState.AlphaBlend  = blend;
                state.RenderState.StencilTest = stencilState;


                if (!UseSize)
                {
                    size = new Vector2(1, 1);
                }
                else
                if (IsNormalised)
                {
                    size *= scale;
                }

                PreDraw(size);

                DrawElement(state);

                List <Element> children = Children;
                if (children != null)
                {
                    foreach (Element child in children)
                    {
                        if (((IDraw)child).CullTest(state))
                        {
                            child.Draw(state, size, clipDepth);
                        }
                    }
                }

                if (clearStencil)
                {
                    BindShader(state, true);
                    stencilState                      = new StencilTestState();
                    stencilState.Enabled              = true;
                    stencilState.StencilFunction      = CompareFunction.Never;
                    stencilState.StencilFailOperation = StencilOperation.Zero;
                    state.RenderState.StencilTest     = stencilState;

                    DrawElement(state);
                }

                state.PopWorldMatrix();
            }


            if (parent == null)
            {
                state.PopRenderState();
                state.PopCamera();
            }

            if (device != null)
            {
                device.RenderState.MultiSampleAntiAlias = true;
                state.EndGetGraphicsDevice();
            }
        }
		private void Draw(DrawState state, Vector2 scale, byte clipDepth)
		{
			Element parent = this.parent;


			Matrix matrix;

			if (parent == null)
			{
				this.clipTestActive = false;

				state.RenderState.Push();
				state.RenderState.CurrentRasterState.MultiSampleAntiAlias = false;
				state.RenderState.CurrentDepthState.DepthWriteEnabled = WriteToDepth;
				state.RenderState.CurrentDepthState.DepthTestEnabled = WriteToDepth;

				if (camera == null)
				{
					camera = state.Application.UserValues[cameraID] as Xen.Camera.Camera2D;
					if (camera == null)
					{
						camera = new Xen.Camera.Camera2D(true);
						state.Application.UserValues[cameraID] = camera;
					}
				}

				state.Camera.Push(camera);
			}
			else
				this.clipTestActive = parent.clipTestActive | parent.ClipsChildren;

			StencilState stencilState = new StencilState();
			if (clipTestActive)
			{
				stencilState.Enabled = true;
				stencilState.ReferenceValue = clipDepth;
				stencilState.StencilFunction = CompareFunction.Equal;
				stencilState.StencilPassOperation = StencilOperation.Keep;
			}

			bool clearStencil = false;
			if (this.ClipsChildren)
			{
				clearStencil = clipDepth == 255;
				clipDepth--;

				if (!clipTestActive)
				{
					//check there actually is a stencil buffer
#if DEBUG
					DepthFormat format = state.DrawTarget.SurfaceDepthFormat;

					if (format != DepthFormat.Depth24Stencil8)
						throw new InvalidOperationException("ElementRect.ClipChildren requires the DrawTarget has a valid Depth Buffer with an 8bit Stencil Buffer");
#endif

					stencilState.Enabled = true;
					stencilState.ReferenceValue = clipDepth;
					stencilState.StencilPassOperation = StencilOperation.Replace;
				}
				else
					stencilState.StencilPassOperation = StencilOperation.Decrement;
			}

			if ((scale.X != 0 && scale.Y != 0))
			{
				Vector2 size = ElementSize;
				GetDisplayMatrix(out matrix, scale, ref size);

				using (state.WorldMatrix.PushMultiply(ref matrix))
				{

					IShader shader = BindShader(state, false);
					if (shader != null)
						state.Shader.Push(shader);

					state.RenderState.CurrentBlendState = blend;
					state.RenderState.CurrentStencilState = stencilState;


					if (!UseSize)
						size = new Vector2(1, 1);
					else
						if (IsNormalised)
							size *= scale;

					PreDraw(size);

					DrawElement(state);

					List<Element> children = Children;
					if (children != null)
						foreach (Element child in children)
							if (((IDraw)child).CullTest(state))
								child.Draw(state, size, clipDepth);

					if (shader != null)
						state.Shader.Pop();

					if (clearStencil)
					{
						shader = BindShader(state, true);
						if (shader != null)
							state.Shader.Push(shader);
						stencilState = new StencilState();
						stencilState.Enabled = true;
						stencilState.StencilFunction = CompareFunction.Never;
						stencilState.StencilFailOperation = StencilOperation.Zero;
						state.RenderState.CurrentStencilState = stencilState;

						DrawElement(state);

						if (shader != null)
							state.Shader.Pop();
					}

				}
			}


			if (parent == null)
			{
				state.RenderState.Pop();
				state.Camera.Pop();
			}
		}