University Project - OpenGL Adventure

A Graphical Programming learning experience - utilizing OpenGL and FreeGLUT to start understanding the basics of Graphical Programming.

Demonstration Video


Background

This Project expands on the initial work done in the S2D Framework Project by introducing us to what happens under the hood, as the S2D Framework is a 2D OpenGL Framework.

Initially we were given the task of drawing a shape onto the screen manually, using screen-space coordinates, by manually creating vertices and converting them into a polygon through OpenGL's functions.

After this, I started to create Classes that can store Object data, such as Transform, which contains two Vector3s, of which describe Position and Rotation.
Once this was completed I wrote a 2D N-gon generator and gave the data from this into Object Classes - which formed the basis of future work with 3D models and loading in from .obj files.
Next for this was a Parent-Child relationship, which required researching how OpenGL handles its matrices internally. The solution for this was Popping and Pushing matrices in order of how they would be seen in something like Unity's Scene Viewer.
You Pop the Parent's matrix, so the parent's transformations, then you Pop any children's matrices and calculate the transformations and one the way back up you Push them back.
This is a recursive process and as such I wrote recursive function to handle this.

Texturing and Object Loading

The next few things I worked on were pretty simple:
  • Converting the Camera to use Perspective instead of Orthographic views.
  • Use OpenGL Callbacks to get Keyboard data and write a Class to deal with the data separately.
  • Convert the Scene Graph to use LinkedLists instead of std::vectors - which improves memory efficiency as vectors may or may not free memory until it goes out of scope.
  • Allow the Screen to be resized without stretching the Viewport.
  • Converting to all Objects to use std::shared_ptrs so that Heap data is managed for me through Smart Pointers.
After those, the next two big things were loading 3D Objects from .obj files and Textures from .tga files.
The format of .obj files is readable in UTF-8 so understanding what each line of data does becomes somewhat simpler.
Each line of an .obj file starts with a 'token' that describes what the data on the line does. For example v 0.4 0.1 1.0 describes a Vertex and its position relative to the centre of the object in 3D coordinates.
Reading the data in was as simple as grabbing the 'token' and then an if statement to determine what the token does.

Texture files (.tga) on the other hand are not readable in UTF-8, however they are simply image files with a header with data.
The header is 18 bytes and describes the image file, such as its Width, Height and Bit-Depth - of which some of the data needs to be used by OpenGL to determine if:
  1. The image is uncompressed
  2. The image follows either RGB or RGBA formats
Once these checks pass, the rest of the data in the .tga file is the raw colour data, which can be read directly into an array and given to OpenGL to generate textures internally.
After texturing was complete, I started work on lighting and materials - even if in the OpenGL fixed pipeline it's simple.

Materials and Lighting

The Material contains 4 values, 3 float4s for Ambient, Specular and Diffuse and also a float for Shininess.
Using these Materials in the rendering is made very simple by using glMaterialfv() and glMaterialf().
Lights are simple in fixed pipeline OpenGL too, they need the same 3 float4s. Then using glLightfv() you light the scene that frame.

Text

Text functions similarly to a regular GameObject, as such the Text class derives from GameObject.
All is needed for the functionality is a std::string, Transform and Vector3 of colour.

Due to how the SceneGraph works, the Text would be Sliced, if it was not a pointer - this is because of how C++ handles memory. If it was declared on the stack, the memory allocated would be exactly for the base type, and not the derived class - thus losing data.