I’m writing some code that renders a spaceship to a png image. Make a new framebuffer, viewport, camera etc. and then use the code from ScreenShotAppState to save to file.
Everything seems to be pretty much working except skeletal animations. The parts of mesh which have bones attached to just simply dissappear.
An image for example:
Regular game:
Rendered to png:
See the turrets not being there? To be clear: I don’t need to run the actual animations, I just need to have all parts of the model rendered.
Class I use for rendering to png:
public class ShipToImageRenderer implements SceneProcessor{
private ViewPort renderingViewport;
private FrameBuffer fbuff;
private RenderManager renderManager;
private Camera renderCam;
private DirectionalLight dl;
//Exporting stuff
private static final String outPath = "workShopRender.png";
private ByteBuffer outBuff;
private Renderer renderer;
private boolean cheese = false;
public ShipToImageRenderer(RenderManager renderManager) {
this.renderManager = renderManager;
renderCam = new Camera(1280, 720);
renderCam.setLocation(new Vector3f(20, 20, 20));
renderCam.lookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y);
Camera c = CPU.game.getCam();
renderCam.setFrustum(c.getFrustumNear(), c.getFrustumFar(), c.getFrustumLeft(), c.getFrustumRight(), c.getFrustumTop(), c.getFrustumBottom());
renderCam.setFrustumPerspective(45f, 16f/9f, 1f, 1000f);
renderingViewport = renderManager.createPreView("imageRenderer", renderCam);
renderingViewport.setClearFlags(true, true, true);
renderingViewport.setBackgroundColor(ColorRGBA.LightGray);
dl = new DirectionalLight(new Vector3f(-1, -1, -2));
dl.setColor(ColorRGBA.White);
DirectionalLightShadowRenderer dlsr = new DirectionalLightShadowRenderer(CPU.game.getAssetManager(), 1024, 2);
dlsr.setLight(dl);
renderingViewport.addProcessor(dlsr);
renderingViewport.addProcessor(this);
fbuff = new FrameBuffer(1280, 720, 1);
fbuff.setDepthBuffer(Image.Format.Depth);
fbuff.setColorBuffer(Image.Format.RGBA8);
renderingViewport.setOutputFrameBuffer(fbuff);
}
public void renderShip(Ship shipToRender){
Spatial ship = shipToRender.clone();
ship.addLight(dl);
ship.setLocalTranslation(shipToRender.size3f.x / 2, 0, 0);
ship.setLocalRotation(new Quaternion().fromAngles(0, 0, 0));
ship.updateGeometricState();
renderingViewport.attachScene(ship);
cheese = true;
}
@Override
public void initialize(RenderManager renderManager, ViewPort viewPort) {
this.renderManager = renderManager;
renderer = renderManager.getRenderer();
reshape(viewPort, viewPort.getCamera().getWidth(), viewPort.getCamera().getHeight());
}
@Override
public void reshape(ViewPort viewPort, int w, int h) {
outBuff = BufferUtils.createByteBuffer(w * h * 4);
System.out.println("Width " + w + " Height: " + h);
}
@Override
public boolean isInitialized() {
return renderer != null;
}
@Override
public void preFrame(float v) {
if (!renderingViewport.getScenes().isEmpty())
renderingViewport.getScenes().get(0).updateGeometricState();
}
@Override
public void postQueue(RenderQueue renderQueue) {
}
@Override
public void postFrame(FrameBuffer out) {
if (cheese){
cheese = false;
Camera ccam = renderManager.getCurrentCamera();
int viewX = (int) (ccam.getViewPortLeft() * ccam.getWidth());
int viewY = (int) (ccam.getViewPortBottom() * ccam.getHeight());
int viewWidth = (int) ((ccam.getViewPortRight() - ccam.getViewPortLeft()) * ccam.getWidth());
int viewHeight = (int) ((ccam.getViewPortTop() - ccam.getViewPortBottom()) * ccam.getHeight());
//Read the data into outbuff
renderer.setViewPort(0, 0, 1280, 720);
renderer.readFrameBuffer(out, outBuff);
renderer.setViewPort(viewX, viewY, viewWidth, viewHeight);
//Save
File outFile = new File(outPath);
outFile.delete();
try (FileOutputStream fout = new FileOutputStream(outFile)){
JmeSystem.writeImageFile(fout, "png", outBuff, 1280, 720);
} catch (IOException e) {
System.err.println("Problem rendering ship to image:");
e.printStackTrace();
}
renderingViewport.clearScenes();
}
}
@Override
public void cleanup() {
}
Help?