1 00:00:01,690 --> 00:00:02,818 - In this lecture 2 00:00:02,818 --> 00:00:06,644 we are going to talk more about OpenGL, 3 00:00:06,644 --> 00:00:09,213 making the mytest1 program 4 00:00:09,213 --> 00:00:11,483 that you saw a couple of lectures ago 5 00:00:11,483 --> 00:00:13,424 more complicated 6 00:00:13,424 --> 00:00:17,973 to introduce more of the functionalities of OpenGL. 7 00:00:17,973 --> 00:00:21,315 This segment talks about basic geometry set up. 8 00:00:21,315 --> 00:00:25,110 The way we will do this is start with the mytest1 program 9 00:00:25,110 --> 00:00:29,136 and gradually add code to take you though a squence 10 00:00:29,136 --> 00:00:32,356 of steps that makes it more ambitious. 11 00:00:32,356 --> 00:00:34,106 At the end of this lecture, 12 00:00:34,106 --> 00:00:36,415 we will first have program mytest2 13 00:00:36,415 --> 00:00:38,522 that has a teapot like you can see 14 00:00:38,522 --> 00:00:41,810 with four pillars and where the teapot can animate, 15 00:00:41,810 --> 00:00:45,977 and finally we will add texturing and lighting as well. 16 00:00:46,925 --> 00:00:50,144 Let me show you the demo of the program. 17 00:00:50,144 --> 00:00:53,977 So here I can move into and out of the screen 18 00:00:54,979 --> 00:00:57,080 like I could previously, 19 00:00:57,080 --> 00:00:59,484 and I can also animate my teapot. 20 00:00:59,484 --> 00:01:02,456 Let me also show you the code for this. 21 00:01:02,456 --> 00:01:05,456 In fact I have a DEMO variable here. 22 00:01:06,787 --> 00:01:10,704 In this case I will now set it to zero to start 23 00:01:11,589 --> 00:01:14,263 a basic program similar to mytest1. 24 00:01:14,263 --> 00:01:17,201 I quit this program by hitting escape. 25 00:01:17,201 --> 00:01:18,868 I compile my program 26 00:01:21,520 --> 00:01:23,087 and now if I run this, 27 00:01:23,087 --> 00:01:26,524 I see that I have just a single plane, 28 00:01:26,524 --> 00:01:28,126 a single white plane. 29 00:01:28,126 --> 00:01:30,528 I can zoom in and out as before. 30 00:01:30,528 --> 00:01:33,559 The only changes from the earlier demo 31 00:01:33,559 --> 00:01:35,696 a couple of lectures back in mytest1 32 00:01:35,696 --> 00:01:38,608 was that I changed the floor to all white. 33 00:01:38,608 --> 00:01:42,775 I have also added new globals for the teapot location 34 00:01:44,553 --> 00:01:46,209 which is -0.5, 35 00:01:46,209 --> 00:01:48,792 that is the left end of the screen in x, 36 00:01:48,792 --> 00:01:50,877 where it starts its animation. 37 00:01:50,877 --> 00:01:53,257 And animate is equal to zero, 38 00:01:53,257 --> 00:01:55,978 says whether to animate the teapot or not 39 00:01:55,978 --> 00:01:57,891 which is initially zero. 40 00:01:57,891 --> 00:02:00,878 And of course my DEMO variable. 41 00:02:00,878 --> 00:02:04,186 The other globals are what we saw previously. 42 00:02:04,186 --> 00:02:06,915 I will now show you the basic geometry 43 00:02:06,915 --> 00:02:10,498 set up for the cubes or pillars and colors. 44 00:02:12,230 --> 00:02:15,587 First let me review the geometry set up in general. 45 00:02:15,587 --> 00:02:18,432 The number of objects is equal to 2 46 00:02:18,432 --> 00:02:20,905 because you have the floor and the cubes. 47 00:02:20,905 --> 00:02:24,464 The number of buffers for objects is equal to 3 48 00:02:24,464 --> 00:02:26,882 corresponding to the vertices, colors and indices. 49 00:02:26,882 --> 00:02:29,882 In addition we will have four colors 50 00:02:32,131 --> 00:02:35,007 for the four colors of the cubes 51 00:02:35,007 --> 00:02:37,913 corresponding to the four pillars. 52 00:02:37,913 --> 00:02:40,547 We now define a number of vertex array objects, 53 00:02:40,547 --> 00:02:44,272 in this case is not just the number of objects 54 00:02:44,272 --> 00:02:47,039 but it is also the number of colors 55 00:02:47,039 --> 00:02:49,625 because we have to account for these four colored cubes 56 00:02:49,625 --> 00:02:53,792 and a separate vertex array object for the teapot. 57 00:02:55,582 --> 00:02:57,859 We now define the number of buffers 58 00:02:57,859 --> 00:03:01,534 which includes the number of colors and the teapot buffers. 59 00:03:01,534 --> 00:03:02,367 Objects, 60 00:03:03,766 --> 00:03:07,043 with the object ID, the primitive type of the object, 61 00:03:07,043 --> 00:03:09,349 the number of elements in the object. 62 00:03:09,349 --> 00:03:14,074 Then we define for the teapot a vector of vertices, of normals 63 00:03:14,074 --> 00:03:15,100 for the teapot, 64 00:03:15,100 --> 00:03:16,573 for lighting calculations 65 00:03:16,573 --> 00:03:20,022 and the indices for the teapot. 66 00:03:20,022 --> 00:03:21,820 If you are interested in more details 67 00:03:21,820 --> 00:03:23,842 about the teapot definition, 68 00:03:23,842 --> 00:03:27,546 please look in the appropriate header files. 69 00:03:27,546 --> 00:03:31,245 We also define the modelviewStack, 70 00:03:31,245 --> 00:03:34,744 which is just a vector of mat4 matrices. 71 00:03:34,744 --> 00:03:36,811 We will push and pop on to this stack. 72 00:03:36,811 --> 00:03:39,922 We now define an enum for the vertices, 73 00:03:39,922 --> 00:03:41,695 colors and elements, 74 00:03:41,695 --> 00:03:44,613 corresponding to the arrays for the object. 75 00:03:44,613 --> 00:03:47,922 We have an enum for the floor in the cube 76 00:03:47,922 --> 00:03:50,936 and we define the floor vertices. 77 00:03:50,936 --> 00:03:54,488 Note that the floor is at Z = 0 78 00:03:54,488 --> 00:03:58,157 so the vertices just correspond to X = .5, 79 00:03:58,157 --> 00:03:59,497 Y = .5, 80 00:03:59,497 --> 00:04:00,890 and X = -.5 81 00:04:00,890 --> 00:04:01,895 and Y is -.5 82 00:04:01,895 --> 00:04:03,976 and finally X is .5, 83 00:04:03,976 --> 00:04:05,462 Y is -.5. 84 00:04:05,462 --> 00:04:06,927 The colors, 85 00:04:06,927 --> 00:04:09,198 since it's a uniform white floor 86 00:04:09,198 --> 00:04:11,731 are simply RGB equal to (1,1,1). 87 00:04:11,731 --> 00:04:14,365 The indices for the floor correspond 88 00:04:14,365 --> 00:04:17,121 to the indices for the triangles 89 00:04:17,121 --> 00:04:21,463 and these are just defined as two triangles for the floor. 90 00:04:21,463 --> 00:04:24,505 For later purposes we'll also define the texture coordinates. 91 00:04:24,505 --> 00:04:27,439 The texture coordinates go between 0 and 1, 92 00:04:27,439 --> 00:04:28,812 not -.5 and .5. 93 00:04:28,812 --> 00:04:33,050 We now define the cube geometry for the pillars. 94 00:04:33,050 --> 00:04:36,376 First, I define the width and the height, 95 00:04:36,376 --> 00:04:40,244 which correspond to the width of the pillar 96 00:04:40,244 --> 00:04:42,147 and the height of the pillar. 97 00:04:42,147 --> 00:04:46,245 Then I have this cube color (_cubecol) which is with an underscore. 98 00:04:46,245 --> 00:04:49,230 It's with an underscore because it just defines 99 00:04:49,230 --> 00:04:51,486 the uniform color for the four cubes: 100 00:04:51,486 --> 00:04:53,017 red, green, 101 00:04:53,017 --> 00:04:54,152 blue and yellow, 102 00:04:54,152 --> 00:04:55,352 which is red and green. 103 00:04:55,352 --> 00:04:58,286 Later on when I'm initializing the cube, 104 00:04:58,286 --> 00:05:00,688 I'll have cube color (cubecol) without the underscore, 105 00:05:00,688 --> 00:05:03,523 which for each vertex of the corresponding cube 106 00:05:03,523 --> 00:05:05,669 will just set it to the uniform color 107 00:05:05,669 --> 00:05:07,287 in _cubecol. 108 00:05:07,287 --> 00:05:09,656 I then define the eight vertices for the cube, 109 00:05:09,656 --> 00:05:12,558 where I define the lower plane 110 00:05:12,558 --> 00:05:14,973 with Z is equal to zero first 111 00:05:14,973 --> 00:05:18,012 and then the upper plane with Z is equal to height second. 112 00:05:18,012 --> 00:05:21,057 And notice that the coordinates 113 00:05:21,057 --> 00:05:23,807 are given by plus or minus width. 114 00:05:27,072 --> 00:05:28,578 I initalize this cube color, 115 00:05:28,578 --> 00:05:31,246 which is for each of the eight vertices: 116 00:05:31,246 --> 00:05:32,956 what is its RGB color? 117 00:05:32,956 --> 00:05:34,420 We'll define it later. 118 00:05:34,420 --> 00:05:36,704 And I specify the cube indices, 119 00:05:36,704 --> 00:05:40,260 which is two triangles for each of the six faces, 120 00:05:40,260 --> 00:05:42,848 so 12 triangles for the bottom, 121 00:05:42,848 --> 00:05:44,052 top, left, 122 00:05:44,052 --> 00:05:45,054 front, right 123 00:05:45,054 --> 00:05:46,526 and back faces. 124 00:05:46,526 --> 00:05:50,020 Here is my Initialize Geometry function. 125 00:05:50,020 --> 00:05:53,367 This is just the basic Initialize Geometry function, 126 00:05:53,367 --> 00:05:54,933 it's the same thing 127 00:05:54,933 --> 00:05:56,834 that was used for the plane in mytest1. 128 00:05:56,834 --> 00:05:59,193 It takes as input the vertex array, 129 00:05:59,193 --> 00:06:00,496 the color array and the elements, 130 00:06:00,496 --> 00:06:03,062 as well as their sizes and the type, 131 00:06:03,062 --> 00:06:04,812 which is GL_TRIANGLES. 132 00:06:07,100 --> 00:06:08,632 It defines an offset, 133 00:06:08,632 --> 00:06:12,640 which is object ID times the number of buffers per object, 134 00:06:12,640 --> 00:06:14,109 binds the vertex array, 135 00:06:14,109 --> 00:06:15,786 corresponding to the object. 136 00:06:15,786 --> 00:06:19,571 It binds the buffer corresponding to the vertices plus offset, 137 00:06:19,571 --> 00:06:22,276 so it takes in the buffer data, 138 00:06:22,276 --> 00:06:25,513 uses layout location 0 for the vertices, 139 00:06:25,513 --> 00:06:28,092 enables the corresponding attribute, 140 00:06:28,092 --> 00:06:31,320 which will be passed later to the shaders, 141 00:06:31,320 --> 00:06:33,653 and sets the data appropriately. 142 00:06:34,752 --> 00:06:37,124 This is the VertexAttribPointer, 143 00:06:37,124 --> 00:06:38,285 for example, 144 00:06:38,285 --> 00:06:40,817 saying that you have three floating point numbers 145 00:06:40,817 --> 00:06:42,953 for each vertex, 146 00:06:42,953 --> 00:06:44,521 corresponding to X, 147 00:06:44,521 --> 00:06:45,519 Y and Z. 148 00:06:45,519 --> 00:06:48,399 You bind the buffer for the colors next. 149 00:06:48,399 --> 00:06:50,592 You specify the buffer data. 150 00:06:50,592 --> 00:06:53,855 You use layout location 1 for the colors, 151 00:06:53,855 --> 00:06:56,758 enable the VertexAttribArray and set the vertex attribute. 152 00:06:56,758 --> 00:06:59,496 Summarizing we use location 0 for the vertices, 153 00:06:59,496 --> 00:07:01,959 location 1 for the colors. 154 00:07:01,959 --> 00:07:03,376 Finally, you bind 155 00:07:04,560 --> 00:07:07,747 the buffer corresponding to the elements of the indices. 156 00:07:07,747 --> 00:07:09,993 You set the buffer data. 157 00:07:09,993 --> 00:07:12,141 You specify the primitive type, 158 00:07:12,141 --> 00:07:14,137 which will be GL_TRIANGLES. 159 00:07:14,137 --> 00:07:16,402 You specify the number of elements 160 00:07:16,402 --> 00:07:19,451 and then you do this glBindVertexArray of zero 161 00:07:19,451 --> 00:07:22,416 to prevent further modification of this vertex array object 162 00:07:22,416 --> 00:07:24,607 which is not desired. 163 00:07:24,607 --> 00:07:27,280 We now come to the interesting function, 164 00:07:27,280 --> 00:07:29,811 which is initalizing the cubes 165 00:07:29,811 --> 00:07:33,062 where you have the same geometry for each cube 166 00:07:33,062 --> 00:07:35,291 but it has different colors. 167 00:07:35,291 --> 00:07:37,056 Again, you take as input 168 00:07:37,056 --> 00:07:39,413 the object, the vertices, 169 00:07:39,413 --> 00:07:41,932 the indices and the type. 170 00:07:41,932 --> 00:07:45,984 First we define the outer loop over the number of colors. 171 00:07:45,984 --> 00:07:49,718 This outer loop is the four colors, 172 00:07:49,718 --> 00:07:51,301 or correspondingly, 173 00:07:52,161 --> 00:07:54,078 it is the four pillars. 174 00:07:56,839 --> 00:08:01,294 The next element says "For int j=0; j < 8" 175 00:08:01,294 --> 00:08:03,585 that is the vertices 176 00:08:03,585 --> 00:08:05,658 and the final element k = 0; 177 00:08:05,658 --> 00:08:09,096 k < 3 is the RGB color. 178 00:08:09,096 --> 00:08:12,896 Now notice this line which sets the cube color 179 00:08:12,896 --> 00:08:15,934 for each of the vertices in RGB 180 00:08:15,934 --> 00:08:18,666 to the corresponding uniform color 181 00:08:18,666 --> 00:08:21,416 in _cubecol for that value of 'i' 182 00:08:22,811 --> 00:08:26,117 in (i = 0 ; i < ncolors) 183 00:08:26,117 --> 00:08:29,231 and the 'k' is just the RGB color 184 00:08:29,231 --> 00:08:33,154 So that will be set, for each of the number of colors to red, 185 00:08:33,154 --> 00:08:34,071 green, blue 186 00:08:35,675 --> 00:08:36,592 and yellow in this case. 187 00:08:37,576 --> 00:08:40,151 Notice that this happens for each element 188 00:08:40,151 --> 00:08:42,218 in the outer loop, 189 00:08:42,218 --> 00:08:44,203 which is each of the four pillars 190 00:08:44,203 --> 00:08:46,048 or each of the four colors. 191 00:08:46,048 --> 00:08:48,174 We now bind the vertex array, 192 00:08:48,174 --> 00:08:50,310 corresponding to object + i. 193 00:08:50,310 --> 00:08:54,374 So, object will be the object corresponding to the cube, 194 00:08:54,374 --> 00:08:58,458 but you have different vertex array objects 195 00:08:58,458 --> 00:09:00,851 for each of the different pillars. 196 00:09:00,851 --> 00:09:03,649 That's why I'm saying object + i. 197 00:09:03,649 --> 00:09:05,225 The offset is just 198 00:09:05,225 --> 00:09:08,015 the object * numperobj as before 199 00:09:08,015 --> 00:09:11,486 because the offset will be used for the vertices. 200 00:09:11,486 --> 00:09:14,923 Recall that the geometry is the same for all of the cubes. 201 00:09:14,923 --> 00:09:18,401 However, the colors are different for all of the cubes 202 00:09:18,401 --> 00:09:20,574 and that's why I also define the base 203 00:09:20,574 --> 00:09:23,837 as the number of objects times number per object 204 00:09:23,837 --> 00:09:26,473 because after that each buffer will correspond 205 00:09:26,473 --> 00:09:27,625 to a different color. 206 00:09:27,625 --> 00:09:31,162 The first step is to bind the buffer corresponding 207 00:09:31,162 --> 00:09:33,197 to the vertices for the cube. 208 00:09:33,197 --> 00:09:35,063 That's why we said Vertices + offset. 209 00:09:35,063 --> 00:09:37,665 You get the buffer data 210 00:09:37,665 --> 00:09:41,506 and you use layout location 0 for the vertices. 211 00:09:41,506 --> 00:09:43,852 You enable the vertex attribute array. 212 00:09:43,852 --> 00:09:46,314 You set the vertex attribute pointer. 213 00:09:46,314 --> 00:09:49,505 The interesting thing is what happens with colors 214 00:09:49,505 --> 00:09:52,540 and in this case you're binding the buffer 215 00:09:52,540 --> 00:09:54,951 at base + i because the colors are stored 216 00:09:54,951 --> 00:09:58,421 after vertices color elements vertices color elements for the floor and the cube. 217 00:09:58,421 --> 00:10:02,588 But then I have a sequence of buffers for just the color 218 00:10:04,486 --> 00:10:07,040 and that's what base + i is doing. 219 00:10:07,040 --> 00:10:10,326 After that the standard commands for buffer data 220 00:10:10,326 --> 00:10:13,089 and enabling the VertexAtttribAarray(1) 221 00:10:13,089 --> 00:10:15,980 and its VertexAttribPointer 222 00:10:15,980 --> 00:10:19,426 so you can store layout location 1 for the colors. 223 00:10:19,426 --> 00:10:21,666 We now go to the elements. 224 00:10:21,666 --> 00:10:24,130 Again, Elements + offset; 225 00:10:24,130 --> 00:10:26,998 the elements are the same for all of the four pillars 226 00:10:26,998 --> 00:10:28,635 or all of the four cubes. 227 00:10:28,635 --> 00:10:30,992 You set the buffer data for them, 228 00:10:30,992 --> 00:10:33,126 you specify the primitive type, 229 00:10:33,126 --> 00:10:36,797 the number of elements and then you unbind the vertex array. 230 00:10:36,797 --> 00:10:38,039 In init, 231 00:10:38,039 --> 00:10:39,869 this is what happens. 232 00:10:39,869 --> 00:10:41,869 There is an initobject command for the floor, 233 00:10:41,869 --> 00:10:42,877 which is just 234 00:10:42,877 --> 00:10:45,907 the standard initobject we saw earlier in mytest1 235 00:10:45,907 --> 00:10:47,768 a couple of lectures ago. 236 00:10:47,768 --> 00:10:50,167 But then there is a separate initcubes command 237 00:10:50,167 --> 00:10:54,742 for the cube which will initialize the four cubes 238 00:10:54,742 --> 00:10:56,836 of the four pillars, 239 00:10:56,836 --> 00:10:59,003 each with different colors. 240 00:11:00,374 --> 00:11:02,884 And then there is a loadteapot command, 241 00:11:02,884 --> 00:11:05,067 which we will not be talking about here 242 00:11:05,067 --> 00:11:07,675 but if you are interested you can look below the hood, 243 00:11:07,675 --> 00:11:11,289 which initializes and sets up the teapot. 244 00:11:11,289 --> 00:11:15,793 We'll not talk about how you draw with and without colors. 245 00:11:15,793 --> 00:11:16,895 You may first be interested 246 00:11:16,895 --> 00:11:19,147 in the standard drawobject command 247 00:11:19,147 --> 00:11:22,024 which just binds the vertex array for the object 248 00:11:22,024 --> 00:11:26,191 and draws the elements corresponding to the primitive type 249 00:11:27,512 --> 00:11:29,440 of the object. 250 00:11:29,440 --> 00:11:30,818 The number of elements that the object, 251 00:11:30,818 --> 00:11:32,177 in this case we are using 252 00:11:32,177 --> 00:11:34,572 the UNSIGNED_BYTEs for the elements and then I unbind. 253 00:11:34,572 --> 00:11:36,647 For drawing with color it's very simple, 254 00:11:36,647 --> 00:11:39,805 I simply say object + color, 255 00:11:39,805 --> 00:11:41,068 object in this case would be cube 256 00:11:41,068 --> 00:11:44,151 and color would be the pillar number. 257 00:11:45,655 --> 00:11:47,504 So 0 would be red, 258 00:11:47,504 --> 00:11:49,444 then green, blue, yellow. 259 00:11:49,444 --> 00:11:51,706 And apart from that it's exactly 260 00:11:51,706 --> 00:11:53,774 the same as the drawobject command. 261 00:11:53,774 --> 00:11:56,651 So, I just bind the appropriate vertex array object 262 00:11:56,651 --> 00:11:59,056 and finally I load the teapot.