Texture from texturepacker in LibGDX

Try tricking the texture wrapper into the (awesome) LibGDX structure and I need help.

I would like to snap a texture (according to Mesh, Color and Texture ) which is extracted from a TextureAtlas packaged in a TexturePacker. The texture is snapped to a rectangular grid.

I want the texture (Texture instance) to be mostly extracted from the packed file.

Is it possible to use the createprite or findregion methods and somehow skip the file descriptor step?

Optional: Anything special to consider when combining the above method with AssetManager?

Thanks for taking me apart!

+4
source share
2 answers

Create a TextureRegion

First, you create a TextureAtlas object, pointing to a text file that describes your atlas (the tool that creates the atlas will create two files: an image and a text file that describes its contents):

 TextureAtlas myTextures = new TextureAtlas("images/packed.txt"); 

You can then find the TextureRegion in that atlas (i.e. the specific sub-texture of the atlas). The region should have the base name of the source file that was used (there is additional information and parameters if you follow some special naming conventions for creating arrays of texture elements, but leave it now):

 TextureRegion region = myTextures.findRegion(fname); 

Customize Textured Grid

To draw this area of ​​the texture on the grid, you need to initialize the Mesh with support for texture coordinates:

 Mesh myMesh = new Mesh(..., new VertexAttribute(Usage.TextureCoordinates, 2, "y")); 

new VertexAttribute(Usage.TextureCoordinates, 2, ...) tells libGDX that this grid will have two texture coordinates per vertex (traditionally two texture coordinates are called u and v ). You may have a bunch of different attributes on top, but I guess the only other attribute is the 3-digit Usage.Position for the spatial coordinates x, y, z.

Now in the float array that defines your grid (the array you pass to setVertices ), you need to set the spatial coordinates x, y and z plus the u and v texture coordinates for each vertex:

 final int floatsPerVertex = 5; // 3 spatial + 2 texture float[] meshData = new float[numVerticies * floatsPerVertex]; for (int i = 0; i < numVerticies; i++) { meshData[(i * floatsPerVertex) + 0] = ... ; // x coordinate of i'th vertex meshData[(i * floatsPerVertex) + 1] = ... ; // y coordinate of i'th vertex meshData[(i * floatsPerVertex) + 2] = ... ; // z coordinate of i'th vertex meshData[(i * floatsPerVertex) + 3] = ... ; // u texture coordinate of i'th vertex meshData[(i * floatsPerVertex) + 4] = ... ; // v texture coordinate of i'th vertex } myMesh.setVertices(meshData); 

You can calculate the correct u and v for a specific TextureRegion using getU , getV , getU2 and getV2 . Note that the texture coordinates have the origin (u1, v1) in the upper left corner, and the y-axis points are β€œdown” (the screen and spatial coordinates in OpenGL usually have a origin in the lower left corner and β€œup” at the y-axis points). It's a bit complicated, but very flexible, so you can flip or stretch or distort the texture when it is displayed on your grid.

Since the texture is large (say, 512x512), and the specific area is a small subset of it (say, 20x20 by 128x128), you will actually end up with the coordinates of the grid texture, which only use a 20x20 subset of the entire 512x512 image.

Display Textured Grid

Finally, when rendering, you need to snap the image and enable texturing before rendering:

 region.getTexture().bind(); Gdx.graphics.getGL10().glEnable(GL10.GL_TEXTURE_2D); myMesh.render(); Gdx.graphics.getGL10().glDisable(GL10.GL_TEXTURE_2D); 

Please note that this is much less effective than it should be. Part of the benefits of a texture atlas is that it should contain many areas that can be displayed together, so you only need to snap one texture and then display many different textured meshes from one related texture.

SpriteBatch supports sprites defined using TextureRegion , and AssetManager supports loading and searching for the TextureAtlas class.

+10
source

Got a job using the above explanation.

I can’t believe that so few people work asking this question, because it looks like what others would like to do.

From the decision I made, I created a function that also does the math for the new UV position.

Tested and it works for me, but please check out that I'm not a Java developer.

 public Mesh RebuildMeshUVtoTextureRegion(Mesh ObjectMesh, TextureRegion UVMapPos) { int numFloats = ObjectMesh.getNumVertices() * ObjectMesh.getVertexSize() / 4; float[] vertices = new float[numFloats]; ObjectMesh.getVertices(vertices); int numIndices = ObjectMesh.getNumIndices(); short SourceIndices[] = new short[numIndices]; ObjectMesh.getIndices(SourceIndices); final int floatsPerVertex = 5; int TimesToLoop = ((vertices.length) /floatsPerVertex); float previousU; float previousV; float FullMapHeight = UVMapPos.getTexture().getHeight(); float FullMapWidth = UVMapPos.getTexture().getWidth(); float NewMapWidth = UVMapPos.getRegionWidth(); float NewMapHeight = UVMapPos.getRegionHeight(); float FullMapUPercent; float FullMapVPercent; for (int i = 0; i < TimesToLoop; i++) { previousU = (vertices[(i * floatsPerVertex) + 3]); previousV = (vertices[(i * floatsPerVertex) + 4]); FullMapUPercent = previousU / FullMapWidth; FullMapVPercent = previousV / FullMapHeight; vertices[(i * floatsPerVertex) + 3] = (NewMapWidth * FullMapUPercent) + UVMapPos.getU(); //New U vertices[(i * floatsPerVertex) + 4] = (NewMapHeight * FullMapVPercent) + UVMapPos.getV();//New V } ObjectMesh.setVertices(vertices); ObjectMesh.setIndices(SourceIndices); return ObjectMesh; } 
+1
source

All Articles