TextureAtlas bug?

This relates to the current version in svn. This might be a bug in TextureAtlas or my own code…



When calling atlas.applyCoords(geom), in the method applyCoords

TextureAtlasTile tile = getAtlasTile(tex);

tries to find the tile via the texture name. In turn, getAtlastTile calls

textureName() to get a textures name. This is where

AssetKey key = texture.getKey();

is null. For some reason,the asset key for the geometries texture is null.

Therefore, it is unable to apply the correct texture coordinates for the geometry

Any suggestions? (I have added a test-case. Replace the texture loaded with any other texture)







[java]

package core;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;



public class TextureAtlasTestCase extends SimpleApplication

{

static TextureAtlas atlas = new TextureAtlas(512, 512);

static Material mat;

static Box box = new Box(new Vector3f(0,0,0),0.5f,0.5f,0.5f);

public static Geometry createGeom(float x,float y,float z)

{

Geometry geom = new Geometry(x+""+y+""+z, box);

geom.setLocalTranslation(x,y,z);

geom.setMaterial(mat);



Material mat2 = geom.getMaterial();

MatParamTexture param = (MatParamTexture) mat2.getParam("ColorMap");

Texture texture = param.getTextureValue();

System.out.println(texture.getKey()); //Asset key is null!





atlas.applyCoords(geom); //This is the line which does not work

return geom;

}



public static void main(String[] args)

{

TextureAtlasTestCase app = new TextureAtlasTestCase();

app.start();

}

public void simpleInitApp()

{

flyCam.setMoveSpeed(50);

atlas.addTexture(assetManager.loadTexture("resources/tex/stone.png"), "Stone");

mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

mat.setTexture("ColorMap", atlas.getAtlasTexture("Stone"));

mat.getAdditionalRenderState().setAlphaTest(true);

for (int i=0;i<5;i++)

{

for (int j=0;j<5;j++)

{

rootNode.attachChild(createGeom(i,0,j));

}

}

}

}

[/java]

@Normen: Can you look at this? Textures are not required to have a TextureKey if they have been procedurally generated

This is intentional, procedural textures should also get a key. Or the other way round, textures that are to be used in an atlas need a unique key to reference them. You can also get them by name if you don’t have a texture with key to look them up.

I am trying to run this example to test it out but getting this error:



[java]



Mar 22, 2012 5:18:11 PM com.jme3.scene.Node attachChild

INFO: Child (BitmapFont) attached to this node (null)

Mar 22, 2012 5:18:11 PM com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.IllegalArgumentException: The given texture for parameter “ColorMap” is null.

at com.jme3.material.Material.clearTextureParam(Material.java:454)

at com.jme3.material.Material.setTexture(Material.java:512)

at mygame.TestTextureAtlas.simpleInitApp(TestTextureAtlas.java:42)

at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:228)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)

at java.lang.Thread.run(Thread.java:619)

Mar 22, 2012 5:18:11 PM com.jme3.renderer.lwjgl.LwjglRenderer cleanup

INFO: Deleting objects and invalidating state

Mar 22, 2012 5:18:11 PM com.jme3.input.lwjgl.LwjglMouseInput destroy

INFO: Mouse destroyed.

Mar 22, 2012 5:18:11 PM com.jme3.input.lwjgl.LwjglKeyInput destroy

INFO: Keyboard destroyed.

Mar 22, 2012 5:18:11 PM com.jme3.system.lwjgl.LwjglAbstractDisplay deinitInThread

INFO: Display destroyed.

[/java]



all i’ve done was replace your stone.png with .png file I created. Whats so special about it?

you mean on the geometry? then it can obviously not be loaded, its null.

no I mean the same exact testCase he wrote… I am trying to get a working example on how to use TextureAtlas, a code example. I did the same exact thing , and since I don’t have his/her file Stone.png, I used my own atlas file that I called Stone.png but I get a null on the ColorMap.

Stone.png or stone.png?

stone.png

:brainsout:

@homsi said:
stone.png


And you've put it in the same path under the assets folder?

atlas.getAtlasTexture(“Stone”); makes absolutely no sense. Why you copy/paste some code (that announcedly doesn’t work) and then wonder/complain it doesnt work? :?

normen I read the javaDoc and I am trying to understand what’s happening but yet it doesn’t work:





[java]import com.jme3.app.SimpleApplication;

import com.jme3.material.MatParamTexture;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.shape.Box;

import com.jme3.texture.Texture;

import jme3tools.optimize.TextureAtlas;



public class TestTextureAtlas extends SimpleApplication

{

static TextureAtlas atlas = new TextureAtlas(1024, 1024);

static Material mat;

static Box box = new Box(new Vector3f(0,0,0),0.5f,0.5f,0.5f);



public static Geometry createGeom(float x,float y,float z)

{

Geometry geom = new Geometry(x+""+y+""+z, box);

geom.setLocalTranslation(x,y,z);

atlas.addGeometry(geom);

mat.setTexture(“Blue”, atlas.getAtlasTexture(“Blue”));



atlas.applyCoords(geom);

geom.setMaterial(mat);



return geom;

}



public static void main(String[] args)

{

TestTextureAtlas app = new TestTextureAtlas();

app.start();

}

public void simpleInitApp()

{

flyCam.setMoveSpeed(50);

atlas.addTexture(assetManager.loadTexture(“Materials/podAtlas.png”), “Blue”);

mat = new Material(assetManager, “Common/MatDefs/Light/Lighting.j3md”);





for (int i=0;i<5;i++)

{

for (int j=0;j<5;j++)

{

rootNode.attachChild(createGeom(i,0,j));

}

}



}

}[/java]



and I get



[java]thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.IllegalArgumentException: Material parameter is not defined: Blue[/java]

[java]

mat.setTexture(“Blue”, atlas.getAtlasTexture(“Blue”));

[/java]



My guess is, your shader doesn’t have a “Blue” parameter.

that was my question before that I am not sure if I am creating the atlas png file correctly. All I did was combine 3 .png files with different colors (orange, green, and blue) and I called this file podAtlas.png (I used Atlas Maker software to combine) so yeah I don’t understand how the mapping works.



I thought the steps were:



1- static TextureAtlas atlas = new TextureAtlas(1024, 1024); // create texture atlas



2- atlas.addTexture(assetManager.loadTexture(“Materials/podAtlas.png”), “Blue”); // add textures to it blue then later green & orange



3- mat.setTexture(“Blue”, atlas.getAtlasTexture(“Blue”)); // set this texture to the material



4- atlas.addGeometry(geom); // add geom to the atlas → I dont understand why this step is needed



5- atlas.applyCoords(geom); // apply atlas



6- geom.setMaterial(mat); // finally set the material to the geom





what am I missing :(??

and if I changed to:



[java] mat.setTexture("DiffuseMap", atlas.getAtlasTexture("orange"));



atlas.applyCoords(geom);[/java]





I get that the feometry has no proper texture when applyCoords() is called

What the heck are you doing? Whats the point of a textire atlas with just one texture? Please sit down and meditate a bit about what you want to do.

There are things you don’t get.



[java]

ta.addTexture(“path/to/texture.png”, “MapName”);

[/java]



This will add the given texture to an Atlas Map named “MapName”.



I’ve never used TextureAtlas but a quick look told me the above. So, what you do is add textures to a map name. When all your texture files (spites or whatnot) are in there you can retrieve each texture in that map by using:



[java]

Texture someTexture = atlas.getAtlasTexture(“path/to/texture.png”, “MapName”);

[/java]



What I’m reading from your snippet is you’re trying to get “orange” but you’ve never put it there? Or maybe it’s trying to return the whole map… One way or the other, you’re doing it wrong.

okay great so I add all these textures to my master map:



[java]atlas.addTexture(assetManager.loadTexture("Materials/podGreenMaterial.png"), "atlasColorMap");

atlas.addTexture(assetManager.loadTexture("Materials/podBlueMaterial.png"), "atlasColorMap");

atlas.addTexture(assetManager.loadTexture("Materials/podORangeMaterial.png"), "atlasColorMap");[/java]





and then how do I get them?



atlas.getAtlasTexture only takes a String (mapName) so how will it find that specific sub-texture??





edit: and if I try



[java]mat.setTexture("Materials/podOrangeMaterial.png", atlas.getAtlasTexture("atlasColorMap"));[/java]



I get:



[java]java.lang.IllegalArgumentException: Material parameter is not defined: Materials/podOrangeMaterial.png

at com.jme3.material.Material.checkSetParam(Material.java:384)

at com.jme3.material.Material.setTextureParam(Material.java:486)

at com.jme3.material.Material.setTexture(Material.java:534)[/java]

getAtlasTexture gets the whole map as one atlas, doh… Didn’t I ask you to meditate about this?

@homsi said:
atlas.getAtlasTexture only takes a String (mapName) so how will it find that specific sub-texture??


You're right. My bad.

Honestly I have no idea, as I said I've never used that as I don't need this. But I'm sure there's a wiki explaining everything. Have you looked?