In this lecture, we're going to talk more about OpenGL. We're going to look at the demo we had a couple of lectures back with the simple plane. And we're going to gradually make it more complicated. We'll start with the simple mytest1 program that I showed in OpenGL 1, which just drew a plane. And through a sequence of steps, each of which will show a demo, we will make it gradually more complicated. Let me show you first the program. So here you see now that I have not just my plane. But I also have the 4 pillars with different colors and I have my teapot which is animated over the scene. Let's first review the last demo and then we'll add more functionality. As I said earlier, we're actually going to be able to compile and run these programs. So here is the source code for the program. And I've introduced this nice DEMO flag so that I don't have to write code. And so if I just set it to zero, it will reduce back to the previous assignment. I can even compile this. And again, I mean, you see that it's a fairly standard compilation, it just has the few additional flags. And now I can actually run this. Note that the text here is just reading off the fragment shader, so that I can see what it is. And now I have the simple plane I can move around, and it's just the first demo. Okay. So let's get rid of these compilation and source code windows, so we can look again at the slide. And if you download and play with the program, which I highly encourage you to do, then you can set the DEMO variable as equal to 4 for all of the features, or you can step up slowly, and you can see the different features. Notice that I've included GLUT, I've included shaders and geometry. And I defined as before mouseoldx, mouseoldy, eye location. The new definition is the teapot location, which is where the teapot is located. I also include a flag to say whether we are actually animating or not, and then vertex, fragment shaders and the shader programs, and then the DEMO variable to see what parts you want to actually show. Let's do a brief overview of this lecture. So first, we do the review of the demo from the last lecture. This segment concerns the basic geometry setup for the cubes, which is the pillars. And how you can use a single geometric object, but you can draw it at different locations in the scene with different colors. Subsequent segments will deal with basic matrix stacks, and transforms, depth testing or Z-buffering, animation and texture mapping. Here is the basic geometry setup. Again, I have two objects, which in this case is the cube and the floor. The number of buffers per objects again, I have the colors, I have the positions, I have the index faces to specify the object. And now defining the number of colors for the floor and so the number of buffers is the product of the num per object times the number of objects, plus the same colors variable because I will have four colors for the floor. And number of objects again defining, and then there's this buffer offset macro, I enum Vertices, Colors and Elements, which are the three buffers, and I enum FLOOR and CUBE for the objects for floor and the cube. Let's now talk about the cube geometry. And, I've defined the width as 0.1 and the height is 0.5, and I define the cube colors, so this is red, this is green, this is blue, and this is red plus green which is yellow. And the cube vertices now, so the definition of the cube vertices is in terms of width and height and I mean it's fairly straightforward, so it's going from 0 to height and -width to width. And then I define the cube indices. So what zero, one, two, and three is, is the bottom face of the cube. And you can see, it's -width, -width, zero, -width, +width, zero. So it's just the bottom-most plane of the cube. And the other ones are defining the different other faces of the cube. So in this way I've just defined arrays for the cube geometry. So here is a function that initializes the object but does not include colors. So the draw geometry types of functions that we saw earlier on the plane in OpenGL 1 also set the colors for the object. But in this case we are going to instantiate the same object in multiple locations with multiple different colors and therefore we write this function to not consider colors. So offset is just where in the buffer array where you want to be. You bind the buffers, vertices plus offset and then you specify the vertex data. You define the vertex pointer and enable the client state. And then you define the elements which is your indices or faces, such as 0, 1, 2 and 3 to define the bottom face. You specify the buffer data for that. And you define the primitive type and the number of elements for the object. So everything you did earlier for drawing vertex buffer objects, except for specifying the colors. Finally we come to the function to actually define the colors on the cube. And again, you have this base as numobjects times numperobj, and you define the colors as follows. So here you go through the number of colors and what I am doing is that I am considering all of the 8 vertices on the cube, in order to define the color appropriately. And k is equal to 0, k is equal to 3, this is just RGB. So this is RGB, and I am just going through those indices. So cube color j and k. So j is the face. So this is the appropriate face on the cube. And cube color i is the appropriate color. So we define the appropriate face with the correct color, okay? And then for each step here, so for each of the colors, notice that this whole loop is applied for each of the colors. You bind the buffer which is base + i. So the first numobjects * numperobj buffers are for the vertices and the face definitions. Whereas, after that, you start with the buffers for the appropriate color. And for each of these, you specify the appropriate color data. Then you set up the color pointer, as we did earlier in draw objects. And you enable the color array. Notice that this goes on for each of the 4 colors, and so you have 4 different color arrays. When we eventually draw, we will associate the right color array with the object, in order to draw it. So in init, you init the objects without colors, and then you will init the colors. So now we come to the draw function, and it's drawing with colors. So again, you define the offset appropriately and then the base for the colors that you're choosing. So you first bind the vertices. And you enable the vertex array. Then you bind the colors. And here, it's base plus color instead of offset plus vertices. So earlier, it was using the offset, but now we're using the base. And then again, you do the same thing for the colors. And finally, you do it for the elements. So the only thing that's different from the standard draw routine is that the color buffer now comes from one of the fixed buffers at the end, instead of being associated with each object separately.