SaveState not working?

As you might have experienced when using XNA, some of the render states are set incorrectly when rendering sprites with SpriteBatch or when rendering a model using a shader. Remember, SaveState is a heavy process so use it only when you really need this, try setting the render states manually instead!
 
There are many posts about this issue, but I will create another myself, as I came across another problem( see last solution point ).
 
Let’s take a look on common solutions to this problem.

My render states get distorted after rendering sprites/textures with SpriteBatch

To solve this, you can set the SaveStateMode to SaveState when calling the Begin() method of SpriteBatch.

spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);
// Render your sprites
spriteBatch.End();

If SaveStateMode is set to SaveState, a StateBlock object will capture the current state of you rendering device. Once you call End(), the StateBlock will call Apply(), witch applies the state captured earlier.
This usually works in most situations.

My render states get distorted after rendering a model using a shader/effect
To solve this, you can set the SaveStateMode to SaveState when calling the Begin() method of Effect.
effect.Begin(SaveStateMode.SaveState);

Again, If SaveStateMode is set to SaveState, a StateBlock object will capture the current state of you rendering device. Once you call End(), the StateBlock will call Apply(), witch applies the state captured earlier.
This usually works in most situations.


I am saving the state on my sprites/models, but the renderstates still get distorted!??
Ok, this is the problem I had today. I was rendering a 3D model, and after rendering it, everything got distorted..
I tried, just for fun, to call spriteBatch.Begin(…SaveState), render the model, and calling spriteBatch.End().
This worked by my model got some big problems related to the Z-buffer/Depth buffer and so on, so the model got pretty ugly.

I also tried to set the SaveStateMode to SaveState in Effect.Begin(..) and in mesh.Draw(SaveStateMode.SaveState); but without any luck..

So, finally, I treid to save the state manually, and to my suprise, it worked very well! 😀
To save the state manually, add the following lines of code to your application:

StateBlock stateBlock = new StateBlock(GraphicsDevice); // pass in your GraphicsDevice here.
stateBlock.Capture(); // Saves the state.

//Do your magic, like mesh.Draw();

stateBlock.Apply(); // restores the state again.
stateBlock.Dispose(); // remember to call dispose!

This method works on the computer. When I run it on an xbox360( not sure if this is the reason ) I get an DriverInternalErrorException. If anyone know how to solve this, I would be really glad if you send me the solution!!

 

Good luck!

Advertisements
This entry was posted in XNA. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s