Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Simply: Why don't all of these sprites draw? What do I need to do to make them draw?

I'm trying to use SpriteBatch.Draw with the layerDepth parameter to help reduce overdrawn. However I can't get it to work properly. It keeps outputting negative Z values when I try to use it with AlphaTestEffect! I've created a basic test case below to show the problem of.

The code for creating the effects and matrixes are based on this :"SpriteBatch and custom shaders in XNA Game Studio 4.0" from the XNA blog.

I think the projection matrix given should make sense, looking at the docs for CreateOrthographicOffCenter. But for some reason it doesn't! Can any one figure out why and tell me, please?

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace SpriteBatchTest
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        BasicEffect basicEffect;
        AlphaTestEffect alphaTestEffect;
        Texture2D mysprite;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            base.Initialize();

            Viewport viewport = this.GraphicsDevice.Viewport;
            Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
            Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

            basicEffect = new BasicEffect(this.GraphicsDevice);
            basicEffect.World = Matrix.Identity;
            basicEffect.View = Matrix.Identity;
            basicEffect.Projection = halfPixelOffset * projection;

            basicEffect.TextureEnabled = true;
            basicEffect.VertexColorEnabled = true;




            alphaTestEffect = new AlphaTestEffect(GraphicsDevice);
            alphaTestEffect.VertexColorEnabled = false;
            alphaTestEffect.DiffuseColor = Color.White.ToVector3();
            alphaTestEffect.AlphaFunction = CompareFunction.Greater;
            alphaTestEffect.ReferenceAlpha = 0;
            alphaTestEffect.World = Matrix.Identity;
            alphaTestEffect.View = Matrix.Identity;
            alphaTestEffect.Projection = halfPixelOffset * projection;

        }

        protected override void LoadContent()
        {



            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            mysprite = Content.Load<Texture2D>("test");

            // TODO: use this.Content to load your game content here
        }

        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
                Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            this.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.CornflowerBlue, 1.0f, 0);

            spriteBatch.Begin();
            //drawn
            spriteBatch.Draw(mysprite, new Vector2(100, 100), Color.White);
            //drawn
            spriteBatch.Draw(mysprite, new Vector2(500, 100), null, Color.White, 0.0f, Vector2.Zero,
                 Vector2.One, SpriteEffects.None, 0.50f);
            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp,
                DepthStencilState.Default, RasterizerState.CullNone, basicEffect);
            //drawn
            spriteBatch.Draw(mysprite, new Vector2(150, 150), Color.White);
            //neg z, not drawn
            spriteBatch.Draw(mysprite, new Vector2(500, 150), null, Color.White, 0.0f, Vector2.Zero,
                 Vector2.One, SpriteEffects.None, 0.50f);
            spriteBatch.End();

            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp,
                DepthStencilState.Default, RasterizerState.CullNone,
                alphaTestEffect);
            //drawn
            spriteBatch.Draw(mysprite, new Vector2(200, 200), Color.White);
            //not draw - negative Z
            spriteBatch.Draw(mysprite, new Vector2(500, 200), null, Color.White, 0.0f, Vector2.Zero,
                Vector2.One, SpriteEffects.None, 0.50f);
            spriteBatch.End();

            //drawn
            spriteBatch.Begin();
            spriteBatch.Draw(mysprite, new Vector2(200, 100), null, Color.White, 0.0f, Vector2.Zero,
                            Vector2.One, SpriteEffects.None, 0.50f);
            spriteBatch.End();

            //not draw - negative Z
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp,
                DepthStencilState.Default, RasterizerState.CullNone, basicEffect);
            spriteBatch.Draw(mysprite, new Vector2(250, 150), null, Color.White, 0.0f, Vector2.Zero,
                Vector2.One, SpriteEffects.None, 0.60f);
            spriteBatch.End();

            //not draw - negative Z
            spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp,
                DepthStencilState.Default, RasterizerState.CullNone, alphaTestEffect);
            spriteBatch.Draw(mysprite, new Vector2(300, 200), null, Color.White, 0.0f, Vector2.Zero,
                            Vector2.One, SpriteEffects.None, 0.70f);
            spriteBatch.End();

            base.Draw(gameTime);
        }
    }
}
share|improve this question
    
I see two unusual things with this code sample. First, you are using CompareFunction.Greater, usually for depth functions I've seen CompareFunction.LessEqual used. Second, your use of SpriteSortMode.Deferred means you cannot be sure which order your sprites will be drawn. Until you solve this problem, I would switch that to SpriteSortMode.Immediate. –  Jim Sep 27 '12 at 17:09
1  
I forgot about this question :) The problem was that XNA sprite's use a RHS and DX uses a LHS. So my Z values would get flipped, as XNA has positive Z going into the screen and DX has negative Z. –  Pod Sep 27 '12 at 22:04
    
Could you mark this question as closed then please? –  simonalexander2005 Jan 31 at 14:30
    
@simonalexander2005 The question should not be marked "closed;" closure is for questions that are no on-topic or not appropriate here (and is something voted on by the community, it is not something the asker can do). –  Josh Petrie Jan 31 at 21:45
1  
@Pod What simonalexander probably meant to say is that you should post your solution as an answer (and not a comment). Then, after a brief timeout, you should be able to mark that answer as "the" answer, marking the question as "answered" (not "closed"). –  Josh Petrie Jan 31 at 21:46

1 Answer 1

up vote 0 down vote accepted

The problem was that XNA sprite's use a Right Hand coordinate system and the DirectX API by default uses a Left Hand coordinate system by default. So my Z values would get flipped as XNA has positive Z going into the screen and DX has negative Z going into the screen.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.