Welcome to the Hello World tutorial. It's based on the HelloWorld-sources that you can find in the examples-directory of the distribution. Our goal here is to create a textured box spinning around in a window.
You should know how to do some simple Swing programming like creating a JFrame for this. If you don't, learn that first and come back later.
We'll start with the first jPCT related line in the source code, the import:
This imports all basic classes of jPCT. There are a few more sub-packages like util and procs, but for this example, we don't need them.
Now we'll play god and create a world:
world = new World(); world.setAmbientLight(0, 255, 0);
These two lines are creating a new instance of World and set the ambient light for this world to green. A World in jPCT is the container, that accumulates everything that is needed to describe a 3D scene, like light sources, the 3D objects and the camera. Without an instance of World, you can't do much in jPCT.
We'll leave our world alone for a while now and load a texture instead. Loading a texture to texture an object requires two steps in jPCT, which are both combined in this line:
TextureManager.getInstance().addTexture("box", new Texture("box.jpg"));
At first, we load create a new texture by simply creating a new instance of Texture. We create it from a file, "box.jpg" in this case. You can also create textures out of images, inputstreams or just create a single colored texture out of thin air.
The texture alone can't be assigned to our object (we'll create that later). We have to add it to the TextureManager first. The TextureManager is a singleton, i.e. it exists only once per VM/classloader and can't be instantiated from outside. To obtain it, there's a getInstance()-method in TextureManager like shown above. To add our new texture, we are using the addTexture()-method. To identify the texture later, we give it a unique name. In this case, that's simply "box".
We now have a world and a texture, it's time to create an object. An object in jPCT is an instance of Object3D. You can either load one, create one yourself triangle by triangle or pick one from a set of predefined primitives. We choose the latter option for this simple application:
box = Primitives.getBox(13f, 2f); box.setTexture("box"); box.setEnvmapped(Object3D.ENVMAP_ENABLED);
getBox() has two parameters, scale and scaleHeight. Please refer to the java docs for a more detailed explanation. We are using 13 and 2 here simply because it gives us the box that we want. Now the box needs a texture. We have already added one to the TextureManager and because the manager is a singleton, we just have to give the object the name of the texture in the manager, which is "box". This is not all. Most primitives aren't created with proper texture coordinates, so we won't see our texture. To keep things simple, we let jPCT create coordinates on the fly by using environment mapping. This is enabled in the third line of that code snippet.
The next step is pretty important, because it's something that has to be done to all object in jPCT: We have to build it, if we are ready to render it. Building an object does some internal work on the object like creating normals, calculating a bounding box, calculating a rotation pivot etc... Doing so, is pretty straight forward:
There's also an option in the Config-class to turn on automatic building of object, but i prefer it this way. Otherwise, building the objects on demand may cause stuttering.
Are we done now? No, not yet. We now have the world and the object, they just don't known from each other. But that's pretty easy, we simply make the world know our object by doing:
Please note that an object can only belong to one instance of World. If you want to use the same object in more than one World instance, you have to create a clone of it.
However, we are ready to render our object now...almost. Because we haven't done anything to move the object or ourselves around in the world, we both occupy the same space, i.e. we are located inside the object. This is perfectly fine from a technical point of view but it just doesn't look good. So we move the camera now. We don't have to create a camera ourselves, the world already brings one with it:
world.getCamera().setPosition(50, -50, -5); world.getCamera().lookAt(box.getTransformedCenter());
This code moves the camera 50 units to the right, 50 units up and 5 units out of the screen. This also shows another fact: In jPCT, the x-axis goes to the right, the positive z-axis goes INTO the screen and the negative y-axis goes UP. This isn't a very common setup, but it really doesn't matter...it's just something you have to know. To make our camera look at the object, we use the camera's lookAt-method.
Now we are ready to render that thing...