Writing real time opengl-es game for android - some question (optimizing) - android

1.
TIMING in a game:
Is there a way to use other then System.Currentmillis()-starttime>XX to update anything in a game? Is it safe or CPU expensive?
2.
In my game I have 20 items (moving square vertexes), when it comes up to 60-70 vertex, the FPS drop down to 30-40 FPS, from 60 FPS. (testing on a galaxy S i9000 phone).
Is there a way to my game FPS will be 30FPS? Is it good for update my game to 30 FPS, or I dont need to handle this? (because there will be a lagg on lower FPS - it will be slow)
How I can do to my objects run on the same speed, at any time?
3.
what is the best way: do the phisyx, and all the stupp in onDrawFrame, or: start a Thread what is made the mathematics for me? What is faster and better?

TIMING in a game: Is there a way to use other then System.Currentmillis()-starttime>XX to update anything in a game? Is it safe or CPU expensive?
You should use a time delta system. There are a lot of tutorials about this. This is a very good tutorial: deWiTTERS Game Loop.
In my game I have 20 items (moving square vertexes), when it comes up to 60-70 vertex, the FPS drop down to 30-40 FPS, from 60 FPS. (testing on a galaxy S i9000 phone). Is there a way to my game FPS will be 30FPS? Is it good for update my game to 30 FPS, or I dont need to handle this? (because there will be a lagg on lower FPS - it will be slow)
That's depending on which method you're using. If 3D, you should consider using Vertex Buffer Objects (VBO:s) (like a Vertex Array but in your device's GPU memory). That makes a huge difference since the CPU doesn't need to copy the data from CPU to GPU every iteration.
If 2D, you can still use VBO:s but if draw_texture is supported on the device that's recommended.
However, the options are:
Vertex Arrays (slowest).
Vertex Buffer Objects (fastest in 3D, slower than draw_texture in 2D).
draw_texture extension (fastest in 2D, but doesn't render 3D stuff).
You can support all of this methods to cover the whole range of Android devices but remember to check the extensions of the device's OpenGL drivers. Some might support all of these, but there can be devices that only support Vertex Arrays and VBO:s (for example).
I've answered a related question here, but just to show you; here's a print from one of Chris Pruett's lectures at Google I/O:
How I can do to my objects run on the same speed, at any time?
You can't. Android is a multi-processing operating system and you have no idea what's going on (maybe another Service application is updating?). What you can do is to use a time delta system, like I mentioned above.
what is the best way: do the phisyx, and all the stupp in onDrawFrame, or: start a Thread what is made the mathematics for me? What is faster and better?
It's recommended to multi-threading (two Thread's running in parallel). Shortly, do your drawing stuff inside onDrawFrame and update stuff inside your own created Thread/Runnable.
Recommended resources:
Google I/O 2009 and Google I/O 2010
Game Development for Android: A Quick Primer

Related

Starling for IOS & Android: Very low FPS in a static situation

I created an application with Starling, on the new mobile devices it performs amazingly well, however on the older devices (e.g. iPhone 4) I encounter a very odd lag.
I have as far as I can tell a completely static situation:
There are quite a few display objects added to stage, many of them are buttons in case it matters, their properties are not changed at all after initialization (x, y, rotation, etc...).
There are no enterframes / timeouts / intervals / requests of any kind in the background.
I'm not allocating / deallocating any memory.
In this situation, there's an average of 10 FPS out of 30, which is very odd.
Since Starling is a well established framework, I imagine it's me who's doing something wrong / not understanding something / not aware of something.
Any idea what might be causing it?
Has anyone else experienced this sort of problem?
Edit:
After reading a little I've made great optimizations in every possible way according to this thread:
http://wiki.starling-framework.org/manual/performance_optimization
I reduced the draw calls from around 90 to 12, flattened sprites and set blendmode to none in specific cases to ease on CPU, and so on...
To my surprise when I tested again, the FPS was unaffected:
fps: 6 / 60
mem: 19
drw: 12
Is it even possible to get normal fps with Starling on mobile? What am I missing?
I am using big textures that are scaled down to the size of the device, is it possible that such a thing affects the fps that much?
Regarding "Load textures from files/URLs", I'm downloading different piles of assets for different situations, therefore I assumed compiling each pile into a SWF would be way faster than sending a separate request for each file. The problem is, for that I can only use embed, which apparently uses twice the memory. Do you have any solution in mind to enjoy the best of both worlds?
Instead of downloading 'over-the-wire' your assets and manually caching them for re-use, you can embed the assets into your app bundle vs. embedding them and then use the Starling AssetManager to load the textures at the resolution/scale that you need for the device:
ie.
assets.enqueue(
appDir.resolvePath("audio"),
appDir.resolvePath(formatString("fonts/{0}x", scaleFactor)),
appDir.resolvePath(formatString("textures/{0}x", scaleFactor))
);
Ref: https://github.com/Gamua/Starling-Framework/blob/master/samples/scaffold_mobile/src/Scaffold_Mobile.as
Your application bundle gets bigger of course, but you do not take the 2x ram hit of using 'embed'.
Misc perf ideas from my comment:
Testing FPS with "Release" mode correct?
Are you using textures that are scaled down to match the resolution of the device before loading them?
Are you mixing BLEND modes that are causing additional draw calls?
Ref: The Performance Optimization is great reading to optimize your usage of Starling.
Starling is not a miracle solution for mobile device. There's quite a lot of code running in the background in order to make the GPU display anything. You the coder has to make sure the amount of draw call is kept to a minimum. The weaker the device and the less draw call you should force. It's not rare to see people using Starling and not pay any attention to their draw calls.
The size of graphics used is only relevant for the GPU upload time and not that much for the GPU display time. So of course all relevant texture need to be uploaded prior to displaying any scenes. You simply cannot try to upload any new texture while any given scene is playing. Even a small texture uploading will cause idling.
Displaying everything using Starling is not always a smart choice. In render mode the GPU gets a lot of power but the CPU still has some remaining. You can reduce the amount of GPU uploading and GPU charge by simply displaying static UI elements using the classic display list (which is where the Staling framework design is failing). Starling was originally made to make it very difficult to use both display system together that's one of the downsides of using this framework. Most professional I know including myself don't use Starling for that reason.
Your system must be flexible and you should embed your assets for mobile and not use any external swf as much as possible and be able to switch to another system for the web. If you expect to use one system of asset for mobile/desktop/web version of your app you are setting yourself up for failure. Embedding on mobile is critical for memory management as the AIR platform internally manages the cache of those embedded assets. Thx to that when creating new instances of those assets the memory consumption stays under control, if you don't embed then you are on your own.
Regarding overall performance a very weak Android device will probably never be able to go passed 10 fps when using Starling or any Stage3D framework because of the amount of code those framework need to run (draw calls) in the background. On weak device that amount of code is already enough to completely overload the CPU. On the other hand on weak device you can still get a good performance and user experience by using GPU mode instead of render mode (so no Stage3D) and displaying mostly raster graphic.
IN RESPONSE TO YOUR EDIT:
12 draw calls is very good (90 was pretty high).
That you still get low FPS on some device is not that surprising. Especially low end Android device will always have low FPS in render mode with Stage3D framework because of the amount of code that those framework have to run to render one frame. Now the size of the texture you are using should not affect the FPS that much (that's the point of Stage3D). It would help with the GPU uploading time if you reduce the size of those graphics.
Now optimization is the key and optimizing on low end device with low FPS is the best way to go since whatever you do will have great effect on better device as well. Start by running tests and only displaying static graphics with no or very little code on your part just to see how far the Stage3D framework can go on its own on those weak device without losing any FPS and then optimize from there. The amount of object displayed on screen + the amount of draw calls is what affects FPS with those Stage3D framework so keep a count of those and always seek ways to reduce it. On some low end device it's not practical to try to keep a 60fps so try to switch to 30 and adjust your rendering accordingly.

Unity3D frame rate dropped after importing Blender model

I am making a 3D game with Unity for Android. In the game there is a main character and up to around 10 opponents possibly on the screen at the same time, all using the same model (prefabs for "opponents" differ only in one material for other colors).
The model was designed using MakeHuman and Blender.
On PC (since rendering is a lot faster) there are no problems, but when testing it on an Android device, the rendering time drops the frame rate to around 25-30 FPS when there are 3-4 or more bodies on the screen, creating a really "laggy" feeling (I am expecting a frame rate of about 60 FPS).
Before importing the Blender model I used placeholder spheres and there was no such behavior. Since this is the first time I am using Blender and such 3D models, I am not sure whether my model is within the expected sizes for a mobile game. My current model consists of: 5,956 Verts, 10,456 Faces, 10,819 Tris with a file size of around 6.5 MB (it was generated even larger by MakeHuman at first, but I managed to compress it and optimize it significantly, but still without major effects).
I attempted different solutions, including merging all meshes in the model into one, turning off shadows, using as least materials as possible, etc. All attempts were with no or very limited improvement.
Any ideas are welcome. Cheers!
My current model consists of: 5,956 Verts, 10,456 Faces, 10,819 Tris
with a file size of around 6.5 MB
Sounds like way too much to me.
Also, keep in mind that if you're doing anything such collision calculations, every extra complexity takes exponentially more time
for a mobile game I would suggest you to remesh the model (even though its not a nice work, but the results are much better than the decimate-modifyer for example) an than bake normalmaps for it from the high-res model.

How many FFTs per second can I do on my smartphone? (for performing voice recognition)

I'm exploring voice recognition and DSP, and so I would like to implement a simple sound frequency analyzer on my smartphone (I have both an iPhone and a Samsung Nexus S running Android). I have done basic DSP in Matlab previously.
From my understanding, I need to perform an FFT to get the fundamental frequencies of a signal.
So now, I would like to sample the microphone at 44100 Hz. If I use a sliding window of sample size 512 with 50% overlap, that means I need to do an FFT every 256 samples, or 0.00580 seconds.
That rate seems really high, particularly if I program in Java for Android. Will my smartphone be able to handle that speed? I am aware that you can program in C/C++ on Android, but I would like to keep it with Java for the time being.
Performing a real-to-complex FFT requires ~5/2 n lg n floating-point operations (additions and multiplications). In your case, n=512, so:
flops per fft ~= (5/2) * 512 * 9 = 11520
So 172 ffts per second requires about 2 million floating-point operations per second. That sounds like a lot, but it really isn't that many. The hardware of a typical armv7-class smartphone is capable of hundreds of millions or billions of floating-point operations per second.
Note however that you will want to have a carefully-written high-performance FFT; poorly written FFTs are notoriously inefficient. On the iPhone, you can use the Accelerate framework (built right into the OS, and available in the SDK), which provides a nice set of FFT functions; I'm not sure what's available on Android.
For the iPhone, the Accelerate framework for iOS can do all the FFTs you specify using on the order of 1% of CPU time (exact percentage depending on device model and FFT data types).
For Android, you might strongly want to consider using an NDK native library for processor intensive numerical calculations.
Also note that an FFT will give you the peak frequencies, which will not necessarily include the fundamental or voice pitch frequency.
ADDED: This Java benchmark web page suggests that Android phones are capable of in the range of 5 to over 50 MFlops using Java for well written matrix math. A well written FFT should fall around roughly the same performance range in MFlops. #Stephan Cannon posted that on the order of 2 MFlops might be required for your spec.
Your Android device will be able to handle this fine. I've written realtime, FFT-based frequency analyzers that ran on Windows Mobile devices from a few years ago (using pure C#), and these devices had much worse processors than current Android devices. The most computationally expensive aspect of FFT is the trig functions, and since you're using a fixed-size window you can easily replace the trig function calls with a pre-calculated lookup table.
As an aside you can probably cut down your computation time by reducing your sampling rate. Speech doesn't have much energy above 8 kHz, so you could likely downsample your audio to 16 KHz before doing any FFTs, without losing much accuracy. At 16 kHz your FFTs would be smaller, and so faster.
Wikipedia claims that 16 kHz is a standard sampling rate for speech recognition in desktop applications.
(I realize that this doesn't answer the OP's question, but I think it might be helpful to him nonetheless, given his application.)

glDrawElements extremally slow on Android ( HTC Wildfire )

I'm testing OpenGL performance on an Android phone ( HTC Wildfire to be exact ), and I came across a strange thing - when I try to draw a textured indexed rectangle the size of the screen ( 320 x 480 ), I can get a framerate up to 40 fps!!! - and that's only when I use a 32x32 texture.
If I increase the texture size to 256x256, the performance drops down to 35 frames.
My question is - how is it possible for all those Android games to run smoothly and still be so full of cool graphics.
There are a bunch of different ways to eek performance out of your device.
Make sure you aren't doing blending, or drawing that you don't need and from experience a lot of the lower end HTC devices (eg the desire) are fill rate limited.
Use triangle strips instead of triangles.
Use draw elements and cache your calls eg load your vertex buffer and call draw multiple times for a frame.
But most importantly use the DDMS with method profiling to determine where your bottle necks actually are they may be places you don't expect them eg logging, gc, slow operation in a loop. You will be able to see how much of the time is due to rendering and how much for other operations. (look for GLImpl.glDrawElements)
My biggest ones were with GC kicking in too often (5 times per second and causing my fps to be very sluggish), something you will see with mem allocations often in places you won't even think of. Eg if you are concatenating a string to a float with the + operator or using traditional java get() functions everywhere or (worst) collections, these create a large number of objects that can trigger GC.
Also if you have expensive operations separate them out into a separate thread.
Also I am assuming you are creating your texture once and using the same index each time. I have seen some tutorials which create the texture every time a frame is rendered.
With extensive use of the DDMS I was able to take fps from 12 to 50 on the HTC Desire for a busy scene.
Hope that gets you going in the right direction :)
In my own experience, they don't on devices like the wildfire.

Android Canvas Performance Terrible on Droid

I've been developing a game for Android for the past few months, and it's just about finished. I recently acquired a Motorola Droid for testing purposes, as I developed the game using a HTC Incredible. On my Incredible I can get a pretty solid 59 fps throughout the game. On the Droid, the game becomes very choppy with an average of about 40 fps. Both phones are running Android 2.2.
I looked up the tech specs are here are the only differences I noted that might affect gameplay: 1 GHz processor vs 550 MHz and 512 MB RAM vs 256 MB RAM.
Just for giggles, I thought I would strip down the game to a very minimal state to see if it was my coding to blame. I stripped it down to the point where the only thing being down was drawing the main menu and moving various bitmaps around the screen. Not a hair over 45 fps.
So, is this the approximate cap for the Motorola Droid? If so...my game is pretty simple and non-CPU intensive, so what can I do? There are thousands of other Android games that are much more demanding than my own, yet they seem to run very smoothly.
Is it the fact that I'm using Android's built-in Canvas and not Open-GL or some other alternative? Would anybody recommend doing that?
Could somebody enlighten me to what might be my problem here?
Thanks in advance.
OpenGL ES is the way to go. Canvas is most likely implemented on top of OpenGL ES anyway, and not very efficiently by the sounds of it.
40fps is pretty good, the human eye can only detect jerkiness when the framerate falls below 25fps. Anything above 15fps is considered 'full motion'.
If you can see jitter then it may be the game pausing while the garbage collector kicks in - you can reduce this by reducing the number of objects that you create and you should be able to see it happening by using ddms.
Other than that perhaps there is a glitch calculating the frame rate?

Categories

Resources