hmm… @oxplay2 I created a new test using an offViewPort created with renderManager.createPreView()
, it seems transparency works fine at runtime if I set
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
on quad in simpleInitApp()
but not exported when I create png file.
here is new test:
public class TestIconGenerator2 extends SimpleApplication {
public static final FunctionId F_GENERATE_ICON = new FunctionId("Generate Icon");
private static final String TOGGLE_UPDATE = "Toggle Update";
private Spatial offModel;
private float angle = 0;
private ViewPort offView;
private Texture offTex;
private FrameBuffer offBuffer;
public static void main(String[] args) {
TestIconGenerator2 app = new TestIconGenerator2();
AppSettings settings = new AppSettings(true);
settings.setRenderer(AppSettings.LWJGL_OPENGL3);
settings.setGammaCorrection(true);
settings.setVSync(true);
app.setSettings(settings);
app.start();
}
public Texture setupOffscreenView() {
Camera offCamera = new Camera(512, 512);
offView = renderManager.createPreView("Offscreen View", offCamera);
offView.setClearFlags(true, true, true);
offView.setBackgroundColor(ColorRGBA.BlackNoAlpha);
// create offscreen framebuffer
offBuffer = new FrameBuffer(512, 512, 1);
//setup framebuffer's cam
offCamera.setFrustumPerspective(45f, 1f, 1f, 1000f);
offCamera.setLocation(new Vector3f(0f, 0f, 15f));
offCamera.lookAt(new Vector3f(0f, 0f, 0f), Vector3f.UNIT_Y);
//setup framebuffer's texture
Texture2D offTex = new Texture2D(512, 512, Format.RGBA8);
offTex.setMinFilter(Texture.MinFilter.Trilinear);
offTex.setMagFilter(Texture.MagFilter.Bilinear);
//setup framebuffer to use texture
offBuffer.setDepthBuffer(Format.Depth);
offBuffer.setColorTexture(offTex);
//set viewport to render to offscreen framebuffer
offView.setOutputFrameBuffer(offBuffer);
// setup framebuffer's scene
offModel = getAssetManager().loadModel("tree/model-1/green-tree.gltf");
// attach the scene to the viewport to be rendered
offView.attachScene(offModel);
return offTex;
}
protected Image createFrameBufferImage(FrameBuffer fb) {
int width = fb.getWidth();
int height = fb.getHeight();
int size = width * height * 4;
ByteBuffer buffer = BufferUtils.createByteBuffer(size);
Image.Format format = fb.getColorBuffer().getFormat();
// I guess readFrameBuffer always writes in the same
// format regardless of the frame buffer format
//format = Image.Format.BGRA8;
return new Image(format, width, height, buffer);
}
public void savePng(File f, Image img) throws IOException {
OutputStream out = new FileOutputStream(f);
try {
JmeSystem.writeImageFile(out, "png", img.getData(0), img.getWidth(), img.getHeight());
} finally {
out.close();
}
}
public void generateIcon() {
Renderer renderer = getRenderer();
Image image = createFrameBufferImage(offBuffer);
//Texture2D texture = new Texture2D(image);
renderer.readFrameBuffer(offBuffer, image.getData(0));
//image.setUpdateNeeded();
try {
savePng(new File("/home/ali/Desktop/icon.png"), image);
} catch (IOException ex) {
Logger.getLogger(IconGeneratorState.class.getName()).log(Level.SEVERE, null, ex);
}
}
@Override
public void simpleInitApp() {
GuiGlobals.initialize(this);
cam.setLocation(new Vector3f(3, 3, 3));
cam.lookAt(Vector3f.ZERO, Vector3f.UNIT_Y);
//setup main scene
Quad mesh = new Quad(2, 2);
Geometry quad = new Geometry("box", mesh);
offTex = setupOffscreenView();
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", offTex);
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
quad.setMaterial(mat);
rootNode.attachChild(quad);
viewPort.setBackgroundColor(ColorRGBA.White);
initLight();
initInput();
}
@Override
public void simpleUpdate(float tpf) {
Quaternion q = new Quaternion();
if (offView.isEnabled()) {
offModel.setLocalRotation(q);
offModel.updateLogicalState(tpf);
offModel.updateGeometricState();
}
}
private void initLight() {
Node probeNode = (Node) assetManager.loadModel("lightprobe/test-scene.j3o");
LightProbe probe = (LightProbe) probeNode.getLocalLightList().iterator().next();
offModel.addLight(probe);
/**
* A white ambient light source.
*/
AmbientLight ambient = new AmbientLight();
ambient.setColor(ColorRGBA.White);
offModel.addLight(ambient);
}
private void initInput() {
InputMapper inputMapper = GuiGlobals.getInstance().getInputMapper();
inputMapper.addDelegate(F_GENERATE_ICON, this, "generateIcon");
inputMapper.map(F_GENERATE_ICON, KeyInput.KEY_G);
}
}
Result looks like this with BlendMode.Alpha in JME (runtime):
Without BlendMode.Alpha
but transparency is not exported when saving to png :