How to load texture from a tiled image?

I have an image consisting of many images arranged nicely as tiles, and want to use each tile as a separate texture. Is there anyway to load the whole image and crop the part I want as a texture? The solution of adjusting texture coordinates on a material to bound an individual tile does not appeal to me because I like to use all materials and all textures in a uniform manner, if possible. The reason is each individual tile is meant to be a full-citizen texture, they just happen to live in a single image.

Well, that kind of IS the solution. What you describe is a texture atlas. Texture atlases are based on texture coordinates.

Else you will have to split the image into multiple images yourself and take the performance hit of having a ton of textures instead of just one.

Here are some thoughts on that matter:

texture atlas:

  • If you use texture min/mag filters with mipmaps, your tiles must be a power of two size - e.g. 64x64 tiles in a 1024x1024 texture. Which will then work for the first 6 mipmap levels and break at the 7th mipmap level, because the tiles “bleed” into each other (“color bleeding” is actually the term for that phenomenon).
  • You will get problems with “wrap around” - i.e. when trying to use a large polygon with one of your tiles repeating multiple times, then strange lines will appear between the repetitions. This comes from having different pixels next to your quad. I observed this behavior when writing a special shader with tiled textures. Note: this is not a problem if you use the tiles on e.g. quads (max number of repetitions is 1).
  • Texture atlases are often used for game characters and objects and to avoid the problems above, special care must be taken - example: configure a margin of 8 or 16 pixels when you bake your textures in Blender - which then minimizes “color bleeding” (parts in such an atlas are not power two tiles but random sized n-gons) and it also fixes “wrap around artifacts” (when using a special tile-based shader)

other (better?) solution:

  • In more recent versions of OpenGL you have “texture arrays” or “array textures”
  • I don’t know if jME 3.0 or 3.1 support that feature (but I would like to know)
  • I don’t know what kinds of graphics cards support that feature (driver version, GL version)
  • But it’s definitely going to solve the problems of a texture atlas
  • Another possi might be to use a “3D texture” (sampler3d) which is quite an old feature (I think) and then you would simply put your tiles as slices in the w-coordinate (u and v are sampler2d, w is the third axis)

Not sure what you are trying to do - so I just said everything that came to my mind regarding that topic… :chimpanzee_smile:

@pspeed, thanks for the reply. I actually tried to use TextureAtlas before I post my question. In Libgdx, I can have a ‘sprite sheet’ and use TextureRegion to designate the different tiles as separate textures. It is conceptually very simple. TexturePacker is easy to use. For nice tile maps, it is straight forward to manually create the ‘atlas’ by using a notepad (that is actually how I create).

Unfortunately the scene graph support of Libgdx is weak. I decided to convert my games to JMonkey. I am less familiar with JMonkey; it seems JMonkey’s TextureAtlas is a different concept, am I right?

I am currently working on a 2D game. I will add 3D feature after I port the game. If I already have a sprite sheet. Do I have to cut the tiles and save them as individual images on my hard drive before loading them back to JMonkey as different textures? It is much easier for me to edit the sprites if they are all on one single sheet; thus I don’t want to cut them up.

I am thinking the second possibilities is to load the sprite image as one BufferedImage and draw the individual tiles on smaller BufferedImage and convert them to Texture. This seems straight forward, does JMonkey has built-in functions such as loadBufferedImage() and bufferedImageToTexture()?

Can TextureAtlas be used to avoid all these mess? If so, can you give me a hint how to do it. Thanks

Ah, this is about sprite sheets and 2d games. That changes a lot…
Did you look at jme3test.tools.TestTextureAtlas.java ? It demonstrates the jME texture atlas.
What do you mean by “create the ‘atlas’ by using a notepad” ? I assume you mean a text editor?

When I think how my workflow would look … I would also prefer editing all on one image.
But I would want to have a nice tool for it - not a text editor. Something to mark rectangles which are then saved to a file like: image_name.txt or image_name_meta.txt and then use a text editor to edit those meta info files. Even better is a tool that combines both: image editor and a panel for the text - similar to the svg editor “Inkscape” (lets you edit the xml text while editing the vector graphics at the same time) - so you can give the texture regions names while still editing them.

@Ogli, The ‘atlas’ in Libgdx is actually a simple ASCII file annotating the ‘tiles’ in the sprite sheet. It may looks like:

vehicles.png
format: RGBA8888
filter: Nearest,Nearest
repeat: none
airplane
    rotate: false
    xy: 10, 150
    size: 280, 200
    orig: 280, 200
    offset: 0, 0
    index: 4
...

To use the atlas, just load the text file, Libgdx will then know how to craft the texture region ‘airplane’. The Libgdx’s Texture Packer can aggressively (optimally) places individual images of different sizes in a single bigger image, and write the ‘atlas’. For an already packed sprite sheet, there is no juggling of the tiles, hence it is very easy to generate the ‘atlas’ (or create by hand, if necessary) – just write the actual position of the tiles to a text file.

Ah … Aha … I just watched this … Creating and Using Spritesheets in LibGDX - YouTube

“Texture atlas” (.atlas) is the libgdx term for the image_name_meta.txt that I sketched…
“Sprite sheet” is the thing that in jME is called “Texture atlas”. :chimpanzee_smile:

EDIT:
Saw your text popping up at the same time. :chimpanzee_grin:
Okay … so you see how important context and exact words are… :chimpanzee_smile:

I doubt that jME has support for .atlas files (and does not seem to have a concept for that either).
You could write some custom code that reads .atlas files (should be quite easy).

.fnt files is very similar in concept - it is very similar to .atlas files, but comes from a different corner. I’m currently working on a .fnt2 format that might be “missused” as .atlas files. But still those are all font-related. My .fnt2 files will also contain information that .atlas files contain (names for regions, image format and even sub-channel format).

In the end - it’s just some small text data written in a .atlas (or .fnt) file - and a large texture, that contains many smaller texture regions (in computer sience this is called “texture atlas” for 3d and “sprite sheet” for 2d)…

libgdx might be hiding the texture coordinates from you but it is almost certainly using them under the covers to implement this feature.

yes, the texture coordinates are in the .atlas files :chimpanzee_smile:

Yes, the actual pixel coord are in the text file ‘atlas’, I assume they will be converted to a fraction internally by Libgdx. Conceptually, the whole sprite sheet is a single Libgdx’s Texture, and the individual rectangles (sub-images) are Libgdx’s TextureRegion. To use the smaller sub-image texture, I just provide the single large Tetxure, and specify the TextureRegion. Since the single large image is common to many objects, I don’t really need to worry about it. Conceptually, I can treat each small sub-image as a full-citizen texture in my game.

See the video I posted at [6:20] - [7:05] and [8:38] - [8:41] → he explains it.

Also note that I edited that post quite a bit to contain more useful information.

Thanks for the extra info. I am still trying to load the WHOLE sprite sheet in one SINGLE load, and use the sub-images in a simple manner.

To try to understand TextureAtlas, I cut the sprite sheet as tiles and save them as individual images, and then try the following:

TextureAtlas ta = new TextureAtlas(1024, 1024);
Texture tex1 = assetManager.loadTexture(tileFilename1);
ta.addTexture(tex1, "T1");  // master map is T1
Texture tex2 = assetManager.loadTexture(tileFilename2);
// tex2 and tex1 will share same tex-coord (0,0) to (1,1)
ta.addTexture(tex2, "T2", "T1");   // master map is T1
Texture tex3 = assetManager.loadTexture(tileFilename3);
ta.addTexture(tex3, "T3", "T3");   // master map is T1
...

But the above doesn’t work. My understanding of TextureAtlas must be wrong. Even if it works, it doesn’t solve my problem because it still require many individual image files because I might just load the individual image as a Texture directly.

So, if you already split the images up then you don’t need texture atlas. It is taking multiple images and making them into an atlas. You already started with an atlas.

So basically you took an atlas, chopped it up, then turned it back into an atlas again. I mean, you can do it that way… but then you’d also need to show use the code where you are actually using the atlas. You set it up but you don’t show us how you use it so it’s impossible to guess what could be wrong.

You are going through a lot of trouble to avoid calculating texture coordinates, though. :slight_smile: Seems like you could read the atlas file and calculate them yourself and then just set them on your mesh as you like. Once calculated you could do it in one line of code per quad.

Okay…
There are generally two pathes that you could take:

  1. Trying to build all new from scratch in jME (assets and game)
  2. Trying to convert your Libgdx assets, then code game with jME

path 1:
In fact, you are using it wrong. Look for “Usage examples” in this javadoc:
http://javadoc.jmonkeyengine.org/jme3tools/optimize/TextureAtlas.html
The geometry that you use will be your quads (what’s the name for that in libgdx?).
You will need to serialize the resulting texture and quads (write to .j3o file) in prestep.
And then you will need to deserialize (load from .j3o file) them at game init again.
You probably will need to create lots of clones too (best have a pool for each type).
(If you need really many clones - like in bullet hell games - you need some tricks).
During your running 2d / 2.5d game you will make your clones visible/invisible.
→ That’s all just my very basic ideas, others might explain the details…

path 2:
You could use .atlas files and write some import logic or convert logic for that.
It sounds very simple to me, at least for the .atlas files and sprite sheets.
Then you could keep the workflow that you know for asset creation.
The rest should be similar to path 1.

Sorry, not really a full jME expert yet, maybe could help somehow… :chimpanzee_smile:

I really dont want to split the images. I split it just to try TextureAtlas. The reason I want to approach the way I approach is because: (1) sprite sheet is very common in 2D games (at least for amateur game developers), (2) most 2D game developer treat each sprite as an independent image, not part of the larger sprite sheet, (3) I have a somewhat high-level treatment of sprites in my Libgdx code base, I like to port the code as high level as possible.

I am interested in hiding the details of texture coord in JMonkey port, although I don’t know how to do atm.

You just have to ask yourself if the port is really necessary and what you gain from it.
Your real intentions were very unclear to me at the beginning and are becoming important now.
Compare the engine features (you already start to notice that jME is not designed for 2d games).
But still there are very cool 2d games that people made (like “Dots”).
And then there is this tutorial series:

1 Like

The link is an excellent tutorial. I looked at that before and learned something. The game uses separate images for separate sprites, hence one texture per sprite. Since there is only a handful of sprites in that tutorial, so it is not a problem to have a few small images in the asset folder. No effort, at least in this particular tutorial, is attempted on using one single Texture.

If that game were done in Libgdx, (as far as sprites are concerned) it would be very natural to have all sprites live in one bigger image, and have the whole image as one single Libgdx’s Texture. Thus more efficient in rendering, without game developer’s effort at all!

I know JMonkey and Libgdx are not 2D game engines. But I want to be able to add a touch of 3D-ness to my 2D games. With this in mind, I believe both are the best choices for Java game developers. The deciding feature of choosing JMonkey is the scene graph.

We don’t really have enough information to help you. You are trying to “be compatible” with something but there will already be a thousand differences and it seems like you are going a loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong way to avoid:

quad.setBuffer(Type.TexCoord, 2, new float[]{x1/width, y1/height,
                                                    x2/width, y1/height,
                                                    x2/width, y2/height,
                                                    x1/width, y2/height});

To me it seems like it would take about five minutes to wrap that in something more palatable.

1 Like

@pspeed: Your snipcode is exactly what I need! Thanks a lot!!! :smiley: I was playing with the material and TextureAtlas earlier. I didn’t know that it is so simple to set texture coord in the quad.

Now I can have the whole sprite sheet as a single Texture and use the sub-images as tiles! I can hide this details easily in my own code, and thus use the higher level stuff from my Libgdx code!

You guys are great. Really glad that I started exploring JMonkey.