Texture Mapping

From OpenGL Wiki
Revision as of 07:37, 27 January 2007 by V-man (talk | contribs)
Jump to navigation Jump to search

First, let's talk about texture types available.

GL has GL_TEXTURE_1D. You can ignore this and use GL_TEXTURE_2D instead.
This has been part of GL since 1.0

GL_TEXTURE_2D has width and height and usually the GPU stores this in memory in a format that is quick to access.
For example, small blocks of the texture are stored in sequence so that cache memory works better. This has been part of GL since 1.0

GL_TEXTURE_3D has width and height and depth and usually the GPU stores this in memory in a format that is quick to access.
Just like 2D, small blocks of the texture are stored in sequence so that cache memory works better but other techniques exist as well.
This has been part of GL since 1.2

GL_TEXTURE_CUBE_MAP has width and height and 6 faces. Kind of like 2D except it has 6 faces and texcoords work in a special way.
This has been part of GL since 1.3

GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_RECTANGLE_ARB are supported as extensions. For having non power of 2 dimension 2D textures. Texcoords worked in a unusual way. From 0 to width for S. From 0 to height for the T.

With GL 2.0, GL_TEXTURE_RECTANGLE becomes obsolete. You can make textures with any dimension, mipmap it, use any anisotropy supported, use any texture wrap mode.

How to create a texture?

Create a single texture ID
GLuint textureID;
glGenTextures(1, &textureID);

You have to bind the texture before doing anything to it. glBindTexture(GL_TEXTURE_2D, textureID);
Now you should define your texture properties. Any call sequence will work since GL is a state machine.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, TextureWrapS);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, TextureWrapT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, MagFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter);

Some people make the mistake of not calling glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter); and they get the default state GL_LINEAR_MIPMAP_NEAREST and they don't define the mipmaps, so the texture is considered incomplete and you just get a white texture.

If you will use mipmapping, you can either define them yourself by making many calls to glTexImage2D
Since current GPUs can generate it automatically with a box filter technique, you can call
Mipmapping is usually good and increases performance.

If you need anisotropy call

Anisotropy is an extension. It can drag down performance greatly and make your results look better. Use as less as possible.

Define the texture with
glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, border, format, type, ptexels);

You need to make sure that your width and height are supported by the GPU.
Very old GPUs don't support border texels.
Make sure the format is supported by the GPU else the drivers will convert into a proper format.
Make sure the internal format is supported by the GPU (example : GL_RGBA8) else the driver will convert the texture for you.
You should also call glGetError to make you don't get an error message like running out of memory.

The only thing left is calling glTexEnv but this isn't part of the texture state. It is part of the texture_environment, in other words the texture unit.

To use the texture, bind it to a texture unit with glBindTexture and don't forget to enable texturing with glEnable(GL_TEXTURE_2D) and disable with glDisable(GL_TEXTURE_2D)
That's the basics of creating a texture and using it.