GL3DEngine v2.0 & GL3DLifeEngine

GL3DEngine Webpage


I can’t explain what I have done to improve the 3D engine, if I don’t explain what it was doing before the upgrade. I will spend a short paragraph explaining what GL3D Engine 1.0 does and then I will explain the upgrade I chose to implement.

I started programming this 3D engine trying to think big. I wanted this to be as close as I could to a professional 3D engine with room for improvement if I had the opportunity. OpenGL is “linear”, there is no concept of object. As far as OpenGL is concerned, there are no objects; it’s all a bunch of points linked together forming triangles. Any changes made at one point in the process of drawing triangles (such as setting the color of polygons) will affect all the following polygons (all polygons will have the color we set until we change the color again). So, using C++, I created an object oriented structure for each 3D Object. For instance: a GL3DLight, a GL3DCamera and a GL3DVAObject ARE_ALL GL3DObject using inheritance provided by C++.
In order to have a decent frame rate, we cannot afford to send every object in the world to the video card. This latter will choke crunching numbers. We must only draw objects that are in front of the camera. I implemented a quad tree in which I store the ID of each object depending on its x,z coordinate. (Note: In OpenGL, y is the height coordinate)
For every single frame, the program parses the tree and creates a linked list of object to be drawn.
Drawing realistic 3D object can take hours if we don’t use a tool such as 3D Studio Max. Computing manually the position of every point of simple cylinder would probably take at least 15 minutes. So I implemented a tool that converts ASE (ASCII Scene) into 3OB (3d OBjects) which is a file format I create for the 3D engine. I could have loaded ASE file straight into the 3D engine, but I wanted to have control over what is in the file and ASE is a text file which take much longer to load. Load time of text file would noticeably increase when you have many objects to load. 3OB is a binary file and therefore doesn’t take as long to read. So I can create an entire scene in 3DStudio Max, export it as an ASE file and convert it into 3OB file that I then load into the 3D engine each time it starts
Finally, I have a bitmap manager and a 3D structure manager so that if I have 10 cars that have the same 3D structure but different bitmap, I only store the vertices for the car once in the structure manager and draw it 10 times with a different texture. The same way, I can have different object with the same texture and the bitmap for that texture is stored only once in memory. This makes a major difference when you start having thousands of objects that are mostly similar.
The drawing below shows how the memory is organized between the different C++ classes. Arrays are represented as tables and pointers as arrows.


fig 1. GL3D Engine V1.0 Architecture

Well, this all sounds very nice, but you may ask, what did I improve that justifies turning it into a project for the Modern Game Design class?
In order to have this 3D engine plug into the Marinakis’ artificial life program, I had to make some major modifications and additions.
Here is the list of improvements up to this date:
• Object Templates
• Complex Objects
• Adding & removing object to/from the tree on the fly
• Transparency
• GL3DLifeEngine interface
• 2D User Interface
• Optimization
• Level of Detail
• Design the 3D Objects
• Vertex program

I will give a detailed description of each of these in the next section, but I will first make a quick overview.

Object Templates:
Object Template allows the user to have objects (3D Structure & texture) ready to use in memory but without any actual position. They cannot be draw to screen. It sound very similar to what the Texture manager and Structure manager does, but a template associate both a texture and a structure. Obviously, without the texture manager and the structure manager, I couldn’t have implemented a template system efficiently since the template uses both. A template object is like a class in C++. It is the blue print of an object.

Complex Objects
Complex object is a 3D object made out of many other objects. For example, an animal has a body and legs. Each object can be translated and rotated independently relative the complex object’s position and rotation.

Adding object to the quad tree on the fly
In version 1.0, all objects had to be in memory in order to build the quad tree. The id’s of objects where added to each node of the tree as the tree was built. Once the program started, no object could be added to the tree or removed from the tree. That implies implementing the necessary functions to add the ID of an object at the right location in the tree.

Transparency
Transparency is used to create some objects such as trees. A tree would have too many polygons if we wanted to create every leaf. One way to create a good looking tree and save on polygons is to map the texture of a tree with a transparent background. Transparent objects have to be drawn in a specific order. So this requires some ordering of the object being draw before actually drawing them.

GL3DLifeEngine Interface
The GL3DLifeEngine is a class inherited from GL3DScene. It has a set of functions that Marinakis’ program requires in order to add, remove and draw objects in the 3D world.

2D User Interface
A program without a user interface is useless. So I created a full set of classes for user interface including text display, menu, window and button.

Optimization
Much optimization was needed and still is needed. Some functions may take more CPU time than needed which slows down the whole process. As I mentioned earlier, in a real time 3D program, speed is very important. Any program displaying 3D graphic need to draw at least 15 frames per second or no one will be interested in using it.

Level of Detail
Level of detail is used to improve performance. Basically, each 3D object will have a very detailed 3d structure when they are close to the camera, a less detail version of the object if the object is a little further from the camera, and if the object is at the horizon, it has only one triangle with an image of the object textured onto it. Far objects are basically billboards. It doesn’t make sense to have a very detailed object at the horizon. The user cannot see the details but the graphic card will still compute every point, every line, every triangle and texture onto those triangles as if the object was close to the camera.

3D Objects
Finally, the 3D engine is very nice but useless if we don’t have any 3D object to load into it. So I created 3 types of animals (Spiders, LadyBugs and Ants), 3 types of plants (Weed, Algae and SunPlants), 3 types of rocks and a tree.
And for each of these objects, I created up to 3 different levels of detail and for each level of detail of each animals and plants, I created 3 sizes since the animals and the plants can grow.

Vertex Program
Vertex program is used to modify the vertices by the graphic card. In this program, I use vertex programming to make the plant move as if it was a windy day. This could be done without vertex program but the program would be very slow; I would expect the frame rate to drop under 5 FPS. There are sometimes hundreds of plants being drawn on the screen at the same time. The vertex program run on each plant and modify the x,z coordinate of the vertices.
The graphic processor is modifying those points which allow having good looking effects without asking too much to the main CPU of the computer.

As I showed the memory organization of GL3DEngine v1.0, I show on the graph below the memory organization in the new version of the 3D engine.


fig 2. GL3D Engine V2.0 Architecture

I should also mention how Marinakis’ program is going to plug in with my program. And the best way of doing that is with a diagram


fig 3. Organization of the different modules

The whole logic of where object should be, where they should go, collision detection, AI of the animals is all done by Marinakis’ program ALIFE. I have no concept of collision and the program will happily draw 2 objects at the same location if ALIFE program asks me too. GL3DLifeEngine is only a 3D graphical interface.

Credits

FREE TYPE:
In order to write text to the screen within the program, I am using GNU FreeType. They have done an excellent job of display smooth looking text based on TTF fonts.

Thanks

NEHE on Gamedev.net:
I have learned most of the basics and some of the advanced feature of OpenGL on NeHe. The author of this site has a large collection of OpenGL tutorial that are very well written.

Gamedev.net:
And of course, I have to mention the forum of gamedev.net where I got excellent help every time I was stuck with a problem writting the 3D Engine.

Links