Пример #1
0
        public void Draw(DrawState state)
        {
            SetupShadowShader(state);

            //set render mode to shadow map
            state.PushDrawFlag(new ModelInstance.ShaderProviderFlag(this.shaderProvider));
            state.PushDrawFlag(TutorialRenderMode.DrawShadow);

            //Push the shadow map camera as a post-culler.
            //This way, anything not within the frustum of the shadow map
            //camera will not be drawn with the shadow shader
            state.PushPostCuller(this.shadowMapTarget.Camera);

            //set an additive blending mode
            state.PushRenderState();
            state.RenderState.AlphaBlend = AlphaBlendState.Additive;
            state.RenderState.DepthColourCull.DepthWriteEnabled = false;

            //draw the shadowed scene
            scene.Draw(state);

            state.PopRenderState();
            state.PopPostCuller();

            state.PopDrawFlag <TutorialRenderMode>();
            state.PopDrawFlag <ModelInstance.ShaderProviderFlag>();
        }
Пример #2
0
        /// <summary>
        /// End the modifier (This method is called by the DrawTarget)
        /// </summary>
        /// <param name="state"></param>
        public void End(DrawState state)
        {
            if (enabledBuffer)
            {
                state.PopPostCuller();
            }

            if (cubes.Count > 0 ||
                spheres.Count > 0)
            {
                state.PushCamera(camera);

                state.PushRenderState();
                state.RenderState.DepthColourCull.DepthWriteEnabled = false;
                state.RenderState.AlphaBlend = AlphaBlendState.Alpha;

                Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>();
                shader.FillColour = new Vector4(1, 1, 1, 0.25f);
                shader.Bind(state);

                GenCubeVS(state);
                GenSphereVS(state);

                Matrix mat;
                for (int i = 0; i < cubes.Count; i++)
                {
                    mat = cubes[i];
                    state.PushWorldMatrix(ref mat);

                    cubeVS.Draw(state, null, PrimitiveType.LineList);

                    state.PopWorldMatrix();
                }

                mat = Matrix.Identity;
                Vector4 v;
                for (int i = 0; i < spheres.Count; i++)
                {
                    v = spheres[i];

                    mat.M11 = v.W;
                    mat.M22 = v.W;
                    mat.M33 = v.W;
                    mat.M41 = v.X;
                    mat.M42 = v.Y;
                    mat.M43 = v.Z;

                    state.PushWorldMatrix(ref mat);

                    sphereVS.Draw(state, null, PrimitiveType.LineList);

                    state.PopWorldMatrix();
                }

                state.PopRenderState();
                state.PopCamera();
            }
        }
Пример #3
0
        /// <summary>
        /// Draw the items in sorted order
        /// </summary>
        /// <param name="state"></param>
        public void Draw(DrawState state)
        {
            if (itemCount == 0)
            {
                return;
            }

            sortFrameIndex++;

            //sortEvery so many frames...
            if (sortFrameIndex > sortEvery)
            {
                sortFrameIndex = 0;                 // ok, time to sort
            }
            else
            {
                //otherwise,
                //draw using the previous frame sorting...

                if (sortMode == DepthSortMode.FrontToBack)
                {
                    for (int i = 0; i < previousFrameVisibleCount; i++)
                    {
                        IDraw item = items[i].item;
                        if (item.CullTest(state))
                        {
                            item.Draw(state);
                        }
                    }
                }
                else
                {
                    for (int i = previousFrameVisibleCount - 1; i >= 0; i--)
                    {
                        IDraw item = items[i].item;
                        if (item.CullTest(state))
                        {
                            item.Draw(state);
                        }
                    }
                }
                int drawn = 0;
                //draw the rest...
                for (int i = previousFrameVisibleCount; i < this.itemCount; i++)
                {
                    IDraw item = items[i].item;
                    if (item.CullTest(state))
                    {
                        item.Draw(state);
                        drawn++;
                    }
                }
                return;
            }

            //sort and draw...

            ICuller culler = state;

            state.PushPostCuller(postCuller);

            postCuller.BeginPreCullItem(state);

            int index           = 0;
            int visible         = 0;
            int backIndex       = itemCount - 1;
            int backIndexCulled = itemCount - 1;
            int unsortedItems   = 0;

            Vector3 position, camera, direction;

            state.Camera.GetCameraPosition(out camera);
            state.Camera.GetCameraViewDirection(out direction);

            for (int i = 0; i < itemCount; i++)
            {
                Entry item = items[index];

                postCuller.ResetPreCullItem();

                bool cullTest = item.item.CullTest(culler);

                if (cullTest && postCuller.TryGetPosition(out position))
                {
                    //keep item in the list
                    items[index] = items[visible];

                    //centre of cull tests
                    position.X -= camera.X;
                    position.Y -= camera.Y;
                    position.Z -= camera.Z;

                    float depth = direction.X * position.X + direction.Y * position.Y + direction.Z * position.Z;

                    if (depth > 0)
                    {
                        depth = position.X * position.X + position.Y * position.Y + position.Z * position.Z;
                    }

                    depths[visible] = depth;
                    items[visible]  = item;

                    visible++;
                    index++;
                }
                else
                {
                    //swap the back culled element to this one, don't increment index
                    items[index]           = items[backIndexCulled];
                    items[backIndexCulled] = item;
                    backIndexCulled--;

                    if (cullTest)
                    {
                        //as the last step, put this item at the very back.
                        items[backIndexCulled + 1] = items[backIndex];
                        items[backIndex]           = item;
                        depths[backIndex]          = item.addIndex;

                        backIndex--;
                        unsortedItems++;
                    }
                }
            }

            state.PopPostCuller();

            if (unsortedItems > 0)
            {
                backIndex++;

                //due to the way the algorithm works, the unsorted list is usually ordered like so:
                //1,2,3,4,5,6,7,0

                //so put the last element first, and check if they are out of order

                float lastD      = this.depths[this.itemCount - 1];
                Entry lastE      = this.items[this.itemCount - 1];
                bool  outOfOrder = lastD > this.depths[backIndex];

                for (int i = this.itemCount - 2; i >= backIndex; i--)
                {
                    if (i != this.itemCount - 2)
                    {
                        outOfOrder |= this.depths[i] > this.depths[i + 1];
                    }

                    this.items[i + 1]  = this.items[i];
                    this.depths[i + 1] = this.depths[i];
                }
                this.depths[backIndex] = lastD;
                this.items[backIndex]  = lastE;

                //draw the unsorted items in their add order (which was written to depths)
                //this sort won't be all that efficient
                if (outOfOrder)
                {
                    Array.Sort(this.depths, this.items, backIndex, unsortedItems);
                }

                for (int i = 0; i < unsortedItems; i++)
                {
                    items[backIndex++].item.Draw(state);
                }
            }

            if (visible > 0)
            {
                //if the frame hasn't changed, the items should already be in sorted order,
                //so this sort should be quick

                //test if the values are already sorted...
                float depth      = this.depths[0];
                bool  outOfOrder = false;
                for (int i = 1; i < visible; i++)
                {
                    outOfOrder |= depths[i] < depth;
                    depth       = depths[i];
                }

                if (outOfOrder)
                {
                    Array.Sort(this.depths, this.items, 0, visible);
                }

                if (sortMode == DepthSortMode.FrontToBack)
                {
                    for (int i = 0; i < visible; i++)
                    {
                        items[i].item.Draw(state);
                    }
                }
                else
                {
                    for (int i = visible - 1; i >= 0; i--)
                    {
                        items[i].item.Draw(state);
                    }
                }
            }
            previousFrameVisibleCount = visible;
        }