Fix on Mojave
[opengl.git] / report.latex
1 \documentclass{article}
2 \usepackage{fullpage}
3 \usepackage{listings}
4 \usepackage{graphicx}
5 \begin{document}
6
7 \author{Luke Lau}
8 \title{CS4052 Assignment 1}
9 \maketitle
10
11 \lstset{basicstyle=\ttfamily}
12
13 \section{Fragment shader colours}
14 In order to get the fragment shader to use the position as the colour,
15 I had to add an input \texttt{vec4} for the \texttt{vec4 color} that the vertex shader
16 outputted. Since the inputs to the fragment shader are from the vertex shader, I had to
17 use \texttt{color} and not \texttt{vColor}.
18 \lstinputlisting[language=C++]{fragment.glsl}
19 \begin{center}
20         \includegraphics[width=0.8\textwidth]{part1}
21 \end{center}
22
23
24 \section{Two triangles}
25
26 Two add two triangles, I had to increase the number of vertices drawn to 6
27
28 \begin{lstlisting}[language=C++]
29 glDrawArrays(GL_TRIANGLES, 0, 6);
30 \end{lstlisting}
31
32 And add 9 new coordinates and colours for them.
33
34 \begin{lstlisting}[language=C++]
35 GLfloat vertices[] = {
36         0.0f, -1.0f, 0.0f,
37         1.0f, -1.0f, 0.0f,
38         0.5f, 1.0f, 0.0f,
39         -1.0f, -1.0f, 0.0f,
40         0.0f, -1.0f, 0.0f,
41         -0.5f, 1.0f, 0.0f
42 }
43 GLfloat colors[] = {
44         0, 1, 0, 1,
45         1, 0, 0, 1,
46         0, 0, 1, 1,
47         0, 1, 0, 1,
48         1, 0, 0, 1,
49         0, 0, 1, 1              
50 };
51 \end{lstlisting}
52
53 \begin{center}
54         \includegraphics[width=0.8\textwidth]{part2}
55 \end{center}
56
57
58 \section{Two triangles, two VAOs and two VBOs}
59
60 In order to use two VAOs and two VBOs, I had to combine the VAO setup and the VBO setup
61 into one function, since you need to bind the VBO at the time that you create the 
62 corresponding VAO.
63
64 \begin{lstlisting}[language=C++]
65 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
66
67 GLuint setupBuffers(GLfloat* vertices, GLuint progId) {
68
69         GLfloat colors[] = {
70                 0, 1, 0, 1,
71                 1, 0, 0, 1,
72                 0, 0, 1, 1
73         };
74
75         GLuint numVerts = 3;
76
77         GLuint vbo;
78         glGenBuffers(1, &vbo);
79
80         GLuint vao;
81         glGenVertexArrays(1, &vao);
82
83         GLuint posId = glGetAttribLocation(progId, "vPosition");
84         GLuint colorId = glGetAttribLocation(progId, "vColor");
85
86         GLuint vertsLen = numVerts * 3 * sizeof(GLfloat);
87         GLuint colorsLen = numVerts * 4 * sizeof(GLfloat);
88
89         glBindBuffer(GL_ARRAY_BUFFER, vbo);
90         glBufferData(GL_ARRAY_BUFFER, vertsLen + colorsLen, NULL, GL_STATIC_DRAW);
91
92         glBufferSubData(GL_ARRAY_BUFFER, 0, vertsLen, vertices);
93         glBufferSubData(GL_ARRAY_BUFFER, vertsLen, colorsLen, colors);
94         
95         glBindVertexArray(vao);
96
97         glEnableVertexAttribArray(posId);
98         glEnableVertexAttribArray(colorId);
99         
100         glVertexAttribPointer(posId, 3, GL_FLOAT, GL_FALSE, 0, 0);
101         glVertexAttribPointer(colorId, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVerts * 3 * sizeof(GLfloat)));
102
103         return vao;
104 }
105 \end{lstlisting}
106
107 This could then be used like so:
108 \begin{lstlisting}[language=C++]
109 GLfloat vertices[2][9] = {
110         {
111                 0.0f, -1.0f, 0.0f,
112                 1.0f, -1.0f, 0.0f,
113                 0.5f, 1.0f, 0.0f
114         },
115
116         {
117                 -1.0f, -1.0f, 0.0f,
118                 0.0f, -1.0f, 0.0f,
119                 -0.5f, 1.0f, 0.0f
120         }
121 };
122 GLuint* vaos = new GLuint[2];
123 vaos[0] = setupBuffers(vertices[0], progId);
124 vaos[1] = setupBuffers(vertices[1], progId);
125 \end{lstlisting}
126
127 When drawing, the VAOs needed to be switched out:
128
129 \begin{lstlisting}[language=C++]
130 void display() {
131         glClear(GL_COLOR_BUFFER_BIT);
132         for (int i = 0; i < 2; i++) {
133                 glBindVertexArray(vaos[i]);
134                 glDrawArrays(GL_TRIANGLES, 0, 3);
135         }
136         glutSwapBuffers();
137 }
138 \end{lstlisting}
139
140 \section{Two separate shaders}
141
142 I modified the \texttt{compileShaders} function to load in the shader source from a file:
143 \begin{lstlisting}[language=C++]
144 GLuint compileShaders(char* vertexShader, char* fragmentShader) {
145         GLuint progId = glCreateProgram();
146
147         attachShader(progId, vertexShader, GL_VERTEX_SHADER);
148         attachShader(progId, fragmentShader, GL_FRAGMENT_SHADER);
149
150         glLinkProgram(progId);
151         GLint success = 0;
152         glGetProgramiv(progId, GL_LINK_STATUS, &success);
153         if (!success) {
154                 GLchar log[1024];
155                 glGetProgramInfoLog(progId, sizeof(log), NULL, log);
156                 fprintf(stderr, "error linking: %s\n", log);
157                 exit(1);
158         }
159
160         return progId;
161 }
162 \end{lstlisting}
163
164 Which meant I could easily swap out the programs used when setting up the buffers:
165
166 \begin{lstlisting}[language=C++]
167 progIds = new GLuint[2];
168
169 GLuint progId1 = compileShaders((char*)"vertex.glsl", (char*)"fragment.glsl");
170 vaos[0] = setupBuffers(vertices[0], progId1);
171 progIds[0] = progId1;
172 validateProgram(progId1);
173
174 GLuint progId2 = compileShaders((char*)"vertex.glsl", (char*)"yellow.glsl");
175 vaos[1] = setupBuffers(vertices[1], progId2);
176 progIds[1] = progId2;
177 validateProgram(progId2);
178 \end{lstlisting}
179
180 The new yellow shader looked like this:
181
182 \lstinputlisting[language=C++]{yellow.glsl}
183
184 I needed to switch programs during the display function:
185
186 \begin{lstlisting}[language=C++]
187 void display() {
188         glClear(GL_COLOR_BUFFER_BIT);
189         for (int i = 0; i < 2; i++) {
190                 glUseProgram(progIds[i]);
191                 glBindVertexArray(vaos[i]);
192                 glDrawArrays(GL_TRIANGLES, 0, 3);
193         }
194         glutSwapBuffers();
195 }
196 \end{lstlisting}
197
198 \begin{center}
199         \includegraphics[width=0.8\textwidth]{part4}
200 \end{center}
201
202
203 \end{document}