0

I am trying to draw text on to the screen using a spritefont in XNA. I can get the text to appear, but no matter what I try there is always something going wrong with something else when I draw the text.

I am trying to display the FPS. I have tried it in a few different ways and in various different XNA projects I have made. Some of the things that happen when drawing the text to the screen include - Vertices being drawn further away and in the wrong spots, vertices not being drawn at all, wire frame mode not being able to be turned on. Just depending on how I try to render the text I always end up with one of these. And then if I comment out the part that draws the text, everything will be back to normal.

Here is some code My variables at the top of the code are -

    GraphicsDeviceManager graphics;
    SpriteFont font;
    SpriteBatch spriteBatch;

In my LoadContent I have

        font = Content.Load<SpriteFont>("SpriteFont1");
        RasterizerState rs = new RasterizerState();
        rs.FillMode = FillMode.WireFrame;
        GraphicsDevice.RasterizerState = rs;
        spriteBatch = new SpriteBatch(GraphicsDevice);

And here is my entire Draw method -

protected override void Draw(GameTime gameTime)
    {
        CreateMesh();
        GraphicsDevice.Clear(Color.SkyBlue);

        effect.Parameters["View"].SetValue(cam.viewMatrix);
        effect.Parameters["Projection"].SetValue(projectionMatrix);
        effect.CurrentTechnique = effect.Techniques["Technique1"];
        effect.CurrentTechnique.Passes[0].Apply();
        GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Count, 0, indices.Length / 3);

        spriteBatch.Begin();
        spriteBatch.DrawString(font, frameRate.ToString(), new Vector2(1, 1), Color.Black);
        spriteBatch.End();

        frameCounter++;
        base.Draw(gameTime);
    }

This is the closest way I have foundto working yet, but for some reason it makes wireframe not work no matter what I try to do, and I really need wire frame.

EDIT: I debugged the fill mode as the program runs and it sets it back to solid on its own for some reason when using the sprite font. I can reset the the fill mode every frame before the vertices are drawn, but I'd really rather not have to do that.

Skami
  • 1,506
  • 1
  • 18
  • 29
Frobot
  • 1,224
  • 3
  • 16
  • 33
  • Very likely a duplicate of this: http://stackoverflow.com/questions/4902494/xna-spritebatch-causing-problems-with-basiceffect – Dave Carlile May 04 '12 at 20:42
  • Ok so spritebatch.Begin() changes some things automatically. I think that is pretty dumb but I guess I'll just have to reset them per frame... – Frobot May 04 '12 at 20:46
  • SpriteBatch.Begin doesn't, but DrawString does, which isn't dumb. You should really set the state you need before drawing, then these types of things aren't issues. See this blog by Shawn Hargreaves: http://blogs.msdn.com/b/shawnhar/archive/2006/11/13/spritebatch-and-renderstates.aspx You should read all of Shawn's XNA blog posts. – Dave Carlile May 04 '12 at 21:03
  • Drawstring is what I meant. I do set the state I need before drawing. Drawing the string changes it though. – Frobot May 04 '12 at 21:48

2 Answers2

1

You should apply your rasterizer state just before drawing somthing win wireframe mode, not only in the load method... because batch.Begin() method will set a default rasterizer state

if you want use other rasterizer state for spritebatch, you should provide one

spritebatch.Begin(SortMode,...,,.., rs );

your code should be changed this way:

static RasterizerState rs = new RasterizerState() { FillMode = FillMode.Wireframe; }

protected override void Draw(GameTime gameTime)
{
    CreateMesh();
    GraphicsDevice.Clear(Color.SkyBlue);

    GraphicsDevice.RasterizerState = rs;

    effect.Parameters["View"].SetValue(cam.viewMatrix);
    effect.Parameters["Projection"].SetValue(projectionMatrix);
    effect.CurrentTechnique = effect.Techniques["Technique1"];
    effect.CurrentTechnique.Passes[0].Apply();
    GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices.Count, 0, indices.Length / 3);
    ....
Blau
  • 5,742
  • 1
  • 18
  • 27
  • I actually have my code working with almost the exact same thing you posted so I'll just accept this as the answer – Frobot May 05 '12 at 02:50
0

Using a SpriteBatch changes the render state to the point that 3D graphics no longer work unless you change the render state back to a 3D-friendly state. See this article for more details.

http://blogs.msdn.com/b/shawnhar/archive/2006/11/13/spritebatch-and-renderstates.aspx

Kendall Frey
  • 43,130
  • 20
  • 110
  • 148