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);
}
}
}
CompareFunction.Greater
, usually for depth functions I've seenCompareFunction.LessEqual
used. Second, your use ofSpriteSortMode.Deferred
means you cannot be sure which order your sprites will be drawn. Until you solve this problem, I would switch that toSpriteSortMode.Immediate
. – Jim Sep 27 '12 at 17:09