www.jpct.net

jPCT - a 3d engine for Java => Support => Topic started by: Veko on December 16, 2008, 08:10:38 pm

Title: problems with gears example
Post by: Veko on December 16, 2008, 08:10:38 pm
When I try to make the gears application I keep getting

Code: [Select]
Loading file E:/SCHOOL/Java/JCPT_test/res/RedGear.3ds
[ Tue Dec 16 20:09:38 CET 2008 ] - ERROR: Couldn't read file E:/SCHOOL/Java/JCPT_test/res/RedGear.3ds
[ Tue Dec 16 20:09:38 CET 2008 ] - ERROR: Not a valid 3DS file!
Unknown file format: E:/SCHOOL/Java/JCPT_test/res/RedGear.3ds

I'm using the 3ds files that come with the example and I've just copied the original code from the example into a new application.
Title: Re: problems with gears example
Post by: EgonOlsen on December 16, 2008, 08:15:23 pm
The error message may be a bit misleading. What it actually tries to say is, that the file can't be found. Check if your file is really located where the application looks for it (i.e. in "E:/SCHOOL/Java/JCPT_test/res/RedGear.3ds"). Most likely, it isn't...
Title: Re: problems with gears example
Post by: Veko on December 16, 2008, 08:19:11 pm
it's in the right location :p (first thing I checked)
Title: Re: problems with gears example
Post by: EgonOlsen on December 16, 2008, 08:42:31 pm
Which example is that? It's none of mine, so it has to be made by somebody else. Where can i get it? (I hope that i'm not hosting it myself and forgot about it... :-[)
Title: Re: problems with gears example
Post by: Veko on December 16, 2008, 08:48:27 pm
the example from the "How to create an Applet" thread (http://www.jpct.net/forum2/index.php/topic,1247.0.html)

Title: Re: problems with gears example
Post by: EgonOlsen on December 16, 2008, 08:52:38 pm
I see...maybe Paul can comment on this then. May have something to do with the fact that it actually is an applet example and your path doesn't look very applet-like...but that's just a guess... ???
Title: Re: problems with gears example
Post by: paulscode on December 16, 2008, 10:53:08 pm
In this demo applet, I recommend compiling the 3ds file into the JAR.  The problem may be that the AppletLoader is not able to access the 3ds file through a local directory, not sure.

--EDIT--
Oh, in case you already have compiled the 3ds file into the JAR but don't know how to access it in your code, the path you want to use is its JAR path, not the local path.  The path will usually look something like "Models/RedGear.3ds".  If you stick the file in the root directory of the JAR (i.e. the "<default package>"), just use the filename without any path - just "RedGear.3ds" (that is how I did it in the example, which is why the files are referenced that way in the source code).
--END EDIT--

It might be possible to tell applet loader about the file in the HTML part of the applet loader - I'll look into it and let you know.

That being said, an applet will normally be run from an online location, and in that case, you would not be accessing the file from a local directory.  You will have to either compile it into the JAR as I mentioned above, or access it through an instance of java.net.URL.  If you need help with the later, let me know.
Title: Re: problems with gears example
Post by: paulscode on December 16, 2008, 11:28:05 pm
I just noticed that you used the word "application" in your initial post.  If you are actually trying to convert the gears demo into an application, I can help you with that as well (it isn't too difficult).
Title: Re: problems with gears example
Post by: fireside on December 17, 2008, 12:16:31 am
Quote
Loading file E:/SCHOOL/Java/JCPT_test/res/RedGear.3ds

Also, I don't know if you did it the same way, but you have "jcpt", which may be a transposition error for jpct.

Title: Re: problems with gears example
Post by: Veko on December 17, 2008, 12:24:42 am
alright I got the thing working in 2sec now :p (took some hours of coding to clear my head),
don't know what I did differently now, but it works

thnx for the fast responses !

+ paulscode, nono I meant to say applet :)
Title: Re: problems with gears example
Post by: paulscode on December 17, 2008, 12:36:15 am
Cool.  BTW, I updated the source code on the "How to create an applet" thread.  I had wrote this demo some time ago, so it had a couple of minor problems (I fixed a potential null-pointer exception in the paint() method, and I replaced the "loadMeshFile" method with a more versitile method compatible with both simple and complex 3DS files).  I also added in comments for how to convert it into an application (takes just a few lines of code), in case that is something you ever want to know how to do.  I recommend building on that source rather than what I had up there originally.
Title: Re: problems with gears example
Post by: Veko on December 17, 2008, 01:39:32 am
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

Code: [Select]
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

Code: [Select]
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 ?
Title: Re: problems with gears example
Post by: paulscode on December 17, 2008, 02:02:51 am
Just to test your suspicions about the display parent painting over the gears state, you could try setting the display parent to not visible to see if the gears state shows through.  Looking at the code, though, this doesn't look like it would be the problem unless calling Display.update() or Display.sync() causes the display_parent canvas to gain focus.  Another thing to try would be to create a different state with a canvas that is not using anything related to jPCT.  That might indicate whether or not the problem is related to a conflict between Display and jPCT.
Title: Re: problems with gears example
Post by: Veko on December 17, 2008, 02:44:46 am
I got another non jcpt canvas working :s
so it must be an interferance between Display and jpct.

Is there a way to work with 'gamestates' in jpct (like menustate, ingamestate, etc.) ?
Title: Re: problems with gears example
Post by: paulscode on December 17, 2008, 03:18:04 am
The problem appears to be a conflict between Display and jPCT, so you should be able to implement switching between different Canvases/gamestates in general, so long as you don't use Display.  Just write your gamestate switching code so that switching from one state to another sets the previous one to not visible and takes care of things like pausing the game, loading, freeing resources, etc.

I am going to try and create a working example of state switching, and I'll post the source for reference when I finish it.
Title: Re: problems with gears example
Post by: paulscode on December 17, 2008, 01:35:03 pm
I finished a working example of state switching with jPCT.  It's very basic, but it proves the concept works.

Demo Applet (http://www.paulscode.com/demos/jpct/StateSwitch/)  (Source Code (http://www.paulscode.com/demos/jpct/StateSwitch/StateSwitchAppletSource.zip))

The applet has three states:
Loading State  (Loads everything and displays messages)
Gear State      (Gears demo, press "ESC" to exit)
Exit State       (Says "Goodbye")
Title: Re: problems with gears example
Post by: Veko on December 17, 2008, 01:46:04 pm
wow, sweet man :D
will test this asap

*edit* very nice, that should be stickied up :D + big thanks for the fast support
Title: Re: problems with gears example
Post by: fireside on December 17, 2008, 05:12:11 pm
I'm going to look at that source too.  Not to belabor a point, but a wiki would be really nice for these things, better than stickies because they tend to get messy. 
Title: Re: problems with gears example
Post by: Veko on January 24, 2009, 02:14:32 am
ok I'm back with a new question. I'm still using this system for my applet and now I'm trying to implement FengGUI.
I've gotten so far as

Code: [Select]
private org.fenggui.Display display;
...

this.display = new Display(new AWTGLCanvasBinding((AWTGLCanvas)m_Canvas));

Window window = FengGUI.createWindow(display, true, false, false, true);
window.setTitle("my window");
window.setPosition(new Point(50,200));
window.getContentContainer().setLayoutManager(new RowLayout(false));
window.getContentContainer().getAppearance().setPadding(new Spacing(10, 10));

after that I tried adding stuff (but here I stumbled upon the null pointer exception)

Code: [Select]
final ToggableGroup<String> toggableGroup = new ToggableGroup<String>();
RadioButton<String> radioButtonCoffee = new RadioButton<String>("coffee", toggableGroup, "coffee");
RadioButton<String> radioButtonTea = new RadioButton<String>("tea", toggableGroup, "tea");
radioButtonTea.setSelected(true);

Container container = new Container(new RowLayout(true));
container.addWidget(radioButtonCoffee);
container.addWidget(radioButtonTea);
window.getContentContainer().addWidget(container);


but why I try to add stuff to the window (like radio buttons etc.) I get a null pointer exception. I've been reading up about common null pointer exceptions with FengGUI, but I haven't found a solution yet

here's the exception:

Code: [Select]
Exception in thread "Thread-21" java.lang.NullPointerException
at org.lwjgl.opengl.GL11.glGenTextures(GL11.java:1348)
at org.fenggui.render.lwjgl.LWJGLTexture.createTextureID(Unknown Source)
at org.fenggui.render.lwjgl.LWJGLTexture.createTexture(Unknown Source)
at org.fenggui.render.lwjgl.AWTGLCanvasBinding.getTexture(Unknown Source)
at org.fenggui.theme.DefaultTheme.setUp(Unknown Source)
at org.fenggui.theme.StandardTheme.setUp(Unknown Source)
at org.fenggui.StandardWidget.setupTheme(Unknown Source)
at org.fenggui.RadioButton.<init>(Unknown Source)
at facebookgame.IngameState.buildGUI(IngameState.java:417)
at facebookgame.IngameState.enter(IngameState.java:105)
at facebookgame.MainApp.switchState(MainApp.java:136)
at facebookgame.MainApp.stateEvent(MainApp.java:148)
at facebookgame.LoadingState.tick(LoadingState.java:75)
at facebookgame.MainApp.run(MainApp.java:87)
at java.lang.Thread.run(Unknown Source)

also, I have no idea where to put the display.display()

hopefully you guys can help me as good as before :)
Title: Re: problems with gears example
Post by: paulscode on January 24, 2009, 03:35:47 am
From the stack trace, this looks like it might be a thread synchronization problem.  Are you creating the window on a different thread than the one MainApp.run() method is running from?  If so, this could cause a problem if the loading state finishes and tries to switch to the ingame state before the window has been fully instantiated.  You could try synchronizing on an Object instance every time the window and its components are accessed or changed.

Oh, and about where to put the display.display().  I am not familiar with fenggui myself - what does the display() method do?  If it updates the contents of the canvas, for example, a good place for it might be in either the state's tick() or paint() method.

--EDIT--
Another place I thought of to check for thread synchronization problems is when calling the MainApp.stateEvent() method.  If you are using the same setup as in the example I posted above, make sure this method is being called from the same thread that the State.tick() method is being called from (i.e. the MainApp.run() thread).  From the stack trace, I can see that it is, so this is not causing your current problem.

--EDIT #2--
One more potential problem I just thought of is the fact that paint() always runs on a different thread than tick(), so it might be a good idea to use a synchronized interface to a "safeToPaint" boolean.  Set the boolean to false when the state is initializing or shutting down, to avoid null pointer exceptions.  I hadn't considered this when I created the above example applet.  Again, this doesn't appear to be related to your current problem, though.
Title: Re: problems with gears example
Post by: Veko on January 24, 2009, 01:08:28 pm
I've set aside the FengGUI for a moment (think its to overkill for what I want, I just want some simple text in a custom font on my screen)

so now I'm looking into the whole blitting thingie and stumbled on this topic
http://www.jpct.net/forum2/index.php/topic,1074.0.html

this looks very promising, but when I try to do:

Code: [Select]
private GLFONT glfont;
...
m_Buffer.update();

glfont.blitString(m_Buffer, "this is a blitted text", 10, 10, 1, Color.ORANGE);

m_Buffer.displayGLOnly();
       
m_Canvas.repaint();

I'm getting null pointer exception:

Code: [Select]
Exception in thread "AWT-EventQueue-2" java.lang.NullPointerException
at facebookgame.IngameState.paint(IngameState.java:218)
at facebookgame.MainApp.paint(MainApp.java:58)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Title: Re: problems with gears example
Post by: EgonOlsen on January 24, 2009, 01:13:42 pm
Are you sure that glFont has actually been initialized?
Title: Re: problems with gears example
Post by: Veko on January 24, 2009, 03:26:59 pm
ok silly me, you're right I forgot to initialize :D
can someone also point me in the right direction for bitmapFonts ?