Jump to content
  • Advertisement
Sign in to follow this  
MatsK

Depth sorting issues

This topic is 767 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I enabled SpriteSortMode.FrontToBack in my drawing callback:

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            Resolution.BeginDraw();

            spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend, null, null, 
                RasterizerState.CullCounterClockwise, null, Resolution.getTransformationMatrix());
            m_ScrManager.Draw();
            spriteBatch.End();

            //Reset device to defaults before rendering...
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
            GraphicsDevice.Viewport = new Viewport(0, 0, GlobalSettings.Default.ScreenWidth, GlobalSettings.Default.ScreenHeight);
            GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.Black, 0.5f, 1);
            m_ScrManager.Draw3D();

            HitVM.Step();

            base.Draw(gameTime);
        }

Then, in my UIScreen.Draw method, I did:

        public virtual void Draw()
        {
            foreach (KeyValuePair<string, UIElement> KVP in m_Elements)
            {
                try
                {
                    if (KVP.Value is UIDialog || KVP.Value is WillWrightDiag)
                        KVP.Value.Draw(m_SBatch, UIElement.GetLayerDepth(LayerDepth.DialogLayer));
                    else if (KVP.Value is UIButton)
                        KVP.Value.Draw(m_SBatch, UIElement.GetLayerDepth(LayerDepth.ButtonLayer));
                    else if (KVP.Value is UIImage)
                        KVP.Value.Draw(m_SBatch, UIElement.GetLayerDepth(LayerDepth.ImageLayer));
                    else
                        KVP.Value.Draw(m_SBatch, UIElement.GetLayerDepth(LayerDepth.Default));
                }
                catch(Exception)
                {
                    continue;
                }
            }
        }

Here is UIElement.GetLayerDepth:

        /// <summary>
        /// Gets the value of the corresponding layer depth.
        /// </summary>
        /// <param name="Depth">The depth for which to retrieve a value.</param>
        /// <returns>The value of the specified depth.</returns>
        public static float GetLayerDepth(LayerDepth Depth)
        {
            switch(Depth)
            {
                case LayerDepth.Default:
                    return 0.0f;
                case LayerDepth.ImageLayer:
                    return 0.8f;
                case LayerDepth.ButtonLayer:
                    return 0.9f;
                case LayerDepth.DialogLayer:
                    return 0.10f;
                default:
                    return 0.0f;
            }
        }

Then in Credits.cs, I added the WillWrightDiag to my list of elements to be drawn by UIScreen.Elements, as such:

            m_WillWrightDiag = new WillWrightDiag(WillImage, this, new Vector2(100, 100));
            m_WillWrightDiag.IsDrawn = false;
            m_Elements.Add("WillWrightDiag", m_WillWrightDiag);

Here's how I draw a UIDialog:

        public override void Draw(SpriteBatch SBatch, float? LayerDepth)
        {
            float Depth;
            if (LayerDepth != null)
                Depth = (float)LayerDepth;
            else
                Depth = 0.10f;

            if (IsDrawn)
            {
                Image.DrawTextureTo(SBatch, null, Image.Slicer.TLeft, Image.Position + Vector2.Zero, Depth);
                Image.DrawTextureTo(SBatch, Image.Slicer.TCenter_Scale, Image.Slicer.TCenter, Image.Position + new Vector2(Image.Slicer.LeftPadding, 0), Depth);
                Image.DrawTextureTo(SBatch, null, Image.Slicer.TRight, Image.Position + new Vector2(Image.Slicer.Width - Image.Slicer.RightPadding, 0), Depth);

                Image.DrawTextureTo(SBatch, Image.Slicer.CLeft_Scale, Image.Slicer.CLeft, Image.Position + new Vector2(0, Image.Slicer.TopPadding), null);
                Image.DrawTextureTo(SBatch, Image.Slicer.CCenter_Scale, Image.Slicer.CCenter, Image.Position + new Vector2(Image.Slicer.LeftPadding, Image.Slicer.TopPadding), Depth);
                Image.DrawTextureTo(SBatch, Image.Slicer.CRight_Scale, Image.Slicer.CRight, Image.Position + new Vector2(Image.Slicer.Width - Image.Slicer.RightPadding, Image.Slicer.TopPadding), Depth);

                int BottomY = Image.Slicer.Height - Image.Slicer.BottomPadding;
                Image.DrawTextureTo(SBatch, null, Image.Slicer.BLeft, Image.Position + new Vector2(0, BottomY), null);
                Image.DrawTextureTo(SBatch, Image.Slicer.BCenter_Scale, Image.Slicer.BCenter, Image.Position + new Vector2(Image.Slicer.LeftPadding, BottomY), Depth);
                Image.DrawTextureTo(SBatch, null, Image.Slicer.BRight, Image.Position + new Vector2(Image.Slicer.Width - Image.Slicer.RightPadding, BottomY), Depth);

                if (m_HasExitBtn)
                {
                    m_CloseBtnBack.Draw(SBatch, null, Depth);
                    m_CloseButton.Draw(SBatch, Depth);
                }
            }
        }

And here's how I draw a WillWrightDiag, which inherits from UIDialog:

        public override void Draw(SpriteBatch SBatch, float? LayerDepth)
        {
            float Depth;
            if (LayerDepth != null)
                Depth = (float)LayerDepth;
            else
                Depth = 0.10f;

            if (IsDrawn)
                SBatch.Draw(m_WillWrightImg.Texture, m_WillWrightImg.Position, null, null, new Vector2(0.0f, 0.0f), 0.0f, null, 
                    Color.White, SpriteEffects.None, Depth);

            base.Draw(SBatch, LayerDepth);
        }

Despite this, I still get this weird case where the Maxis-button is drawn on top of the dialog and the exit button is occasionally not drawn.

Why? :\

 

[attachment=32955:tsocredits.png]

 

Is there a better, less error-prone way to achieve depth sorting?


Here is the entire code for Credits.cs if it helps:

using System;
using System.Timers;
using System.Collections.Generic;
using System.Text;
using Gonzo;
using Gonzo.Elements;
using Files.Manager;
using Files.IFF;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace GonzoTest
{
    public class CreditsScreen : UIScreen
    {
        private UIImage BackgroundImg, TSOLogoImage, BackButtonIndentImage, WillImage;
        private UIButton MaxisButton;

        private Iff m_Credits;
        private List<string> m_CreditsStrings = new List<string>();
        private UIControl m_CreditsArea;
        private float m_CreditsY = 0;       //Upwards position of credits text.
        private float m_CreditsCenterX = 0; //Center of credits area.
        private Timer m_CreditsTimer;       //Timer for controlling text scroll.

        private WillWrightDiag m_WillWrightDiag;

        public CreditsScreen(ScreenManager Manager, SpriteBatch SBatch) : base(Manager, "Credits", SBatch, 
            new Vector2(0, 0), new Vector2(GlobalSettings.Default.ScreenWidth, GlobalSettings.Default.ScreenHeight), 
            GlobalSettings.Default.StartupPath + "\\" + "gamedata\\uiscripts\\credits.uis")
        {
            BackgroundImg = (UIImage)m_Elements["\"BackgroundImage\""];
            TSOLogoImage = m_Controls["\"TSOLogoImage\""].Image;
            BackButtonIndentImage = m_Controls["\"BackButtonIndentImage\""].Image;
            WillImage = (UIImage)m_Elements["\"WillImage\""];

            MaxisButton = (UIButton)m_Elements["\"MaxisButton\""];
            MaxisButton.OnButtonClicked += MaxisButton_OnButtonClicked;

            m_WillWrightDiag = new WillWrightDiag(WillImage, this, new Vector2(100, 100));
            m_WillWrightDiag.IsDrawn = false;
            m_Elements.Add("WillWrightDiag", m_WillWrightDiag);

            m_Credits = FileManager.GetIFF("credits.iff");
            m_CreditsArea = (UIControl)m_Controls["\"CreditsArea\""];
            m_CreditsY = m_CreditsArea.Size.Y;

            foreach(TranslatedString TStr in m_Credits.GetSTR(163).GetStringList(LanguageCodes.EngUS))
            {
                foreach (string Str in TStr.TranslatedStr.Split('\n'))
                    m_CreditsStrings.Add(Str);
            }

            m_CreditsTimer = new Timer(300);
            m_CreditsTimer.Elapsed += M_CreditsTimer_Elapsed;
            m_CreditsTimer.Start();
        }

        private void M_CreditsTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            m_CreditsY -= 1.5f;
        }

        private void MaxisButton_OnButtonClicked(UIButton ClickedButton)
        {
            m_WillWrightDiag.IsDrawn = true;
        }

        public override void Update(InputHelper Input)
        {
            m_WillWrightDiag.Update(Input);

            base.Update(Input);
        }

        public override void Draw()
        {
            BackgroundImg.Draw(m_SBatch, null, 0.0f);
            TSOLogoImage.Draw(m_SBatch, null, 0.0f);
            BackButtonIndentImage.Draw(m_SBatch, null, 0.0f);

            float Separation = 1.0f;

            foreach (string Str in m_CreditsStrings)
            {
                m_CreditsCenterX = (m_CreditsArea.Size.X / 2) - (Manager.Font12px.MeasureString(Str).X / 2);

                if ((m_CreditsY + Separation) > m_CreditsArea.Position.Y && (m_CreditsY + Separation) < m_CreditsArea.Size.Y)
                {
                    m_SBatch.DrawString(Manager.Font12px, Str, new Vector2(m_CreditsArea.Position.X + 
                        m_CreditsCenterX, m_CreditsY + Separation), Color.Wheat);
                }

                Separation += 15.0f;
            }

            base.Draw();
        }
    }
}

Also, why is the chat down? :\ There's a much higher signal to noise ratio in the chat.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!