XNA - sprite merging for better drawing performance?

I read somewhere that when rendering many 3D objects, you can combine them to form a giant grid so that only one call can be made. So let me quote: "The GPU does its magic," while the processor is free for calls other than drawing.

So, in my question, would it be possible to do this in a 2D environment with performance ?

For example, let's say that we have a simple tile system, and instead of making a drawing call for each fragment in question, instead we need to combine all the tiles to form a large sprite, and then call a draw on it.

Any understanding of this matter — tips, links, or much more — is greatly appreciated since I have no experience with graphics.

Edit: Sorry for my poor explanation. I create tileengine for personal use and want it to be as versatile as possible. Therefore, I want to optimize in case in the near future I will need to draw a lot of tiles.

I use a table layout, but I had in mind the question is that merging all the fragments that need to be extracted from the sheet into the new Texture2D will lead to better performance. For example:

We have 128x72 tiles for drawing on the screen. Instead of going through all the tiles and calling a draw for each drawn fragment, we merge all the tiles into a new 1280x720 sprite and draw it. Thus, the draw () method will be called only once for each frame. My question was that this would improve performance, since in 3D there will be a merging of three-dimensional objects into one grid.

Since the information I gathered is that the draw () call is a hog producer and should be called as little as possible. Can anyone confirm or deny? :)

+3
source share
4 answers

XNA 3D, 2D-. XNA . , - , - , . , , .

, , " ". , , " ". , , , , . , !

, 2D-, , , . , , . , , , , , , , , . ! - , SpriteBatch .

, , - , . , ( ). , , , , . , , , , . , , , (. ).

, , , Shawn Hargreaves , ​​.. , XNA , , .

http://forums.xna.com/forums/p/24254/131437.aspx#131437

Update:

, . , . Draw() :

        GraphicsDevice.Clear(Color.CornflowerBlue);

        Stopwatch sw = new Stopwatch();
        sw.Start();

        spriteBatch.Begin();

#if !DEBUG
        spriteBatch.Draw(tex, new Rectangle(0, 0, 
                         GraphicsDevice.Viewport.Width,
                         GraphicsDevice.Viewport.Height), 
                         Color.White);            
#else
        for (int i = 0; i < 128; i++)
            for (int j = 0; j < 72; j++)
            {
                Rectangle r = new Rectangle(i * 10, j * 10, 10, 10);
                spriteBatch.Draw(tex, r, r, Color.White);
            }
#endif
        spriteBatch.End();

        sw.Stop();

        if (draws > 60)
        {
            numTicks += sw.ElapsedTicks;
        }
        draws++;

        if (draws % 100 == 0)
            Console.WriteLine("avg ticks: " + numTicks / (draws - 60));

        base.Draw(gameTime);

"#if! DEBUG", . 60 , ( , ) . 1280x720, . , 12872, . .

:

avg ticks: 68566
avg ticks: 73668
avg ticks: 82659
avg ticks: 81654
avg ticks: 81104
avg ticks: 84664
avg ticks: 86626
avg ticks: 88211
avg ticks: 87677
avg ticks: 86694
avg ticks: 86713
avg ticks: 88116
avg ticks: 89380
avg ticks: 92158

128x72 :

avg ticks: 7902592
avg ticks: 8052819
avg ticks: 8012696
avg ticks: 8008819
avg ticks: 7985545
avg ticks: 8028217
avg ticks: 8046837
avg ticks: 8291755
avg ticks: 8309384
avg ticks: 8336120
avg ticks: 8320260
avg ticks: 8322150
avg ticks: 8381845
avg ticks: 8364629

, , . , , , , , .

+10

, . SpriteBatch.Begin(), , .

/ , . , , . .

, , . , .

+3

r = (i * 10, j * 10, 10, 10);

, ! :

+1

Fulfillment is not a universal imperative or commandment from God; it is a means to an end. If what you have is good enough, you have nothing to gain from improved performance. Maintaining "the best possible performance at all times" is a definition of premature optimization, and it will cause more headaches than it will prevent.

0
source

Source: https://habr.com/ru/post/1721294/


All Articles