The AndEngine framework for Android has a way to load textures into an atlas. The atlas way of loading textures was new to me and so I looked into it. From what I've read around the forums, an atlas is a large rectangular region of image data where the width and height have to be powers of 2 (although they don't have to be equal, i.e. you can have a 512x1024 if you want). Textures are loaded into this region and this is used to keep them all in memory during the lifetime of the app. It allocates all of that space even if you don't use some of it.
With that in mind, what process can I use to optimally place an arbitrary number of graphics into the same atlas? I don't plan to do this at runtime within the app, but once all the graphics for my game have been created, I was hoping I could run the images and their sizes through some algorithm to determine how big to make the atlas and where each image should be loaded in it. Once I know those things, I can hard code their location for my game.
This is not an AndEngine or even Android specific question. I'm sure there are other graphics oriented frameworks that load textures this way.
I was about to post the question on Math.StackExchange.com but instead I found that it was already asked and already answered. There's even a link to a CodeProject article that does this for CSS Sprites.
EDIT: What I ended up doing in the long run was using a program called TexturePacker. Not only did it pack the images, it produced files to be used in AndEngine (as well as other supported platforms) and made the whole process easier for me.
Related
A lot of different questions were asked around the question "How to deal with Textures for different devices in Libgdx". I would like to summarize information here and ask what is not clear for me still.
Tips for the good quality of Textures:
Forget about the approach to build huge Textures with transparency. RAM will be destroyed on low devices. explanation
Use Viewport. Aspect Ratio for Textures will look the same for each device. explanation
Avoid raw textures. Apply the TextureFilter. explanation
Use AssetManager. It allows you to load, dispose, make screen loading progress in the easiest way. example
Use different resolutions for different devices. Use ResolutionFileResolver. It allows Libgdx automatically to choose the most appropriate Texture for each device. example
Note: feel free to add ideas to this list
The question is about the last point. Android platform has a huge amount of different phones and tablets. I understand that it doesn't make sense to create each Texture for each Resolution.
How many resolutions to cover separately? I suppose to take 3 categories: for lower, middle and high devices.
If so - how to choose the most appropriate one for each category?
Are there any cases to use the same Texture somewhere? (small icons, HUD, etc)
I'm looking for an android 2d game engine, where you can create your game at the resolution you want, and the game will work the same on every phone, no matter the resolution, maybe by auto creating thoose black rectangles.
I was working with libGDX, but i could not find any ways to do that, just some viewport scalling methods, that will make the game graphics quality crappy.
I also used to work with the android sdk using surfaceview, and i had to code everything by a ratio, and also scale the bitmaps by a ratio, but i don't really think that that is a good way to do it.
Are there any android game engines that support every device resolutions?
You are asking for something you won't get. I doubt that there's a tool or engine released to the public that will automagically fix all resolutions possible to fit your needs. This is something that developers has to tackle, and it's a nice thing to handle independently.
Now when working in LibGdx, did you even try to use Texture filters? Linear filtering will smoothen your images when enlarged. They may get some blur but I've released a commercial game using this method.
All in all, i really think you should give it another shot. LibGdx will spare you a large amount of troubles and in my opinion; The request of yours ain't that hard to overtake.
I am trying to write a libgdx livewallpaper (OpenGL ES 2.0) which will display a unique background image (non splittable into sprites).
I want to target tablets, so I need to somehow be able to display at least 1280x800 background image on top of which a lot more action will also happen, so I need it to render as fast as possible.
Now I have only basic knowledge both about libgdx and about opengl es, so I do not know what is the best way to approach this.
By googling I found some options:
split texture into smaller textures. It seems like GL_MAX_TEXTURE_SIZE on most devices is at least 1024x1024, but I do not want to hit max, so maybe I can use 512x512, but wouldn't that mean drawing a lot of tiles, rebinding many textures on every frame => low performance?
libgdx has GraphicsTileMaps which seems to be the tool to automate drawing tiles. But it also has support for many features (mapping info to tiles) that I do not need, maybe it would be better to use splitting by hand?
Again, the main point here is performance for me - because drawing background is expected to be the most basic thing, more animation will be on top of it!
And with tablet screen growing in size I expect soon I'll need to be able to comfortably render even bigger image sizes :)
Any advice is greatly appreciated! :)
Many tablets (and some celphones) support 2048 textures. Drawing it in one piece will be the fastest option. If you still need to be 100% sure, you can divide your background into 2 pieces whenever GL_MAX_TEXTURE happens to be smaller (640x400).
'Future' tables will surely support bigger textures, so don't worry so much about it.
For the actual drawing just create a libgdx mesh which uses VBOs whenever possible! ;)
Two things you dindn't mention will be very important to the performance. The texture filter (GL_NEAREST is the ugliest if you don't do a pixel perfect mapping, but the fastest), and the texture format (RGBA_8888 would be the best and slowest, you can downgrade it until it suits your needs - At least you can remove alpha, can't you?).
You can also research on compressed formats which will reduce the fillrate considerably!
I suggest you start coding something, and then tune the performance up. This particular problem you have is not that hard to optimize later.
My game already consists of an atlas the size of 1024x1024 as I am aware that is the max size for a texture. The problem is I need about 1-2 more of these 1024x1024 textures. That should give me 3 glBindTexture() calls which I know is huge performance drag. I have not tested it yet because I am having other problems currently but would this slow my application by a considerable amount? Is there another solution?
If you are worried about any performance loss, I'd recommend you to profile your application so you really can see where your application's bottleneck is, and then come back if it turns out to be horrible.
Three big atlas textures are still better than many small textures that you bind over and over again.
Currently my game has around 6 512x512 texture atlases and I still dont require any loading screens on any phone so far. Although if you are going to do a lot of binding you may want to look into making a Batcher class that will submit all of your vertices to the GPU at one, it will speed up your application considerably
In my view I have a simple ARGB drawable that takes about 2ms to draw but I can draw the same file as a bitmap in under 0.5ms (just some quick code, I can't really consider it an option). What are the best ways to optimize the drawing speed of a drawable?
It will depend on the number of drawables and how many times each gets drawn. For a small number, use canvas (an exact number will also depend on the device) I would suggest using Canvas as it's a nice higher level approach to drawing.
If you want to crank out a lot of images (think hundreds), I would suggest creating a GLSurfaceView and using openGL to render your images using VBOs tailored to your app. I would also recommend using a texture sheet if you go down this route since you'll get a huge increase in performance at the cost of code complexity.
But this will also depend on that type of app. My background is in game development so I use openGL exclusively for better performance. for a simple app (something along the lines of androidify) Canvas should be fine. If you want a simple tutorial for openGL, I suggest visiting Bergman's series of posts on the topic (google should give you a link for that). It is a nice intro to openGL.