First of all you need a material definition (Spritesheet.j3md)
MaterialDef Spritesheet {
MaterialParameters {
Texture2D ColorMap
Float SizeX : 1
Float SizeY : 1
Float Position
}
Technique {
VertexShader GLSL100: MatDefs/Spritesheet.vert
FragmentShader GLSL100: MatDefs/Spritesheet.frag
WorldParameters {
WorldViewProjectionMatrix
}
Defines {
}
}
}
Then you need the the fragment shader (Spritesheet.frag)
uniform sampler2D m_ColorMap;
varying vec2 texCoord;
void main(){
vec4 color = texture2D(m_ColorMap, texCoord);
gl_FragColor=color;
}
And then you need the vertex shader (Spritesheet.vert)
uniform mat4 g_WorldViewProjectionMatrix;
uniform float m_SizeX;
uniform float m_SizeY;
uniform float m_Position;
attribute vec3 inPosition;
attribute vec2 inTexCoord;
varying vec2 texCoord;
void main(){
float t = m_Position;
float tPointerY = 1.0 - ((floor(m_Position / m_SizeX)) / m_SizeY) - 1.0 / m_SizeY;
float tPointerYOffset = (floor(t / m_SizeX)) / m_SizeY;
float tPointerX = (t - (tPointerYOffset * m_SizeX * m_SizeY)) / m_SizeX;
texCoord.x = inTexCoord.x / m_SizeX + tPointerX;
texCoord.y = inTexCoord.y / m_SizeY + tPointerY;
gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}
You should put these 3 files on the MatDefs folder.
Then you need the actual spritesheet. With TexturePacker you create a
spritesheet-only file with these parameters.
Finally on the game you need to build a Material with the new material definition:
//create the material with the spritesheet material definition
Material mat = new Material(assetManager, "MatDefs/Spritesheet.j3md");
//set the spritesheet png built with TexturePacker
mat.setTexture("ColorMap", assetManager.loadTexture("Models/myspritesheet.png"));
//specify the number of columns and rows
mat.setFloat("SizeX", 5f);
mat.setFloat("SizeY", 3f);
//tell the shader to draw the sprite number 1
mat.setFloat("Position", 1f);
//your sprites most likely contain transparency, so it's probably better to set Alpha otherwise you'll see artefacts
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
Of course, when you want to change sprite from the spritesheet you must do it from Java, by setting:
mat.setFloat("Position", 14f);
The material can be applied to any Geometry. For example we put the sprite as a texture for a cube:
http://wiki.jmonkeyengine.org/doku.php/jme3:beginner:hello_simpleapplication
package jme3test.helloworld;
import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA;
/** Sample 1 - how to get started with the most simple JME 3 application.
* Display a blue 3D cube and view from all sides by
* moving the mouse and pressing the WASD keys. */
public class HelloJME3 extends SimpleApplication {
public static void main(String[] args){
HelloJME3 app = new HelloJME3();
app.start(); // start the game
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1); // create cube shape
Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
//create the material with the spritesheet material definition
Material mat = new Material(assetManager, "MatDefs/Spritesheet.j3md");
//set the spritesheet png built with TexturePacker
mat.setTexture("ColorMap", assetManager.loadTexture("Models/myspritesheet.png"));
//specify the number of columns and rows
mat.setFloat("SizeX", 5f);
mat.setFloat("SizeY", 3f);
//tell the shader to draw the sprite number 1
mat.setFloat("Position", 1f);
//your sprites most likely contain transparency, so it's probably better to set Alpha otherwise you'll see artefacts
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
}
}