In this tutorial, you have learned the following:
Textures are objects that store one or more arrays of data of some dimensionality. They can be created and filled with data from OpenGL. Shaders can reference them with sampler types, and they can access them using texturing functions. The values in a texture have a specific meaning; never forget what the texture and its stored data represent.
The data in textures can represent arbitrary information. They can be used to vary a material parameter across a surface, replace a complex function with a look-up table, or anything else you might need a multi-dimensional array of values for.
Vertex or geometry shader outputs interpolated across polygons can be interpolated linearly in window space or linearly in pre-projection space. The GLSL interpolation qualifiers control which kind of interpolation happens.
Textures can be associated with points on a surface by giving those vertex attributes texture coordinates. The texture coordinate is interpolated across the triangle's surface and then used to fetch values from a texture. This is but a part of the utility of textures.
Try doing these things with the given programs.
If you were to look at the look-up table for our specular function, you will see that much of it is very dark, if not actually at 0.0. Even when the dot product is close to 1.0, it does not take very far before the specular value becomes negligible. One way to improve our look-up table without having to use larger textures is to change how we index the texture. If we index the texture by the square-root of the dot-product, then there will be more room in the table for the values close to 1.0, and less for the values close to 0.0. This is similar to how gamma correction works. Implement this by storing the values in the table based on the square-root of the dot-product, and then take the square-root of the dot-product in the shader before accessing the texture.
Animate the texture coordinates in the texture mapping tutorial. Do this
by sending an offset to the fragment shader which is applied to the texture
coordinates. You can generate the offset based on the
g_lightTimer. Make sure to use the
mod function on the texture coordinates with a
value of 1.0, so that the texture coordinate will always stay on the range
These functions create texture objects and bind them to a specific
texture target in the OpenGL context.
glActiveTexture selects which texture unit the
texture all texture object commands refer to, including
glBindTexture. The first time a texture is
bound to a target, that texture object takes on the texture type
associated with that target. It then becomes illegal to bind that
texture to a different target. So if you bind a texture to
GL_TEXTURE_2D the first time, you cannot bind it
to any other target ever again.
Allocates storage for an image in the currently bound texture of the currently active texture unit. If the last parameter is not NULL, then these functions will also upload data to that image. Otherwise, the content of this image is undefined.
Sets a parameter in the currently bound texture of the currently active texture unit.
These functions create sampler objects and bind them to the context for use.
Sets a parameter to the given sampler object. Unlike most OpenGL functions that operate on objects, this function takes a sampler object as a parameter; it does not require that the sampler object be bound to the context.
Accesses the texture associated with
texSampler, at the
location given by
texCoord. The sampler type can
be any of the sampler types. The number of components of vec depends on
the type of sampler used; a sampler1D takes a single
float, while a sampler2D takes a vec2.