Getting Started


Requirements

You will need to install the following software:

Project Submission


Submitting your assignment

Submitting your artifact

OpenGL


What is OpenGL?

OpenGL sits between the graphics hardware and the application, providing a standard, cross-platform API for hardware accelerated rendering. There are a few other popular rendering technologies, such as Microsoft’s DirectX, Apple’s Metal, and the more recent Vulkan. But we will be using OpenGL because it is supported on Windows, Mac, and Linux.

In the first project, you will be writing OpenGL code that draws primitives like triangles and lines to emulate brush strokes. In the second project, you will be writing OpenGL shaders that affect describe how the GPU colors your 3d scene and models. At any time, you are free to explore OpenGL on your own and go above and beyond to extend the program to suit your own needs.

How does it work?

Graphics hardware used to be very specific and non-flexible, a fixed function pipeline that output pixels to the screen. But these days, many stages of this pipeline are programmable (shaders) and we can even perform arbitrary massively parallel computations on the GPU.

OpenGL operates like a state machine with global variables. When something is changed, it stays changed until something else changes it again. All the state associated with an instance of OpenGL is stored in an OpenGL Context. However, while the OpenGL API is defined as a standard, the creation of an OpenGL Context is not. Every operating system does it differently, so we want to use a windowing toolkit like Qt or FLTK that handles cross-platform context creation automatically, as well as provide a GUI framework.

Since there is no single implementation of OpenGL, graphics hardware vendors need to supply their own implementation of OpenGL with the graphics drivers, necessitating the step of loading OpenGL functions dynamically. It would be an enormous pain to do this by hand, so instead loading libraries are used such as GLEW.

Graphics hardware does not understand higher level primitives such as circles and rectangles. It only understands how to draw things like points, lines, and triangles. A 3d sphere drawn on the GPU is actually a whole bunch of triangles that approximate a sphere. Each primitive has one (point), two (line), or three (triangle) vertices that you can attach any data you would like, such as a 3d position, or intrinsic color.

Specifics

The set of all data and data types belonging to a vertex is defined as the Vertex Format. The vertices of these basic primitives are stored in something called a Vertex Buffer, which is really just a GPU allocated piece of memory. You can store all the data for each vertex in separate vertex buffers, for example: one vertex buffer for 3d positions, another for intrinsic colors. Or you can store it interleaved in one giant vertex buffer. Everything required to render a specific set of primitives is saved in a Vertex Array Object.

A lot of OpenGL functions operate on the notion of a global “current” something that is “bound.” For instance, there is a global GL_ARRAY_BUFFER variable which must have a Vertex Buffer bound to it before you can do anything with the GL_ARRAY_BUFFER like upload data to it.

OpenGL manages its own memory. OpenGL objects are represented by unique integers. There are a whole slew of glGenX functions that basically request for a GPU resource to be allocated and you are given its ID in return. However you must also remember to ask OpenGL to delete those resources when they are not used anymore.

Resources

If you would like to know more about OpenGL and how it works, you can read a lot more about it on the Khronos OpenGL Wiki.

We provide most of the boilerplate OpenGL code required to run the program because we believe that would take too long and would not be a very good use of time. We would rather that time be spent towards learning higher level graphics concepts and trying out cool bells and whistles. If you would like to learn more about OpenGL, this website goes through how to start drawing things from scratch.

C++ Resources


Unity Resources


Full documentation can be found here, but below is a brief overview of the most common Unity structures.

GameObjects

A GameObject is something that can be placed in the world. You can create a GameObject by right-clicking in the Hierarchy on the left, and choosing any of the options. Selecting the object will open the Inspector on the right. You can edit the GameObject's properties here. A GameObject can have attachments called a Component. A Component can add behavior to the GameObject, such as being a 3D model or a light source. You can also create your own Component through the using of Unity's Scripting API.

To add a Component, click on the object either in the Scene view or in the Hierarchy tab on the left. Then, under the Insepector view on the right, click Add Component at the bottom of the inspector (you may have to scroll down). A list will pop up and you can search for what you want to add. If you create scripts, they will show up here so you can add them to the GameObject.

Scripts

You may make a script by going to the Project view in the bottom and navigating to Assets. Then right click and do Create -> C# Script. If you have installed Visual Studio, double clicking on the script will open it there. By default, the script is populated with two methods, Start() and Update(). Start() is called once to initialize the script and Update() is called on each frame. Inside your scripts, you can use the Debug.Log() function to output data to Unity's console. By default, this is found as a tab titled Console near the Project area. You can also set breakpoints in your scripts in Visual Studio. These breakpoints will only be triggered if you use Attach to Unity or Attach to Unity and Play inside Visual Studio.

Your script extends the MonoBehaviour class, for which the documentation can be found here. It has various methods that you may override, each of which have slightly different behavior. You will mostly likely only need to use Start(), Update(), and FixedUpdate().

Declaring public qualified fields in your script allows you to control the behavior of the script from within the Unity editor itself. This is important when you want to reference another GameObject within your scene. For instance, the below script will result in the view in the Inspector for the GameObject which has the script attached:

You can drag a GameObject from the Hierarchy into the field in the Unity editor to set the field in the C# script. You can retrieve a specific component within a GameObject by calling the method GetComponent<ComponentType>() on a GameObject.

C# Resources


C# is a language most similar to Java, supporting garbage collection. Unity uses it as its scripting language. You will not need to have an extensive knowledge of it as you will be using Unity's own library functions.

Having a good knowledge of Java or C++ will suffice to be able to write C# code, but if you are struggling, there are resources below that may be of help.

Additional Resources