Jump to content
  • Advertisement
Sign in to follow this  
maldakkak

my application slowing down when using two textures in spritebatch.Draw

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

Hi everyone I didn’t post here in a long time but now I have few questions I am trying to make a simple tile based game (like pacman) using XNA Basically I have two textures, one to store 15 tiles which are 24*24 Pixels each, and the other one to store player and enemies’ sprites which are 36*36 each. I am drawing the tile map using 2D array (20*20) and I get 60 frames per second. Now when I tried to draw the player using the other texture the frame count went down to 20. The code looks something like this: spritebatch.Begin(); spritebatch.Draw(texture1,…..); spritebatch.Draw(texture2,…..); spritebatch.End(); When I combined the two textures in one the frame count was 60 again. Now I know that switching between many textures is costly but I was surprised to see the frame rate to go down like this for only using two textures. So my first question here is how do games handle too many textures? And I would think this will be even more problematic in 3D games where there are many models and many textures. Are all tiles and sprites usually saved in one big texture file? Or is this a limitation of XNA and I would not have the same problem if I had used D3D instead? The other question is, for my by luck I found that having two textures in my program caused the problem but I read sometimes that you can actually by using some utilities figure out which part of your code is making the program to slow down. I am not sure how to do this, any help is really appreciated. Thanks for help and sorry for this long post.

Share this post


Link to post
Share on other sites
Advertisement
Nope, the above sounds fine, something fishy's going on.

Any chance of a block of code to look through?

Share this post


Link to post
Share on other sites
Unfortunately I don't have the actual code in front of me now. But there is nothing else going on in the code at all. If I comment the second spriteBatch.Draw then I get 60 FPS, and when I uncomment it I get 20 FPS or less. I was trying to add collision detection and I though that was the problem first but then I deleted all that code and still had the same issue.

Share this post


Link to post
Share on other sites
So here is my code



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;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace WindowsGame5
{
public class Game1 : Microsoft.Xna.Framework.Game
{
int framePerSecond = 0, framePerSecondDisplay = 0;
double start = 0;
int[,] map = {
{01,05,05,05,05,05,05,05,05,05,07,05,05,05,05,05,05,05,05,05,02 },
{06,15,15,15,15,15,15,15,15,15,06,15,15,15,15,15,15,15,15,15,06 },
{06,00,01,05,02,15,01,05,02,15,06,15,01,05,02,15,01,05,02,00,06 },
{06,15,03,05,04,15,03,05,04,15,11,15,03,05,04,15,03,05,04,15,06 },
{06,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,06 },
{06,15,01,05,02,15,14,15,12,05,07,05,13,15,14,15,01,05,02,15,06 },
{06,15,03,05,04,15,06,15,15,15,06,15,15,15,06,15,03,05,04,15,06 },
{06,15,15,15,15,15,09,05,13,00,11,00,12,05,08,15,15,15,15,15,06 },
{03,05,05,05,02,15,06,00,00,00,00,00,00,00,06,15,01,05,05,05,04 },
{00,00,00,00,06,15,06,00,01,16,16,16,02,00,06,15,06,00,00,00,00 },
{12,05,05,05,04,15,11,00,06,00,00,00,06,00,11,15,03,05,05,05,13 },
{00,00,00,00,00,15,00,00,06,00,00,00,06,00,00,15,00,00,00,00,00 },
{12,05,05,05,02,15,14,00,03,05,05,05,04,00,14,15,01,05,05,05,13 },
{00,00,00,00,06,15,06,00,00,00,00,00,00,00,06,15,06,00,00,00,00 },
{01,05,05,05,04,15,11,00,12,05,07,05,13,00,11,15,03,05,05,05,02 },
{06,15,15,15,15,15,15,15,15,15,06,15,15,15,15,15,15,15,15,15,06 },
{06,15,12,05,02,15,12,05,13,15,11,15,12,05,13,15,01,05,13,15,06 },
{06,00,15,15,06,15,15,15,15,15,00,15,15,15,15,15,06,15,15,00,06 },
{09,05,13,15,11,15,14,15,12,05,07,05,13,15,14,15,11,15,12,05,08 },
{06,15,15,15,15,15,06,15,15,15,06,15,15,15,06,15,15,15,15,15,06 },
{06,15,01,05,05,05,10,05,02,15,06,15,01,05,10,05,05,05,02,15,06 },
{06,15,03,05,05,05,05,05,04,15,11,15,03,05,05,05,05,05,04,15,06 },
{06,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,06 },
{03,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,05,04 },
};
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteFont gameFont;
Texture2D pacmanTextures, pacmanTexture_1;


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

protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.IsFullScreen = true;
graphics.ApplyChanges();

base.Initialize();
}

protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
pacmanTextures = Content.Load<Texture2D>("PacManTextures");
pacmanTexture_1 = Content.Load<Texture2D>("PacManTextures_1");
gameFont = Content.Load<SpriteFont>("score");
}

protected override void UnloadContent()
{

}


protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();

base.Update(gameTime);
}

protected override void Draw(GameTime gameTime)
{
start += gameTime.ElapsedGameTime.TotalMilliseconds;
if (start >= 1000)
{
start = 0;
framePerSecondDisplay = framePerSecond;
framePerSecond = 0;
}
framePerSecond += 1;
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
for (int x = 0; x < 24; x++)
for (int y = 0; y < 21; y++)
{
if (map[x, y] == 0)
continue;
spriteBatch.Draw(pacmanTextures, new Rectangle(y * 24, x * 24, 24, 24), new Rectangle(map[x, y] * 25, 0, 24, 24), Color.White);
spriteBatch.Draw(pacmanTexture_1, new Rectangle(100, 100, 36, 36), new Rectangle(450, 0, 36, 36), Color.White);
}
spriteBatch.DrawString(gameFont, "Frames Per Second= " + framePerSecondDisplay.ToString(), new Vector2(550, 20), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}



As I said earlier, if I delete or comment this line: spriteBatch.Draw(pacmanTexture_1, new Rectangle(100, 100, 36, 36), new Rectangle(450, 0, 36, 36), Color.White);
then I get 60 frames per second, but if I leave it there then I get 20 frames per second, may be I am not calculating Frames Per Second correctly, any advice.

Thanks

Share this post


Link to post
Share on other sites
Your sending a gameTime structure to your Draw function, how are you determining game time? are you doing something like GetTickCount() outside your draw loop?
and your adding it to the "start" variable, is this a global? does it get killed everytime your Draw function goes out of scope?

<- is not familiar with XNA

Share this post


Link to post
Share on other sites
I have a question.


for (int x = 0; x < 24; x++)
for (int y = 0; y < 21; y++)
{
if (map[x, y] == 0)
continue;
spriteBatch.Draw(pacmanTextures, new Rectangle(y * 24, x * 24, 24, 24), new Rectangle(map[x, y] * 25, 0, 24, 24), Color.White);
spriteBatch.Draw(pacmanTexture_1, new Rectangle(100, 100, 36, 36), new Rectangle(450, 0, 36, 36), Color.White);
}


Why do you have the second Draw call in the loop? It's drawing to the same location every time, so there seems to be no point in drawing it over and over inside the loop.


for (int x = 0; x < 24; x++)
{
for (int y = 0; y < 21; y++)
{
if (map[x, y] == 0)
continue;
spriteBatch.Draw(pacmanTextures, new Rectangle(y * 24, x * 24, 24, 24), new Rectangle(map[x, y] * 25, 0, 24, 24), Color.White);
}
}
spriteBatch.Draw(pacmanTexture_1, new Rectangle(100, 100, 36, 36), new Rectangle(450, 0, 36, 36), Color.White);


This should fix it. Also, it's generally good practice to put braces around blocks of code like inside loops.

Edit: To give a bit more detail about what was going on, you had two different textures in two different draw calls inside a for loop. What this means is there was a lot of texture swapping going on in the GPU, which was slowing it down a lot. In general you want to batch textures together as much as possible. Eg- Draw all tiles using this texture, then draw all sprites using this texture, etc.

Share this post


Link to post
Share on other sites
Yep, that looks like your problem. since you're drawing the batches over and over, you re-bind textures twice per loop... so 24 x 21 x 2 is 504 times, which is 502 times more than you need.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!