Using large textures with opengl on android - android

What is the best way to go about using large textures with opengl on android?
I want to load some background images for my game with my target resolution being 480x800. Going by the recommended 512x512 resolution cap, I've tried scaling the images down to 240x400 and having opengl scale them back up, but that looks like trash and I would rather keep them as high-res as possible. I've seen one or two other people talking about using 512x1024 so I'm wondering:
How many phones would actually have trouble handling these image sizes?
Would it be better to risk an OOM and use 512x1024 textures, or risk a performance hit by splitting the images in two and increasing opengl calls?
For consideration: In general I will only be using two other 512x512 atlases at a time (aside from the background), with a maximum of three on menu screens where framerate isn't important.
Thanks!

I've experimented using large textures for for planets in my game. With two 1024x1024 hemispheres per planet and probably only one or max two planets visible at a time. Once in game, they render fine on my somewhat dated ZTE Blade running 2.1.
However, the load times were terrible (talking an extra 10 to 30 seconds for two large textures to load).

Related

Resulution of graphics for mobile games

Does it matter, how high the resultion of my graphics are (the picture of my player is 1500 x 2000 px) or are there any problems, that the game couldn't work very well or smooth or something like that? (Unity, 2D Game)
This really depends on the target device, as well as the scale of your game. I wouldn't think that it would cause issues, but it really depends on how many large images you have rendered at the same time. You can also always change the max size in the sprite settings if it becomes a problem.
Also keep in mind that if your player is small it really doesn't need to be that large, so I would just go ahead and decrease the max size in the sprite settings if that is the case.
I'm assuming that you are asking about texture size.
modern hardware can handle resolution such as 1500 x 2000 very easily and I would not worry about rendering speed.
However, texture loading (affects both CPU & GPU) may become issue if you have large textures (or large number of textures). if you have 1000 textures of 1500 x 2000, it will become hard to load the texture without affecting user experience.

Should I make different spritesheets for different resolutions

Im designing a game for android, I have my assets in low resolution that looks fine in small screens, if the game runs in a bigger screen it comes out pixelated, should I make different spritesheets for different resolutions or just one in HD and then reduce the images according to resolution? the second one sounds better but Im worried if all the scaling would take its toll on performance
I do use several SpriteSheets with different resolutions on LibGDX, here is why :
When you have to support devices with screen resolution ranging from 320*480 to 2560*1400 (And maybe up to 4K in a few years), it's almost impossible to have a perfect result on all these screens with an unique spritesheet resolution. If you use a virtual screen resolution (viewport), you may work on a single resolution and create assets accordingly and let this viewport automatically scale to the screen, so that your game will look the same on any device.
So, one may argue that a single HD spritesheet may be enough. However, most low-cost or old mobile devices are sometimes unable to load high resolution textures, so you may lose support for these devices if you only use HD graphics. What's more, downscaling assets programmatically often lead to poor and unpredictable graphics results in my own experience.
So personnaly, here is what i do :
I check the screen resolution and the max size of texture the device can load.
Using these values, i choose a viewport size and a spritesheet size choosing from spritesheet resolutions i pre-defined. (Low, medium or high resolution)
To help resolving assets according to the screen resolution, libgdx provide the ResolutionFileResolver class.
However, you should also read : https://gamedev.stackexchange.com/questions/24638/resolution-independence-in-libgdx

Why do we have to provide images for all device screen sizes (mobile development)?

Why do we have to provide images for all screen sizes when developing mobile applications? Wouldn't it be more efficient to just have 1 very large image for each unique image and then scale the image down whenever the app is being run on a smaller device? It would definitely make the game's file size much smaller.
In lots of cases, it wouldn't look as good.
If you find a set of well designed icons, you'll see that they've been independently designed for each resolution: the smaller ones will deliberately have less detail in, because downscaling just doesn't produce as good results.
Here are two GNOME icons, for the same thing, but one at 256x256 and one at 48x48. You can see that the 48x48 one has less detail in the writing on the letter, but the writing is also designed rather differently: on the 256x256 one it looks like the middle page of a document, and on the 48x48 one it looks like the opening of a letter, with an address at the top.
It would make the size of the .apk file significantly smaller, but it would have more undesirable tradeoffs for runtime efficiency.
Having to load large bitmap objects and scale them down is an un-necessary load for the device's processor. But more importantly, having to load large bitmap objects into memory makes the VM's memory fill up more quickly. This means that the VM has to do garbage collection more often, which can cause noticeable delays at runtime (this can cause animations to lose frames and look rougher).

Drawing large background image with libgdx - best practices?

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.

Android opengles glBindTexture() calls

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

Categories

Resources