Add assignment 2 report
[opengl.git] / assignment-1 / report.latex
diff --git a/assignment-1/report.latex b/assignment-1/report.latex
new file mode 100644 (file)
index 0000000..3193a7e
--- /dev/null
@@ -0,0 +1,203 @@
+\documentclass{article}
+\usepackage{fullpage}
+\usepackage{listings}
+\usepackage{graphicx}
+\begin{document}
+
+\author{Luke Lau}
+\title{CS4052 Assignment 1}
+\maketitle
+
+\lstset{basicstyle=\ttfamily}
+
+\section{Fragment shader colours}
+In order to get the fragment shader to use the position as the colour,
+I had to add an input \texttt{vec4} for the \texttt{vec4 color} that the vertex shader
+outputted. Since the inputs to the fragment shader are from the vertex shader, I had to
+use \texttt{color} and not \texttt{vColor}.
+\lstinputlisting[language=C++]{fragment.glsl}
+\begin{center}
+       \includegraphics[width=0.8\textwidth]{part1}
+\end{center}
+
+
+\section{Two triangles}
+
+Two add two triangles, I had to increase the number of vertices drawn to 6
+
+\begin{lstlisting}[language=C++]
+glDrawArrays(GL_TRIANGLES, 0, 6);
+\end{lstlisting}
+
+And add 9 new coordinates and colours for them.
+
+\begin{lstlisting}[language=C++]
+GLfloat vertices[] = {
+       0.0f, -1.0f, 0.0f,
+       1.0f, -1.0f, 0.0f,
+       0.5f, 1.0f, 0.0f,
+       -1.0f, -1.0f, 0.0f,
+       0.0f, -1.0f, 0.0f,
+       -0.5f, 1.0f, 0.0f
+}
+GLfloat colors[] = {
+       0, 1, 0, 1,
+       1, 0, 0, 1,
+       0, 0, 1, 1,
+       0, 1, 0, 1,
+       1, 0, 0, 1,
+       0, 0, 1, 1              
+};
+\end{lstlisting}
+
+\begin{center}
+       \includegraphics[width=0.8\textwidth]{part2}
+\end{center}
+
+
+\section{Two triangles, two VAOs and two VBOs}
+
+In order to use two VAOs and two VBOs, I had to combine the VAO setup and the VBO setup
+into one function, since you need to bind the VBO at the time that you create the 
+corresponding VAO.
+
+\begin{lstlisting}[language=C++]
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
+
+       GLfloat colors[] = {
+               0, 1, 0, 1,
+               1, 0, 0, 1,
+               0, 0, 1, 1
+       };
+
+       GLuint numVerts = 3;
+
+       GLuint vbo;
+       glGenBuffers(1, &vbo);
+
+       GLuint vao;
+       glGenVertexArrays(1, &vao);
+
+       GLuint posId = glGetAttribLocation(progId, "vPosition");
+       GLuint colorId = glGetAttribLocation(progId, "vColor");
+
+       GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
+       GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
+
+       glBindBuffer(GL_ARRAY_BUFFER, vbo);
+       glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
+
+       glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
+       glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
+       
+       glBindVertexArray(vao);
+
+       glEnableVertexAttribArray(posId);
+       glEnableVertexAttribArray(colorId);
+       
+       glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
+       glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
+
+       return vao;
+}
+\end{lstlisting}
+
+This could then be used like so:
+\begin{lstlisting}[language=C++]
+GLfloat vertices[2][9] = {
+       {
+               0.0f, -1.0f, 0.0f,
+               1.0f, -1.0f, 0.0f,
+               0.5f, 1.0f, 0.0f
+       },
+
+       {
+               -1.0f, -1.0f, 0.0f,
+               0.0f, -1.0f, 0.0f,
+               -0.5f, 1.0f, 0.0f
+       }
+};
+GLuint* vaos = new GLuint[2];
+vaos[0] = setupBuffers(vertices[0], progId);
+vaos[1] = setupBuffers(vertices[1], progId);
+\end{lstlisting}
+
+When drawing, the VAOs needed to be switched out:
+
+\begin{lstlisting}[language=C++]
+void display() {
+       glClear(GL_COLOR_BUFFER_BIT);
+       for (int i = 0; i < 2; i++) {
+               glBindVertexArray(vaos[i]);
+               glDrawArrays(GL_TRIANGLES, 0, 3);
+       }
+       glutSwapBuffers();
+}
+\end{lstlisting}
+
+\section{Two separate shaders}
+
+I modified the \texttt{compileShaders} function to load in the shader source from a file:
+\begin{lstlisting}[language=C++]
+GLuint compileShaders(char* vertexShader, char* fragmentShader) {
+       GLuint progId = glCreateProgram();
+
+       attachShader(progId, vertexShader, GL_VERTEX_SHADER);
+       attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
+
+       glLinkProgram(progId);
+       GLint success = 0;
+       glGetProgramiv(progId, GL_LINK_STATUS, &success);
+       if (!success) {
+               GLchar log[1024];
+               glGetProgramInfoLog(progId, sizeof(log), NULL, log);
+               fprintf(stderr, "error linking: %s\n", log);
+               exit(1);
+       }
+
+       return progId;
+}
+\end{lstlisting}
+
+Which meant I could easily swap out the programs used when setting up the buffers:
+
+\begin{lstlisting}[language=C++]
+progIds = new GLuint[2];
+
+GLuint progId1 = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
+vaos[0] = setupBuffers(vertices[0], progId1);
+progIds[0] = progId1;
+validateProgram(progId1);
+
+GLuint progId2 = compileShaders((char*)"vertex.glsl", (char*)"yellow.glsl");
+vaos[1] = setupBuffers(vertices[1], progId2);
+progIds[1] = progId2;
+validateProgram(progId2);
+\end{lstlisting}
+
+The new yellow shader looked like this:
+
+\lstinputlisting[language=C++]{yellow.glsl}
+
+I needed to switch programs during the display function:
+
+\begin{lstlisting}[language=C++]
+void display() {
+       glClear(GL_COLOR_BUFFER_BIT);
+       for (int i = 0; i < 2; i++) {
+               glUseProgram(progIds[i]);
+               glBindVertexArray(vaos[i]);
+               glDrawArrays(GL_TRIANGLES, 0, 3);
+       }
+       glutSwapBuffers();
+}
+\end{lstlisting}
+
+\begin{center}
+       \includegraphics[width=0.8\textwidth]{part4}
+\end{center}
+
+
+\end{document}