Tile World 3 is a game/demo I have made using Java and LWJGL (3.0 beta version). Light weight Java Game Library acts just as a bridge between Java and OpenGL. the library itself does not provide any other functionality that what is already available in OpenGL. This did mean that I had to program everything in the demo myself, and this made Tile World 3 a very interesting and very educational project.
The Demo itself consists of a 3D world built of ground tiles with different heights and properties. The world also contains some trees. The user controls a first person camera, and can explore the world by walking, running, swimming, jumping and sneaking using the mouse and keyboard or a XBox360 controller or similar.
Go to the Tile World 3 download page to try the game/demo yourself.
Java and Games
Java programs run slower than for example C++ programs do to the fact that they run on the “Java Virtual Machine” and not directly on the computer itself. This make Java not ideal for game programming. To only reason I use Java instead of C++ is that Java is the programming language I am most comfortable with.
The idea with LWJGL is make the GPU do as much of the work as possible, and at the same tile limit the number of calls to the GPU as mush as possible since the connection between the Java program and the GPU is relativly slow. This way this game/demo will probably run fine anyway. Minecraft is a well known game and a great example of using Java and (an older verson of) LWJGL to render 3D graphics, and still have decent performance.
Modern OpenGL and GLSL shaders
The demo now uses modern OpenGL (ver 3.3) with GLSL shaders. When I started this project I used old “Legacy OpenGL”. It is easier to get started with the legacy code and rendering something but the performance is bad and it is awkward to work with when the programs become larger. I did also experience a lot of problems that my program simply wold not run on some types of GPUs or systems. This was probably because I started to mix in some “modern” OpenGL stuff while still keeping some old “legacy” functions in the code.
After version 8 of the demo (tw3v8) it uses only modern OpenGL and should run fine on NVIDIA, AMD and Intel GPUs.
The use of shaders also allows for a lot more flexibility than what is possible with old “Legacy OpenGL”. For example. I use “fog” in my fragment shader with a dencity that is dependent on the radial distance from the player to the fragment. For now I use a simple shading model that is based of ambient light and diffuse reflections from a directinal light representing the sun, but this lighting model can easily be improved. All animations is the demo, for example water waves, or the trees blowing in the wind, are done by displacements in the frgmentshader, directly on the GPU. This helps performance a lot since math functions as sin and cos are not very fast in Java.
3D collision engine
To handle collisions is the game a have written a simple “collision engine”. It is based on boxes around all objects. The boxes can have different sizes depending on the type of objects, but the boxes can not rotate with the objects, this makes calculations simple.
When for example the player moves, the program checks all boxes for the objects (both ground tiles and entities, such as trees) within a small radius. If the player will intersect with any rectangle after the move, the move is not allowed. The collision check is done independently on each axis to allow for “sliding” against walls etc. while walking.
The demo uses a tile map, it is not a voxel world as it may seem like at first glance. The world is loaded and built using an image where every pixel is a tile and the color of the pixel describes the type of tile in that location. Different tiles can have different heights and textures, but all tiles of a certain type will have the same height. The size of the map is currently 512 by 512 tiles, but it can easily be increased by simply loading a bigger tile map image.
To improve performance while rendering the map is divided up in “chunks” with the size of 16×16 tiles. a VBO (vertex buffer object) containing vertex positions, vertex normals, and texture coordinates, is generated for each chunk the first time it is rendered.
To import stuff to the game and not relying on coding the position of every single vertex, a have written my of “importer” for OBJ-files. OBJ-files are a simple standard format for saving 3D models in a text file. The text file contains information about vertex positions, vertex normals and texture coordinates. Since OBJ is a standard format it is possible to easily export models from 3D modeling programs such as 3DS MAX as I use, and import them directly the the game. The downside to this is that the OBJ-format does not support any animations or moments. Also in my application, every single OBJ-model that is used in the game needs to have a single associated texture image. one model can not have multiple textures for efferent parts.
The trees and the “collectables” (torus knots) in the game are imported OBJ-models. The “skybox” used in the game are also an imported model with the associated texture. The skybox is actually a cylinder with a flat top in this case, but is can easily be swapped out for another model if needed.
Planned future features
- Improve the shading model and make new textures to make the game look better.
- Try to implement shadow mapping to simulate shadows from the sun, render the sun.
- Program a selection system to allow the player so select thing with a cross hair on the center of the screen or similar. This opens up a lot of possibilities to ad some game play/goal to the game later.
- Add sound and music to the game.
- Add some sort of enemies or AI creatures to the world.
- Make a start menu for the game.
I will update this page when I have changed stuff or added more functionality to the game, so check back regularly if you are interested!
Videos of older versions
first person, using old legacy OpenGL. All animations are done in the java-code. The performance was a big problem, therefore the tiny render distance. Here all tiles are rendered separately, not divided into “chunks” like i did later.
one of the first working versions, using old legacy OpenGL. All animations are done in the java-code, and only the tiles visible are rendered, still large performance problems.