java - Textura de texturizado en LibGDX
android textures (2)
Crea la TextureRegion
Primero, crea un objeto TextureAtlas
apuntando al archivo de texto que describe su atlas (la herramienta que crea el atlas creará dos archivos: una imagen y un archivo de texto que describa su contenido):
TextureAtlas myTextures = new TextureAtlas("images/packed.txt");
Luego puede buscar una TextureRegion
en ese atlas (es decir, una subtextura específica del atlas). La región debe tener el nombre base del archivo original que se usó (hay más detalles y opciones si sigue algunas de las convenciones de nomenclatura especiales para crear matrices de elementos de textura, pero déjelo por ahora):
TextureRegion region = myTextures.findRegion(fname);
Configurar una malla texturizada
Para dibujar esta región de textura en una malla, deberá inicializar la Mesh
con soporte para las coordenadas de textura:
Mesh myMesh = new Mesh(...,
new VertexAttribute(Usage.TextureCoordinates, 2, "y"));
El new VertexAttribute(Usage.TextureCoordinates, 2, ...)
le dice a libGDX que esta malla tendrá dos coordenadas de textura por vértice (tradicionalmente, las dos coordenadas de textura se llaman u
v
). Puede tener un conjunto de atributos diferentes por vértice, pero supongo que el único otro atributo es un Usage.Position
3 valores. Usage.Position
para las coordenadas espaciales x, y, z.
Ahora, en la matriz de flotantes que define tu malla (la matriz que pasas a setVertices
) necesitas establecer las coordenadas espaciales x, y, y las coordenadas de texturas v y v para cada vértice:
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);
Puede calcular el u
correcto para una TextureRegion
específica utilizando los getU
, getV
, getU2
y getV2
. Tenga en cuenta que las coordenadas de textura tienen el origen (u1, v1) en la esquina superior izquierda, y el eje y señala "abajo" (las coordenadas espaciales y de pantalla en OpenGL suelen tener el origen en los puntos inferior izquierdo y eje y " arriba"). Es un poco complicado, pero muy flexible, ya que puedes voltear, estirar o distorsionar la textura a medida que se mapea en tu malla.
Dado que la textura es grande (digamos 512x512) y la región específica es un pequeño subconjunto de eso (digamos 20x20 a 128x128), terminará dando las coordenadas de textura de malla que utilizan solo el subconjunto de 20x20 de la imagen completa de 512x512.
Renderizar la malla texturizada
Finalmente, cuando renderiza, debe enlazar la imagen y habilitar texturas antes de renderizar:
region.getTexture().bind();
Gdx.graphics.getGL10().glEnable(GL10.GL_TEXTURE_2D);
myMesh.render();
Gdx.graphics.getGL10().glDisable(GL10.GL_TEXTURE_2D);
Tenga en cuenta que esto es mucho menos eficiente de lo que debería ser. Parte del beneficio de un atlas de textura es que debe contener muchas regiones que se pueden juntar juntas, por lo que solo tiene que unir una textura y luego renderizar una gran cantidad de mallas texturizadas diferentes de esa textura ligada.
SpriteBatch
admite sprites definidos con una TextureRegion
y AssetManager
permite cargar y encontrar un TextureAtlas
como un elemento de primera clase.
Estoy tratando de entender cómo funciona el envoltorio de textura en el impresionante marco LibGDX y necesito ayuda.
Me gustaría vincular una textura (según Malla, Color y textura ) que se extrae de un TextureAtlas empaquetado con TexturePacker. La textura se une a una malla rectangular.
Quiero que la textura (instancia de Textura) se extraiga básicamente de un archivo empaquetado.
¿Es factible utilizar los métodos createprite o findregion y de algún modo omitir el paso filehandle?
Además: ¿Algo especial debe tener en cuenta al combinar el método anterior con AssetManager?
¡Gracias por solucionarme!
Lo tengo que trabajar usando la explicación anterior.
No puedo creer que haya tan pocas personas corriendo para hacer esta pregunta, ya que parece algo que otros querrían hacer.
A partir de la solución aceptada, creé una función que también hace los cálculos para la nueva posición UV.
Probado, y funciona para mí, por favor revise ya que no soy un desarrollador de Java.
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;
}