Hello! I’m trying to fill 1920x1080 screen with sprites 16x16 size (120x67 tiles). For testing worst possible scenario i switch texture every tile. I know it is wrong and i should use tilemap and switch texture less often, but it’s only test.
My code is here
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Fna1
{
public class Tile
{
public Texture2D texture;
}
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D t1;
Texture2D t2;
SpriteFont font;
int sizeX = 120;
int sizeY = 67;
Tile[,] tiles;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
graphics.PreferredBackBufferWidth = 1920;
graphics.PreferredBackBufferHeight = 1080;
graphics.SynchronizeWithVerticalRetrace = false;
IsFixedTimeStep = false;
graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
t1 = GenerateTexture(Color.DarkGreen);
t2 = GenerateTexture(Color.DarkCyan);
font = Content.Load<SpriteFont>("font");
int c = 0;
tiles = new Tile[sizeX, sizeY];
for (int x = 0; x < sizeX; x++)
{
for (int y = 0; y < sizeY; y++)
{
tiles[x, y] = new Tile();
tiles[x, y].texture = (c % 2) == 0 ? t1 : t2;
c++;
}
}
}
private Texture2D GenerateTexture(Color color)
{
Texture2D texture = new Texture2D(GraphicsDevice, 16, 16);
var cdata = new Color[16 * 16];
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
cdata[i * 16 + j] = color;
}
}
texture.SetData(cdata);
return texture;
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Transparent);
spriteBatch.Begin();
for (int x = 0; x < sizeX; x++)
{
for (int y = 0; y < sizeY; y++)
{
spriteBatch.Draw(tiles[x, y].texture, new Vector2(x * 16, y * 16), Color.White);
}
}
spriteBatch.End();
var fps = 1 / gameTime.ElapsedGameTime.TotalSeconds;
spriteBatch.Begin();
spriteBatch.DrawString(font, fps.ToString(), Vector2.Zero, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
On my hardware (Geforce 760 GT) i have about 100 fps in release build. But later i tested the same code on FNA and received 500 fps! Both my projects is net.core 3.1 if it matters.
I checked source code of SpriteBatch.cs on both MonoGame and FNA. And saw that FNA uses DrawIndexedPrimitives and DynamicVertexBuffer instead of DrawUserIndexedPrimitives in Monogame. Then i recreated FNA’s SpriteBatch from source code and make some fixes. And get only 130 fps.
Сan someone explain to me what’s the matter?