Chapter 15. Many Images

Table of Contents

Playing Checkers
Linear Filtering
Needs More Pictures
Anisotropy
How Mipmap Selection Works
Performance
In Review
Glossary

In the last tutorial, we looked at textures that were not pictures. Now, we will look at textures that are pictures. However, unlike the last tutorial, where the textures represented some parameter in the light equation, here, we will just be directly outputting the values read from the texture.

Playing Checkers

We will start by drawing a single large, flat plane. The plane will have a texture of a checkerboard drawn on it. The camera will hover above the plane, looking out at the horizon as if the plane were the ground. This is implemented in the Many Images tutorial project.

Figure 15.1. Basic Checkerboard Plane

Basic Checkerboard Plane

The camera is automatically controlled, though it's motion can be paused with the P key. The other functions of the tutorial will be explained as we get to them.

If you look at the BigPlane.xml file, you will find that the texture coordinates are well outside of the [0, 1] range we are used to. They span from [-64, 64] now, but the texture itself is only valid within the [0, 1] range.

Recall from the last tutorial that the sampler object has a parameter that controls what texture coordinates outside of the [0, 1] range mean. This tutorial uses many samplers, but all of our samplers use the same S and T wrap modes:

glSamplerParameteri(g_samplers[samplerIx], GL_TEXTURE_WRAP_S, GL_REPEAT);
glSamplerParameteri(g_samplers[samplerIx], GL_TEXTURE_WRAP_T, GL_REPEAT);

We set the S and T wrap modes to GL_REPEAT. This means that values outside of the [0, 1] range wrap around to values within the range. So a texture coordinate of 1.1 becomes 0.1, and a texture coordinate of -0.1 becomes 0.9. The idea is to make it as though the texture were infinitely large, with infinitely many copies repeating over and over.

Note

It is perfectly legitimate to set the texture coordinate wrapping modes differently for different coordinates. Well, usually; this does not work for certain texture types, but only because they take texture coordinates with special meanings. For them, the wrap modes are ignored entirely.

You may toggle between two meshes with the Y key. The alternative mesh is a long, square corridor.

The shaders used here are very simple. The vertex shader takes positions and texture coordinates as inputs and outputs the texture coordinate directly. The fragment shader takes the texture coordinate, fetches a texture with it, and writes that color value as output. Not even gamma correction is used.

The texture in question is 128x128 in size, with 4 alternating black and white squares on each side. Each of the black or white squares is 32 pixels across.

Fork me on GitHub