示例#1
0
        public void Draw(DrawState state)
        {
            state.PushWorldTranslateMultiply(ref this.position);

            if (geometry.CullTest(state))
            {
                //draw the geometry
                shader.Bind(state);
                geometry.Draw(state);

                //now, if set, draw the wireframe too
                if (wireframeShader != null)
                {
                    wireframeShader.Bind(state);

                    //show the wireframe, disabling depth testing
                    state.PushRenderState();
                    state.RenderState.DepthColourCull.DepthTestEnabled = false;
                    //also set additive blending
                    state.RenderState.AlphaBlend = AlphaBlendState.Additive;
                    //set wireframe
                    state.RenderState.DepthColourCull.FillMode = FillMode.WireFrame;

                    //draw
                    geometry.Draw(state);

                    state.PopRenderState();
                }
            }

            state.PopWorldMatrix();
        }
        private void DrawSphere(DrawState state)
        {
            //draw the geometry with a solid colour shader
            if (geometry.CullTest(state))
            {
                Xen.Ex.Shaders.FillSolidColour shader = state.GetShader <Xen.Ex.Shaders.FillSolidColour>();

                shader.FillColour = lightColour.ToVector4();
                shader.Bind(state);

                geometry.Draw(state);
            }
        }
示例#3
0
        public void Draw(DrawState state)
        {
            //generate the rotation matrix for the object.
            Matrix basis = new Matrix(1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1);             //xna_dude model is on his side

            state.PushWorldMatrixMultiply(ref basis);

            Matrix.CreateRotationZ(RotationAngle, out basis);             // generate the rotation.
            state.PushWorldMatrixMultiply(ref basis);

            if (item.CullTest(state))
            {
                item.Draw(state);
            }

            state.PopWorldMatrix();
            state.PopWorldMatrix();
        }
示例#4
0
 public bool CullTest(ICuller culler)
 {
     return(scene.CullTest(culler));
 }
示例#5
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;
        }
示例#6
0
        /// <summary>
        /// Draw the predicate, and if the predicate draws at least <see cref="MinimumPixelCount"/> pixels, the 'complex' object will be drawn
        /// </summary>
        /// <param name="state"></param>
        public void Draw(DrawState state)
        {
            int frame = state.FrameIndex;

            if (!supported || frame == frameIndex)
            {
                if (item.CullTest(state))
                {
                    item.Draw(state);
                }
                return;
            }

            if (resetOnCullChange && frameIndex != frame - 1)
            {
                //XNA requires IsComplete to be checked.
                if (query != null)
                {
                    queryInProgress = query.IsComplete;
                }

                queryInProgress = false;                //reset the query
                queryPixelCount = ushort.MaxValue;
            }

            if (queryInProgress && query.IsComplete)
            {
                queryInProgress      = false;
                this.queryPixelCount = (ushort)query.PixelCount;
            }

            if (!queryInProgress)
            {
                GraphicsDevice device = state.BeginGetGraphicsDevice(Xen.Graphics.State.StateFlag.None);

                //run the query
                if (query == null)
                {
                    query = new OcclusionQuery(device);
                    if (query.IsSupported == false)
                    {
                        supported = false;
                        query.Dispose();
                        query = null;

                        if (item.CullTest(state))
                        {
                            item.Draw(state);
                        }
                        return;
                    }
                }

                query.Begin();

                state.PushRenderState();

                state.RenderState.DepthColourCull.DepthWriteEnabled = false;
                state.RenderState.DepthColourCull.ColourWriteMask   = ColorWriteChannels.None;
                state.RenderState.AlphaBlend = new AlphaBlendState();

                predicate.Draw(state);

                state.PopRenderState();

                query.End();

                queryInProgress = true;

                state.EndGetGraphicsDevice();
            }

            frameIndex = frame;

            if (queryPixelCount >= pixelCount && item.CullTest(state))
            {
                item.Draw(state);
            }
        }