+For each pixel position $(x,y)$ normalised relative to the bounding rectangle, if $x^2 + y^2 \leq 1$ then $(x,y)$ should be filled.
+
+Although $x$ and $y$ may be treated as integers on the CPU, since the OpenGL API requires floating point vertex coordinates, our CPU implementation also normalises the coordinates relative to the bounding rectangle; this way we can compare the performance of floating point operations on the CPU and GPU(s).
+
+\pagebreak
+\subsection{GLSL Fragment Shader}
+\begin{minted}{glsl}
+#version 140
+// Fragment shader (others omitted)
+
+in vec2 objcoords; // Coordinates x, y, relative to bounding rectangle (from other shaders)
+out vec4 output_colour;
+
+uniform vec4 colour;
+
+void main()
+{
+ if ((objcoords.x)*(objcoords.x) + (objcoords.y)*(objcoords.y) > 1.0)
+ {
+ discard;
+ }
+ output_colour = colour;
+}
+\end{minted}
+
+\subsection{CPU Rendering Algorithm (simplified)}
+\begin{minted}{c++}
+// where bounds = {x,y,w,h} gives the bounding rectangle in integer pixel positions
+// and centre = {x,y} is the centre of the circle
+// and pixels[][] is the display buffer
+for (int x = bounds.x; x < bounds.x+bounds.w; ++x)
+{
+ for (int y = bounds.y; y < bounds.y+bounds.h; ++y)
+ {
+ float dx = 2.0*(float)(x - centre.x)/(float)(bounds.w);
+ float dy = 2.0*(float)(y - centre.y)/(float)(bounds.h);
+ if (dx*dx + dy*dy <= 1.0)
+ {
+ pixels[x][y] = true;
+ }
+ }
+}
+\end{minted}
+
+Note: The \verb/pixels/ buffer is uploaded directly to the GPU after CPU rendering is completed.