Tutorial 11 :
Environment Mapping

Tutorial Advanced Download Section

IN this tutorial, we will use automatic texture coordinate generation to create environment and reflection mapping.

This tutorial containts a port NeHe and McCLaw (www.sulaco.co.za) tutorial. The NeHe's port shows how to use sphere mapping and the McClaw's one shows how to use cube mapping.
 

Texture coordinates can be automatically generated by OpenGl. Automatic texture generation is used here to create an environment/reflection effect.

Texture coordinate generation is specified with :
  gl.glTexGen*(coordinate, parameter, value)

Here is how to specify texture coordinate generation :
 coordinate is the component of the texture coordinate ie GL_R, GL_S, GL_T or GL_Q.
 parameter is GL_TEXTURE_GEN_MODE to specify that we want texture coordinate generation.
 value associated to parameter are :

GL_OBJECT_LINEAR is suitable to apply a fix texture to an object. GL_EYE_LINEAR is suitable to apply moving texture depending on eye position.

Here is how to specify the projection direction :
 coordinate is the component of the texture coordinate ie GL_R, GL_S, GL_T or GL_Q.
 parameter is GL_OBJECT_PLANE or GL_EYE_PLANE, they are associated respectively to GL_OBJECT_LINEAR and GL_EYE_LINEAR.
 value associated to this parameter is a plane equation (see tutorial 8 to find basic plane equation)
 

The effect created with such mapping is as if we look through a lens/glass. The environment viewed throught the lens/glass is distorded to light perturbation when passing through the transluscent material (light diffracted).

Look how it is simple, we enable GL_S and GL_T coordinate generation with sphere mapping and bind our texture. Then draw any shape you want and that's done.
Note: As you use automatic texture coordinate generation, you don't need to call glTexCoord.
 

GL_SPHERE_MAP

  //Texture use for automatic coordinate generation
  gl.glBindTexture(GL.GL_TEXTURE_2D, texture);
  gl.glEnable(GL.GL_TEXTURE_2D);

  //Sphere mapping and enable s & t texture generation
  gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
  gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_SPHERE_MAP);
  gl.glEnable(GL.GL_TEXTURE_GEN_S);
  gl.glEnable(GL.GL_TEXTURE_GEN_T);

  //Draw the shapes to apply the texture
  ...

  gl.glDisable(GL.GL_TEXTURE_GEN_S);
  gl.glDisable(GL.GL_TEXTURE_GEN_T);
  gl.glDisable(GL.GL_TEXTURE_2D);

The texture used for GL_SPHERE_MAP is a distorded environment.
Such texture can be created either with or with some advanced paint program.

 
Environment
(for background)
  Distorded texture
(for GL_SPHERE_MAP)

If the distorded texture is the distortion of the foreground, effect created with such mapping is some reflection mapping.
 

The environment is defined as a cube, each faces with a texture.

GL_TEXTURE_CUBE_MAP define 6 textures for a cube GL_TEXTURE_CUBE_MAP_dir_axis.
 dir (direction) is POSITIVE or NEGATIVE
 axis is X, Y or Z
So, GL_TEXTURE_CUBE_MAP_POSITIVE_Z is the front face of the cube, GL_TEXTURE_CUBE_MAP_NEGATIVE_X the left side and so.
Note : when creating the textures, the target should be GL_TEXTURE_CUBE_MAP_dir_axis instead of GL_TEXTURE_2D.
 

GL_TEXTURE_CUBE_MAP

   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_X, cubeMap[0]);
   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, cubeMap[1]);
   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, cubeMap[2]);
   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, cubeMap[3]);
   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, cubeMap[4]);
   gl.glBindTexture(GL.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, cubeMap[5]);

   gl.glEnable(GL.GL_TEXTURE_CUBE_MAP);

   //Environment mapping (see underneath)
   ...

   gl.glDisable(GL.GL_TEXTURE_CUBE_MAP);


We want this environment to be reflected on our shapes/objects. That's what GL_REFLECTION_MAP will do for you.
Enable GL_S, GL_T and GL_R with GL_REFLECTION_MAP and draw the object and that's done !

GL_REFLECTION_MAP

   //GL_REFLECTION_MAP for s,t,r texture coordinates
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
   gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);
   gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_REFLECTION_MAP);

   gl.glEnable(GL.GL_TEXTURE_GEN_S);
   gl.glEnable(GL.GL_TEXTURE_GEN_T);
   gl.glEnable(GL.GL_TEXTURE_GEN_R);

   //Draw shape to aply reflection on it
   ...

   gl.glDisable(GL.GL_TEXTURE_GEN_S);
   gl.glDisable(GL.GL_TEXTURE_GEN_T);
   gl.glDisable(GL.GL_TEXTURE_GEN_R);

 

GL_OBJECT_LINEAR apply a fix texture on an object. You can see that the texture of the two above pictures are fixed relatively to the object. The different between the two picture is the plane equation GL_OBJECT_PLANE. First have the x plane (plane perpendicular to x axis ie vertical plane), second is an oblique plane.
GL_EYE_LINEAR apply texture that depends on the eye position. The eye is moving relatively to the object, so texture coordinate generation is varying (case of the underneath example). The texture is fixed relatively to the eye.
 

GL_OBJECT_LINEAR
GL_S, X plane

GL_OBJECT_LINEAR
GL_S, Oblique plane

GL_EYE_LINEAR
GL_S, X plane

GL_EYE_LINEAR
GL_S,
Oblique plane

Note : Texture used is a 1 dimensional texture (1x128 pixels) with 3 strips (one at left, right and center)

 

File Name

   gl.glEnable(GL.GL_TEXTURE_GEN_S);

   //Top left viewport
   ...
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
   gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, xPlane);
   ...

   //Top right viewport
   ...
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);
   gl.glTexGenfv(GL.GL_S, GL.GL_OBJECT_PLANE, xyzPlane);
   ...

   //Bottom left viewport
   ...
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, xPlane);
   ...

   //Bottom right viewport
   ...
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, xyzPlane);
   ...

   gl.glDisable(GL.GL_TEXTURE_GEN_S);

 

We want a fix texture on the teapot, so we use GL_OBJECT_LINEAR :

Texture to a teapot

   gl.glEnable(GL.GL_TEXTURE_GEN_R);
   gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_OBJECT_LINEAR);

   //Draw the teapot
   ...

   gl.glDisable(GL.GL_TEXTURE_GEN_R);

Result is shown on the following picture


GL_OBJECT_LINEAR example

Use 1-7 keys to select a scene.
 

Remember to download the GraphicEngine-1.1.2 to run this tutorial !


If you've got any remarks on this tutorial, please let me know to improve it.
Thanks for your feedback.
 

Previous Tutorial

Back

Next turorial

Copyright © 2004-2012 Jérôme Jouvie - All rights reserved. http://jerome.jouvie.free.fr/