Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Fast graphics in C#

Fast graphics in C#

Scheduled Pinned Locked Moved C#
graphicsperformancecsharpwinformsgame-dev
14 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Philip Fitzsimons

    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."

    S Offline
    S Offline
    Stephane David
    wrote on last edited by
    #5

    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?

    P I 3 Replies Last reply
    0
    • S Stephane David

      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?

      P Offline
      P Offline
      Philip Fitzsimons
      wrote on last edited by
      #6

      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."

      1 Reply Last reply
      0
      • S Stephane David

        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?

        P Offline
        P Offline
        Philip Fitzsimons
        wrote on last edited by
        #7

        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."

        S 1 Reply Last reply
        0
        • S Stephane David

          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 Offline
          I Offline
          Ista
          wrote on last edited by
          #8

          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.

          1 Reply Last reply
          0
          • M Meysam Mahfouzi

            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 of PictureBox control(and use e.Graphics). 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. I hope this helps


            Don't forget, that's

            Persian Gulf

            not Arabian gulf!

            I Offline
            I Offline
            Ista
            wrote on last edited by
            #9

            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.

            1 Reply Last reply
            0
            • P Philip Fitzsimons

              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."

              S Offline
              S Offline
              Stephane David
              wrote on last edited by
              #10

              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?

              P 1 Reply Last reply
              0
              • S Stephane David

                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?

                P Offline
                P Offline
                Philip Fitzsimons
                wrote on last edited by
                #11

                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."

                S 1 Reply Last reply
                0
                • P Philip Fitzsimons

                  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."

                  S Offline
                  S Offline
                  Stephane David
                  wrote on last edited by
                  #12

                  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

                  P 1 Reply Last reply
                  0
                  • S Stephane David

                    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?

                    J Offline
                    J Offline
                    J Dunlap
                    wrote on last edited by
                    #13

                    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

                    1 Reply Last reply
                    0
                    • S Stephane David

                      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

                      P Offline
                      P Offline
                      Philip Fitzsimons
                      wrote on last edited by
                      #14

                      glad to here you fixed it!


                      "When the only tool you have is a hammer, a sore thumb you will have."

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups