X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=assignment-1%2Freport.latex;fp=assignment-1%2Freport.latex;h=3193a7e306da9f61834cb9afff161fbd04293e5a;hp=0000000000000000000000000000000000000000;hb=150ba29f1ce70777762cb7fc44e00e52339bb66e;hpb=5fa27af6222eab1f43e6ca01f1c37cbfa1d86fcd diff --git a/assignment-1/report.latex b/assignment-1/report.latex new file mode 100644 index 0000000..3193a7e --- /dev/null +++ b/assignment-1/report.latex @@ -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}