Fast graphics in C#
-
something not right here. - are you drawing all 400 tiles each time? - are you moving them onscreen in one move or 400 moves?
"When the only tool you have is a hammer, a sore thumb you will have."
I draw all the 400 tiles each times, because if the user clicks on the globalview "somewhere", I need to redraw all of it. However, I do it only when the map change (scroll or editor change of terrain), no when things in the layers (a unit animation change). I move them on screen in one move : I start by drawing them in a bitmap, which is stored, and then in the render function (with a timer), I draw the stored bitmap in the PictureBox. This last part is fast. I don't understand why drawing the 400 128x64 tiles in the backbuffer is so much longer than drawing the whole image in a 1024x768 PictureBox?
-
I draw all the 400 tiles each times, because if the user clicks on the globalview "somewhere", I need to redraw all of it. However, I do it only when the map change (scroll or editor change of terrain), no when things in the layers (a unit animation change). I move them on screen in one move : I start by drawing them in a bitmap, which is stored, and then in the render function (with a timer), I draw the stored bitmap in the PictureBox. This last part is fast. I don't understand why drawing the 400 128x64 tiles in the backbuffer is so much longer than drawing the whole image in a 1024x768 PictureBox?
becuase its 400 times more work.... you need less calls
"When the only tool you have is a hammer, a sore thumb you will have."
-
I draw all the 400 tiles each times, because if the user clicks on the globalview "somewhere", I need to redraw all of it. However, I do it only when the map change (scroll or editor change of terrain), no when things in the layers (a unit animation change). I move them on screen in one move : I start by drawing them in a bitmap, which is stored, and then in the render function (with a timer), I draw the stored bitmap in the PictureBox. This last part is fast. I don't understand why drawing the 400 128x64 tiles in the backbuffer is so much longer than drawing the whole image in a 1024x768 PictureBox?
you should cache your whole "world". i.e. make your buffer as big as the world, and only redraw those in the 400 that have changed. this way you should only have to do a few redraws..
"When the only tool you have is a hammer, a sore thumb you will have."
-
I draw all the 400 tiles each times, because if the user clicks on the globalview "somewhere", I need to redraw all of it. However, I do it only when the map change (scroll or editor change of terrain), no when things in the layers (a unit animation change). I move them on screen in one move : I start by drawing them in a bitmap, which is stored, and then in the render function (with a timer), I draw the stored bitmap in the PictureBox. This last part is fast. I don't understand why drawing the 400 128x64 tiles in the backbuffer is so much longer than drawing the whole image in a 1024x768 PictureBox?
Well your first and biggest mistake is not using direct x as a window in your application. GDI sucks for that type of application Second you need to redraw based on regions. My advice: get rid of gdi+ dont even bother with it. learn direct x and set up the buffered pages one for the map, cities, and the objects then flip the pages and you ll get plenty of speed nick I'm not an expert yet, but I play one at work. Yeah and here too.
-
Try this approach: Choose the graphics surface of a PictureBox control instead of drawing on a Bitmap object, I mean do your drawing in
OnPaint
event ofPictureBox
control(and usee.Graphics
). This way you can use benefits of auto scrolling thatPictureBox
control has. And also speed is more acceptable than when you draw on aBitmap
object. I hope this helps
Don't forget, that's
Persian Gulf
not Arabian gulf!
Meisi wrote: This way you can use benefits of auto scrolling that PictureBox control has. And also speed is more acceptable than when you draw on a Bitmap object. For a business app maybe. BitBltFast would actually be the wiseest choice. picture boxes are slow. I only say this because I'm writing a game in c# right now and have discovered the the GDI+ sucks I'm not an expert yet, but I play one at work. Yeah and here too.
-
you should cache your whole "world". i.e. make your buffer as big as the world, and only redraw those in the 400 that have changed. this way you should only have to do a few redraws..
"When the only tool you have is a hammer, a sore thumb you will have."
World = 200x200 tiles. Tile = 128x64 pixels. As they overlap (isometric view), let say it's 100x100 tiles. That's still 81 920 000 pixels... Isn't it to much to store the whole background?
-
World = 200x200 tiles. Tile = 128x64 pixels. As they overlap (isometric view), let say it's 100x100 tiles. That's still 81 920 000 pixels... Isn't it to much to store the whole background?
yes that is pretty big... maybe you need to reconsider how you draw your world - maybe tiles are not a good idea...
"When the only tool you have is a hammer, a sore thumb you will have."
-
yes that is pretty big... maybe you need to reconsider how you draw your world - maybe tiles are not a good idea...
"When the only tool you have is a hammer, a sore thumb you will have."
Before I did this graphics.DrawImage(backgroundSprite.Canvas.PictureFile,destinationRectangle,backgroundSprite.SourceRect,GraphicsUnit.Pixel); and I had in memory one file with 9x9 tiles. I selected the tile from the source rectangle, and copied it in my PictureBox. Now I have that : graphics.DrawImage(backgroundCanvasArray[BackgroundCanvas].TilesArray[line,column],offsetX,offsetY); and I have an array of tile 9x9. Initialization is a bit longer, as I have to break my 9x9 tiles images into 81 images in an array. But then, for the rendering I simply draw the tiles directly at the offset, without specifying a source and destination rectangle. Result : rendering time for a 20x20 tiles world has dropped from 950 ms to 30 ms. What took time was the resampling of the image to fit the new size, EVEN IF IT WAS THE SAME SIZE. Now it works well enough
-
I'm trying to write a game in C# to learn the language. It's a mini clone of civilization III. The main game window is a map, drawn with tiles (20x20 tiles right now). To draw the map, I have somewhere a Bitmap that I store as backbuffer, where I draw the tiles themselves. Then to animate the sprites I use this "map bitmap", and draw the sprites above it. To draw a tile, I have canvas in memory, with all the braw bitmaps (they contains 9x9 tiles), I select the right tile (-> creation of a source rectangle, corresponding to the right tile in the canvas), then I draw it in my Bitmap, after having found the destination rectangle. So basically it's something like graphics.Draw(CanvasBitmap, SourceRectangle, DestinationRectangle). I have some problem with speed : rendering 20x20 tiles (each is 128x64) takes 950 ms. As I need to render it anytime I scroll (because the map is 200x200, but the viewport is only 20x20), it is not acceptable. Is there a way to speed the process using only GDI+ and C#? Must I use direct X?
Beware of creating a large bitmap buffer every time you re-paint. Instead, create a new buffer bitmap when the window is resized. (You might already be doing this, but just checking.)
"Blessed are the peacemakers, for they shall be called sons of God." - Jesus
"You must be the change you wish to see in the world." - Mahatma Gandhi -
Before I did this graphics.DrawImage(backgroundSprite.Canvas.PictureFile,destinationRectangle,backgroundSprite.SourceRect,GraphicsUnit.Pixel); and I had in memory one file with 9x9 tiles. I selected the tile from the source rectangle, and copied it in my PictureBox. Now I have that : graphics.DrawImage(backgroundCanvasArray[BackgroundCanvas].TilesArray[line,column],offsetX,offsetY); and I have an array of tile 9x9. Initialization is a bit longer, as I have to break my 9x9 tiles images into 81 images in an array. But then, for the rendering I simply draw the tiles directly at the offset, without specifying a source and destination rectangle. Result : rendering time for a 20x20 tiles world has dropped from 950 ms to 30 ms. What took time was the resampling of the image to fit the new size, EVEN IF IT WAS THE SAME SIZE. Now it works well enough
glad to here you fixed it!
"When the only tool you have is a hammer, a sore thumb you will have."