Gif of Final Graphics Project

Overview

During my work at Staffordshire University, I was tasked with understanding the fundamentals of the fixed graphical pipeline using OpenGL to prepare for the programmable pipeline in Year Two. Throughout this project I learnt many techniques, Object Oriented Programming is an important concept to understand for this project to keep code manageable and readable, researching skills and problem-solving also helped when an issue was encountered, and good coding practice such as comments and naming standards allowed me to navigate and understand my code base quickly and efficiently.

This GIF shows the final piece I produced which is a complex 3D scene that can load .obj files and render them using lighting, materials, and textures, in the scene that they are rendered Text is also displayed and a depth buffer is used, and to ensure smooth animations double buffering has been implemented. The player can move around the scene using their keyboard to control the camera or turn the lighting off and on.

White REctangle in OpenGL

Getting Started

My experience in the OpenGL library was also my first implementation of a state machine, by defining a current state that is then kept until changed, this meant that if a colour was defined then everything would be that colour until redefined. These screenshots demonstrate the colour blending that happens when drawing a simple shape using the RGB colour model.

My first step was to create a shape in 2D space to understand the coordinate system, OpenGL sets the origin of the world (0,0) in the centre of the screen, this was a crucial first step as previous frameworks use the origin at the top left-hand corner of the screen.

First Rotation of Objects in OpenGL

Moving Forward

Using the skills learnt from the previous session to add new features to the program, this included creating a game loop allowing animations to be played, simulations to be run and players to interact with the program moving away from a static image on the screen.

Once the game loop was established rotation was added to one of the shapes created previously this led to multiple shapes rotating at the same time as shown in the gif.

Wireframe Cube

Adventures in 3D

After creating my first animation I noticed that the object movement was jittery and lacked the smoothness expected, to fix this I created a double buffer smoothing the frames.

However if the update gets increasingly complex then the program may face FPS problems due to the time it takes to run the update loop and then fire the next frame. To fix this elapsed time was used to ensure that the frames, whether late or early, fired in the same 16ms that the others have smoothing them out to the expected 60fps and adding a dynamically altering frame rate to the program.

Solid Rainbow Cube in OpenGL

Adventures in 3D Continued

I also explored multiple ways of creating a 3D cube, initially using a prebuilt wireframe version, then moving on to create my own using a few different methods starting with the basic plot of every vertex in 3D space for each triangle. However, this meant that there was some overlap and the vertices were plotted on top of each other taking up memory and causing potential issues later. To fix this rather than replotting vertices I reused them, along with the back face culling, resulting in the cube presented in the GIF.

To take this even further and more akin to the industry standard OOP practices using the file provided for us to practice with pulling the cube data in from a file and drawing the object that way.

Cube Field

Travering the Cube Field

Creating a single object that spins in space was a fun way to further my understanding of 3D Space but I wanted to take it further this led me to create an array of cubes that will be rendered in space using random positions, as seen in the gif. This was created to expand this to create multiple different objects in 3D space.

Textured Cube Field

Texturing

After creating a cube field I wanted to add more more depth to my objects by adding textures. Up until this point I had just been using solid colours or interpolated colours to give life to my cubes, however, in games textures are used to breathe life into boring objects. To add textures I created a class to read in values from a txt file to create a more modular program. Once the file was read in the values were assigned to the UV coordinates and imprinted on the cubes.

Cube Field

Lighting and Materials

Now that my objects had depth and textures I wanted to highlight both of these and make it easier for a user to see the different objects using lighting. However I did not stop there I wanted to give the user a way to turn the lights on or off, I did this using a simple method that checks if the light is on when the 'l' key is pushed and if so turns them off and vice versa.

To keep with the OOP standards I created a material library in its class that would be called by the object, I also wanted to implement a call that would change the material when the user pressed a key. This is where a major problem arose, while creating materials I accidentally put the material new call in the cube update loop, this meant that I was creating a new material to assign to every one of the cubes every frame but also creating it on the heap so it never went out of scope creating a major memory leak. After a few days of searching for this memory leak I turned to Google for help, this led me to tools that could help me and found that VS has a built-in way of seeing how many new objects are created, so after finding out that I had created a ridiculous number of materials this narrowed down the search enough for me to find the problem and solve it.

Final Product

Final Product

Finally, I created a scene graph to demonstrate an understanding of matrices I used this inherited relationship to rotate objects around another object. so rather than using a rotation and the object rotation around the object and then translating them into another area of space I translated the object first and then rotated around the object's origin point this allowed objects to orbit other objects. Once I was happy with this I downloaded some free-use textures and obj files to create an array of different objects to show my program is modular.

I am very proud of how this project turned out, as I was very overwhelmed when beginning but kept working at it and very happily walked away with a first.