|
|||||||||||||||
|
Very often in 3D, it is desirable to use an image (perhaps a distinguishable image like a face or just some different colours arranged to make a 'texture') to "wrap around" the surface of an object. You will see this in 3D games, (e.g. Goldeneye for N64), where the bad guys look quite good from a distance, but when you get really close you notice their faces aren't modelled, they're just boxes with pictures of faces on them. This is quite acceptable, of course.
This example is a cylinder with a label mapped on to it - in front of a plane with an image of bricks mapped on to it. How much harder would it be to model this? There are two kinds of textures used in 3D (for both OpenGL and programs like Inspire3D):
Images can be any regular picture from any source (although the size and format might be important depending on your use). Procedural textures are images that are created from some form of procedure or mathematical function. Inspire3D's built in "ripples" and "fractal bumps" are good examples of these (covered in lecture 06).
The image of the dog above is an image map, with the ball on the right being a procedural texture. Textures are created by a texture function - texture(t,s), the parameters of which are the x and y coordinates of the pixels in the image (or parameters for the function if it's procedural). t and s are always defined from 0 to 1, with 1 being the extremity of the image. To get textures on to your surfaces in OpenGL, you use the glTexCoord2f(s,t) function along with each vertex in your face. This sets the position of the texture with respect to the face. Normally a quad polygon will have the four texture coordinate extremities mapped on to its vertices, but this can be set at will.
The above code maps the current texture (see below) on to the polygon using the coordinates as defined. OpenGL does not provide functionality for loading external images,
but this has been implemented in the source code example files below.
The first line binds the texture to a particular 'name' (integer) so that it can be referenced when needed. The next two set the parameters for how OpenGL should deal with the image when it needs to be resized up or down (as will almost always be the case, unless the number of pixels in the image are equal to the number in the polygon in both directions). The 'GL_NEAREST' property means to simply use the texel (texture element) that is nearest the centre of the pixel. The final line does the actual associating of the pixmap (in this case a 2D array of pixels called "pixel") to the current texture. To tile the image over a surface, you can simply use s and t values of
more than 1; e.g. a value of 2 in s and 3 in t will tile (perfectly) twice
horizontally and three times vertically. You also need to enable texturing - glEnable(GL_TEXTURE_2D); You can use any bitmap format for textures, provided you can write code
to read it in to a 2D array (although textures can also be 1D and 3D).
The code from Hill, chapter 8 reads 24 bit BMP files. As well as using textures for image mapping, you can also use them for defining contours (bump mapping) and reflections (environment mapping) (as in Inspire3D). Code The source code example below was compiled from various parts of the
text, mainly Figure 8.52, with the RGBpixmap.h file added to from the
appendix3.cpp file. There are also some sample bmp files for use in this
program. There is also a sample program here taken from the Romka Graphics link (see links). This file works similarly to the above example, but with some differences. It loads TGA files instead of BMP, it has some interaction (a,z, mouse buttons), and it's implemented in C. |
|
||||||||||||||