Hi!
Can somepne please tell me which methods must inside a GameTaskQueManager? If I undersatnd it correctly the methods which only define a "state" (not necessarily RenderState but also Geometric states, positions locations etc.) save the data locally in memory. Only if I call a GL method directly (of course, using one of the JME wrapper class methods) GameTaskQueManager has to be used.
I asked due to the fact that I don't get any error messages but sometimes I see no graphics output in the window. Sometimes it works, sometimes not. I must say that I love the engine but the tutorial about creating a running application from the scratch is rather poor. The tutorials only deal with BaseSimpleGame, SimopleGame etc classes. I have included the JME within my NetBeans framework, i.e. a Swing application and find it very hard to implement everything correctly. If someone could give me a hint or even a process flow in which row to call the necessary methods to get a minimum JMECanvasImplementation to run insight a Swing application I would be very grateful.
Thanks a lot in advance,
Regards,
Equilibrium
Use GameTaskQueueManager whenever you need to use a method that needs to be implimented within the OpenGL thread. There is no definite way of telling whether a call needs to be done in the openGL thread or not; however, if your messing with rendering or context, then it is a most likely a openGL call. This is a list of some of the most commonly used methods that needs to access OpenGL HERE.
You’ll always know its a openGL call if you get an odd error that references it, otherwise if it compiles and runs fine without any errors then it is probably not a openGL thing.
As for your meshes not showing up if your running jME or jME2, remember to always call .updateRenderState(); anytime you make changes to the geometry
I'm writing a Swing-JME application (with SimplePassCanvasImpl) and i found that everything runs inside the EDT so, in practice, there is no need to use GameTaskQueueManager.
In theory JME could use a dedicated thread to manage the scene graph so GameTaskQueueManager is the way to go if you have to alter the scene.
Unfortunately the GameTaskQueueManager API doesn't state (or i don't see it) that an happens-before relationship exists between actions prior to the update invocation and the call of the given Callable (but this relationship seems to exist in the implementation because GameTaskQueue uses a ConcurrentLinkedQueue) so you have to enforce an HB for the values created in the EDT and passed to the JME-Thread.
Thank you so much for SimplePassCanvasImpl hint. I didn't know this. class. I'll look for it…
Regards,
Equilibrium
Be careful, i didn't meant to say that SimplePassCanvasImpl enforces everything to run inside the edt.
Maybe it is just a side effect of the way i use the jme api and it can be wrong. What i do is simply pack stuff.
The Canvas3D (in the project it is not a standalone class but there's no difference) is something like this:
package it.tukano.jupiter.test;
import com.jme.input.KeyInput;
import com.jme.renderer.Camera;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;
import com.jme.system.canvas.CanvasConstructor;
import com.jme.system.canvas.JMECanvas;
import com.jme.system.canvas.SimplePassCanvasImpl;
import com.jme.system.lwjgl.LWJGLSystemProvider;
import com.jme.util.GameTaskQueueManager;
import com.jmex.awt.input.AWTMouseInput;
import com.jmex.awt.lwjgl.LWJGLAWTCanvasConstructor;
import java.awt.Canvas;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyListener;
import java.util.concurrent.Callable;
import javax.swing.JPanel;
public class Canvas3D extends JPanel {
private final String DISPLAY_SYSTEM_ID = LWJGLSystemProvider.LWJGL_SYSTEM_IDENTIFIER;
private final Class<? extends CanvasConstructor> CANVAS_CONSTRUCTOR_CLASS = LWJGLAWTCanvasConstructor.class;
private SimplePassCanvasImpl CANVAS_IMPL;
private JMECanvas canvas;
private final int MIN_WIDTH = 64;
private final int MIN_HEIGHT = 64;
public Canvas3D() {
super(new GridLayout(1, 1));
}
public void addNotify() {
super.addNotify();
initializeJME();
}
public Camera getCamera() {
return CANVAS_IMPL.getCamera();
}
public Node getSceneRoot() {
return CANVAS_IMPL.getRootNode();
}
public int getWidth() {
return Math.max(super.getWidth(), MIN_WIDTH);
}
public int getHeight() {
return Math.max(super.getHeight(), MIN_HEIGHT);
}
private void initializeJME() {
CANVAS_IMPL = new SimplePassCanvasImpl(getWidth(), getHeight()) {};
KeyInput.setProvider(KeyInput.INPUT_AWT);
DisplaySystem display = DisplaySystem.getDisplaySystem(DISPLAY_SYSTEM_ID);
display.registerCanvasConstructor("AWT", CANVAS_CONSTRUCTOR_CLASS);
canvas = display.createCanvas(getWidth(), getHeight());
canvas.setUpdateInput(true);
canvas.setTargetRate(15);
final Canvas awtCanvas = (Canvas) canvas;
awtCanvas.setPreferredSize(new Dimension(getWidth(), getHeight()));
awtCanvas.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Component component = e.getComponent();
CANVAS_IMPL.resizeCanvas(getWidth(), getHeight());
updateCameraPerspective();
}
});
KeyListener kl = (KeyListener) KeyInput.get();
awtCanvas.addKeyListener(kl);
AWTMouseInput.setup(awtCanvas, false);
canvas.setImplementor(CANVAS_IMPL);
add(awtCanvas);
}
private void updateCameraPerspective() {
final float RATIO = (float) getWidth() / (float) getHeight();
GameTaskQueueManager.getManager().update(new Callable<Void>() {
public Void call() {
System.out.println("IS THIS THE EDT? " + java.awt.EventQueue.isDispatchThread());
if(getCamera() != null) {
getCamera().setFrustumPerspective(45.0f, RATIO, 1, 250);
getCamera().update();
}
return null;
}
});
}
}
This is a simple test class:
package it.tukano.jupiter.test;
import javax.swing.JFrame;
public class TestCanvas3D {
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
Canvas3D canvas = new Canvas3D();
JFrame window = new JFrame("Canvas3D Test");
window.add(canvas);
window.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
window.setSize(640, 480);
window.setVisible(true);
}
});
}
}
No. Everything is ok and works fine. thanks a lot for the hint.