Android - Storing 3d models or creating them - java

Which is best for Android?
I have 30 3D models but there is only ever one drawn on the screen at any time.
Do I:
create the model and destroy the previous model every time the displayed one changes.
or
create all 30, store them and just reference them when I want to draw them.
Note that when one model is removed another model appears and the transition must be smooth.
In what context would one be better than the other?

Have you tried loading all of them at once? Start with that, and if it doesn't work, then look at memory management. You should be able to keep at least three or four models in memory on an older device. If you do have issues with ram, try to predict which models are going to be used next, and pre-load them in.
Keeping them all loaded is normally preferable, because it means your app will appear fluid and responsive.

Related

Saving multithreaded game

I have written a 2d platformer in java, and i was wondering how i would save the game. I looked at just serializing the whole game using XMLEncoder or ObjectOutputStream, however those didn't save threads correctly. When i started the game again the thread weren't running. So then i tried calling start on all of the threads after the game loaded, but that created a major problem with the threads being in invalid states and the game started glitching up. What is the best way to just write the whole game to a save file.
Saving a game will rarely be as straightforward as saving all objects exactly as they are in memory at the time of exit/saving and then loading them back to their exact state afterward.
It is more likely that you will need/want to create a data structure to represent your game's state which you will then write to disk. Multithreading is unlikely to be your primary concern. You will want to start these threads back up anew when you load your game state.
Consider that many games save/load via a menu. If your game starts out with a splash screen, or at least a main menu, you wouldn't want to be loading objects from their exact state on startup anyway. Find the minimal important elements that you need to reconstruct everything that is important about the state of the game and save that to disk. Most of the state of a game can be implicitly recreated from a very small amount of data.
Sadly, the exact method of how you should save/load your game is not easily answered on a Q/A website as it will depend heavily on the exact data structures you are using and the entire nature of your game.
You should serialize only your business domain data, not threads. Threads need to be created again when you reload data. ObjectOutputStream is ok assuming your domain classes are Serializable.

Where should I store my game level state?

I have a game where I draw and move bitmaps over a SurfaceView. The user can interact (drag and drop) these bitmaps. When the player hits the home button then goes back into the game, I want to be able to pause the game, then restore it to where it was before he left it. What is the best way to store my custom objects?
Should I implement onSaveInstanceState(Bundle) and have all of the classes whose objects I want to save implement the Parcelable interface? This would be quite a bit of work, and I'm still not sure how I would save things like bitmaps. I suppose I wouldn't and I would just reload those from disk.
I am also confused about what kind of storage a bundle offers: disk storage that never goes away unless you clear it yourself, or memory storage that goes away if the OS decides to remove your program from memory while it's in the background. According to the comments in this question, it is disk storage. The documentation implies that it is memory storage, saying Note that it is important to save persistent data in onPause(), however I don't find it very clear. This page also implies that it is not persistent: it only lasts as long as the application remains in memory. So which one is it?
The last link above suggests using onRetainNonConfigurationInstance() to keep objects in memory while the application is in the background. This would imply that if the program is taken out of memory by the OS while in the background, everything would be lost. This seems to be what most (all I tested on) games do: if you hit home while playing then go back in, the level resumes. If you hit home, open a lot of stuff (sufficient to make Android remove the game from memory), then go back in, nothing is resumed, the game starts from the main menu. Does that mean this is what they use, and if so, is that a good practice?
Note that the question about a Bundle's persistency is just a secondary curiosity. I don't really care if the state of this game is not permanently saved and can be lost after the game being in the background for a while (as described in 2 above). I'm interested in the best practice for this case.
The basic idea is, IMO, identify the smallest collection of values that will enable you to recreate the state of your game. Save those in shared preferences.

high cpu load during rendering

I am rendering rather heavy object consisting of about 500k triangles. I use opengl display list and in render method just call glCallList. I thought that once graphic primitives is compiled into display list cpu work is done and it just tells gpu to draw. But now one cpu core is loaded up to 100%.
Could you give me some clues why does it happen?
UPDATE: I have checked how long does it take to run glCallList, it's fast, it takes about 30 milliseconds to run it
Most likely you are hitting the limits on the list length, which are at 64k verteces per list. Try to split your 500k triangles (1500k verteces?) into smaller chunks and see what you get.
btw which graphical chips are you using? If the verteces are processed on CPU, that also might be a problem
It's a bit of a myth that display lists magically offload everything to the GPU. If that was really the case, texture objects and vertex buffers wouldn't have needed to be added to OpenGL. All the display list really is, is a convenient way of replaying a sequence of OpenGL calls and hopefully saving some of the function call/data conversion overhead (see here). None of the PC HW implementations I've used seem to have done anything more than that so far as I can tell; maybe it was different back in the days of SGI workstations, but these days buffer objects are the way to go. (And modern OpenGL books like OpenGL Distilled give glBegin/glEnd etc the briefest of mentions only before getting stuck into the new stuff).
The one place I have seen display lists make a huge difference is the GLX/X11 case where your app is running remotely to your display (X11 "server"); in that case using a display list really does push all the display-list state to the display side just once, whereas a non-display-list immediate-mode app needs to send a bunch of stuff again each frame using lots more bandwidth.
However, display lists aside, you should be aware of some issues around vsync and busy waiting (or the illusion of it)... see this question/answer.

Load array using separate thread

I've written a speedlimit app that loads data from a set of tiled xml files representing 0.05 sided degree maps.
At the moment, the app checks if I've moved into a new square (using OnLocationChanged) and if so loads in the data for it and the surrounding other 8 tiles.(has a bit of a sanity check and only loads data for new tiles so tends to just load in another 3 tiles worth of data)
Anyway, it currently does this on the UI thread and so there is a noticeable pause when moving into new square and I'd like to shift it to background using Asynctask (It also loads in bitmap maps for display purposes and I've already moved that code into an Asynctask so I know how to do that bit)
My problem is to do with checking the arrays (actually using ArrayLists) used for the speed limits while the Asynctask is possibly adding (and in future version - subtracting) to them in the background.
I was wondering if there was a "professional" :) way of dealing with this sort of situation.
A synchronized access should be dealing with all problems of concurrency accessing the ArrayList. Just use
synchronized(myArrayList) {
// update/read/modifiy
}
Both in your AsyncTask and your UI.
Good resource is the stackoverflow search

Efficient undo/redo for Photoshop-like mobile app

I'm trying to write a painting app for a mobile device (Android) that will have a bit more functionality than MS Paint (e.g. various brushes and brush settings, selections, layers) but won't be as complex as Photoshop. I need my app to have a decent undo/redo feature. Unlimited undo/redo is probably not possible. I'd be happy with being able to undo about the last minute worth of user actions (maybe about 20 actions).
The main approaches I know of for undo/redo is:
save the whole state or just the bits that changed after each operation. Undoing involves updating the state by restoring snapshots. Pros: simple to implement Cons: memory intensive.
use the command pattern where each command has a "do action" and "undo action" method. To undo, you just call the undo action of the previous commands. Pros: memory efficient, Cons: much more complex to implement.
My pathological undo/redo scenarios I have to consider is:
the user paints over the whole canvas in one go, where you would want this whole operation to be undone when the user clicks undo. With option 1, we'd need to store a bitmap the size of the whole canvas.
the user draws something, imports image 1.jpg onto the canvas, does some more drawing, 1.jpg is then deleted/modified at some point by another application and then the user wants to undo then redo all their actions in the paint application. I'm really not sure how to undo correctly here without saving a copy of any imported image while it's on the undo stack.
Can anyone give any recommendations about how best to implement undo/redo on a mobile device where memory and processor speed are low? I like the simplicity of 1 and 3 but it seems like the only realistic option is 2. I'm not sure how to cope with my second pathological example with this option though.
On the iPhone, Core Data has built in support for undo and redo. Just make your data model reflect the objects drawn and you can easily roll it back and forward between saves. Usually you would save the procedures and objects used to create the graphic instead of the graphic itself.
Edit:
OK, but this is just a little API
support for implementing number 2 and
won't help with the examples I gave.
The key idea to making this work is that you don't configure your data model to modal and persist the graphical output of the program, you configure it to modal and persist the process of creating the graphical output.
The naive way of creating a graphical program would be to set up the data flow like:
Input_UI-->Display_UI-->Data_Model
The user manipulates the Input_UI which directly alters the onscreen graphics of the Display_UI. Only when the user saved would the Data_Model come into play. This type of data flow makes undo/redo (and other things) very hard to implement especially in a painting e.g. compositing program. Every single operation has to know how to undo itself and has to be able operate on the altered graphic.
The better way is to set up a data flow like this:
Input_UI-->Data_Model-->Display_UI
The user manipulates the Input_UI which communicates to the Data_Model which manipulations the user chose. The Data_Model records the process e.g. "add file jpg.1 at rect {0,0,100,100}". A change to the Data_Model sends a notification to the Display_UI which reads the changed data and implements the process described.
The Data_Model rolls itself back and the Display_UI simply draws what the Data_Model tells it to. The Display_UI doesn't have to understand the undo process at all.
In a drawing program you would create logical layers of individual graphical objects so that redoing is just a matter of removing layers in the reverse order they were added. For painting/composition programs, you have to start at the last save point and recreate the graphic going forward until the last-1 step.
So, in your examples for a compositing program:
The Data_Model stores the coordinates of the selected area (the entire canvas) which is still just "rect {0,0,canvas.width,canvas.height}" and then the operation "fill with black". For undo, the Display_UI whips the image back to the last save point and then invisibly applies the changes made up to last-1.
You just need to save a cache of the image up until the next save. At that point, the Data_Modal commits all the changes and exports the composition to a file. The next time the app starts, it begins with the image from the last time. If you want infinite undo, then yes you have to save the imported image permanently.
The way to approach this is to ignore the GUI and instead think about how you would design an app to be run from the command line with out any GUI input or output. The Data_Modal would work just the same. It would save the text commands and the data (e.g. imported images) for creating the output image, not just a snapshot of the image on screen.
I like the simplicity of 1 and 3 but
it seems like the only realistic
option is 2.
I'm not sure what "3" is, since you only appear to have two options in your question.
With respect to the memory consumption of #1, it's only an issue if you use memory. Only hold onto history in memory for as long as it takes an AsyncTask (or possibly a regular background thread working off a LinkedBlockingQueue) to write them to the SD card. No SD card -- no undo/redo. On an undo, if your history has already written it to disk, reload it from disk. Just be sure to clean up the SD card (delete history on a clean exit, delete all lingering files on next startup).
Bear in mind that I have never written a painting application, let alone on Android, and so there may yet be performance problems (e.g., undo may take a second to load the bitmap off of the SD card).

Categories

Resources