I can make particle effects load fine in a SimpleGame extension, but they don't show up at all in my FixedLogicrateGame. I do have models loading fine. Is there something in particular a particle system depends upon being initialized that SimpleGame does that FixedLogicrateGame doesn't?
Okay, maybe some simple test code could better illustrate the problem? Those kinds of posts seem to be getting more answers.
First, I've made a layered particle effect in the editor. I wrote a static loader method for it:
package testing;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import com.jme.scene.Node;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.state.ZBufferState;
import com.jme.scene.state.ZBufferState.TestFunction;
import com.jme.system.DisplaySystem;
import com.jme.util.export.binary.BinaryImporter;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
public class StaticLoader {
/**
* Imports a particle effect created with the editor.
* @param effect the saved particle effect file.
* @param textureDir the directory with the particle's
* texture file(s). Can be null if effect requires no texture.
* @return Node with the effect
*/
public static Node loadJmeParticleSystem(
File effect, File textureDir) {
Node output = null;
try {
if (textureDir != null) {
final SimpleResourceLocator location =
new SimpleResourceLocator(textureDir.toURI().toURL());
ResourceLocatorTool.addResourceLocator(
ResourceLocatorTool.TYPE_TEXTURE, location );
} output = (Node)
BinaryImporter.getInstance().load(effect);
} catch (IOException e) {
e.printStackTrace();
System.err.println("file not found at: "+effect);
} catch (URISyntaxException e) {
e.printStackTrace();
System.err.println("unable to load image at: "+textureDir);
}
ZBufferState zs = DisplaySystem.getDisplaySystem(
).getRenderer().createZBufferState();
// turn off lighting?
output.setLightCombineMode(LightCombineMode.Off);
zs.setWritable(false);
zs.setFunction(TestFunction.LessThan);
output.setRenderState(zs);
output.updateRenderState();
return output;
}
}
To test this loader, I used a SimpleGame extension class:
package testing;
import java.io.File;
import com.jme.app.SimpleGame;
import com.jme.scene.Node;
public class SimpleMain extends SimpleGame {
public static void main(String[] args) {
//Instantiate
SimpleMain myTest = new SimpleMain();
//Always show dialog to set resolution
myTest.setConfigShowMode(ConfigShowMode.AlwaysShow);
//Begin the game
myTest.start();
}
@Override
protected void simpleInitGame() {
Node foo = StaticLoader.loadJmeParticleSystem(
new File("particle/purplefirejetflare.jme"),
new File("particle/"));
foo.setLocalScale(.1f);
foo.setLocalTranslation(0,0,-50);
this.rootNode.attachChild(foo);
}
@Override
protected void simpleUpdate() {
}
}
I try basically the same thing in a FixedLogicRateGame extension:
package testing;
// Java
import java.io.File;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
// jME
import com.jme.app.FixedLogicrateGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.DirectionalLight;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.CameraNode;
import com.jme.scene.Node;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.state.LightState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.GameSettings;
import com.jme.system.JmeException;
import com.jme.system.PreferencesGameSettings;
import com.jme.util.Timer;
public class FixedLogicrateMain extends FixedLogicrateGame
{
//variable declarations
private int width, height, depth, freq;
private boolean fullscreen;
private Camera cam;
private static Node sceneRoot;
protected Timer timer;
private CameraNode camNode;
private ZBufferState buf;
private MaterialState mat;
// *** Main entry point
public static void main(String[] args) {
FixedLogicrateMain app = new FixedLogicrateMain();
app.setConfigShowMode(FixedLogicrateMain.ConfigShowMode.AlwaysShow);
try {
app.start();
} catch (Exception e) {
// we will want to know what happened.
e.printStackTrace();
}
}
// *** Private helper methods
@Override
protected void initSystem() {
//store the properties information
width = this.settings.getWidth();
height = this.settings.getHeight();
depth = this.settings.getDepth();
freq = this.settings.getFrequency();
fullscreen = this.settings.isFullscreen();
//cam init
initCam();
KeyBindingManager.getKeyBindingManager().set("exit",
KeyInput.KEY_ESCAPE);
}
@Override
protected void initGame() {
// generate basic scene and logic elements
initialize();
// // testing particles
Node foo = StaticLoader.loadJmeParticleSystem(
new File("particle/purplefirejetflare.jme"),
new File("particle/"));
foo.setLocalScale(100f);
// foo.setLocalTranslation(0,0,0);
sceneRoot.attachChild(foo);
// commit.
sceneRoot.updateRenderState();
sceneRoot.updateGeometricState(0, true);
}
/**
* Called once by initSystem()
*/
private void initCam() {
try {
display = DisplaySystem.getDisplaySystem(
this.getNewSettings().getRenderer());
display.createWindow(width, height, depth, freq, fullscreen);
cam = display.getRenderer().createCamera(width, height);
} catch (JmeException e) {
e.printStackTrace();
System.exit(1);
}
//set the background to black
display.getRenderer().setBackgroundColor(ColorRGBA.black);
display.getRenderer().setCamera(cam);
cam.setFrustumPerspective(45.0f,
(float)display.getWidth()/(float)display.getHeight(),
1, 1000);
cam.setFrame(
new Vector3f(0,12,0),
Vector3f.UNIT_X,
Vector3f.UNIT_Y,
Vector3f.UNIT_Z);
cam.setFrustumFar(10000);
cam.update();
}
/**
* Called once by initGame()
*/
private void initialize() {
display.setTitle("Space Arena");
sceneRoot = new Node();
sceneRoot.setLightCombineMode(LightCombineMode.CombineClosestEnabled);
buildOverheadCamera();
setLogicTicksPerSecond(20);
// private helper methods
initZBuf();
// does this even do anything?
initMat();
initLight();
// apply the render states
sceneRoot.updateRenderState();
}
/**
* Called by initialize()
*/
private void buildOverheadCamera()
//uses a camNode
{
camNode = new CameraNode("Camera Node", cam);
Quaternion q = new Quaternion();
float angle = 0;
angle -= 180;
angle *= -1 * FastMath.DEG_TO_RAD;
q.fromAngleAxis(angle, Vector3f.UNIT_Y);
camNode.setLocalRotation(q);
camNode.setCamera(cam);
camNode.setLocalTranslation(new Vector3f(0, 0, 200));
}
/**
* Called once by initialize()
*/
private void initZBuf() {
buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.TestFunction.LessThan);
sceneRoot.setRenderState(buf);
}
/**
* Called once by initialize()
*/
private void initMat() {
// add a material state?
mat = display.getRenderer().createMaterialState();
mat.setEnabled(true);
sceneRoot.setRenderState(mat);
}
/**
* Called once by initialize()
*/
private void initLight() {
//Create a Basic Directional Light?
DirectionalLight dl = new DirectionalLight();
dl.setDirection(Vector3f.UNIT_Z);
// does this even do anything?
dl.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
dl.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
dl.setEnabled(true);
// add a light state?
LightState ls = display.getRenderer().createLightState();
ls.setEnabled(true);
ls.attach(dl);
sceneRoot.setRenderState(ls);
sceneRoot.updateRenderState();
}
// *** Overrides
@Override
protected void render(float interpolation) {
//update Overhead Camera
camNode.updateWorldData(interpolation);
// Clear the screen
display.getRenderer().flush();
display.getRenderer().clearBuffers();
display.getRenderer().draw(sceneRoot);
}
@Override
protected void update(float interpolation)
{
//check for keyboard input
if (KeyBindingManager.getKeyBindingManager().isValidCommand("exit"))
{
finished = true;
}
sceneRoot.updateGeometricState(interpolation, true);
}
@Override
protected void reinit()
{
display.recreateWindow(width, height, depth, freq, fullscreen);
}
@Override
protected void quit()
{
super.quit();
System.exit(0);
}
@Override
protected void cleanup()
{
// So far, unused?
}
@Override
protected GameSettings getNewSettings()
{
boolean newNode = true;
Preferences userPrefsRoot = Preferences.userRoot();
try
{
newNode = !userPrefsRoot.nodeExists("");
}
catch (BackingStoreException bse) { }
return new PreferencesGameSettings(userPrefsRoot.node(""), newNode,
"game-defaults.properties");
}
}
Compare your code with BaseSimpleGame and see whats different.
Maybe a BlendState , ZBuffer or Light problem
I wouldn't suggest using FixedLogicrateGame at all. It has not been touched since a very long time and it's possible that its not compatible with many new changes in jME. I am sure that it's possible to extent StandardGame or any other variant to support fixed update intervals. The issue here is probably that the interpolation variable given to the root node update is sent as 0.0 which means that time never progresses -> particles never updated.
I dont know what could be incompatible, since you implement most things yourself anyway.
I think the problem is your update cycle.
FixedLogirateGame passes -1 as interpolation value into your update() method, so don't use that value.
public abstract class FixedLogicrateGame extends AbstractGame {
<snip>
//main loop
while (!finished && !display.isClosing()) {
time1 = timer.getTime();
loops = 0;
while ((time1 - time0) > tickTime && loops < MAX_LOOPS) {
//handle input events prior to updating the scene
// - some applications may want to put this into update of the game state
InputSystem.update();
//update game state, do not use interpolation parameter
update(-1.0f);
time0 += tickTime;
loops++;
}
//If the game logic takes far too long, discard the pending
// time
if ((time1 - time0) > tickTime) time0 = time1 - tickTime;
float percentWithinTick = Math.min(1.0f,
(float) (time1 - time0) / tickTime);
//render scene with interpolation value
render(percentWithinTick);
//swap buffers
display.getRenderer().displayBackBuffer();
Thread.yield();
}
<snip>