Faster Drawing Question


Last Updated:

  1. FoxMulder900

    FoxMulder900 Member This Topic's Starter

    Joined:
    Jun 13, 2010
    Messages:
    6
    Likes Received:
    0
    I am looking at the Snake example that comes with the SDK, specifically the onDraw method inside the TileView class:

    Code (Text):
    1.     public void onDraw(Canvas canvas) {
    2.         super.onDraw(canvas);
    3.         for (int x = 0; x < mXTileCount; x += 1) {
    4.             for (int y = 0; y < mYTileCount; y += 1) {
    5.                 if (mTileGrid[x][y] > 0) {
    6.                     canvas.drawBitmap(mTileArray[mTileGrid[x][y]],
    7.                             mXOffset + x * mTileSize,
    8.                             mYOffset + y * mTileSize,
    9.                             mPaint);
    10.                 }
    11.             }
    12.         }
    13.  
    14.     }
    This works great for the snake application but I am thinking of doing something a bit more intensive so I want my draw method to be as quick as possible. I was thinking of something a bit more like this:

    Code (Text):
    1.    
    2. public Drawable canvasBuffer;
    3. public Coordinate[] dirtyTiles; //A list of tiles that need to be re-drawn
    4.  
    5. public void onDraw(Canvas canvas) {
    6.         super.onDraw(canvas);
    7.         for (int i = 0; i < dirtyTiles.length; i += 1) {
    8.             //I need a way to do this - drawOtherImage is not a real function
    9.             canvasBuffer.drawOtherImage(mTileGrid[dirtyTiles.x][dirtyTiles.y],
    10.                                      dirtyTiles.x*mTileSize, dirtyTiles.y*mTileSize)
    11.         }
    12.         canvasBuffer.draw(canvas);
    13.  }
    14.  
    The idea being that I store a separate image (canvasBuffer) that I only draw the tiles that need to be changed, then I draw the buffer to the canvas. Also this way I do not have to calculate the offset for every tile, I can set the offset at anytime by setting the bounds of the canvasBuffer.
    My question here is how to draw one drawable onto another, I can only find methods that allow you to draw to a canvas object. Any suggestions?
     

    Advertisement
  2. KlaymenDK

    KlaymenDK Well-Known Member

    Joined:
    May 29, 2009
    Messages:
    1,217
    Likes Received:
    130
    Welcome to the forum! :D

    Mind you, I have zero Android graphics experience, but I like your way of thinking. Can you initialise the offscreen image to be transparent, and then display it (the non-transparent parts overwriting the existing image)? But I wonder if it's not slower to paint this relatively large image than it is to paint a number of tiny ones ... just a thought.

    Remember: I know nothing! :p
     
    FoxMulder900 likes this.
  3. seafit

    seafit New Member

    Joined:
    Jun 9, 2010
    Messages:
    4
    Likes Received:
    0
    it seems like you are drawing a map on screen, right? why not using scroll Carmack to do that. in most case it will be used in drawing game maps.
     
  4. FoxMulder900

    FoxMulder900 Member This Topic's Starter

    Joined:
    Jun 13, 2010
    Messages:
    6
    Likes Received:
    0
    Klaymen, your transparency idea is interesting, I might have to give that a try; however that still leaves me trying to figure out how to draw a smaller image onto another larger image that is not the canvas. I was also wondering if the cost of drawing a single large image would be much better than a bunch of small ones, but if I can figure it out I will do some timing and post the results! - also, BIG fan of The Neverhood here! :D

    seafit, what exactly is scroll Carmack? I'm assuming you mean something that John Carmack came up with, but I can't seem to find anything on google!

    Thanks for the replies!
     
  5. FoxMulder900

    FoxMulder900 Member This Topic's Starter

    Joined:
    Jun 13, 2010
    Messages:
    6
    Likes Received:
    0
    I have finally gotten back around to taking a look at this and I have found a solution if anyone is interested. I simply did not understand the concept that you do not actually draw onto a Canvas object, rather the Canvas object is a tool used to draw onto a Bitmap. So I did something like this.

    Code (Text):
    1.  
    2. Bitmap bufferBitmap = Bitmap.createBitmap(mapWidth, mapHeight, Bitmap.Config.ARGB_8888);
    3. Canvas bufferCanvas = new Canvas(bufferBitmap);
    4. Vector<Drawable> dirtyTiles = new Vector<Drawable>();
    5.  
    Then simply keep track of your dirty(changed) tiles and during the drawing routine, loop through the array and draw them using the bufferCanvas, then draw the bufferBitmap to the main canvas. (don't forget to clear out the dirtyTiles array after you have drawn them all)

    My timings for this method were around 4 times faster than looping through every tile, every frame!
     

Share This Page

Loading...