- The Basic Graphics Pipeline
- Setting Up Your Coordinate System
- Using the Stock Shaders
- Connecting The Dots
- Blending
- Summary
Using the Stock Shaders
In the OpenGL Core Profile, there is no built-in rendering pipeline; you must specify a shader before you can submit geometry for rendering. This presents a bit of a chicken and egg scenario (which came first, the chicken or the egg) when learning graphics programming. The approach we think works best is to supply a set of stock shaders that you can use for the first part of this book. These stock shaders are managed by the GLTools C++ class GLShaderManager and provide a simple baseline of common rendering needs. Programmers with simple needs may even find the stock shaders sufficient for all their anticipated tasks. With time, however, it is unlikely that all but the most casual 3D programmer will be happy being kept in this box, and thus near the end of the introductory section of this book is Chapter 6.
The GLShaderManager must be initialized before use, and in all the sample programs you find an instance of GLShaderManager near the top of the source file and a call to InitializeStockShaders in SetupRC.
shaderManager.InitializeStockShaders();
Attributes
OpenGL supports up to 16 different generic attributes that can be set per vertex. These are numbered 0 through 15 and can be associated with any specific variable in your vertex shader (how to do this is covered in Chapter 6). The stock shaders all use a consistent variable naming convention internally and the same attribute slot for each variable. These attributes are listed in Table 3.1 and represent the most common basic attributes needed for simple rendering needs. The attribute mechanism is quite flexible and can be used in ways far beyond these few predefined values. You learn more about this in Chapter 6 and Chapter 11, "Advanced Shader Usage."
Table 3.1. GLShaderManager Predefined Attribute Identifiers
Identifier |
Description |
GLT_ATTRIBUTE_VERTEX |
Three component (x, y, z) vertex position |
GLT_ATTRIBUTE_COLOR |
Four component (r, g, b, a) color value |
GLT_ATTRIBUTE_NORMAL |
Three components (x, y, z) surface normal |
GLT_ATTRIBUTE_TEXTURE0 |
Primary two component (s, t) texture coordinate |
GLT_ATTRIBUTE_TEXTURE1 |
Secondary two component (s, t) texture coordinate |
Uniforms
To render geometry, you need to submit the attribute arrays for your object, but first you must bind to the shader program you want to use and supply the program's uniforms. The GLShaderManager class takes care of this for you (for now). The function UseStockShader selects one of the stock shaders and supplies the uniforms for that shader, all in one function call.
GLShaderManager::UseStockShader(GLenum shader, ...);
The ... signifies in C (or C++) that the function takes a variable number of parameters. In the function itself, it pulls the appropriate arguments off the stack based on which shader you selected, which are the uniforms that the particular shader requires. Each of the stock shaders is discussed next. Although all of the uniforms may not make sense to you at this point, they should by the time you finish the introductory section of this book. This is a section you may want to bookmark, as you may find yourself referring back to this reference periodically.
The Identity Shader
The identity shader simply draws geometry using the default Cartesian coordinate system (-1.0 to 1.0 on all axes). A single color is applied to all fragments, and the geometry is solid and unshaded. The only attribute used is GLT_ATTRIBUTE_VERTEX. The vColor parameter contains the desired color.
GLShaderManager::UseStockShader(GLT_SHADER_IDENTITY, GLfloat vColor[4]);
The Flat Shader
This shader extends the identity shader by allowing a 4 x 4 transformation matrix to be specified for geometry transformations. This is typically the premultiplied modelview matrix and the projection matrix, often called the modelview projection matrix (this is explained further in Chapter 4). The only attribute used is GLT_ATTRIBUTE_VERTEX.
GLShaderManager::UseStockShader(GLT_SHADER_FLAT, GLfloat mvp[16], GLfloat vColor[4]);
The Shaded Shader
This shader's only uniform is the transformation matrix that is to be applied to the geometry. Both the GLT_ATTRIBUTE_VERTEX and the GLT_ATTRIBUTE_COLOR are used by the shader. Color values are interpolated smoothly between vertices (smooth shading this is called).
GLShaderManager::UseStockShader(GLT_SHADER_SHADED, GLfloat mvp[16]);
The Default Light Shader
This shader creates the illusion of a single diffuse light source located at the eye position. Essentially, it makes things look shaded and lit. Uniforms needed are the modelview matrix, the projection matrix, and the color value to use as the base color. Required attributes are GLT_ATTRIBUTE_VERTEX and GLT_ATTRIBUTE_NORMAL. Most lighting shaders require the normal matrix as a uniform. This shader derives the normal matrix from the modelview matrix—convenient, but not terribly efficient. Bear that in mind for performance-sensitive applications.
GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);
Point Light Shader
The point light shader is similar to the default light shader, but the light position may be specified. This shader takes four uniforms, the modelview matrix, the projection matrix, the light position in eye coordinates, and the base diffuse color of the object. Attributes used are GLT_ATTRIBUTE_VERTEX and GLT_ATTRIBUTE_NORMAL.
GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);
Texture Replace Shader
This shader transforms geometry by the given modelview projection matrix and uses the texture bound to the texture unit specified in nTextureUnit. Fragment colors are taken directly from the texture sample. Attributes used are GLT_ATTRIBUTE_VERTEX and GLT_ATTRIBUTE_TEXTURE0.
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfloat mvpMatrix[16], GLint nTextureUnit);
Texture Modulate Shader
This shader multiplies a base color by a texture from texture unit nTextureUnit. Attributes used are GLT_ATTRIBUTE_VERTEX and GLT_ATTRIBUTE_TEXTURE0.
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfloat mvpMatrix[16], GLfloat vColor, GLint nTextureUnit);
Textured Point Light Shader
This shader modulates (multiplies) a texture by a diffuse lighting calculation, given a light's position in eye space. Uniforms are the modelview matrix, projection matrix, the light position in eye space, the base color of the geometry, and the texture unit to use. Attributes used are GLT_ATTRIBUTE_VERTEX, GLT_ATTRIBUTE_NORMAL, and GLT_ATTRIBUTE_TEXTURE0.
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vBaseColor[4], GLint nTextureUnit);