• Advertisement
Sign in to follow this  

Depth sorting issues

This topic is 524 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