Monday, April 30, 2007

Bitter Sweet Success

Having quickly modified Decade, to store saved/generated terrains using floating point values rather than unsigned chars, I am happy and disappointed with the result.


As you can see above the smoother gradient makes the terrain looks allot more natural. It has been commented that the staired terrain looks cool, like contour farming, and perhaps it does in unique circumstances but it will not work for the terrain in general. Despite this success the loading/saving time and file size has been affected even more than predicted. Huge Height Map files and long loading times are not acceptable.

Some more research needs to be done for terrain storing and loading. Different possibilities which instantly come to mind which may or may not work are

  • Split the terrain over many files and load the segments coming into view on another thread
  • Store the terrain in the original .raw file and use some logic to smooth the vertices's

If a man owns land, the land owns him - Ralph Waldo Emerson

Just back from a weekend break in London so I did not program for the past few days. Coming home yesterday we were delayed in the train station for 7 hours so while sitting around I had plenty of time to think about what I wanted to achieve with the terrain segment of the Decade Engine. Here are some improvements. (I know I said in my last post that I was just going to add Vertex Arrays and VBO's but after some consideration I believe that the following additions are also required.)

1) Change from using a .raw file to using my own custom format. The .raw file used 1 byte for each value. This limits the range of values from 0 to 255 and only whole numbers are included. I didn't notice any issue with this when I was rendering small terrains (up to 512x512) however now that much larger terrains are being rendered 8192x8192 (134,217,728 faces) a very undesirable stair case effect is emerging. Take a look at the attached screenshots. As the values of the terrain are rounded the terrain grows in increments making it look unnatural. I am going to create my own file format which will use floats instead of unsigned chars. This has the advantage of being correctly able represent the terrain however will result in a larger file size and a longer read/write time for the file. I believe the advantage greatly outweighs the problems.

Stepped Terrain caused by .raw file data storage

2) Now that larger terrains are being rendered some more intelligent culling of patches is required. Simply checking if each patch is visible to the camera (by checking collision with the viewing frustum) is not enough. The mentioned 8192x8192 terrain segment is made up of 232,324 patches. With the current implementation this results in 232,324 frustum checks per frame. By adding a simple node tree most of these checks can be bypassed.

A node tree is a method of subdividing the mesh (terrain in this instance) into smaller sections. For instance, with the terrain I would divide it horizontally and vertically through the centre resulting in 4 segments, top right, top left, bottom right and bottom left. These segments would then be recursively divided until the required tree depth is reached. When doing frustum checks the terrain algorithm would first check collision with the node tree. If the Top Right Segment (or any other segment) was not visible by the frustum all of its children could immediately be ignored as not visible. If the Tree Node is visible by the frustum each of its children would be checked etc..etc... I expect that this will give a huge performance increase when used with large terrains for both geomipmapped and brute force terrains.

Stepped Terrain caused by .raw file data storage

3) Add support for Vertex Arrays and VBO's in geomipmapped terrains.

Friday, April 27, 2007

Patch Culling

Brute Force Terrain. 32258 Polygons Rendered

As a further addition to the Geomipmapped terrain I have added Patch Culling.

In my original implementation of Geomipmapping the distance from the camera to the terrain patch was calculated and from this the level of detail deciphered. If you remember your maths from school you will know that getting the distance between two points always returns a number which is greater than or equal to zero. Because of this no spatial relation between the objects is known so we still rendered patches which were out of view of the camera, although at its correct Level of Detail.


Geomipmapping with no Patch Culling. 5757 Polygons Rendered

With Patch Culling we simply check if the current patch is inside the Fustrum of the Camera. A fustrum is like a pyramid on its side, the pointy part at the lens of the camera extending out into the world. By doing some simple plane tests we can quickly and easily see if a point is inside this pyramid and therefore immediately ignore it if it is not. This does not only help us ignore faces to render, but we can also ignore patches to update so is useful for the GPU and the CPU.


Geomipmapping with Patch Culling. 2192 Polygons Rendered

The final addition to my Geomipmapped Terrain (for now) is to add support for Vertex Arrays and VBO's. I hope that this will increase the fps but it will also keep the render code separate from the terrain code therefore keep me on track for an engine which should be easier to update to DX.

Tuesday, April 24, 2007

Geomipmapping

Geomipmapping my first implementation of a CLOD algorithm, is working in its most basic form. The images below show the different outputs from the algorithms. To render a segment of terrain which is 128x128 Brute Force renders 32510 faces while Geomipmapping only has to render 1240 in this instance (this varies depending on camera position).

Brute Force and Geomipmapped Terrains Rendered in Wire Frame

Brute Force and Geomipmapped Terrains. (Very little visual difference)

Even at this stage I am happy with the frame rate increase. In the images shown you can see that Geomipmapping achieves 72fps whereas Brute Force gets 67.7fps. This may not seem like much of an increase but please remember how the Brute Force vertices are stored and rendered. VBO (Vertex Buffer Objects) are used therefore the vertices are stored and rendered by the Graphics Card. My Geomipmapping implementation currently renders all faces with individual software calls. If I do the same for Brute Force for the selected terrain its fps drops to about 54.


By implementing Vertex Arrays or VBO's for Geomipmapping, which is also maintain my desire of keeping the algorithms and graphics API calls separate, I expect to see a frame increase. Also by adding Frustum Culling on each of the terrain patches in the Geo terrain I can further reduce the number of vertices to be rendered.

Sunday, April 22, 2007

Memory feeds imagination - Amy Tan

Problems with Vertex and Index buffers are fixed. It took a long round-about way to get there. To isolate the issue I created a software renderer for the Vertex and Index Buffers. This involved parsing the vertex and index data during the render loop and using individual glTexCoord2f, glVertex3 etc... calls to render each face. This immediately showed that the vertex data was correct however the index data was only half populated.

ASE Mesh incorrectly rendered with Index Buffers

Terain Segment incorrectly rendered with Index Buffers


e.g. In a terrain segment of of 8x8 there are 64 vertices, 128 faces and 384 indices. During the software rendering of the vertex and index buffers Decade engine crashed when the offset into the index buffer reached 147. It caused incorrect rendering or an Access violation because the value of the index buffer was 52685, but the vertex array has only 384 elements. Further investigation showed this to be an error with the memory copy functionality in the index buffer create function.

Instead of
memcpy( this->m_pusIndices, p_pusIndices, p_iNumberOfIndices );
it should have been
memcpy( this->m_pusIndices, p_pusIndices, p_iNumberOfIndices * sizeof(unsigned short) );


Problem fixed.

Tuesday, April 17, 2007

Fontastic

After some research and help from the good people at GameDev I have found out there there is in fact no problem with the Vertex Arrays or VBO's. The problem lies in the Font Object.

A few days ago I wanted to show the Camera Position and Rotation so I quickly followed a Font Tutorial in order to display this info on screen. I didn't really pay attention to what I was doing as I planned on rewriting this anyway so I fell victim to Copy and Paste.

Upon review I found that the font class used switches from 3D to 2D mode every time a string is rendered, so when I was rendering 6 lines of text this involved 6 Switches to 2D and 6 Switches back to 3D. When I changed this so that it switches to 2D, renders all text and then switches back to 3D I did find some improvements.

Running on a lower end system

Os : Windows XP Pro SP 2
CPU : Intel(R) Pentium 4 3.00GHz
GPU : Intel(R) 82915G/GV/910GL Express Chipset Family (Driver Version 6.14.10.4410)
Ram : 1GB

I get the following results

107fps when rendering in a nested Loop.
128fps when rendering using Vertex Arrays.
130fps when rendering using VBO.

I will now add in Index Buffers and see what results I get, as well as running on my home computer which has a good graphics card.

Monday, April 16, 2007

Vertex Buffer Objects and still no JOY

Yesterday I implemented Vertex Buffer Objects (VBO's) into Decade Engine. Although I am still very happy with the code and the future portability to DX, I am again disappointed with the performance results. There is limited increase in frame rate compared to software rendering and no increase compared to Vertex Arrays.

For those interested in a more in depth description as well as any possible fixes, you can check out here.

Saturday, April 14, 2007

Vertex Arrays

Vertex and Index Arrays have been added to the Decade Engine. The Brute Force Terrain is now rendered using a Vertex Array as a Triangle Strip.

Previously the Terrain was rendered in a nested loop, rendering X Triangle Strips, where X is the length of the terrain. Now when the terrain is created/loaded 1 Triangle Strip is created and loaded into a Vertex Array. At render time I simply ask OpenGL to render this Vertex Array. Sample source for Vertex Arrays can be found at here

Sadly this did not give me the frame rate increase I was hoping for. I will have to investigate if there is a reason for this, and I will also implement Vertex Buffer Objects. Despite the disappointing results the code is now allot more readable, allot more maintainable and the Terrain Object is API independent. I will easily be able reuse the Object as-is when I code my DirectX version of Decade. (if only things were ever that easy)



Many areas of the engine are still in development
  • CLOD Terrain Renders
  • Terrain Texture Generation
  • Terrain Lighting
  • Applying Vertex and Index Buffers to Mesh Renders

Tuesday, April 10, 2007

Terrain with Texture and Detail Map

The issue with the Terrain Texture has been fixed, or at least bypassed for now. I have stopped using IPicture to load my textures and have written code to load the different file types. Currently TGA and BMP are supported. the jpeg lib file causes errors as it was built in VS 2003 and I am using 2005. This can be reviewed later.

As well as fixing the terrain texturing I have added detail mapping. This uses multi texturing to tile another "detail" texture over the terrain. I was quiet surprised to see what a huge difference such a simple technique could make to the realism of the terrain.


Terrain without Detail Map
Terrain with Detail Map

Saturday, April 07, 2007

Terrain Engine

Development today focused on Terrain Rendering. Decade can now load a terrain from a .raw file and can also generate terrain using the Fault Formation and Mid Point Displacement Algorithms.



Terrain is rendered using Brute Force. This means that all the the vertices are rendered regardless of how far they are from the camera. On a small terrain like this that doesn't really matter however when the terrain grows larger it would slow then rendering to render all vertices in this way. ROAM and CLOD will be added soon.


I also tried to add a texture to the terrain however there seems to be some problem. The texture is not complete even though the texture vertices appear to be correct. I am using the IPicture interface to load the textures so maybe there is a problem with this. Tomorrow I will try and manually load the textures and see if this fixes the problem.


Thursday, April 05, 2007

My First Entry

My very first blog and my very first entry. I never thought I would be a blogger. I find the whole idea strange and didn't think I would have anything worth the bother of blogging, however after being very impressed by a development blog of a friend of mine I thought that a similar idea would be a good motivation and diary for my personal project.

The Decade Engine is my new OpenGL graphics engine with which I hope to create 3D games. It is so called because this year it has been 10 years since I first started programming, and with a personal project like this I wouldn't be surprised if it took 10 years to finish.

I hope to use this blog to publish regular updated on the development and features of the engine and then details on the subsequent games made with Decade.

It starts. (Timon : The Lion King)

First Images

ASE and 3DS models with Alpha Blending and Bounding Spheres


ASE and 3DS models with Alpha Blending and Bounding Rects

Here are the first images from the Decade Engine. Nothing impressive to see as they are just tech demo's for my testing purposes. Current features of the engine are

  • ASE Model Loading
  • 3DS Model Loading (with animations)
  • MD2 Model Loading (with animations)
  • MD3 Model Loading (with animations)
  • Camera with Fustrum Culling
  • Object Hierarchy
  • Alpha Blending and Color Keying
  • Bounding Rect and Bounding Sphere

In progress

  • Terrain Rendering with Level of Details
  • Integration of the Open Dynamics Engine (http://www.ode.org/)
  • Scriptable Particle System