After some optimizing, I have still failed to pinpoint the problem : Here is my MainSimpleGame (Warning: Long)
public abstract class MainSimpleGame
extends BaseGame
{
/** The camera that we see through. */
protected Camera cam;
public static String toAdd;
/** The root of our normal scene graph. */
protected Node rootNode;
/** Handles our mouse/keyboard input. */
// protected InputHandler input;
/** High resolution timer for jME. */
protected Timer timer;
/** The root node of our text. */
protected Node fpsNode;
/** Displays all the lovely information at the bottom. */
protected Text fps;
/** Simply an easy way to get at timer.getTimePerFrame(). Also saves time so you don't call it more than once per frame. */
protected float tpf;
protected Node mouseNode;
protected InputHandler input;
protected Node uiNode;
protected InputHandler bufferedInput;
protected AbsoluteMouse mouse;
public MyTextBox myBox;
MainUIEditBox _edit = null;
UIColorScheme _scheme = new UIColorScheme();
/** True if the renderer should display bounds. */
protected boolean showBounds = false;
private ArrayList targets;
/** A wirestate to turn on and off for the rootNode */
protected WireframeState wireState;
/** A lightstate to turn on and off for the rootNode */
protected LightState lightState;
/** Location of the font for jME's text at the bottom */
public static String fontLocation = "com/jme/app/defaultfont.tga";
/** This is used to display print text. */
protected StringBuffer updateBuffer=new StringBuffer(30);
/** This is used to recieve getStatistics calls.*/
protected StringBuffer tempBuffer=new StringBuffer();
protected boolean pause;
/**
* This is called every frame in BaseGame.start()
* @param interpolation unused in this implementation
* @see AbstractGame#update(float interpolation)
*/
protected final void update(float interpolation) {
/** Recalculate the framerate. */
timer.update();
/** Update tpf to time per frame according to the Timer. */
tpf = timer.getTimePerFrame();
/** Check for key/mouse updates. */
input.update(tpf);
mouse.update();
// input2.update(tpf);
bufferedInput.update(tpf);
updateBuffer.setLength(0);
if (pause) return;
/** Call simpleUpdate in any derived classes of SimpleGame. */
simpleUpdate();
/** Update controllers/render states/transforms/bounds for rootNode. */
rootNode.updateGeometricState(tpf, true);
}
/**
* This is called every frame in BaseGame.start(), after update()
* @param interpolation unused in this implementation
* @see AbstractGame#render(float interpolation)
*/
protected final void render(float interpolation) {
/** Reset display's tracking information for number of triangles/vertexes */
display.getRenderer().clearStatistics();
/** Clears the previously rendered information. */
display.getRenderer().clearBuffers();
/** Draw the rootNode and all its children. */
display.getRenderer().draw(rootNode);
/** If showing bounds, draw rootNode's bounds, and the bounds of all its children. */
if (showBounds)
display.getRenderer().drawBounds(rootNode);
/** Draw the fps node to show the fancy information at the bottom. */
// display.getRenderer().draw(fpsNode);
/** Call simpleRender() in any derived classes. */
simpleRender();
}
/**
* Creates display, sets up camera, and binds keys. Called in BaseGame.start() directly after
* the dialog box.
* @see AbstractGame#initSystem()
*/
protected final void initSystem() {
LoggingSystem.getLogger().setLevel(Level.SEVERE);
try {
/** Get a DisplaySystem acording to the renderer selected in the startup box. */
display = DisplaySystem.getDisplaySystem(properties.getRenderer());
/** Create a window with the startup box's information. */
display.createWindow(
properties.getWidth(),
properties.getHeight(),
properties.getDepth(),
properties.getFreq(),
properties.getFullscreen());
/** Create a camera specific to the DisplaySystem that works with
* the display's width and height*/
cam =
display.getRenderer().createCamera(
display.getWidth(),
display.getHeight());
}
catch (JmeException e) {
/** If the displaysystem can't be initialized correctly, exit instantly. */
e.printStackTrace();
System.exit(1);
}
/** Set a black background.*/
display.getRenderer().setBackgroundColor(ColorRGBA.black);
/** Set up how our camera sees. */
cam.setFrustumPerspective(45.0f,
(float) display.getWidth() /
(float) display.getHeight(), 1, 1000);
Vector3f loc = new Vector3f(0.0f, 0.0f, 25.0f);
Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f);
Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
/** Move our camera to a correct place and orientation. */
cam.setFrame(loc, left, up, dir);
/** Signal that we've changed our camera's location/frustum. */
cam.update();
/** Assign the camera to this renderer.*/
display.getRenderer().setCamera(cam);
InputSystem.createInputSystem(properties.getRenderer());
/** Create a basic input controller. */
input = new InputHandler();
bufferedInput = new InputHandler();
input.setKeySpeed(10f);
input.setMouseSpeed(1f);
/** Get a high resolution timer for FPS updates. */
timer = Timer.getTimer(properties.getRenderer());
/** Sets the title of our display. */
display.setTitle("SimpleGame");
/** Signal to the renderer that it should keep track of rendering information. */
display.getRenderer().enableStatistics(true);
/** Assign key P to action "toggle_pause". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_pause",
KeyInput.KEY_P);
/** Assign key T to action "toggle_wire". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_wire",
KeyInput.KEY_T);
/** Assign key L to action "toggle_lights". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_lights",
KeyInput.KEY_L);
/** Assign key B to action "toggle_bounds". */
KeyBindingManager.getKeyBindingManager().set(
"toggle_bounds",
KeyInput.KEY_B);
/** Assign key C to action "camera_out". */
KeyBindingManager.getKeyBindingManager().set(
"camera_out",
KeyInput.KEY_C);
KeyBindingManager.getKeyBindingManager().set(
"Exit",
KeyInput.KEY_ESCAPE);
KeyBindingManager.getKeyBindingManager().set(
"Send",
KeyInput.KEY_RETURN);
}
/**
* Creates rootNode, lighting, statistic text, and other basic render states.
* Called in BaseGame.start() after initSystem().
* @see AbstractGame#initGame()
*/
protected final void initGame() {
/** Create rootNode */
rootNode = new Node("rootNode");
mouseNode = new Node("mouseNode");
uiNode = new Node ("uiNode");
String[] names = { "main", "nice" };
String[] locs = { fontLocation, "conc_font.png" };
UIFonts _fonts = new UIFonts(names, locs);
/** Create a wirestate to toggle on and off. Starts disabled with
* default width of 1 pixel. */
wireState = display.getRenderer().createWireframeState();
wireState.setEnabled(false);
rootNode.setRenderState(wireState);
/** Create a ZBuffer to display pixels closest to the camera above farther ones. */
ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.CF_LEQUAL);
rootNode.setRenderState(buf);
// -- FPS DISPLAY
// First setup alpha state
/** This allows correct blending of text and what is already rendered below it*/
AlphaState as1 = display.getRenderer().createAlphaState();
as1.setBlendEnabled(true);
as1.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as1.setDstFunction(AlphaState.DB_ONE);
as1.setTestEnabled(true);
as1.setTestFunction(AlphaState.TF_GREATER);
as1.setEnabled(true);
// Now setup font texture
TextureState font = display.getRenderer().createTextureState();
/** The texture is loaded from fontLocation */
font.setTexture(
TextureManager.loadTexture(
MainSimpleGame.class.getClassLoader().getResource(
fontLocation),
Texture.MM_LINEAR,
Texture.FM_LINEAR));
font.setEnabled(true);
// Then our font Text object.
/** This is what will actually have the text at the bottom. */
fps = new Text("FPS label", "");
fps.setForceView(true);
fps.setTextureCombineMode(TextureState.REPLACE);
// Finally, a stand alone node (not attached to root on purpose)
fpsNode = new Node("FPS node");
fpsNode.attachChild(fps);
fpsNode.setRenderState(font);
fpsNode.setRenderState(as1);
fpsNode.setForceView(true);
// ---- LIGHTS
/** Set up a basic, default light. */
PointLight light = new PointLight();
light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
light.setLocation(new Vector3f(100, 100, 100));
light.setEnabled(true);
/** Attach the light to a lightState and the lightState to rootNode. */
lightState = display.getRenderer().createLightState();
lightState.setEnabled(true);
lightState.attach(light);
rootNode.setRenderState(lightState);
//
AlphaState as2 = display.getRenderer().createAlphaState();
as2.setBlendEnabled(true);
as2.setSrcFunction(AlphaState.SB_SRC_ALPHA);
as2.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
as2.setTestEnabled(true);
as2.setTestFunction(AlphaState.TF_GREATER);
AlphaState alpha = display.getRenderer().createAlphaState();
alpha.setBlendEnabled(true);
alpha.setSrcFunction(4);
alpha.setDstFunction(1);
alpha.setTestEnabled(true);
alpha.setTestFunction(4);
mouse = new AbsoluteMouse("Mouse Input", display.getWidth(), display
.getHeight());
TextureState cursor = display.getRenderer().createTextureState();
cursor.setEnabled(true);
cursor.setTexture(TextureManager.loadTexture(TestAbsoluteMouse.class
.getClassLoader()
.getResource("jmetest/data/cursor/cursor1.png"),
Texture.MM_LINEAR, Texture.FM_LINEAR));
mouse.setRenderState(cursor);
mouse.setRenderState(as2);
mouse.setMouseInput(InputSystem.getMouseInput());
/*
* Set the speed of the mouse
*/
input.setMouse(mouse);
_edit = new MainUIEditBox("edit", 5 , 4, 400, 15, input, bufferedInput, _scheme,
_fonts, "nice", "", 60f, 0f, UIObject.TEXTURE, display);
/** Let derived classes initialize. */
myBox = new MyTextBox(display, input);
simpleInitGame();
rootNode.attachChild(myBox);
rootNode.attachChild(_edit);
rootNode.attachChild(mouse);
/** Update geometric and rendering information for both the rootNode and fpsNode. */
rootNode.updateGeometricState(0.0f, true);
rootNode.updateRenderState();
fpsNode.updateGeometricState(0.0f, true);
fpsNode.updateRenderState();
}
/**
* Called near end of initGame(). Must be defined by derived classes.
*/
protected abstract void simpleInitGame();
/**
* Can be defined in derived classes for custom updating.
* Called every frame in update.
*/
protected void simpleUpdate() {}
/**
* Can be defined in derived classes for custom rendering.
* Called every frame in render.
*/
protected void simpleRender() {}
/**
* unused
* @see AbstractGame#reinit()
*/
protected void reinit() {
}
/**
* Cleans up the keyboard.
* @see AbstractGame#cleanup()
*/
protected void cleanup() {
LoggingSystem.getLogger().log(Level.INFO, "Cleaning up resources.");
if (InputSystem.getKeyInput() != null)
InputSystem.getKeyInput().destroy();
if (InputSystem.getMouseInput() != null)
InputSystem.getMouseInput().destroy();
}
}