1 00:00:02,377 --> 00:00:06,110 - We are now going to talk about drawing in OpenGL. 2 00:00:06,110 --> 00:00:09,293 So far we've taken a number of steps, 3 00:00:09,293 --> 00:00:13,483 understanding the overall framework of OpenGL, 4 00:00:13,483 --> 00:00:15,786 we've talked about buffers and matrices, 5 00:00:15,786 --> 00:00:18,202 we've talked about callbacks, 6 00:00:18,202 --> 00:00:21,773 but we haven't actually drawn anything on the screen yet. 7 00:00:21,773 --> 00:00:24,690 We'll correct that in this segment. 8 00:00:26,724 --> 00:00:29,856 Let's first talk about the primitives that OpenGL 9 00:00:29,856 --> 00:00:32,459 has available for drawing. 10 00:00:32,459 --> 00:00:34,363 In old style OpenGL, 11 00:00:34,363 --> 00:00:38,076 there used to be a large number of additional primitives, 12 00:00:38,076 --> 00:00:41,698 but many of them have been removed in new OpenGL. 13 00:00:41,698 --> 00:00:44,694 We still have points, which are just specified 14 00:00:44,694 --> 00:00:47,482 in homogeneous coordinates. 15 00:00:47,482 --> 00:00:49,727 Lines, you can also have multiple lines 16 00:00:49,727 --> 00:00:53,227 determined by a line strip or a line loop. 17 00:00:54,259 --> 00:00:56,926 You have triangles, which is perhaps the most important 18 00:00:56,926 --> 00:00:58,900 primitive for drawing. 19 00:00:58,900 --> 00:01:03,730 In old OpenGL there used to be quads, general polygons, 20 00:01:03,730 --> 00:01:07,515 and quad strips, which have all been removed in new OpenGL 21 00:01:07,515 --> 00:01:09,441 for simplicity. 22 00:01:09,441 --> 00:01:13,227 Effectively we can use triangles and 23 00:01:13,227 --> 00:01:17,263 two efficiency improvements for collections of triangles. 24 00:01:17,263 --> 00:01:21,191 The triangle strip essentially takes a single triangle, 25 00:01:21,191 --> 00:01:24,419 and then adds new triangles where you have to specify 26 00:01:24,419 --> 00:01:27,295 only one additional vertex at a time. 27 00:01:27,295 --> 00:01:30,014 So if you have this triangle specified, 28 00:01:30,014 --> 00:01:32,774 the next triangle is just specified by taking 29 00:01:32,774 --> 00:01:37,282 one additional vertex and using the previous two vertices. 30 00:01:37,282 --> 00:01:40,226 Similarly, the subsequent triangle will just need 31 00:01:40,226 --> 00:01:42,920 one additional vertex, one additional vertex, 32 00:01:42,920 --> 00:01:44,920 one additional vertex. 33 00:01:44,920 --> 00:01:47,079 The triangle fan is similar in the sense 34 00:01:47,079 --> 00:01:49,613 that it has one point about which 35 00:01:49,613 --> 00:01:53,674 the different triangles effectively form a fan. 36 00:01:53,674 --> 00:01:56,345 Again, with one additional vertex you can specify 37 00:01:56,345 --> 00:01:58,408 an entire triangle. 38 00:01:58,408 --> 00:01:59,491 To reiterate, 39 00:02:03,173 --> 00:02:07,464 the points are GL_POINTS stored in homogeneous coordinates, 40 00:02:07,464 --> 00:02:09,672 line segments, triangles, which is the most important, 41 00:02:09,672 --> 00:02:14,133 GL_TRIANGLES, you also have strips and fans. 42 00:02:14,133 --> 00:02:18,196 More complex primitives used to be available in GLUT, 43 00:02:18,196 --> 00:02:21,613 in particular spheres, teapots and cubes. 44 00:02:22,817 --> 00:02:26,400 These must now be converted into triangles, 45 00:02:27,299 --> 00:02:30,573 the skeleton code that we are providing you does 46 00:02:30,573 --> 00:02:34,263 do this conversion, and we do not use the deprecated 47 00:02:34,263 --> 00:02:37,724 GLUT sphere, GLUT cube or GLUT teapot commands. 48 00:02:37,724 --> 00:02:41,346 We'll now talk about the mechanics of drawing. 49 00:02:41,346 --> 00:02:45,513 First I have a couple of slides on old style OpenGL drawing, 50 00:02:46,359 --> 00:02:49,681 which although it's deprecated is actually much simpler 51 00:02:49,681 --> 00:02:52,330 to understand and can be a first step for you 52 00:02:52,330 --> 00:02:54,995 to understand the process. 53 00:02:54,995 --> 00:02:57,554 In old style OpenGL drawing, 54 00:02:57,554 --> 00:03:00,225 one could enclose vertices between a pair of 55 00:03:00,225 --> 00:03:02,475 glBegin and glEnd commands. 56 00:03:05,008 --> 00:03:08,683 And within those commands one could include normal C code 57 00:03:08,683 --> 00:03:10,933 and attributes like colors. 58 00:03:12,413 --> 00:03:15,570 So it would be very common to specify a color, 59 00:03:15,570 --> 00:03:17,403 then specify a vertex. 60 00:03:18,889 --> 00:03:23,056 There would be commands like glVertex3f, and glColor3f. 61 00:03:24,160 --> 00:03:27,248 You might be wondering what the 3f stands for. 62 00:03:27,248 --> 00:03:31,172 Remember that OpenGL came into being in the early 90s, 63 00:03:31,172 --> 00:03:35,339 and well before the C++ and object-oriented programming. 64 00:03:36,541 --> 00:03:39,124 In fact OpenGL is written in C. 65 00:03:40,418 --> 00:03:43,942 Therefore in order to have functions that take in 66 00:03:43,942 --> 00:03:46,873 different arguments, three floating point numbers 67 00:03:46,873 --> 00:03:50,839 versus three integers, or versus four floating point numbers 68 00:03:50,839 --> 00:03:52,789 and homogeneous coordinates, 69 00:03:52,789 --> 00:03:55,418 instead of overloading the function call, 70 00:03:55,418 --> 00:03:57,299 we have different functions which are 71 00:03:57,299 --> 00:03:59,784 specified by attributes like 3f, 72 00:03:59,784 --> 00:04:01,640 which simply means the input is 73 00:04:01,640 --> 00:04:04,005 three floating point numbers. 74 00:04:04,005 --> 00:04:06,262 In old style OpenGL, it was also important 75 00:04:06,262 --> 00:04:10,068 that the color would be set before the vertex. 76 00:04:10,068 --> 00:04:13,878 Therefore you might have something like 77 00:04:13,878 --> 00:04:14,711 glColor3f 78 00:04:20,490 --> 00:04:21,907 to set the color, 79 00:04:22,793 --> 00:04:26,741 and then you might have something like glVertex. 80 00:04:26,741 --> 00:04:30,038 This was also done in an assembly line model, 81 00:04:30,038 --> 00:04:34,205 so you pass vertices to the server, they get transformed, 82 00:04:35,305 --> 00:04:38,888 they get shaded within the OpenGL pipeline. 83 00:04:40,391 --> 00:04:43,042 Nowadays, of course, you have modern vertex and 84 00:04:43,042 --> 00:04:46,614 fragment shaders and the graphics processing unit. 85 00:04:46,614 --> 00:04:49,426 In old OpenGL there was also the concept of immediate mode 86 00:04:49,426 --> 00:04:51,866 wherein you specify triangles, 87 00:04:51,866 --> 00:04:55,113 it was immediately sent to the server and drawn. 88 00:04:55,113 --> 00:04:58,414 Let me just show you one example of old OpenGL drawing, 89 00:04:58,414 --> 00:05:01,452 which again I want to emphasize is not used 90 00:05:01,452 --> 00:05:05,005 in your skeleton code or in your homework assignments 91 00:05:05,005 --> 00:05:08,882 where you will be using modern OpenGL. 92 00:05:08,882 --> 00:05:10,486 In the display routine, 93 00:05:10,486 --> 00:05:12,648 we first clear the color buffer bit, 94 00:05:12,648 --> 00:05:15,783 and then we draw a polygon with the vertices 95 00:05:15,783 --> 00:05:18,917 having appropriate colors, blue, white, red and green, 96 00:05:18,917 --> 00:05:21,704 similar to the polygon I showed you in our probe. 97 00:05:21,704 --> 00:05:25,976 You begin with the GL_POLYGON, you set the color, red, 98 00:05:25,976 --> 00:05:27,393 RGB, this is red. 99 00:05:28,972 --> 00:05:32,545 You draw a vertex at (0.5 0.5 0.0), 100 00:05:32,545 --> 00:05:35,979 these are all vertices on the plane z=0. 101 00:05:35,979 --> 00:05:40,146 This is at x=0.5, y=0.5, it's red. 102 00:05:41,069 --> 00:05:45,620 Thereafter you draw another vertex with color green 103 00:05:45,620 --> 00:05:47,120 at (-0.5, 0.5). 104 00:05:48,656 --> 00:05:51,305 Similarly you set the color to blue, 105 00:05:51,305 --> 00:05:54,231 you draw a vertex (-0.5, -0.5), 106 00:05:54,231 --> 00:05:55,926 set the color to white, 107 00:05:55,926 --> 00:05:59,134 you draw a vertex here at (0.5, -0.5). 108 00:05:59,134 --> 00:06:02,301 glEnd ends the sequence of primitives. 109 00:06:03,241 --> 00:06:06,843 This is now sent immediately to the server for drawing. 110 00:06:06,843 --> 00:06:10,326 glFlush flushes the set of commands, 111 00:06:10,326 --> 00:06:13,177 and they are drawn immediately. 112 00:06:13,177 --> 00:06:15,179 I talked about clients and servers. 113 00:06:15,179 --> 00:06:18,965 In fact old OpenGL operates on a client-server model, 114 00:06:18,965 --> 00:06:22,349 even if the client and server are on the same machine, 115 00:06:22,349 --> 00:06:24,212 which is typically the case; 116 00:06:24,212 --> 00:06:26,580 wherein the client, which is the user program, 117 00:06:26,580 --> 00:06:30,038 generates vertices. The server draws them, 118 00:06:30,038 --> 00:06:33,195 even if the server is really running on the same machine 119 00:06:33,195 --> 00:06:35,054 as the client. 120 00:06:35,054 --> 00:06:37,238 There are a couple of synchronization commands. 121 00:06:37,238 --> 00:06:38,932 glFlush forces the client 122 00:06:38,932 --> 00:06:41,575 to send network packets for drawing, 123 00:06:41,575 --> 00:06:45,388 and glFinish waits for an ack and is sparingly used 124 00:06:45,388 --> 00:06:47,569 for synchronization. 125 00:06:47,569 --> 00:06:50,915 In modern OpenGL, all of this has been replaced 126 00:06:50,915 --> 00:06:54,092 using the notion of vertex array objects, 127 00:06:54,092 --> 00:06:56,185 which we will discuss next. 128 00:06:56,185 --> 00:06:59,483 There is a fair warning that this is more complicated, 129 00:06:59,483 --> 00:07:03,150 but is useful for modularity and efficiency. 130 00:07:05,288 --> 00:07:09,491 In modern OpenGL, I specify the floor as follows. 131 00:07:09,491 --> 00:07:13,786 First I have an array of the four vertices of the floor, 132 00:07:13,786 --> 00:07:16,433 with the three locations in the array 133 00:07:16,433 --> 00:07:18,523 for the x, y and z coordinates. 134 00:07:18,523 --> 00:07:21,353 And that's just the same way I specified it earlier, 135 00:07:21,353 --> 00:07:24,816 the (0.5 0.5 0.0), (0.5 0.5, 0.0). 136 00:07:24,816 --> 00:07:29,413 It's the same floor we saw earlier in old style OpenGL. 137 00:07:29,413 --> 00:07:32,338 But I will also specify an array for colors 138 00:07:32,338 --> 00:07:34,543 instead of doing it in immediate mode, 139 00:07:34,543 --> 00:07:37,770 where the colors are red, green, blue and white 140 00:07:37,770 --> 00:07:38,603 as before. 141 00:07:39,444 --> 00:07:43,457 Then there is the specification of indices. 142 00:07:43,457 --> 00:07:47,337 Essentially, by defining the floor vertices, 143 00:07:47,337 --> 00:07:50,262 I put the set of vertices in an array, 144 00:07:50,262 --> 00:07:54,277 but I still need to figure out the way of connecting them. 145 00:07:54,277 --> 00:07:57,068 In this case, I have my floor, 146 00:07:57,068 --> 00:07:59,318 which I can draw like this. 147 00:08:03,407 --> 00:08:05,283 And I have connected it this way, 148 00:08:05,283 --> 00:08:07,200 (0.5 0.5) is vertex 0, 149 00:08:08,934 --> 00:08:11,267 (-0.5 0.5) is vertex 1, 150 00:08:12,644 --> 00:08:15,477 (-0.5 -0.5) is vertex 2, 151 00:08:16,500 --> 00:08:20,010 and (0.5 -0.5) is vertex 3. 152 00:08:20,010 --> 00:08:22,605 So when I'm looking at the indices and 153 00:08:22,605 --> 00:08:24,956 the elements for construction, 154 00:08:24,956 --> 00:08:27,876 (0,1,2) corresponds to the triangle 155 00:08:27,876 --> 00:08:30,087 joining these vertices. 156 00:08:30,087 --> 00:08:33,264 Remember that I only have triangles in OpenGL, 157 00:08:33,264 --> 00:08:35,866 so I have to connect these, 158 00:08:35,866 --> 00:08:40,229 and (0,2,3) is correspondingly this triangle. 159 00:08:40,229 --> 00:08:43,741 So I specified the floor with two triangles. 160 00:08:43,741 --> 00:08:47,074 That's what these indices correspond to. 161 00:08:48,867 --> 00:08:53,141 I also specify the coordinates for my second plane, 162 00:08:53,141 --> 00:08:55,834 with the same vertices except that the z coordinate 163 00:08:55,834 --> 00:08:57,998 is now equal to one. 164 00:08:57,998 --> 00:09:01,407 If you look here, the z coordinates are all one, 165 00:09:01,407 --> 00:09:04,290 and the colors are also different in this case 166 00:09:04,290 --> 00:09:07,030 in that all of the colors are red. 167 00:09:07,030 --> 00:09:09,422 However, the indices are exactly the same 168 00:09:09,422 --> 00:09:11,047 as what we had earlier, 169 00:09:11,047 --> 00:09:15,250 in order to specify the triangles for the second plane, 170 00:09:15,250 --> 00:09:16,848 which is above the first plane. 171 00:09:16,848 --> 00:09:19,449 Let's now talk about the representation of 172 00:09:19,449 --> 00:09:21,844 vertex array objects. 173 00:09:21,844 --> 00:09:23,674 The first line in this code defines 174 00:09:23,674 --> 00:09:25,694 the number of objects as 2, 175 00:09:25,694 --> 00:09:28,065 corresponding to the two planes. 176 00:09:28,065 --> 00:09:31,481 The number of buffers per object is 3, 177 00:09:31,481 --> 00:09:35,379 corresponding to vertices, colors and indices. 178 00:09:35,379 --> 00:09:38,129 Thereafter I use GLuint to define 179 00:09:39,190 --> 00:09:41,925 a number of vertex array objects. 180 00:09:41,925 --> 00:09:45,247 You will need a vertex array object per object. 181 00:09:45,247 --> 00:09:48,198 Then I have the number of buffers, 182 00:09:48,198 --> 00:09:52,518 which is the number per object times the number of objects. 183 00:09:52,518 --> 00:09:56,140 The objects which we'll store like object IDs again 184 00:09:56,140 --> 00:09:58,712 is the number of objects. 185 00:09:58,712 --> 00:10:02,618 The primitive types is the type of the object, 186 00:10:02,618 --> 00:10:05,845 which is triangles or strips, 187 00:10:05,845 --> 00:10:08,328 and finally the number of elements, 188 00:10:08,328 --> 00:10:11,044 or the number of triangles or geometric elements 189 00:10:11,044 --> 00:10:12,377 for each object. 190 00:10:14,039 --> 00:10:18,206 The floor geometry is specified with a vertex array. 191 00:10:20,449 --> 00:10:24,994 We'll define an enum for vertices, colors and elements, 192 00:10:24,994 --> 00:10:27,624 it's just we'll set them to zero, one and two, 193 00:10:27,624 --> 00:10:30,893 and similarly for floor and floor two. 194 00:10:30,893 --> 00:10:33,289 Below that, in the init function, 195 00:10:33,289 --> 00:10:36,651 we will create the buffer objects for later use. 196 00:10:36,651 --> 00:10:40,322 So glGenVertexArrays tells OpenGL 197 00:10:40,322 --> 00:10:43,506 to generate the number of vertex array objects 198 00:10:43,506 --> 00:10:46,011 corresponding to the number of objects. 199 00:10:46,011 --> 00:10:50,049 This just creates the unique identifiers for the objects. 200 00:10:50,049 --> 00:10:52,353 glGenBuffers number per object, 201 00:10:52,353 --> 00:10:56,530 which is three in this case, times number of objects, 202 00:10:56,530 --> 00:11:01,011 generates buffers for vertices, colors and elements. 203 00:11:01,011 --> 00:11:03,706 And finally we have this DeleteBuffers, 204 00:11:03,706 --> 00:11:05,864 which operates like a destruct tail when 205 00:11:05,864 --> 00:11:08,026 a buffer is no longer needed. 206 00:11:08,026 --> 00:11:11,694 Let us now talk about the initobject command, 207 00:11:11,694 --> 00:11:14,481 which effectively initializes the objects 208 00:11:14,481 --> 00:11:18,648 and initializes the buffers needed for drawing an object. 209 00:11:19,613 --> 00:11:24,255 Again, you're give as input the integer ID of the object. 210 00:11:24,255 --> 00:11:28,338 And you're given a pointer to the vertex array, 211 00:11:28,338 --> 00:11:31,079 the size of the vertex array, 212 00:11:31,079 --> 00:11:32,632 a pointer to the color aray, 213 00:11:32,632 --> 00:11:34,535 the size of the color array, 214 00:11:34,535 --> 00:11:37,070 a pointer to the array of indices, 215 00:11:37,070 --> 00:11:39,856 the size of the indices array. 216 00:11:39,856 --> 00:11:42,596 Note that in this case we just use unsigned characters 217 00:11:42,596 --> 00:11:45,197 or bytes for the indices, but of course if we had 218 00:11:45,197 --> 00:11:49,024 more complex objects we would need to use integers. 219 00:11:49,024 --> 00:11:52,418 And then the type, which in this case is triangle. 220 00:11:52,418 --> 00:11:56,480 So the offset is just saying for different objects, 221 00:11:56,480 --> 00:11:58,665 as you increase the object ID, 222 00:11:58,665 --> 00:12:01,939 we will be offset in terms of the buffers 223 00:12:01,939 --> 00:12:06,106 by the object number times the number of buffers per object. 224 00:12:07,392 --> 00:12:10,460 The first thing you do is bind the vertex array 225 00:12:10,460 --> 00:12:13,014 corresponding to the given object, that is 226 00:12:13,014 --> 00:12:16,931 the vertex array object of the given object ID. 227 00:12:17,914 --> 00:12:21,304 Thereafter you bind the corresponding buffer, 228 00:12:21,304 --> 00:12:24,391 which will be given by offset plus vertices, 229 00:12:24,391 --> 00:12:26,058 colors and elements. 230 00:12:27,202 --> 00:12:29,535 You specify the buffer data, 231 00:12:32,124 --> 00:12:35,675 so it's an array buffer, the size of the vertices. 232 00:12:35,675 --> 00:12:37,675 vert is where it starts. 233 00:12:38,626 --> 00:12:40,275 GL_STATIC_DRAW is a hint to OpenGL, 234 00:12:40,275 --> 00:12:43,025 this is meant for static drawing. 235 00:12:44,175 --> 00:12:46,980 We also need to interact with the shader, 236 00:12:46,980 --> 00:12:50,631 and within the shader we will use layout location 0 237 00:12:50,631 --> 00:12:52,326 for the vertices. 238 00:12:52,326 --> 00:12:56,227 So you enable the vertex attribute array zero, 239 00:12:56,227 --> 00:12:59,846 so that you can pass this information to the shader, 240 00:12:59,846 --> 00:13:02,446 Then there is this glVertexAttribPointer command, 241 00:13:02,446 --> 00:13:05,649 so 0 is the layout location, 242 00:13:05,649 --> 00:13:08,649 3 says that this is now a vertex array, 243 00:13:08,649 --> 00:13:12,816 so each element of the array has x, y and z coordinates. 244 00:13:14,937 --> 00:13:18,770 This is GL_FLOAT, which is the data type here. 245 00:13:21,537 --> 00:13:24,068 GL_FALSE corresponds to the fact of whether the data 246 00:13:24,068 --> 00:13:26,320 should be normalized. 247 00:13:26,320 --> 00:13:29,855 Here we talk about the stride in the data; 248 00:13:29,855 --> 00:13:33,193 what is the difference in bytes between 249 00:13:33,193 --> 00:13:36,791 one element and the other element. 250 00:13:36,791 --> 00:13:39,393 And of course it would be three for x y z 251 00:13:39,393 --> 00:13:41,668 times the size of the float variable. 252 00:13:41,668 --> 00:13:45,668 0 is a pointer to how much you have to offset 253 00:13:46,981 --> 00:13:48,314 into the buffer, 254 00:13:49,210 --> 00:13:52,345 and in this case the information is right at the start, 255 00:13:52,345 --> 00:13:54,012 so it's set to zero. 256 00:13:55,408 --> 00:13:58,243 Binding the buffer now corresponding to the colors, 257 00:13:58,243 --> 00:14:01,424 specifying the data for the colors. 258 00:14:01,424 --> 00:14:04,186 We use layout location 1 for the colors. 259 00:14:04,186 --> 00:14:07,345 You enable the vertex attribute array one. 260 00:14:07,345 --> 00:14:10,474 You similarly set up the vertexAttribPointer 261 00:14:10,474 --> 00:14:14,656 for location 1. Again, it's just the same way as vertices, 262 00:14:14,656 --> 00:14:17,444 the same set of arguments. 263 00:14:17,444 --> 00:14:21,596 Binding the buffer for the elements and the indices now, 264 00:14:21,596 --> 00:14:24,175 reading in that buffer data. 265 00:14:24,175 --> 00:14:26,873 Finally we set the primitive type for the object 266 00:14:26,873 --> 00:14:28,914 to the type that is input, 267 00:14:28,914 --> 00:14:31,096 and the number of elements for the object 268 00:14:31,096 --> 00:14:34,253 to the size of the indices array. 269 00:14:34,253 --> 00:14:38,549 Once you have done with this vertex array object, 270 00:14:38,549 --> 00:14:43,007 you can unbind it to prevent unwanted modifications later, 271 00:14:43,007 --> 00:14:44,705 so you should always, as a best practice, 272 00:14:44,705 --> 00:14:47,283 bind 0 in order to unbind 273 00:14:47,283 --> 00:14:50,000 the current vertex array object. 274 00:14:50,000 --> 00:14:52,970 After we have done all of this setup 275 00:14:52,970 --> 00:14:55,778 to initialize the object, 276 00:14:55,778 --> 00:14:58,540 drawing of the actual vertex object 277 00:14:58,540 --> 00:15:01,074 is surprisingly simple. 278 00:15:01,074 --> 00:15:05,023 The drawobject command just takes in the integer value 279 00:15:05,023 --> 00:15:07,531 corresponding to the object, 280 00:15:07,531 --> 00:15:11,031 you bind the vertex array for that object, 281 00:15:12,082 --> 00:15:14,660 and you draw the elements corresponding 282 00:15:14,660 --> 00:15:17,771 with where you're given the primitive type for the object, 283 00:15:17,771 --> 00:15:19,884 the number of elements for that object. 284 00:15:19,884 --> 00:15:23,690 GL_UNSIGNED_BYTE tells you that the elements 285 00:15:23,690 --> 00:15:27,268 are just represented by an unsigned character, 286 00:15:27,268 --> 00:15:30,851 which is the indices specifying the object. 287 00:15:32,539 --> 00:15:34,626 Thereafter you unbind. 288 00:15:34,626 --> 00:15:37,944 In the display routine you have this command glClear, 289 00:15:37,944 --> 00:15:42,111 GL_COLOR_BUFFER_BIT, which clears all of the pixels. 290 00:15:43,500 --> 00:15:45,816 Thereafter you draw the object FLOOR, 291 00:15:45,816 --> 00:15:47,993 draw the object FLOOR2, 292 00:15:47,993 --> 00:15:50,349 and you flush and you start processing 293 00:15:50,349 --> 00:15:53,202 the buffered OpenGL commands. 294 00:15:53,202 --> 00:15:57,369 Finally, I just briefly want to talk about initialization, 295 00:15:58,334 --> 00:16:00,983 including initialization of the shaders. 296 00:16:00,983 --> 00:16:05,150 We'll talk more about shaders in the next video segment. 297 00:16:06,159 --> 00:16:10,527 Notice that you have integer values for the vertex shader, 298 00:16:10,527 --> 00:16:13,659 the fragment shader and the shader program. 299 00:16:13,659 --> 00:16:16,889 This is the initialization you do in init for drawing, 300 00:16:16,889 --> 00:16:20,138 we already talked about glGenVertexArrays and glGenBuffers 301 00:16:20,138 --> 00:16:24,621 to generate unique IDs for the vertex arrays in the buffers. 302 00:16:24,621 --> 00:16:27,060 You initialize the object. 303 00:16:27,060 --> 00:16:29,255 We looked at the initobject command. 304 00:16:29,255 --> 00:16:31,331 You initobject for the floor, 305 00:16:31,331 --> 00:16:34,032 you initobject for floor2. 306 00:16:34,032 --> 00:16:37,555 Then you need to do initialization for the shaders. 307 00:16:37,555 --> 00:16:40,597 the vertex shader lies in this file 308 00:16:40,597 --> 00:16:42,764 shader/nop.vert 309 00:16:43,657 --> 00:16:46,588 Right now it's not doing anything particularly interesting. 310 00:16:46,588 --> 00:16:49,536 The initialization for the fragment shader lies in this file 311 00:16:49,536 --> 00:16:51,536 shaders/nop.frag 312 00:16:52,973 --> 00:16:55,911 These do not actually have to be in files. 313 00:16:55,911 --> 00:16:58,866 In fact they are just strings to the OpenGL program 314 00:16:58,866 --> 00:17:02,098 that are compiled on the fly. 315 00:17:02,098 --> 00:17:06,265 In practice, we read them in from the vertex and frag files 316 00:17:07,486 --> 00:17:09,711 that we have created. 317 00:17:09,711 --> 00:17:12,269 The next part is creating the shader program, 318 00:17:12,269 --> 00:17:15,911 which initializes a program based on the vertex 319 00:17:15,911 --> 00:17:17,726 and fragment shader. 320 00:17:17,726 --> 00:17:19,839 I will now demonstrate the program. 321 00:17:19,839 --> 00:17:23,366 Here I'm showing you the actual text for the program. 322 00:17:23,366 --> 00:17:26,454 You can download this of course, 323 00:17:26,454 --> 00:17:28,360 it is the mytest sequence of demos, 324 00:17:28,360 --> 00:17:30,866 and this is mytest1.cpp. 325 00:17:30,866 --> 00:17:33,533 I can even run the program here. 326 00:17:36,928 --> 00:17:38,576 Let me show it to you. 327 00:17:38,576 --> 00:17:41,431 This is what you saw earlier, you have these two planes, 328 00:17:41,431 --> 00:17:44,721 I can zoom in, I can zoom out, 329 00:17:44,721 --> 00:17:47,804 and I can hit escape or quit to quit. 330 00:17:48,698 --> 00:17:51,786 What I'm going to do now is try to change the color 331 00:17:51,786 --> 00:17:52,869 of the floor. 332 00:17:57,728 --> 00:18:00,645 So I first comment out these lines. 333 00:18:02,069 --> 00:18:04,696 I'm showing you writing of the actual code 334 00:18:04,696 --> 00:18:08,110 so you get a sense that this is simple code 335 00:18:08,110 --> 00:18:09,777 that can be written, 336 00:18:11,570 --> 00:18:12,653 and modified. 337 00:18:15,697 --> 00:18:18,530 Let me now un-comment these lines, 338 00:18:20,765 --> 00:18:23,226 and I will change the colors to have 339 00:18:23,226 --> 00:18:25,643 the lower floor be all white. 340 00:18:27,473 --> 00:18:30,935 I changed all of the colors to be white. 341 00:18:30,935 --> 00:18:33,536 There are a number of different compilation options. 342 00:18:33,536 --> 00:18:35,997 I am working on a Mac, so I'm just going to 343 00:18:35,997 --> 00:18:38,497 compile from the command line. 344 00:18:39,638 --> 00:18:41,635 We are giving you the make files, 345 00:18:41,635 --> 00:18:44,542 so don't worry too much about all of the arguments here, 346 00:18:44,542 --> 00:18:45,819 it should just work. 347 00:18:45,819 --> 00:18:47,723 Now I'm going to run the program. 348 00:18:47,723 --> 00:18:51,761 Notice that it's compiled the shader files for the vertex 349 00:18:51,761 --> 00:18:54,712 and the fragment shader and successfully attached 350 00:18:54,712 --> 00:18:56,629 and linked the shaders. 351 00:18:58,497 --> 00:19:03,002 You notice that now the floor at the bottom is white. 352 00:19:03,002 --> 00:19:04,834 The floor on top is still red, 353 00:19:04,834 --> 00:19:06,296 I didn't change the colors, 354 00:19:06,296 --> 00:19:07,924 but instead of being multi-colored, 355 00:19:07,924 --> 00:19:10,450 the floor at the bottom is still white. 356 00:19:10,450 --> 00:19:12,522 Go ahead, download these programs, 357 00:19:12,522 --> 00:19:14,748 and explore playing with them.