TextureAtlas - how does it affect on RAM usage in open world game? - libgdx

I plan to use TextureAtlas in my open world 2d game.
I need to load textures dynamically (because there are thousands of them, so I cannot load all at once). I plan to load textures that are needed at specific moment in gameplay. Also for some reasons I cannot have many texture atlases per map location.
Generally, I must avoid situation that I read all textures (entire atlas), because RAM usage will be too large. How the TextureAtlas work? Is is possible to keep the atlas open during entire game, but read from the atlas (to the RAM) only chosen textures when needed without worrying about RAM usage?
Best regards.

You cannot load portions of a TextureAtlas. It is all or nothing. You will have to use multiple atlases and carefully plan what to put in each atlas such that you don’t have to load all of them simultaneously.
A Texture represents a single image loaded into GPU memory for use in OpenGL. A page of a TextureAtlas corresponds to a single Texture. Typically, you will have multiple TextureRegions on each page (Texture) of a TextureRegion. If you don’t, there’s no point in using TextureAtlas. The point of TextureAtlas is to avoid SpriteBatch having to flush vertex data and swap OpenGL textures for every sprite you draw. If you draw consecutive TextureRegions from the same Texture (or atlas page), they are batched together into a single mesh and OpenGL texture so it performs better.
Libgdx doesn’t support loading individual pages of a TextureAtlas though. That would make it too complicated to use. So, if you are doing a lot of loading and unloading, I recommend avoiding multipage atlases. Use AssetManager to very easily load and unload what you need.

Related

Writing an HD Game in Staged 3D

I'm trying to write a 2D Game using Starling, and most textures are up to 4k, and I'm getting a resource limit exception.
Is there a way or an algorithm, idea, to get HD Textures and use them with that limited texture resources in stage3d ? Compression ?
Stage3D (which Starling uses underneath) has a max texture size of 2048x2048. If your textures are larger than this, then you are going to have to split them and stitch them together at runtime.
If you find yourself running out of memory (rather than the dimensional size limit) then you can look into compression using ATF textures.

Allocate memory in GPU, flash/air

This is more an "implementation" of technology kind of question.
In old times, when I worked with C language, you could specify to use VGA memory or ram memory for allocation of bitmaps structures, then you could work with them a lot faster.
Now we are in 2013, I create bitmap in AS3, and it is allocated in ram (I've seen no option to use the GPU and 100% of cases im sure it is using the RAM, because it increases exactly the expected bitmap size.
¿Is there any option to use GPU memory?
Thanks
Check out the API docs for flash.display3D.Texture - there are 3 methods:
uploadCompressedTextureFromByteArray(data:ByteArray, byteArrayOffset:uint, async:Boolean = false):void
Uploads a compressed texture in Adobe Texture Format (ATF) from a ByteArray object.
uploadFromBitmapData(source:BitmapData, miplevel:uint = 0):void
Uploads a texture from a BitmapData object.
uploadFromByteArray(data:ByteArray, byteArrayOffset:uint, miplevel:uint = 0):void
Uploads a texture from a ByteArray.
So you can't allocate the memory directly in the GPU. You must upload data from a ByteArray or BitmapData, which first exists in RAM. However, to minimize CPU RAM usage, you could potentially reuse a single ByteArray or BitmapData in RAM, change its contents, and upload it many times, or release it after loading. But you can't access the contents of GPU memory directly, as far as I know.
As far as "read access", the only way to get data back from the GPU memory (again, a slow workaround) is to draw the Context3D back into a BitmapData via Context3D.drawToBitmapData... basically like a screen grab. The Starling Framework has an example of this functionality via Stage.drawToBitmapData.
Basically, the Stage3D APIs weren't setup so you can easily access the GPU memory.
You cannot allocate GPU memory manually like in other languages, but you can indeed accelerate your graphics using the GPU with different Adobe technologies.
For example if you want GPU accelerated video decoding you should be using StageVideo, or if you want to accelerate 2d or 3d graphics you could use Stage3D.
Unless you want to work in a low level fashion with Stage3D, it is recommended you use an intermediary framework.
For 2d the best solution is by far Starling. It is a solid framework endorsed by Adobe which has been used in countless commercial projects and is constantly optimised.
As for 3d take a look at Flare3D or Away3D.

why game is running slow in libgdx?

I am making racing game in Libgdx.My game apk size is 9.92 mb and I am using four texture packer of total size is 9.92 Mb. My game is running on desktop but its run on android device very slow. What is reason behind it?
There are few loopholes which we neglect while programming.
Desktop processors are way more powerful so the game may run smoothly on Desktop but may slow on mobile Device.
Here are some key notes which you should follow for optimum game flow:
No I/O operations in render method.
Avoid creating Objects in Render Method.
Objects must be reused (for instance if your game have 1000 platforms but on current screen you can display only 3, than instead of making 1000 objects make 5 or 6 and reuse them). You can use Pool class provided by LibGdx for object pooling.
Try to load only those assets which are necessary to show on current screen.
Try to check your logcat if the Garbage collector is called. If so than try to use finalize method of object class to find which class object are collected as garbage and try to improve on it.
Good luck.
I've got some additional tips for improving performance:
Try to minimize texture bindings (or generally bindings when you're making a 3D game for example) in you render loop. Use texture atlases and try to use one texture after binding as often as possible, before binding another texture unit.
Don't display things that are not in the frustum/viewport. Calculate first if the drawn object can even be seen by the active camera or not. If it's not seen, just don't load it onto your GPU when rendering!
Don't use spritebatch.begin() or spritebatch.end() too often in the render loop, because every time you begin/end it, it's flushed and loaded onto the GPU for rendering its stuff.
Do NOT load assets while rendering, except you're doing it once in another thread.
The latest versions of libgdx also provide a GLProfiler where you can measure how many draw calls, texture bindings, vertices, etc. you have per frame. I'd strongly recommend this since there always can be situations where you would not expect an overhead of memory/computational usage.
Use libgdx Poolable (interface) objects and Pool for pooling objects and minimizing the time for object creation, since the creation of objects might cause tiny but noticable stutterings in your game-render loop
By the way, without any additional information, no one's going to give you a good or precise answer. If you think it's not worth it to write enough text or information for your question, why should it be worth it to answer it?
To really understand why your game is running slow you need to profile your application.
There are free tools avaiable for this.
On Desktop you can use VisualVM.
On Android you can use Android Monitor.
With profiling you will find excatly which methods are taking up the most time.
A likely cause of slowdowns is texture binding. Do you switch between different pages of packed textures often? Try to draw everything from one page before switching to another page.
The answer is likely a little more that just "Computer fast; phone slow". Rather, it's important to note that your computer Java VM is likely Oracles very nicely optimized JVM while your phone's Java VM is likely Dalvik, which, to say nothing else of its performance, does not have the same optimizations for object creation and management.
As others have said, libGDX provides a Pool class for just this reason. Take a look here: https://github.com/libgdx/libgdx/wiki/Memory-management
One very important thing in LibGDX is that you should make sure that sometimes loading assets from the memory cannot go in the render() method. Make sure that you are loading the assets in the right times and they are not coming in the render method.
Another very important thing is that try to calculate your math and make it independent of the render in the sense that your next frame should not wait for calculations to happen...!
These are the major 2 things i encountered when I was making the Snake game Tutorial.
Thanks,
Abhijeet.
One thing I have found, is that drawing is laggy. This means that if you are drawing offscreen items, then it uses a lot of useless resources. If you just check if they are onscreen before drawing, then your performance improves by a lot surprisingly.
Points to ponder (From personal experience)
DO NOT keep calling a function,in render method, that updates something like time,score on HUD (Make these updates only when required eg when score increases ONLY then update score etc)
Make calls IF specific (Make updations on certain condition, not all the time)
eg. Calling/updating in render method at 60FPS - means you update time 60 times a sec when it just needs to be updated once per sec )
These points will effect hugely on performance (thumbs up)
You need to check the your Image size of the game.If your image size are more than decrease the size of images by using the following link "http://tinypng.org/".
It will be help you.

Bulk texture uploads

I have a specialised rendering app that needs to load up any number of jpegs from a pdf, and then write out the images into a rendered page inside a kernel. This is oversimplified, but the point is that I want to find a way to collectively send up 'n' images as textures, and then, within the kernel, to index into this collective of textures for tex2d() calls. Any ideas welcome for doing this gracefully.
As a side question, I haven't yet found a way to decode the jpeg images in the kernel, forcing me to decode on the CPU and then send up (slowly) a large bitmap. Can i improve this?
First: if texture upload performance is not a bottleneck, consider not bulk uploading. Here are some suggestions, each with different trade-offs.
For varying-sized textures, consider creating a texture atlas. This is a technique popular in game development that packs many textures into a single 2D image. This requires offsetting texture coordinates to the corner of the image in question, and it precludes the use of texture coordinate clamping and wrapping. So you would need to store the offset of the corner of each sub-texture instead of its ID. There are various tools available for creating texture atlases.
For constant-sized textures, or for the case where you don't mind the waste of varying-sized textures, you could consider using a layered texture. This is a texture with a number of independent layers that can be indexed at texture fetch time using a separate layer index. Quote from the link above:
A one-dimensional or two-dimensional layered texture (also know as texture array in Direct3D and array texture in OpenGL) is a texture made up of a sequence of layers, all of which are regular textures of same dimensionality, size, and data type.
A one-dimensional layered texture is addressed using an integer index and a floating-point texture coordinate; the index denotes a layer within the sequence and the coordinate addresses a texel within that layer. A two-dimensional layered texture is addressed using an integer index and two floating-point texture coordinates; the index denotes a layer within the sequence and the coordinates address a texel within that layer.
A layered texture can only be a CUDA array by calling cudaMalloc3DArray() with the cudaArrayLayered flag (and a height of zero for one-dimensional layered texture).
Layered textures are fetched using the device functions described in tex1Dlayered() and tex2Dlayered(). Texture filtering (see Texture Fetching) is done only within a layer, not across layers.
Layered textures are only supported on devices of compute capability 2.0 and higher.
You could consider a hybrid approach: sort the textures into same-sized groups and use a layered texture for each group. Or use a layered texture atlas, where the groups are packed such that each layer contains one or a few textures from each group to minimize waste.
Regarding your side question: a google search for "cuda jpeg decode" turns up a lot of results, including at least one open source project.

Flash Stage3D: Render/Update procedural textures?

I need to update the texture of a 3D object frequently.
(it is a procedurally generated pattern, so it cannot be cached, it has to be dynamically generated each frame)
What is the fastest way of doing this?
First I thought of updating a bitmapData via copyPixels(), then reupload this bitmapdata via
Texture.uploadFromBitmapData() each frame, but I've heard that this is very slow ( due to moving data from system RAM to GPU RAM)
Any way of directly manipulating a Texture on the GPU,so I could avoid this step?
If it's a procedurally generated pattern then it can be done on the gpu. If it's impossible, then only way is the way you described - it's the fastest one. And yes, it's slow process.