Blogger Templates

Thursday, November 23, 2017


Graphics (12 of ∞) Time to go 0s and 1s

Posted in ,
EAE 6320-001

One of the problem we had with the previous setup of our project is the time it took for our application to start. Since I was relying on lot of lua based human readable mesh files, I need to load them in their existing format and parse them based on my need. This would take time for the game to get ready and in this writeup, I will walk you through my experience of getting that process fastened up.

0s and 1s
To fasten up things, I should give my system the readily available data so it don’t have to wait for any extraction. The way I achieved that was to move my mesh reading logic from my mesh.cpp to the MeshBuilder project. This way I would be able to read the lua content when the mesh is being built. Then all I have to do was to store the data in a meaningful format. The order I took was vertex count, index count, vertex data and index data. The reason why I need to start with the count is because I need to know how much I should offset the data to access each individual elements. This wouldn’t have been possible if our starting or the ending elements did not have that data. Having said that, I feel like either of vertex or index count could be at the initial offset of the file. As soon as I had my structure planned for the file and had the data ready to be stored, I started make file IO operations to write the binary data on the file. To debug/read the file contents, I used an external tool called the HXD which reads the binary data and shows equivalent hex values. This way I could easily decipher the binary data and understand where my original data pattern is.

The above is a reference for my plane mesh that is stored in binary and viewed using HXD. The following color pattern is used to identify each data type.
Green - Vertex Count ( 2 bytes )
Red - Index Count ( 2 bytes )
No color - Vertex Data ( 12 bytes for position, 8 bytes for UV, 4 bytes for color )
Blue - Index Data (12 bytes)

Another important thing to take account while writing this binary file is that the intent to do this is to give our graphics system the readily available data. To reach here, we need to overcome our platform based difference which are based on UV and winding order. An ideal way is to have our mesh builder build platform specific binary files that would format the data considering the platform based winding order and uv format.

Let the decipher begin
Pointer math is always fun and I was able to take advantage of some pointer math when I had to read the binary data back into the system. The mesh code where I had the lua based parsing earlier will now be replaced with extracting data from the binary file.

The above screenshot gives a basic idea of how I tracked down each individual data piece by moving through an offset based on the data type. I was able to debug this part in visual studio and confirm if the data I wrote and the data that is being read is correct.

As soon as I had the data ready, I passed it to the graphics system and was able to simulate my plane, cube, disc and the earth model. There was one difference where the runtime was almost instantaneous. This shows how much performance improvement the binary file gave over the human readable lua file. The reason why we have to use a binary format for runtime is because it allows a better load time for our game and that is mainly due to smaller file size and zero parsing requirement. And the reason we need to use a human readable file for our build is because, we need a more control on the data reading/modification as gameplay programmers. That way we will be less error prone while making changes to the data and be more optimized in run time which is for the actual end users.

Benchmark Tests
Comparison on the sizes of meshes and the time to process the data really wowed me and it made me think how important is to have these optimization in place. Here are some comparison that I did with the Earth mesh and the Car mesh.

Earth Mesh
Vertex count is 19307
Index count is 22827

Human readable Mesh file
Time taken to build : 0.30252s
Size : 6.82MB

Binary Mesh file
Time taken to run : 0.001273s
Size : 497KB

Car Mesh :
Vertex count is 5020
Index count is 8412

Human readable Mesh file
Time taken to build :  0.092652s
Size -  1.80 MB

Binary Mesh file
Time taken to run :  0.000859s
Size - 134KB

Comparing the above for binary file and human readable file, the binary file is a clear winner for runtime here in terms of smaller size and faster reading/processing time.

Checkout my awesome new meshes in the Screenshot/Gif below.

Cube Movement
Right Arrow - Move the 3D game object to the right.
Left Arrow - Move the 3D game object to the left.
Up Arrow - Move the 3D game object upwards.
Down Arrow - Move the 3D game object downwards.

Camera Movement
W - Forward Acceleration
S - Backward Acceleration
A - Rotate towards the left side
D - Rotate towards the right side
Q - Rotate Upwards
E - Rotate Downwards

Checkout the fancy elements via this release.