package jme3test.tools;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import com.jme3.app.SimpleApplication;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture2D;
import com.jme3.util.Screenshots;
import jme3test.model.TestMonkeyHead;
import jme3tools.optimize.TextureAtlas;
import jogamp.graph.font.typecast.ot.table.DirectoryEntry;
public class TestMyTextureAtlas extends SimpleApplication {
Geometry g_geom;
public static void main(String[] args) {
TestMyTextureAtlas app = new TestMyTextureAtlas();
app.start();
}
@Override
public void simpleInitApp() {
// TODO Auto-generated method stub
flyCam.setMoveSpeed(50);
Node scene = new Node("Scene");
Spatial obj1 = assetManager.loadModel("Models/Ferrari/Car.scene");
obj1.setLocalTranslation(-4, 0, 0);
Spatial obj2 = assetManager.loadModel("Models/Oto/Oto.mesh.xml");
obj2.setLocalTranslation(-2, 0, 0);
Spatial obj3 = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
obj3.setLocalTranslation(-0, 0, 0);
Spatial obj4 = assetManager.loadModel("Models/Sinbad/Sinbad.mesh.xml");
obj4.setLocalTranslation(2, 0, 0);
// Spatial obj5 = assetManager.loadModel("Models/Tree/Tree.mesh.j3o");
// obj5.setLocalTranslation(4, 0, 0);
scene.attachChild(obj1);
scene.attachChild(obj2);
scene.attachChild(obj3);
scene.attachChild(obj4);
// scene.attachChild(obj5);
Geometry geom = TextureAtlas.makeAtlasBatch(scene, assetManager, 2048);
g_geom = geom;
AmbientLight al = new AmbientLight();
rootNode.addLight(al);
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(0.69077975f, -0.6277887f, -0.35875428f).normalizeLocal());
sun.setColor(ColorRGBA.White.clone().multLocal(2));
rootNode.addLight(sun);
rootNode.attachChild(geom);
//quad to display material
Geometry box = new Geometry("displayquad", new Quad(4, 4));
box.setMaterial(geom.getMaterial());
box.setLocalTranslation(0, 1, 3);
rootNode.attachChild(box);
inputManager.addMapping("My Action",
new KeyTrigger(KeyInput.KEY_SPACE));
// Test multiple listeners per mapping
inputManager.addListener(actionListener, "My Action");
}
private final BufferedImage image = new BufferedImage(2048, 2048,
BufferedImage.TYPE_4BYTE_ABGR);
private void convertScreenShot3(ByteBuffer bgraBuf, BufferedImage out){
WritableRaster wr = out.getRaster();
DataBufferByte db = (DataBufferByte) wr.getDataBuffer();
byte[] cpuArray = db.getData();
// copy native memory to java memory
bgraBuf.clear();
bgraBuf.get(cpuArray);
bgraBuf.clear();
int width = wr.getWidth();
int height = wr.getHeight();
// flip the components the way AWT likes them
// calcuate half of height such that all rows of the array are written to
// e.g. for odd heights, write 1 more scanline
int heightdiv2ceil = height % 2 == 1 ? (height / 2) + 1 : height / 2;
for (int y = 0; y < heightdiv2ceil; y++){
for (int x = 0; x < width; x++){
int inPtr = (y * width + x) * 4;
int outPtr = ((height-y-1) * width + x) * 4;
int inPtr1 = (y * width + x);
int outPtr1 = ((height-y-1) * width + x);
byte b1 = cpuArray[inPtr+0];//a
byte g1 = cpuArray[inPtr+1];//blue
byte r1 = cpuArray[inPtr+2];//green
byte a1 = cpuArray[inPtr+3];//red
byte b2 = cpuArray[outPtr+0];
byte g2 = cpuArray[outPtr+1];
byte r2 = cpuArray[outPtr+2];
byte a2 = cpuArray[outPtr+3];
// byte b1 = (byte) (bgraBuf.get(inPtr1+0)>>6);
// byte g1 = (byte) (bgraBuf.get(inPtr1+0)>>3&0x08);
// byte r1 = (byte) (bgraBuf.get(inPtr1+0)&0x08);
// byte a1 = (byte) 255;
//
// byte b2 = (byte) (bgraBuf.get(outPtr1+0)>>6);
// byte g2 = (byte) (bgraBuf.get(outPtr1+0)>>3&0x08);
// byte r2 = (byte) (bgraBuf.get(outPtr1+0)&0x08);
// byte a2 = (byte) 255;
// cpuArray[outPtr+0] = a1;
// cpuArray[outPtr+1] = b1;
// cpuArray[outPtr+2] = g1;
// cpuArray[outPtr+3] = r1;
//
// cpuArray[inPtr+0] = a2;
// cpuArray[inPtr+1] = b2;
// cpuArray[inPtr+2] = g2;
// cpuArray[inPtr+3] = r2;
cpuArray[outPtr+0] = (byte) 255;
cpuArray[outPtr+1] = g1;
cpuArray[outPtr+2] = r1;
cpuArray[outPtr+3] = a1;
cpuArray[inPtr+0] = (byte) 255;
cpuArray[inPtr+1] = g2;
cpuArray[inPtr+2] = r2;
cpuArray[inPtr+3] = a2;
}
}
}
private void ExportTexture()
{
Texture2D texture = (Texture2D)g_geom.getMaterial().getTextureParam("DiffuseMap").getTextureValue();
ByteBuffer buff = texture.getImage().getData(0);
if(buff != null)
{
System.out.println("hava out put buffer ................");
synchronized (image) {
//Screenshots.convertScreenShot2(buff.asIntBuffer(), image);
this.convertScreenShot3(buff, image); //BGR8
File dir = new File("d:/testdata/");
if( dir.exists() == false )
{
dir.mkdirs();
}
// BufferedImage inputbig = new BufferedImage(2048, 2048,BufferedImage.TYPE_INT_BGR);
// inputbig.getGraphics().drawImage(image, 0, 0, 256, 256, null); //画图
try {
ImageIO.write(image, "png", new File("d:/testdata/"+"texture.png"));//这里导出如果碰到a为0,就不做任何事情,导致其他通道信息全部丢失
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
private void ExportJ3o()
{
File dir = new File("d:/testdata/");
if( dir.exists() == false )
{
dir.mkdirs();
}
File file = new File("d:/testdata/MyModel.j3o");
try {
BinaryExporter.getInstance().save(rootNode, file/*bout*/);
} catch (IOException ex) {
Logger.getLogger(TestMonkeyHead.class.getName()).log(Level.SEVERE, null, ex);
}
}
private ActionListener actionListener = new ActionListener(){
public void onAction(String name, boolean pressed, float tpf){
System.out.println(name + " = " + pressed);
if( pressed == true )
{
ExportJ3o();
ExportTexture();
}
}
};
}