I am implementing a game engine using OpenGL and wonder if it's a good idea to manually unload textures that are not used within a certain radius of the camera. It has been suggested to me for Android and OpenGL ES that it might be a good idea to load and unload textures on the fly as needed to save memory. Is this recommended for OpenGL ES and OpenGL? I am personally not convinced by the approach but I am curious as to when this will have benefits, if any, in the setting of OpenGL on a desktop PC and with OpenGL ES on a mobile phone.
It will depend on how many textures/the size of the textures you use in your game.
I believe the magic number is minimum 10MB of texture memory, so if your textures use more than that people tend to use texture compression (phone compatibility issues here, some compression formats are proprietary, there's a whole topic on this). You could unload textures when they aren't being used but there will be a heavy cost when you reload them, so be aware of that.
Generally speaking, you shouldn't need to resort to this method though.
If you don't need that memory, then it does no harm being there. And if you do need that memory, then you already know that you need to do it. So the answer is... do it if you need to.
Related
I'm contemplating writing an app which does a lot of moving 2D graphics. I'm not very familiar with the standard android 2D graphics API, and I'm a lot more comfortable with OpenGL so I'm naturally considering using OpenGL instead.
My consideration right now is this, if I make sure to reduce my frame rate and not do any continuous updates unless I need to animate stuff, is there a significant difference in power consumption/battery life with using OpenGL ES compared to standard graphics?
Note that I'm not making a game, and I will not need continuous updates except when animating UI elements.
OpenGL-ES on most devices leverages the device's GPU, and therefore likely has a slightly higher battery usage than non-OpenGL-ES display systems, however I believe that this is a negligible difference. Usually battery strain considerations circle areas such as networking or GPS tracking. For graphics, the best approach to minimizing battery consumption would be minimizing the overall usage of the device's CPU.
OpenGL-ES is optimized to be as efficient as possible for heavy graphic rendering, and has a bonus advantage of running outside the sandbox Android allocates to each running app, granting it a much larger pool of memory, along with access to the GPU making it optimal when considering a graphic rich presentation layer in your app.
Barring OpenGL-ES, you would probably either want to work with Bitmaps & Canvases or work with Views nested inside ViewGroups and move them around by altering their LayoutParams, or manipulating their Matrices in order to animate objects around the screen. Performance-wise, animations which are done like this are rarely impressive when compared with animations performed by OpenGL based platforms.
On the other hand, managing a structured app entirely in OpenGL-ES could be a nightmare as well. Using Fragments and Views are always the method of choice when building a non-graphic rich app, simply because they make everything so much simpler, and they were built and optimized for exactly this purpose.
At the end, it really depends on the requirements of the app you're building. You could also consider developing certain segments which have higher graphical requirements in OpenGL-ES and others which do not in more conventional methods such as Fragments.
Battery-wise, utilizing the GPU via OpenGL-ES definitely has some overhead, but if you overclock the CPU using conventional animation methods, you may end up putting even more strain on the battery, and even damaging your app's user experience with low frame rates.
Let's say I wanted to write my own software for Android that would benchmark rendering performance. Something along the lines of 3Dmark basically. What sorts of factors should the different test cases measure? Would it simply be rendering a ton of verts? Running a ton of textures?
Are there any resources out there that are either books or online guides that might help with developing specific test cases that would exercise specific portions of a phone/tablet's GPU?
Thanks,
Besides vertex count and texture sizes, the other major variables you should cover in an OpenGL ES benchmark are the display resolution and the complexity of the shader programs. You might also want to evaluate the compatibility of the OpenGL ES and EGL drivers, including extensions. There is a real need for that on Android.
I'm working on an Android app using Open GL ES 2.0. I'm confused about memory management in Open GL.
My questions are:
How much memory is available to the Open GL hardware? Clearly it's going to vary from device to device.
How can I find out how much memory is in use and how
much is left?
What happens if I exceed the memory limits?
What techniques should I be using to unload data not currently being displayed?
I presume I'm going to have to implement some kind of system to unload textures that are not currently in use on an LRU basis, but I'd like some idea of what criteria to use for this.
The app silently dies at some point and I suspect it is because I'm using too much graphics memory.
Currently I'm never unloading textures and I seem to be able to load quite a few - testing on a Nexus 7 I have been able to load 134 1024x1024 RGBA textures, which I calculate to be over 500MB. I presume once the textures have been loaded into graphics memory they take up less space, but that's still a lot, and clearly I have to manage that but I'd like some tips on how to start.
Simply use gles glDeleteTextures
If you run out of memory you will gen GL_OUT_OF_MEMORY error probably. Another thing is to monitor memory usage in Android.
android memory: How do I discover memory usage of my application in Android?
See here an interesting question for opengl: how to manage memory with texture in opengl?
I'm developing a game in Android using an already existing engine.
I have to use big textures for my animations, and i'm wondering what's better performance wise.
The new version of the engine supports npot textures(in case you ask yourself why i'm using such resolutions).
Is it better to have multiple 2330x1100 texture atlases or only one 2330x(1100 x number_of_textures_i_need) texture atlas?
Does this choice influence load time?(i think the memory they require is the same, since they contain the same number of pixel)
I read somewhere that switching textures can be a slow operation..
side quests:
1) are pot textures more efficient(in an enviroment build so that it can handle npot textures)?
2) can i hit some dimension/memory limit using just one texture?
one big texture should be better because loading and activating is slow because of the memory upload to the video memory. It also should use less energy and so enhances user experience ;-)
Try it - and write a long running test to prove it.
Background
I'm writing a graphing library for an android application (yes yes, I know there are plenty out there but none that offer the customizability we need).
I want the graphs to zoomable and pan-able.
Problem
I want the experience to be smooth, leave a small CPU footprint.
Solutions
Use View.onDraw(Canvas)
Use high resolution Bitmap
Use OpenGL
View.onDraw():
Benefits
Some what easy to implement
Drawbacks
Bad performance? (unless it uses OpenGL, does it?)
Bitmap:
Benefits
Really easy to implement
Great performance
Drawbacks
Have to use scaling which is ugly
OpenGL:
Benefits
Probably good performance depending on my implementation
Drawbacks
More work to implement
Final words
OpenGL would probably be the professional solution and would definitely offer more flexibility but it would require more work (how much is unclear).
One thing that is definitely easier in OpenGL is panning/zooming since I can just manipulate the matrix to get it right, the rest should be harder though I think.
I'm not afraid to get my hands dirty but I want to know I'm heading in the right direction before I start digging.
Have I missed any solutions? Are all my solutions sane?
Additional notes:
I can add that when a graph changes I want to animated the changes, this will perhaps be the most demanding task of all.
The problem with using Views is that you inherit from the overhead of the UI toolkit itself. While the toolkit is pretty well optimized, what it does it not necessarily what you want. The biggest drawback when you want to control your drawing is the invalidate/draw loop.
You can work around this "issue" by using a SurfaceView. A SurfaceView lets you render onto a window using your own rendering thread, thus bypassing the UI toolkit's overhead. And you can still use the Canvas 2D rendering API.
Canvas is however using a software rendering pipeline. Your performance will mostly depend on the speed of the CPU and the bandwidth available. In practice, it's rarely as fast as OpenGL. Android 3.0 offer a new hardware pipeline for Canvas but only when rendering through Views. You cannot at this time use the hardware pipeline to render directly onto a SurfaceView.
I would recommend you give SurfaceView a try first. If you write your code correctly (don't draw more than you need it, redraw only what has changed, etc.) you should be able to achieve the performance you seek. If that doesn't work, go with OpenGL.