Jump to content
  • Advertisement
Sign in to follow this  
gorky20

C#, Sprite Drawing Performance

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

Hello, I'm writing an application that should render simple tile-based 'world', built from System.Drawing.Bitmap tiles, sized 32x32 pixels onto a Form. Here are parts of the code: Class is derived from Form:
class Renderer : Form {

private Device device;
private Sprite sprite;
Initialization:
PresentParameters parameters = new PresentParameters();
parameters.Windowed = true;
parameters.SwapEffect = SwapEffect.Discard;

CreateFlags createflags = CreateFlags.HardwareVertexProcessing | CreateFlags.PureDevice;

device = new Device(0, DeviceType.Hardware, this, createflags, parameters);
sprite = new Sprite(device);
Textures are created from bitmaps:
[...] = new Texture(device, bitmap, 0, Pool.Managed);
And the actual drawing:
            device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
            device.BeginScene();
            sprite.Begin(SpriteFlags.AlphaBlend);
           
            for (int h = 7; h >= z; h--) {              
                for (int ay = 0; ay < 600 / 32 + 2; ay ++) {
                    for (int ax = 0; ax < 800 / 32 + 2 + 2; ax ++) {
      
                        int[] items_array = map.getData(ax, ay, h);
                       
                        foreach (int it in items_array) {
                            Texture texture = map.getTexture(it);             
                            sprite.Draw2D(texture, new Point(0, 0), 0, new Point(ax * 32, ay  * 32), Color.White);
                          
                        }
                    }
                }
            }
            sprite.End();
            device.EndScene();
            device.Present();
Pretty self explaining, it fills the screen area with tiles, but the problem is - with all those up to 8 floors (though not all of them are always completely filled), and single tiles composed of many textures it means a lot of work - in worst cases, around 5000 calls to sprite.Draw2D to redraw the whole scene, which unfortunately takes noticable time. I would like to ask for your advice - is it possible to achieve the effect this code does (by some modifications to it, or maybe with completly diffrent approach?), but with performance that allows for smooth animation and scrolling? How?

Share this post


Link to post
Share on other sites
Advertisement
I can't say for sure, but it looks like you're using multiple textures (perhaps 1 for each tile?) You really should pack those tile bitmaps into the one larger texture. If you're dealing with 32x32 tiles you can pack quite a few onto a 512x512 texture.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tape_Worm
I can't say for sure, but it looks like you're using multiple textures (perhaps 1 for each tile?) You really should pack those tile bitmaps into the one larger texture.


Indeed I am, but that's the nature of the application , it doesn't display some static background, but dynamically gets the data about each single tile and has to build the image from those little pieces.

I know it would be more efficient to provide the device with larger textures, but is there a way to dynamically build those from 32x32 tiles that would be significally faster than drawing each single of them the way I do it now?

Share this post


Link to post
Share on other sites
Quote:
Original post by gorky20
Indeed I am, but that's the nature of the application , it doesn't display some static background, but dynamically gets the data about each single tile and has to build the image from those little pieces.

I know it would be more efficient to provide the device with larger textures, but is there a way to dynamically build those from 32x32 tiles that would be significally faster than drawing each single of them the way I do it now?


I think you've misunderstood what I'm saying. I'm not proposing you display your tile map as a single image. I'm stating that you should pack your individual tile bitmaps onto a single texture. Your map can still be drawn from those tiles, just the tiles will all be located on the same texture as opposed to being single 32x32 bitmaps.

Share this post


Link to post
Share on other sites
Quote:
Original post by Tape_Worm
Quote:
Original post by gorky20
Indeed I am, but that's the nature of the application , it doesn't display some static background, but dynamically gets the data about each single tile and has to build the image from those little pieces.

I know it would be more efficient to provide the device with larger textures, but is there a way to dynamically build those from 32x32 tiles that would be significally faster than drawing each single of them the way I do it now?


I think you've misunderstood what I'm saying. I'm not proposing you display your tile map as a single image. I'm stating that you should pack your individual tile bitmaps onto a single texture. Your map can still be drawn from those tiles, just the tiles will all be located on the same texture as opposed to being single 32x32 bitmaps.


Yes, yes, to Tape_Worm you listen!

Share this post


Link to post
Share on other sites
Quote:
Original post by Mike.Popoloski
Quote:
Original post by Tape_Worm
Quote:
Original post by gorky20
Indeed I am, but that's the nature of the application , it doesn't display some static background, but dynamically gets the data about each single tile and has to build the image from those little pieces.

I know it would be more efficient to provide the device with larger textures, but is there a way to dynamically build those from 32x32 tiles that would be significally faster than drawing each single of them the way I do it now?


I think you've misunderstood what I'm saying. I'm not proposing you display your tile map as a single image. I'm stating that you should pack your individual tile bitmaps onto a single texture. Your map can still be drawn from those tiles, just the tiles will all be located on the same texture as opposed to being single 32x32 bitmaps.


Yes, yes, to Tape_Worm you listen!


So I assume you're about 3 feet tall, have green wrinkly skin, train jedi and have some messed up grammar?

Share this post


Link to post
Share on other sites
Quote:

So I assume you're about 3 feet tall, have green wrinkly skin, train jedi and have some messed up grammar?

On points (1), (2), and (4) you are correct. Point (3) is just what he'd like you to believe. In reality he just makes coffee.

Quote:

Pretty self explaining, it fills the screen area with tiles, but the problem is - with all those up to 8 floors (though not all of them are always completely filled), and single tiles composed of many textures it means a lot of work - in worst cases, around 5000 calls to sprite.Draw2D to redraw the whole scene, which unfortunately takes noticable time.

I would like to ask for your advice - is it possible to achieve the effect this code does (by some modifications to it, or maybe with completly diffrent approach?), but with performance that allows for smooth animation and scrolling? How?

Tape_Worm's suggestion is the correct approach -- pack the reused texture tiles into a single texture and adjust the texcoords to send only a subset of that texture for each unique tile instance.

Since doing this via the sprite interface may be clunky, you may have to handle the quads manually -- this is annoying, but has the benefit of allowing you to take advantages of batching or instancing techniques to reduce draw calls further, in the optimal case producing one instanced draw call for each unique tile image to render all instances of that tile.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
On points (1), (2), and (4) you are correct. Point (3) is just what he'd like you to believe. In reality he just makes coffee.


Sorry about the useless comment, but... [lol]

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!