package com.gebauz.Bauzoid.graphics.sprite;
import com.badlogic.gdx.graphics.Texture;
import com.gebauz.Bauzoid.graphics.Graphics;
import com.gebauz.Bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.Bauzoid.graphics.model.Geometry.PrimitiveType;
import com.gebauz.Bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.Bauzoid.math.Matrix4;
/** Sprite atlas.
* Implements a sprite that defines multiple regions that can be used
* as Sprite Atlas or as Animated Sprite.
*
*/
public class AtlasSprite
extends Sprite
{
public static int NUM_INDICES_PER_REGION =
6;
public static int NUM_ATTRIBUTES_PER_REGION =
4;
/** Stores the seperate regions of the sprite. */
private SpriteRegion
[] mRegions =
null;
/** Geometry cache so that updates of vertex texture coord streams are not necessary. */
//private SimpleGeometry[] mGeometryCache = null;
/** Stores all Geometry of all SpriteRegions. */
private SimpleGeometry mMesh =
null;
/** Constructor. */
public AtlasSprite
(Graphics graphics, Texture texture, SpriteRegion
[] regions
)
{
super(graphics, texture
);
mRegions = regions
;
mMesh = createGeometry
();
/* mGeometryCache = new SimpleGeometry[regions.length];
for (int i = 0; i < mGeometryCache.length; i++)
{
mGeometryCache[i] = createGeometry(i);
}*/
}
public void dispose
()
{
super.
dispose();
mRegions =
null;
if (mMesh
!=
null)
{
mMesh.
dispose();
mMesh =
null;
}
/* for (int i = 0; i < mGeometryCache.length; i++)
{
mGeometryCache[i].dispose();
mGeometryCache[i] = null;
}
mGeometryCache = null;*/
}
public SimpleGeometry createGeometry
()
{
float[] vertices =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
POSITION_COORD_PER_ELEMENT * mRegions.
length];
float[] texCoords =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
TEXCOORD_COORD_PER_ELEMENT * mRegions.
length];
float[] colors =
new float[NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
COLOR_COORD_PER_ELEMENT * mRegions.
length];
// two triangles per region
short[] indices =
new short[NUM_INDICES_PER_REGION
* mRegions.
length];
for (int i =
0; i
< mRegions.
length; i++
)
{
SpriteRegion r = getRegion
(i
);
float[] v =
{
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
float[] t =
{
r.
left, r.
top,
r.
right, r.
top,
r.
right, r.
bottom,
r.
left, r.
bottom
};
float[] c =
{
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1
};
System.
arraycopy(v,
0, vertices, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
POSITION_COORD_PER_ELEMENT * i, v.
length);
System.
arraycopy(t,
0, texCoords, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
TEXCOORD_COORD_PER_ELEMENT * i, t.
length);
System.
arraycopy(c,
0, colors, NUM_ATTRIBUTES_PER_REGION
* SimpleGeometry.
COLOR_COORD_PER_ELEMENT * i, c.
length);
int n = i
*NUM_INDICES_PER_REGION
;
short base =
(short)(i
* NUM_ATTRIBUTES_PER_REGION
);
indices
[n++
] = base
; indices
[n++
] =
(short)(base+
1); indices
[n++
] =
(short)(base+
2);
indices
[n++
] = base
; indices
[n++
] =
(short)(base+
2); indices
[n++
] =
(short)(base+
3);
}
SimpleGeometry mesh =
new SimpleGeometry
(getGraphics
(), PrimitiveType.
TRIANGLES);
mesh.
setPositions(vertices
);
mesh.
setTexCoords(texCoords,
false);
mesh.
setColors(colors
);
mesh.
setIndices(indices
);
return mesh
;
}
/*
public SimpleGeometry createGeometry(int regionIndex)
{
float[] vertices =
{
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
SpriteRegion r = getRegion(regionIndex);
float[] texCoords =
{
r.left, r.top,
r.right, r.top,
r.right, r.bottom,
r.left, r.bottom
};
float[] colors =
{
1, 1, 1,
1, 1, 1,
1, 1, 1,
1, 1, 1
};
short[] indices =
{
0, 1, 2,
0, 2, 3
};
SimpleGeometry mesh = new SimpleGeometry(getGraphics(), PrimitiveType.TRIANGLES);
mesh.setPositions(vertices);
mesh.setTexCoords(texCoords, false);
mesh.setColors(colors);
mesh.setIndices(indices);
return mesh;
}
*/
public final AtlasSpriteInstance createSpriteInstance
(int regionIndex
)
{
return new AtlasSpriteInstance
(this, regionIndex
);
}
public void update
(float deltaTime
)
{
}
public void render
()
{
}
public void render
(int regionIndex
)
{
render
(regionIndex, x, y, w, h
);
}
public void render
(int regionIndex,
float _x,
float _y
)
{
render
(regionIndex, _x, _y, w, h
);
}
public void render
(int regionIndex,
float _x,
float _y,
float _w,
float _h
)
{
if (mRegions ==
null)
return;
/* SpriteRegion r = mRegions[regionIndex];
float[] texCoords = {
r.left, r.top,
r.right, r.top,
r.right, r.bottom,
r.left, r.bottom
};
mMesh.setTexCoords(texCoords);
super.render(_x, _y, _w, _h);*/
SpriteShader shader = getGraphics
().
getSpriteShader();
RenderStates rs = getRenderStates
();
Matrix4 modelMatrix = Matrix4.
multiply(Matrix4.
createScale(_w, _h, 1.0f
), Matrix4.
createTranslation(-pivotX, -pivotY,
0));
modelMatrix = Matrix4.
multiply(modelMatrix, Matrix4.
createScale((mirrorX
? -
1 :
1),
(mirrorY
? -
1 :
1),
1));
modelMatrix = Matrix4.
multiply(modelMatrix, Matrix4.
createRotationZ(angle
));
modelMatrix = Matrix4.
multiply(modelMatrix, Matrix4.
createTranslation(_x, _y,
0));
rs.
pushModelMatrix();
{
rs.
model = modelMatrix
;
// draw sprite
shader.
activate(getTexture
(), alpha, color
);
{
rs.
blending.
setEnabled(true);
rs.
culling.
setEnabled(false);
rs.
activate();
{
//getMesh(regionIndex).render();
mMesh.
render(getMeshStartIndex
(regionIndex
), NUM_INDICES_PER_REGION
);
}
rs.
deactivate();
}
shader.
deactivate();
}
rs.
popModelMatrix();
}
/** Set absolute coordinates for given region. */
public void setAbsolute
(int regionIndex,
float x,
float y,
float w,
float h
)
{
if ((mTexture ==
null) ||
(mRegions ==
null) ||
(regionIndex
>= mRegions.
length))
return;
if (mRegions
[regionIndex
] ==
null)
{
// create region
mRegions
[regionIndex
] =
new SpriteRegion
(x, y, w, h
);
return;
}
mRegions
[regionIndex
].
setAbsolute(mTexture, x, y, w, h
);
}
/** Get number of defined regions. */
public final int getRegionCount
()
{
if (mRegions ==
null)
return 0;
return mRegions.
length;
}
/** Get region. */
public final SpriteRegion getRegion
(int i
)
{
if (mRegions ==
null)
return null;
return mRegions
[i
];
}
/** Get a region's width. */
public final float getRegionWidth
(int i
)
{
if (mRegions ==
null)
return 0.0f
;
return (mRegions
[i
].
right - mRegions
[i
].
left) * mTexture.
getWidth();
}
/** Get a region's height. */
public final float getRegionHeight
(int i
)
{
if (mRegions ==
null)
return 0.0f
;
return (mRegions
[i
].
bottom - mRegions
[i
].
top) * mTexture.
getHeight();
}
/** Get cached mesh. */
/*public final SimpleGeometry getMesh(int regionIndex)
{
return mGeometryCache[regionIndex];
}*/
/** Get the Geometry. */
public final SimpleGeometry getMesh
()
{
return mMesh
;
}
/** Get starting index for region mesh rendering. */
public final int getMeshStartIndex
(int regionIndex
)
{
return (regionIndex
* NUM_INDICES_PER_REGION
);
}
}