The final segment in this initial sequence on OpenGL deals with initializing the shader. Let's go back to the OpenGL rendering pipeline. As you can see, there are vertices and images that both go through the OpenGL pipeline. Vertices are transformed by a vertex shader. Then you do scan conversion, generate fragments, that's where the geometry intersects each pixel, is called a fragment rather than a pixel because multiple geometric objects could intersect the pixel. You might have multiple fragments for a pixel because of things like antialiasing. Those fragments are processed by the fragment shader. This lecture is about how you set up the bare bones, no-op fragment and vortex shaders and hook them into OpenGL. So the simplified OpenGL pipeline, user specified vertices, vertex buffer object. For each vertex in parallel, OpenGL calls the user specified vertex shader, which transforms the vertex. In the simplest case, just does model view and projection matrices. For each primitive, OpenGL then rasterizes these transformed vertices and it generates at least one fragment for each pixel the corresponding vertex covers. For each fragment in parallel, the OpenGL calls the user specified fragment shader, which then goes through shading and lighting calculations. OpenGL, by default, handles the Z-buffer test by itself, but you can override it. The shader setup consists of a number of individual steps. So we'll discuss the shader itself later. First you have to create the shader, vertex and fragment shaders. Then you have to compile the shaders, you have to attach the shaders to a program. You have to link the program, and you have to use the program. And you have to do each of these steps. So what is a shader? It's just a source which is a sequence of strings. As far as the C program goes, it's a sequence of strings. And then, you just compile these strings just as you would compile a normal program. Here is the shader initialization code. This is my initshaders code. GLenum type is vertex or fragment and the file name. And this code is largely derived from what is recommended in the OpenGL book. So look at the different steps. So first you create a shader of the given type. Then you read the text file. That's my own command for reading the text file where the shader is stored. The shader, remember, as far as the program is concerned, is only a sequence of strings. But I've stored it in a text file. Okay, so you set up a new array, which is the size of the string, and let's ignore this. This is just to get a constant character so you don't complain. And it copies it in here. So then you define the shader's source for the given shader. It has only one string. You give the string, and this remaining parameter you don't need to use. You then compile the shader. And here is something interesting. From OpenGL, you can get a number of status flags. So, this is the status flag which tells you what the compile status is. If the compile status has an error, I call this function to describe the shader errors. And this is C++, you throw an exception. If the compile thing doesn't have errors, I return the number of the shader which I get from OpenGL. Next step is to link the shader program, and so here I have given the vertex shader and I have given the fragment shader. I create the program, I attach them to the program and then I link the program. Again, I get the link status, and if it's linked, I use the program. If it's not linked, I have to throw an exception and print out errors. Finally we come to what a basic shader will be, and this is in your directory, it's in the shaders directory, it's called nop because it really doesn't do much. It's almost no-op shader. Of course it will make it more complicated in subsequent lectures. And we have done it for vertex and fragment. It is written if GL shading language known as GLSL, which much like OpenGL itself provides a unified API in which to write shaders, which will later be compiled of course internally onto the graphics card. We have both a vertex shader and fragment shader and they communicate because the outputs of the vertex shader often inputs to the fragment shader. So, in fact, the outputs in vertex shader and vertices are interpolated and rasterized and given to the fragment shader. Version is the version of the GLSL that is used. I think it's currently up to 300 or 400, but I just want to be completely backward compatible, so I am using 120. There's also the, the language has been changing and so this command varying is technically correct in 120 and some cases I've used attribute, and that doesn't work on the Mac. So, just follow the skeleton code that you are given to know the correct command to use. In and out is something that they recommend more modernly, but in either way, the skeletons that we provide should work, and should have the right command. The important thing is that this says that this vec4 color is an output variable from the shader, which will then go into the fragment shader. So the main command, just like in C, it's pretty much code as written like in C, but you have a lot of interesting things you can do also. Like you can swizzle. You can have half vectors and, there's a lot of information that's provided if you look up the GLSL. So gl_Position is equal to projection matrix. So gl_Position is a special thing that says where the position is. Projection matrix times model view matrix times the vertex. And this is just the standard projection times model view. And the color is, again, the special variable GL color, which is the input color. But I have explicitly used this to pass it to the fragment shader, and show you how that's done. Here is my fragment shader. Again, this attribute you should probably replace with varying on the Mac. And our skeletons are correct. In other cases, you might want to use in and out. Essentially it is a no-op, where it just says, GL fragment color, again a specific thing which is what is the color of the fragment, is just equal to color. So it's just showing you the basics of how you pass an argument from the vertex shader to the fragment shader.