Can I use a Bitmaps to pick up speed from Canvas.drawBitmap? - android

Let me give you some substance to my question. I am currently drawing 2 or more full screen drawables to my canvas. The drawables in the foreground slide at different speeds and have large transparent sections to create a shifting scene. (Think side scroller game like mario. I believe they call this parallax)
I then follow that up with several smaller drawables in the foreground that move and do their own thing.
At present drawing all these drawables to my canvas is very taxing on my device. Is there a way to use Bitmaps to programmatically and dynamically layer them while maintaining the alphas, to achieve the same affect and reduce the number of times I call drawBitmap on my canvas?
Thanks

Related

LibGdx Dynamic (Runtime) Textures

I am drawing some dots to represent players of two teams on a map.
Each team has its own colour.
Important to note that the dot contains two circles, outer border and a inner fill so there will be two colours, with the border always being the same.
It makes sense for me to generate this at runtime rather than packing a texture for each combination.
Upon research, there seems to many ways to achieve this but each has a associated problem
ShapeRenderer
ShapeRenderer is for debugging purposes and should not be used for usual drawing as stated by a LibGdx developer here
http://badlogicgames.com/forum/viewtopic.php?t=8573&p=38930
For this reason I avoided using this
Pixmap
This was very promising, I liked the idea that I could just generate two textures and re-use them for each sprite. The biggest problem with this is that Textures made via Pixmap are un-managed so if the OpenGL context is lost and regained (This can be easily reproduced in an Android application, if the user backgrounds the app and restores it from foreground). I am primarily targetting Android so this an issue for me
Texture Re-Colour
Was thinking I could create a grey scale dot and re-colour it but since my asset has two parts to it, I am not sure how I could selectively choose the inner circle and fill it.
Question 1 How Do I Restore Pixmap Texture On Context Loss?
I have not found an example which details how to do this? I assume it is going to be done in the resume lifecycle callback but what do I need to do?
Question 2 Alternative Way?
Is there an alternative way for my issue perhaps?
Thanks for reading!
Load just one texture with white circle. Use SpriteBatch to draw players: first call batch.setColor(borderColor) and draw the circle Texture with outer radius, then call batch.setColor(fillColor) and draw it with inner radius. Sure there is a some performance impact because of drawing fill part twice, but if circles are small enough the impact is going to be negligible.

Android: What to use for rendering the layers of photo-editor?

Hello friends!
I need to create a photo editor, which allow to put the emoticons, text and drawing with a brush on the picture.
Open the illustration
An editor must be able to change the position of smiles & text, their size and rotation with two fingers (multi-touch).
Mechanics is clear to me. I found ready realization of multi-controller:
https://github.com/lukehutch/android-multitouch-controller
But I don't understand how better visualize all the layers in terms of performance:
Layer 3 - text
Layer 2 - emoticons
Layer 1 - drawing
Layer 0 - photo
I am afraid to use the canvas, without your opinion. I heard that the canvas buggy when displaying a large number of images.
I found examples visualize the layers of images using layer-list with the 's inside. I think this method will be more performance numbers for my task.
But I have not found documentation of how to update the position (top / left) when you move an item.
My question is: What is the best use for the visualization of all layers and the possibility to save the final image (merge all layers)?
Please help, what to choose and what is the right path!
Thank you in advance! :)
Canvas is not buggy. It's the only way for you to render things onto a Bitmap. By the looks of your requirement, I think you need to draw your Layers onto different bitmaps. Layer 0 will be your default bitmap. Every other layer will be individual bitmaps on their own. The reason they have to be on a bitmap of their own is so that you can move them as you wish.
You final merge will be to draw all these bitmaps, on the default bitmap via Canvas.drawBitmap() call.

Android drawing on layers

Hi I'm making a drawing application, I'm loading a picture in a canvas, I then want to overlay stickers on it But I want to be able to remove any sticker at any time during the process. It's incredibly painful to restore the background image when I decide to remove the sticker. Is there a way to draw each sticker on different layer so I only have to clear the layer to era the sticker.
Am I clear?
Not really, other than using 1 bitmap per sticker and forming the final screen by drawing all those bitmaps on top of each other. But even if you could- layers aren't magic. When you cleared one, to get the final result you'd still have to composite them all again, which means just as much work for your program.

Android - Most efficient way to draw multiple identical Drawables in a Canvas?

I'm a newbie in android programming, my purpose is to draw multiple identical drawables (and animate them changing their x y coordinates) in a canvas returned calling something like mySurfaceHolder.lockCanvas(). The number of drawables is dynamic and changes with time.
How is it possible keeping the high as possible frame rate?
(Sorry for bad english)
As far as I know, there are two common ways to draw animated images yourself on the screen: SurfaceView OR GLSurfaceView (Android official site).
For the better performance of drawing multiple identical images, my suggestion is to draw images on GLSurfaceView instead of SurfaceView.
If the amount of identical images to draw is large, then the frame rate to draw onto SurfaceView will be affected by the device's computing power (depends on CPU speed). On the other hand, using GLSurfaceView mostly depends on GPU speed, so I suggested using GLSurfaceView to draw images.
But if you are not familiar with OpenGL ES. The most efficient way of drawing multiple identical images is to separate your logic statements from images by drawing code segments with another thread. Drawing using drawable.draw(canvas) or canvas.drawBitmap() will be fine.
ps. Using GLSurfaceView will require translating the Drawables to the texture before they can be drawn on GLSurfaceView.

Android scrolling background of bitmap tiles

I'm tried to determine the "best" way to scroll a background comprised of tiled Bitmaps on an Android SurfaceView. I've actually been successful in doing so, but wanted to determine if there is a more efficient technique, or if my technique might not work on all Android phones.
Basically, I create a new, mutable Bitmap to be slightly larger than the dimensions of my SurfaceView. Specifically, my Bitmap accomodates an extra line of tiles on the top, bottom, left, and right. I create a canvas around my new bitmap, and draw my bitmap tiles to it. Then, I can scroll up to a tile in any direction simply by drawing a "Surfaceview-sized" subset of my background Bitmap to the SurfaceHolder's canvas.
My questions are:
Is there a better bit blit technique than drawing a background bitmap to the canvas of my SurfaceHolder?
What is the best course of action when I scroll to the edge of my background bitmap, and wish to shift the map one tile length?
As I see it, my options are to:
a. Redraw all the tiles in my background individually, shifted a tile length in one direction. (This strikes me as being inefficient, as it would entail many small Bitmap draws).
b. Simply make the background bitmap so large that it will encompass the entire scrolling world. (This could require an extremely large bitmap, yet it would only need to be created once.)
c. Copy the background bitmap, draw it onto itself but shifted a tile length in the direction we are scrolling, and draw the newly revealed row or column of tiles with a few individual bitmap draws. (Here I am making the assumption that one large bitmap draw is more efficient than multiple small ones covering the same expanse.)
Thank you for reading all this, and I would be most grateful for any advice.
I originally used a similar technique to you in my 'Box Fox' platformer game and RTS, but found it caused quite noticeable delays if you scroll enough that the bitmap needs to be redrawn.
My current method these games is similar to your Option C. I draw my tiled map layers onto a grid of big bitmaps (about 7x7) taking up an area larger than the screen. When the user scrolls onto the edge of this grid, I shift all the bitmaps in the grid over (moving the end bitmaps to the front), change the offset of grid, and then just redraw the new edge.
I'm not quite sure which is faster with software rendering (your Option C or my current method). I think my method maybe faster if you ever change to OpenGL rendering as you wouldn't have to upload as much texture data to the graphics card as the user scrolls.
I wouldn't recommend Option A because, as you suggest, the hundreds small bitmap draws for a tiled map kills performance, and it gets pretty bad with larger screens. Option B may not even be possible with many devices, as it's quite easy to get a 'bitmap size exceeds VM budget' error as the heap space limit is set quite low on many phones.
Also if you don't need transparency on your map/background try to use RGB_565 bitmaps, as it's quite a lot faster to draw in software, and uses up less memory.
By the way, I get capped at 60fps on both my phone and 10" tablet in my RTS with the method above, rendered in software, and can scroll across the map smoothly. So you can definitely get some decent speed out of the android software renderer. I have a 2D OpenGL wrapper built for my game but haven't yet needed to switch to it.
My solution in a mapping app relies on a 2 level cache, first tile objects are created with a bitmap and a position, these are either stored on disk or in a Vector (synching is important for me, multithreaded HTTP comms all over the place).
When I need to draw the background I detect the visible area and get a list of all the tiles I need (this is heavily optimised as it gets called so often) then either pull the tiles from memory or load from disk. I get very reasonable performance even on slightly older phones and nice smooth scrolling with no hiccups.
As a caveat, I allow tiles not to be ready and swap them with a loading image, I don't know if this would work for you, but if you have all the tiles loaded in the APK you should be fine.
I think one efficent way to do this would be to use canvas.translate.
On the first drawing the entire canvas would have to be filled with tiles. New android phones can do this easily and quickly.
When the backround is scrolled I would use canvas.translate(scrollX, scrollY), then I would draw individualy one by one tile to fill the gaps, BUT, I would use
canvas.drawBitmap(tileImage[i], fromRect, toRect, null) which would only draw the parts of the tiles that are needed to be shown, by setting fromRect and toRect to correspond to scrollX and scrollY.
So all would be done by mathematics and no new bitmaps would be created for the background - save some memory.
EDIT:
However there is a problem using canvas.translate with surfaceView, because it is double buffered and canvas.translate will translate only one buffer but not the second one at the same time, so this alternating of buffers would have to be taken into account when depending on surfaceView to preserve the drawn image.
I am using your original method to draw a perspective scrolling background. I came up with this idea entirely by accident a few days ago while messing around with an easy technique to do a perspective scrolling star field simulation. The app can be found here: Aurora2D.apk
Just tilt your device or shake it to make the background scroll (excuse the 2 bouncing sprites - they are there to help me with an efficient method to display trails). Please let me know if you find a better way to do it, since I have coded several different methods over the years and this one seems to be superior. Simply mail me if you want to compare code.

Categories

Resources