Advanced Textures

CS 481 Lecture, Dr. Lawlor

Texture Handles and Units

You can have a bunch of different texture images uploaded on the graphics card at the same time.  You then tell OpenGL which texture you want by "binding" a "texture handle" with glBindTexture.  Almost all the texture calls apply to the currently-bound texture.

You can make a new texture with glGenTextures(1,&newHandle).

To render with the texture, you just need it bound to a texture "unit".  You set the active texture unit with glActiveTexture, passing a constant like GL_TEXTURE1 to select the first texture unit.  You then indicate that unit should render a texture by binding the texture.  Here's how it looks:
	static unsigned int someTex=0; /* my texture "handle" */
if (someTex==0) { /* initialize the texture only once */
glGenTextures(1,&someTex); /* make one texture */
glBindTexture(GL_TEXTURE_2D,someTex); /* use texture */
readTextureFromFile("some_thing.bmp"); /* load texture with data */
}

// Later, at rendering time:
glActiveTexture(GL_TEXTURE3); // for texture unit 3...
glBindTexture(GL_TEXTURE_2D,someTex); // ...render someTex
// Tell GLSL that the "uniform sampler2D frigginTex;" is texture unit 3:
glUniform1iARB(glGetUniformLocationARB(prog,"frigginTex"),3);
Yes, it's kinda wonky.  The problem here is that four separate generations of OpenGL added these features one at a time:

Texture Parameters

There sure is a lot of texture state accessible via the glTexParameter function.  All this state applies to the currently-bound texture (last call to glBindTexture).

You can adjust whether textures wrap-around (GL_REPEAT) or clamp  (GL_CLAMP_TO_EDGE) out-of-bounds texture coordinates, on a per-axis basis:
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
You can adjust the minification and magnification modes to disable all filtering:
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
Or you can turn on mipmaps, and have beautiful linear filtering:
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
You can even turn on anisotropic filtering (via this extension), and avoid plain mipmapping's too-blurry horizon:
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT,100);
You can ask OpenGL to rebuild the mipmaps whenever texture level 0 changes:
	glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
And suprisingly *none* of this really costs much runtime performance!

Framebuffer Feedback

You can copy the currently-rendered display into the currently-bound texture with
glCopyTexSubImage2D.