nice
I got myself a new problem now :p. I'm trying to work with a kind of gamestate system in the applet and I'm trying to use to the Gears demo as 1 of the states. But I think I'm not doing it correctly because he isn't drawing anything on screen when he is in the 'Gears-state'
I'm not very familiar with applets and I started working with them without jcpt using examples on the LWJGL-forums (That's why I use Display etc.),
but because I had no 3d animation support yet, I needed an easy to use engine with animation support and thats when I found Jcpt.
here's my code:
MainApp
package testgame;
import java.util.HashMap;
import java.util.Iterator;
import java.awt.BorderLayout;
import java.awt.Canvas;
import org.lwjgl.Sys;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
public class MainApp extends javax.swing.JApplet
{
// DATAMEMBERS -----------------------------------
protected Thread gameThread = null;
private HashMap gameStates = new HashMap();
private GameState currentState = null;
public Canvas display_parent = null;
private boolean running = false;
// -----------------------------------------------
@Override
public void destroy()
{
remove(display_parent);
super.destroy();
System.out.println("Clear Up");
}
@Override
public void start()
{
gameThread = new Thread()
{
@Override
public void run()
{
running = true;
try
{
initGL();
}
catch(LWJGLException e)
{
e.printStackTrace();
}
System.out.println("Entering Gameloop");
gameLoop();
}
};
// If setDaemon(true) the JVM will exit as soon as the main reaches completion?
gameThread.setDaemon(true);
gameThread.start();
}
@Override
public void stop()
{
//
}
@Override
public void init()
{
setLayout(new BorderLayout());
try
{
display_parent = new Canvas()
{
@Override
public final void removeNotify()
{
destroyLWJGL();
super.removeNotify();
}
};
display_parent.setSize(getWidth(),getHeight());
add(display_parent);
display_parent.setFocusable(true);
display_parent.requestFocus();
setVisible(true);
}
catch(Exception e)
{
System.err.println(e);
throw new RuntimeException("Unable to create display");
}
}
private void destroyLWJGL()
{
stopApplet();
try
{
gameThread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
private void stopApplet()
{
running = false;
}
private void addState(GameState state)
{
if (currentState == null) currentState = state;
gameStates.put(state.GetName(), state);
}
private void initGL() throws LWJGLException
{
System.out.println("display_parent.isDisplayable() = " + display_parent.isDisplayable());
// setParent needed for embedding screen in canvas
Display.setParent(display_parent);
Display.setVSyncEnabled(false);
Display.create();
// add the game states that build up our game
addState(new GearsState());
try
{
// initialise all the game states we've just created. This allows
// them to load any resources they require
Iterator states = gameStates.values().iterator();
// loop through all the states that have been registered
// causing them to initialise
while (states.hasNext())
{
GameState state = (GameState) states.next();
state.StateInitialize();
}
}
catch (Exception e)
{
// if anything goes wrong, show an error message and then exit.
// This is a bit abrupt but for the sake of this tutorial its
// enough.
Sys.alert("Error", "Unable to initialise state: " + e.getMessage());
System.exit(0);
}
}
private void gameLoop()
{
currentState.Enter(this);
long oldTime = getTime();
System.out.println("Got Time : " + oldTime);
// while the game is running we loop round updating and rendering the current game state
while (running)
{
long dTime = (getTime() - oldTime);
oldTime = getTime();
Display.update();
if (Display.isCloseRequested())
{
running = false;
break;
}
// the window is in the foreground, so we should play
else if (Display.isActive())
{
int remainder = (int) (dTime % 10);
int step = (int) (dTime / 10);
for (int i=0;i<step;i++)
{
currentState.StateCycle(10);
}
if (remainder != 0)
{
currentState.StateCycle(remainder);
}
currentState.StatePaint();
Display.sync(60);
}
else
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
//
}
currentState.StateCycle(dTime);
// only bother rendering if the window is visible or dirty
if (Display.isVisible() || Display.isDirty())
{
currentState.StatePaint();
Display.sync(60);
}
}
}
}
// Change the current state being rendered and updated.
// Note if no state with the specified name can be found no action is taken.
protected void changeToState(String name)
{
GameState newState = (GameState) gameStates.get(name);
if (newState == null)
{
return;
}
currentState.Leave();
currentState = newState;
currentState.Enter(this);
}
private long getTime()
{
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}
}
Gears-state
package testgame;
import java.awt.BorderLayout;
import java.awt.Canvas;
import com.threed.jpct.Camera;
import com.threed.jpct.FrameBuffer;
import com.threed.jpct.IRenderer;
import com.threed.jpct.Lights;
import com.threed.jpct.Matrix;
import com.threed.jpct.Object3D;
import com.threed.jpct.SimpleVector;
import com.threed.jpct.World;
import java.awt.Color;
import testgame.modelloader.Loader3ds;
public class GearsState extends javax.swing.JPanel implements testgame.GameState//, MouseListener, MouseMotionListener, Runnable
{
// -----------------------------------------------
protected static final String NAME = "gears";
private jPCTGears m_pWindow = null;
private FrameBuffer m_Buffer = null;
private World m_World = null;
private Camera m_Camera = null;
private Canvas myCanvas = null;
private Object3D redGear, greenGear, blueGear, assemblyPivot;
private float gear_rotation = 0.02f;
// -----------------------------------------------
public String GetName()
{
return NAME;
}
public void StateInitialize()
{
//
}
public void Enter(MainApp window)
{
System.out.println("Entering Menu state");
m_pWindow = window;
// sign the applet up to receive mouse messages:
m_World = new World(); // create a new world
World.setDefaultThread(Thread.currentThread());
// create a new buffer to draw on:
m_Buffer = new FrameBuffer( m_pWindow.getWidth(), m_pWindow.getHeight(), FrameBuffer.SAMPLINGMODE_HARDWARE_ONLY );
m_Buffer.disableRenderer( IRenderer.RENDERER_SOFTWARE );
myCanvas = m_Buffer.enableGLCanvasRenderer();
m_pWindow.add( myCanvas, BorderLayout.CENTER);
myCanvas.setVisible(true);
myCanvas.requestFocus();
Loader3ds temp = new Loader3ds();
// load some 3D objects and make sure they have the correct orientation:
redGear = temp.loadMeshFile("http://users.telenet.be/decoy/FacebookApp/models/RedGear.3ds");
redGear.rotateY( (float)Math.PI / 2.0f );
redGear.rotateMesh();
redGear.setRotationMatrix( new Matrix() );
redGear.setOrigin( new SimpleVector( 0, 0, 0 ) );
redGear.build();
greenGear = temp.loadMeshFile("http://users.telenet.be/decoy/FacebookApp/models/GreenGear.3ds");
greenGear.rotateY( (float)Math.PI / 2.0f );
greenGear.rotateZ( 0.35f );
greenGear.rotateMesh();
greenGear.setRotationMatrix( new Matrix() );
greenGear.setOrigin( new SimpleVector( -145.0f, 0, 0 ) );
greenGear.build();
blueGear = temp.loadMeshFile("http://users.telenet.be/decoy/FacebookApp/models/BlueGear.3ds");
blueGear.rotateY( (float)Math.PI / 2.0f );
//blueGear.rotateZ( 0.40f );
blueGear.rotateMesh();
blueGear.setRotationMatrix( new Matrix() );
blueGear.setOrigin( new SimpleVector( 0, -140.0f, 0 ) );
blueGear.build();
// Set up a pivot point for the entire gear assembly:
assemblyPivot = Object3D.createDummyObj();
assemblyPivot.setOrigin( new SimpleVector( 0, 0, 0 ) );
// Make the gears children to assemblyPivot.
// Translations and rotations to assemblyPivot
// will affect the entire gear assembly:
assemblyPivot.addChild(redGear);
assemblyPivot.addChild(greenGear);
assemblyPivot.addChild(blueGear);
// add the objects our world:
m_World.addObject(redGear);
m_World.addObject(greenGear);
m_World.addObject(blueGear);
redGear.build();
greenGear.build();
blueGear.build();
m_World.buildAllObjects();
lookAt(redGear); // make sure the camera is facing towards the object
letThereBeLight(); // create light sources for the scene
// receive mouse input from the main applet:
//addMouseListener(m_pWindow);
//addMouseMotionListener(m_pWindow);
// also get mouse input picked up by the canvas:
//myCanvas.addMouseListener(this);
//myCanvas.addMouseMotionListener(this);
//new Thread(this).start();
}
public void Leave()
{
m_pWindow = null;
m_World.dispose();
}
public void StatePaint()
{
// He enters and does StatePaint, but nothing happens.
m_Buffer.clear(new Color(100, 100, 100)); // erase the previous frame
// render the world onto the buffer:
m_World.renderScene(m_Buffer);
m_World.draw(m_Buffer);
m_Buffer.update();
m_Buffer.displayGLOnly();
myCanvas.repaint(); // Paint the canvas onto the applet (hardware mode)
System.out.println("Painting");
}
public void StateCycle(long dTime)
{
redGear.rotateAxis( redGear.getZAxis(), -gear_rotation );
greenGear.rotateAxis( greenGear.getZAxis(), 2.0f * gear_rotation );
blueGear.rotateAxis( blueGear.getZAxis(), 2.0f * gear_rotation );
}
// create light sources for the scene
private void letThereBeLight()
{
m_World.getLights().setOverbrightLighting (Lights.OVERBRIGHT_LIGHTING_DISABLED );
m_World.getLights().setRGBScale(Lights.RGB_SCALE_2X);
// Set the overall brightness of the world:
m_World.setAmbientLight(50, 50, 50);
// Create a main light-source:
m_World.addLight(new SimpleVector(50, -50, 300 ), 20, 20, 20);
}
// point the camera toward the given object
private void lookAt( Object3D obj )
{
m_Camera = m_World.getCamera(); // grab a handle to the camera
m_Camera.setPosition( 0, 0, 500 ); // set its *relative* position
m_Camera.lookAt( obj.getTransformedCenter() ); // look toward the object
}
}
I'm not sure if creating a Display in my MainApp is causing interferance with the jcpt engine,
but when I run this applet he enters the GearsState with no problems (he even does the StatePaint etc.), but nothing is painted to screen, it just stays black (No errors in console though)
I tried clearing with a different color than black, but that didn't work (still the black screen),
then I added the "System.out.println("Painting");" to check if he actually uses StatePaint, and yes the applet does use it.
I haven't a clue what I'm doing wrong, but I suspect I'm painting the display_parent over the canvas of the GearsState
Is it possible to have world within worlds ?