From 026a72d57ee2ddcbd6bb04ef6efc35981744047e Mon Sep 17 00:00:00 2001 From: "sha..rd" Date: Sat, 23 Jul 2011 22:44:30 +0000 Subject: [PATCH] * Fix crash in TestEverything * Fix crash in TestWalkingChar * Fix crash in TestDopper * Fix crash in TestApplication * Fix deprecation warnings in audio tests * Fixed issues with particle emitter cloning and import/export * Fixed TempVars crashes in BoundingSphere * Fixed incorrect deprecation warning in AudioNode * Added smart caching to materials * Added test to verify that particle export and cloning is working correctly git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7907 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../com/jme3/material/plugins/J3MLoader.java | 13 ++++-- .../src/core/com/jme3/asset/MaterialKey.java | 29 +++++++++++++ engine/src/core/com/jme3/audio/AudioNode.java | 4 +- .../com/jme3/bounding/BoundingSphere.java | 1 - .../core/com/jme3/effect/ParticleEmitter.java | 25 +++++++---- .../src/core/com/jme3/material/Material.java | 28 ++++++------- .../com/jme3/asset/DesktopAssetManager.java | 2 +- .../jme3/audio/lwjgl/LwjglAudioRenderer.java | 12 ++++-- .../jme3/scene/plugins/ogre/MeshLoader.java | 2 +- .../test/jme3test/app/TestApplication.java | 9 ---- engine/src/test/jme3test/audio/AudioApp.java | 2 + .../src/test/jme3test/audio/TestAmbient.java | 4 +- .../src/test/jme3test/audio/TestDoppler.java | 4 +- .../jme3test/audio/TestMusicStreaming.java | 2 +- .../test/jme3test/bullet/TestWalkingChar.java | 2 +- .../jme3test/collision/TestRayCasting.java | 2 +- .../test/jme3test/effect/TestEverything.java | 2 +- ...java => TestParticleExportingCloning.java} | 41 +++++++++++++++---- 18 files changed, 122 insertions(+), 62 deletions(-) create mode 100644 engine/src/core/com/jme3/asset/MaterialKey.java rename engine/src/test/jme3test/effect/{TestParticleEmitter.java => TestParticleExportingCloning.java} (66%) diff --git a/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java b/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java index 3d7525879..733e65330 100644 --- a/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java +++ b/engine/src/core-plugins/com/jme3/material/plugins/J3MLoader.java @@ -41,6 +41,7 @@ import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.asset.AssetLoader; import com.jme3.asset.AssetManager; +import com.jme3.asset.MaterialKey; import com.jme3.asset.TextureKey; import com.jme3.material.RenderState.BlendMode; import com.jme3.material.RenderState.FaceCullMode; @@ -63,7 +64,7 @@ public class J3MLoader implements AssetLoader { private AssetManager owner; private Scanner scan; - private String fileName; + private AssetKey key; private MaterialDef materialDef; private Material material; @@ -538,14 +539,15 @@ public class J3MLoader implements AssetLoader { throw new IOException("Extended material "+extendedMat+" cannot be found."); material = new Material(def); - material.setAssetName(fileName); + material.setKey(key); +// material.setAssetName(fileName); }else if (scan.hasNext("\\{")){ if (extending){ throw new IOException("Expected ':', got '{'"); } materialDef = new MaterialDef(owner, name); // NOTE: pass file name for defs so they can be loaded later - materialDef.setAssetName(fileName); + materialDef.setAssetName(key.getName()); } scan.next(); // skip { @@ -590,7 +592,7 @@ public class J3MLoader implements AssetLoader { try { scan = new Scanner(in); scan.useLocale(Locale.US); - this.fileName = info.getKey().getName(); + key = info.getKey(); loadFromScanner(); } finally { if (in != null) @@ -598,6 +600,9 @@ public class J3MLoader implements AssetLoader { } if (material != null){ + if (!(info.getKey() instanceof MaterialKey)){ + throw new IOException("Material instances must be loaded via MaterialKey"); + } // material implementation return material; }else{ diff --git a/engine/src/core/com/jme3/asset/MaterialKey.java b/engine/src/core/com/jme3/asset/MaterialKey.java new file mode 100644 index 000000000..cc74fbc7e --- /dev/null +++ b/engine/src/core/com/jme3/asset/MaterialKey.java @@ -0,0 +1,29 @@ +package com.jme3.asset; + +import com.jme3.material.Material; + +/** + * Used for loading {@link Material materials} only (not material definitions). + * + * @author Kirill Vainer + */ +public class MaterialKey extends AssetKey { + public MaterialKey(String name){ + super(name); + } + + public MaterialKey(){ + super(); + } + + @Override + public boolean useSmartCache(){ + return true; + } + + @Override + public Object createClonedInstance(Object asset){ + Material mat = (Material) asset; + return mat.clone(); + } +} diff --git a/engine/src/core/com/jme3/audio/AudioNode.java b/engine/src/core/com/jme3/audio/AudioNode.java index b0fefd8d5..1c426b8a9 100644 --- a/engine/src/core/com/jme3/audio/AudioNode.java +++ b/engine/src/core/com/jme3/audio/AudioNode.java @@ -200,8 +200,6 @@ public class AudioNode extends Node { * @param name The filename of the audio file * @param stream If true, the audio will be streamed gradually from disk, * otherwise, it will be buffered. - * - * @deprecated AudioRenderer parameter is ignored. */ public AudioNode(AssetManager assetManager, String name, boolean stream) { this(assetManager, name, stream, false); @@ -213,6 +211,8 @@ public class AudioNode extends Node { * @param audioRenderer The audio renderer to use for playing. Cannot be null. * @param assetManager The asset manager to use to load the audio file * @param name The filename of the audio file + * + * @deprecated AudioRenderer parameter is ignored. */ public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name) { this(assetManager, name, false); diff --git a/engine/src/core/com/jme3/bounding/BoundingSphere.java b/engine/src/core/com/jme3/bounding/BoundingSphere.java index 68e9a6b39..c8ef3e38e 100644 --- a/engine/src/core/com/jme3/bounding/BoundingSphere.java +++ b/engine/src/core/com/jme3/bounding/BoundingSphere.java @@ -258,7 +258,6 @@ public class BoundingSphere extends BoundingVolume { BufferUtils.setInBuffer(tempC, points, j + ap); BufferUtils.setInBuffer(tempB, points, j - 1 + ap); } - vars.release(); recurseMini(points, i, b + 1, ap + 1); } diff --git a/engine/src/core/com/jme3/effect/ParticleEmitter.java b/engine/src/core/com/jme3/effect/ParticleEmitter.java index dccd968fc..a71159f32 100644 --- a/engine/src/core/com/jme3/effect/ParticleEmitter.java +++ b/engine/src/core/com/jme3/effect/ParticleEmitter.java @@ -75,7 +75,8 @@ public class ParticleEmitter extends Geometry { private static final EmitterShape DEFAULT_SHAPE = new EmitterPointShape(Vector3f.ZERO); private static final ParticleInfluencer DEFAULT_INFLUENCER = new DefaultParticleInfluencer(); - private ParticleEmitterControl control = new ParticleEmitterControl(this); + + private ParticleEmitterControl control; private EmitterShape shape = DEFAULT_SHAPE; private ParticleMesh particleMesh; private ParticleInfluencer particleInfluencer = DEFAULT_INFLUENCER; @@ -106,9 +107,12 @@ public class ParticleEmitter extends Geometry { //variable that helps with computations private transient Vector3f temp = new Vector3f(); - private static class ParticleEmitterControl implements Control { + public static class ParticleEmitterControl implements Control { - private ParticleEmitter parentEmitter; + ParticleEmitter parentEmitter; + + public ParticleEmitterControl(){ + } public ParticleEmitterControl(ParticleEmitter parentEmitter){ this.parentEmitter = parentEmitter; @@ -118,7 +122,7 @@ public class ParticleEmitter extends Geometry { return this; // WARNING: Sets wrong control on spatial. Will be // fixed automatically by ParticleEmitter.clone() method. } - + public void setSpatial(Spatial spatial) { } @@ -139,11 +143,9 @@ public class ParticleEmitter extends Geometry { } public void write(JmeExporter ex) throws IOException { - // the data is not written here } public void read(JmeImporter im) throws IOException { - // the data is not written here } } @@ -206,6 +208,7 @@ public class ParticleEmitter extends Geometry { shape = shape.deepClone(); particleInfluencer = particleInfluencer.clone(); + control = new ParticleEmitterControl(this); controls.add(control); switch (meshType) { @@ -1155,12 +1158,13 @@ public class ParticleEmitter extends Geometry { throw new IllegalStateException("Unrecognized particle type: " + meshType); } particleMesh.initParticleData(this, particles.length); + particleMesh.setImagesXY(imagesX, imagesY); particleInfluencer = (ParticleInfluencer) ic.readSavable("influencer", DEFAULT_INFLUENCER); if (particleInfluencer == DEFAULT_INFLUENCER){ particleInfluencer = particleInfluencer.clone(); } - + if (im.getFormatVersion() == 0){ // compatibility before the control inside particle emitter // was changed: @@ -1170,7 +1174,7 @@ public class ParticleEmitter extends Geometry { if (obj instanceof ParticleEmitter){ controls.remove(i); // now add the proper one in - controls.add(control); + controls.add(new ParticleEmitterControl(this)); break; } } @@ -1180,6 +1184,11 @@ public class ParticleEmitter extends Geometry { gravity = new Vector3f(); gravity.y = ic.readFloat("gravity", 0); } + }else{ + // since the parentEmitter is not loaded, it must be + // loaded separately + control = getControl(ParticleEmitterControl.class); + control.parentEmitter = this; } } } diff --git a/engine/src/core/com/jme3/material/Material.java b/engine/src/core/com/jme3/material/Material.java index 76b9552eb..ee6a5fe20 100644 --- a/engine/src/core/com/jme3/material/Material.java +++ b/engine/src/core/com/jme3/material/Material.java @@ -29,6 +29,7 @@ */ package com.jme3.material; +import com.jme3.asset.Asset; import com.jme3.asset.AssetKey; import com.jme3.math.ColorRGBA; import com.jme3.math.Matrix4f; @@ -73,10 +74,7 @@ import java.util.logging.Logger; /** * Material describes the rendering style for a given - * { - *

- * @link Geometry}. - *

+ * {@link Geometry}. *

A material is essentially a list of { * @link MatParam parameters}, those parameters map to uniforms which are * defined in a shader. Setting the parameters can modify the behavior of a @@ -84,7 +82,7 @@ import java.util.logging.Logger; *

* @author Kirill Vainer */ -public class Material implements Cloneable, Savable, Comparable { +public class Material implements Asset, Cloneable, Savable, Comparable { private static final Logger logger = Logger.getLogger(Material.class.getName()); private static final RenderState additiveLight = new RenderState(); @@ -100,7 +98,8 @@ public class Material implements Cloneable, Savable, Comparable { additiveLight.setBlendMode(RenderState.BlendMode.AlphaAdditive); additiveLight.setDepthWrite(false); } - private String assetName; + + private AssetKey key; private MaterialDef def; private ListMap paramValues = new ListMap(); private Technique technique; @@ -139,18 +138,17 @@ public class Material implements Cloneable, Savable, Comparable { * @return Asset key name of the j3m file */ public String getAssetName() { - return assetName; + return key != null ? key.getName() : null; } - /** - * Set the asset key name. This is used internally by the j3m material loader. - * - * @param assetName the asset key name - */ - public void setAssetName(String assetName) { - this.assetName = assetName; + public void setKey(AssetKey key){ + this.key = key; } - + + public AssetKey getKey(){ + return key; + } + /** * Returns the sorting ID or sorting index for this material. * diff --git a/engine/src/desktop/com/jme3/asset/DesktopAssetManager.java b/engine/src/desktop/com/jme3/asset/DesktopAssetManager.java index b28171ee9..a9362de23 100644 --- a/engine/src/desktop/com/jme3/asset/DesktopAssetManager.java +++ b/engine/src/desktop/com/jme3/asset/DesktopAssetManager.java @@ -291,7 +291,7 @@ public class DesktopAssetManager implements AssetManager { } public Material loadMaterial(String name){ - return (Material) loadAsset(new AssetKey(name)); + return (Material) loadAsset(new MaterialKey(name)); } /** diff --git a/engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java b/engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java index b7fcfa783..6a5ea59d5 100644 --- a/engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java +++ b/engine/src/lwjgl-oal/com/jme3/audio/lwjgl/LwjglAudioRenderer.java @@ -47,7 +47,6 @@ import com.jme3.audio.LowPassFilter; import com.jme3.math.Vector3f; import com.jme3.util.BufferUtils; import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; @@ -237,6 +236,13 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable { return; } + // stop any playing channels + for (int i = 0; i < chanSrcs.length; i++){ + if (chanSrcs[i] != null){ + clearChannel(i); + } + } + // delete channel-based sources ib.clear(); ib.put(channels); @@ -253,7 +259,8 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable { EFX10.alDeleteAuxiliaryEffectSlots(ib); } - // XXX: Delete other buffers/sources + // TODO: Cleanup buffers allocated for audio buffers and streams + AL.destroy(); } @@ -930,7 +937,6 @@ public class LwjglAudioRenderer implements AudioRenderer, Runnable { freeChannel(chan); if (src.getAudioData() instanceof AudioStream) { - AudioStream stream = (AudioStream)src.getAudioData(); if (stream.isOpen()) { stream.close(); diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java index 19e4b6cce..d05ac9e4e 100644 --- a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java +++ b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java @@ -215,7 +215,7 @@ public class MeshLoader extends DefaultHandler implements AssetLoader { } if (mat == null) { logger.log(Level.WARNING, "Material {0} not found. Applying default material", matName); - mat = (Material) assetManager.loadAsset(new AssetKey("Common/Materials/RedColor.j3m")); + mat = (Material) assetManager.loadMaterial("Common/Materials/RedColor.j3m"); } } diff --git a/engine/src/test/jme3test/app/TestApplication.java b/engine/src/test/jme3test/app/TestApplication.java index 734cb4102..ae07f8acf 100644 --- a/engine/src/test/jme3test/app/TestApplication.java +++ b/engine/src/test/jme3test/app/TestApplication.java @@ -70,15 +70,6 @@ public class TestApplication { Thread.sleep(3000); System.out.println("Destroying offscreen buffer"); app.stop(); - - System.out.println("Creating JOGL application.."); - settings = new AppSettings(true); - settings.setRenderer(AppSettings.JOGL); - app = new Application(); - app.setSettings(settings); - app.start(); - Thread.sleep(5000); - app.stop(); } } diff --git a/engine/src/test/jme3test/audio/AudioApp.java b/engine/src/test/jme3test/audio/AudioApp.java index 01b80355e..54e146e04 100644 --- a/engine/src/test/jme3test/audio/AudioApp.java +++ b/engine/src/test/jme3test/audio/AudioApp.java @@ -35,6 +35,7 @@ package jme3test.audio; import com.jme3.audio.AudioRenderer; import com.jme3.asset.AssetManager; import com.jme3.asset.DesktopAssetManager; +import com.jme3.audio.AudioContext; import com.jme3.audio.Listener; import com.jme3.system.AppSettings; import com.jme3.system.JmeSystem; @@ -60,6 +61,7 @@ public class AudioApp { } public void initAudioApp(){ + AudioContext.setAudioRenderer(audioRenderer); } public void updateAudioApp(float tpf){ diff --git a/engine/src/test/jme3test/audio/TestAmbient.java b/engine/src/test/jme3test/audio/TestAmbient.java index 506e097c7..e0bc143a1 100644 --- a/engine/src/test/jme3test/audio/TestAmbient.java +++ b/engine/src/test/jme3test/audio/TestAmbient.java @@ -51,10 +51,10 @@ public class TestAmbient extends AudioApp { @Override public void initAudioApp(){ - waves = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Ocean Waves.ogg", false); + waves = new AudioNode(assetManager, "Sound/Environment/Ocean Waves.ogg", false); waves.setPositional(true); - nature = new AudioNode(audioRenderer, assetManager, "Sound/Environment/Nature.ogg", true); + nature = new AudioNode(assetManager, "Sound/Environment/Nature.ogg", true); // river = new AudioSource(manager, "sounds/river.ogg"); // float[] eax = new float[] diff --git a/engine/src/test/jme3test/audio/TestDoppler.java b/engine/src/test/jme3test/audio/TestDoppler.java index 0722c6aa2..9ee7b33ec 100644 --- a/engine/src/test/jme3test/audio/TestDoppler.java +++ b/engine/src/test/jme3test/audio/TestDoppler.java @@ -66,8 +66,6 @@ public class TestDoppler extends AudioApp { @Override public void initAudioApp(){ - assetManager.registerLocator("C:\\", FileLocator.class); - Quaternion q = new Quaternion(); q.lookAt(new Vector3f(0, 0, -1f), Vector3f.UNIT_Y); listener.setRotation(q); @@ -75,7 +73,7 @@ public class TestDoppler extends AudioApp { audioRenderer.setEnvironment(Environment.Dungeon); AL10.alDistanceModel(AL11.AL_EXPONENT_DISTANCE); - ufo = new AudioNode(audioRenderer, assetManager, "test.ogg", false); + ufo = new AudioNode(assetManager, "Sound/Effects/Beep.ogg", false); ufo.setPositional(true); ufo.setLooping(true); ufo.setReverbEnabled(true); diff --git a/engine/src/test/jme3test/audio/TestMusicStreaming.java b/engine/src/test/jme3test/audio/TestMusicStreaming.java index ccd7318b3..f294e060a 100644 --- a/engine/src/test/jme3test/audio/TestMusicStreaming.java +++ b/engine/src/test/jme3test/audio/TestMusicStreaming.java @@ -49,7 +49,7 @@ public class TestMusicStreaming extends AudioApp { @Override public void initAudioApp(){ assetManager.registerLocator("http://www.vorbis.com/music/", UrlLocator.class); - AudioNode src = new AudioNode(audioRenderer, assetManager, "Lumme-Badloop.ogg", true); + AudioNode src = new AudioNode(assetManager, "Lumme-Badloop.ogg", true); audioRenderer.playSource(src); } } \ No newline at end of file diff --git a/engine/src/test/jme3test/bullet/TestWalkingChar.java b/engine/src/test/jme3test/bullet/TestWalkingChar.java index 11dd10c78..3658f18d3 100644 --- a/engine/src/test/jme3test/bullet/TestWalkingChar.java +++ b/engine/src/test/jme3test/bullet/TestWalkingChar.java @@ -262,7 +262,7 @@ public class TestWalkingChar extends SimpleApplication implements ActionListener rock.setWrap(WrapMode.Repeat); matRock.setTexture("DiffuseMap_2", rock); matRock.setFloat("DiffuseMap_2_scale", 128); - Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.png"); + Texture normalMap0 = assetManager.loadTexture("Textures/Terrain/splat/grass_normal.jpg"); normalMap0.setWrap(WrapMode.Repeat); Texture normalMap1 = assetManager.loadTexture("Textures/Terrain/splat/dirt_normal.png"); normalMap1.setWrap(WrapMode.Repeat); diff --git a/engine/src/test/jme3test/collision/TestRayCasting.java b/engine/src/test/jme3test/collision/TestRayCasting.java index 961a6d3ca..e4e75cc57 100644 --- a/engine/src/test/jme3test/collision/TestRayCasting.java +++ b/engine/src/test/jme3test/collision/TestRayCasting.java @@ -57,7 +57,7 @@ public class TestRayCasting extends SimpleApplication { // flyCam.setEnabled(false); // load material - Material mat = (Material) assetManager.loadAsset(new AssetKey("Interface/Logo/Logo.j3m")); + Material mat = (Material) assetManager.loadMaterial("Interface/Logo/Logo.j3m"); Mesh q = new Mesh(); q.setBuffer(Type.Position, 3, new float[] diff --git a/engine/src/test/jme3test/effect/TestEverything.java b/engine/src/test/jme3test/effect/TestEverything.java index b358815b4..0e8e0987c 100644 --- a/engine/src/test/jme3test/effect/TestEverything.java +++ b/engine/src/test/jme3test/effect/TestEverything.java @@ -128,7 +128,7 @@ public class TestEverything extends SimpleApplication { } public void setupFloor(){ - Material mat = assetManager.loadMaterial("Textures/Terrain/Cobblestone/Cobblestone.j3m"); + Material mat = assetManager.loadMaterial("Textures/Terrain/BrickWall/BrickWall.j3m"); mat.getTextureParam("DiffuseMap").getTextureValue().setWrap(WrapMode.Repeat); mat.getTextureParam("NormalMap").getTextureValue().setWrap(WrapMode.Repeat); mat.getTextureParam("ParallaxMap").getTextureValue().setWrap(WrapMode.Repeat); diff --git a/engine/src/test/jme3test/effect/TestParticleEmitter.java b/engine/src/test/jme3test/effect/TestParticleExportingCloning.java similarity index 66% rename from engine/src/test/jme3test/effect/TestParticleEmitter.java rename to engine/src/test/jme3test/effect/TestParticleExportingCloning.java index 6cc2f2c3d..f5d737e04 100644 --- a/engine/src/test/jme3test/effect/TestParticleEmitter.java +++ b/engine/src/test/jme3test/effect/TestParticleExportingCloning.java @@ -36,13 +36,19 @@ import com.jme3.app.SimpleApplication; import com.jme3.effect.ParticleEmitter; import com.jme3.effect.ParticleMesh.Type; import com.jme3.effect.shapes.EmitterSphereShape; +import com.jme3.export.binary.BinaryExporter; +import com.jme3.export.binary.BinaryImporter; import com.jme3.material.Material; import com.jme3.math.Vector3f; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; -public class TestParticleEmitter extends SimpleApplication { +public class TestParticleExportingCloning extends SimpleApplication { public static void main(String[] args){ - TestParticleEmitter app = new TestParticleEmitter(); + TestParticleExportingCloning app = new TestParticleExportingCloning(); app.start(); } @@ -59,15 +65,32 @@ public class TestParticleEmitter extends SimpleApplication { mat.setTexture("Texture", assetManager.loadTexture("Effects/Smoke/Smoke.png")); emit.setMaterial(mat); + ParticleEmitter emit2 = emit.clone(); + emit2.move(3, 0, 0); + rootNode.attachChild(emit); + rootNode.attachChild(emit2); + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + try { + BinaryExporter.getInstance().save(emit, out); + + BinaryImporter imp = new BinaryImporter(); + imp.setAssetManager(assetManager); + ParticleEmitter emit3 = (ParticleEmitter) imp.load(out.toByteArray()); + + emit3.move(-3, 0, 0); + rootNode.attachChild(emit3); + } catch (IOException ex) { + ex.printStackTrace(); + } -// Camera cam2 = cam.clone(); -// cam.setViewPortTop(0.5f); -// cam2.setViewPortBottom(0.5f); -// ViewPort vp = renderManager.createMainView("SecondView", cam2); -// viewPort.setClearEnabled(false); -// vp.attachScene(rootNode); - + // Camera cam2 = cam.clone(); + // cam.setViewPortTop(0.5f); + // cam2.setViewPortBottom(0.5f); + // ViewPort vp = renderManager.createMainView("SecondView", cam2); + // viewPort.setClearEnabled(false); + // vp.attachScene(rootNode); } }