Second Life landscape by Vania Lahtoh, CC-BY-SA
Image data is often saved in or loaded from a file
There are many common image formats: JPEG, TIFF, PNG, GIF, etc
Features which may vary between formats are:
Provides support for reading, writing, and manipulating images in several formats.
PIL website: www.pythonware.com/products/pil/
Handbook: www.pythonware.com/library/pil/handbook/
>>> import Image >>> img = Image.open("foo.jpg") >>> img.size (512, 512) >>> img.mode 'RGB' >>> newimg = img.resize((32,32)) >>> newimg.save("bar.tif")
Note: don't do "from Image import *", because that will replace the normal open() function with the Image package's open().
img = Image.open('myimage.tif')
img = Image.new('RGB', (640,480), (255, 255, 255))
img.save('newimage.jpg')
img2 = img1.resize( (256, 256), Image.ANTIALIAS )
img2 = img1.transpose( Image.FLIP_TOP_BOTTOM )
img2 = img1.rotate(30)
img2 = img1.convert( 'L' )
imgdata = img.tostring()
img.fromstring(imgdata)
or
img = Image.fromstring('RGB', (640, 480), imgdata)
rgb = img.getpixel( (10, 31) )
img.putpixel( (10, 31), (255, 255, 0) )
Applying textures in OpenGL involves the following steps:
Enable texturing | glEnable(GL_TEXTURE_2D) |
Define a texture | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData) |
Assign texture coordinates | glTexCoord2f(0,0) glVertex2f(-1.0, -1.0) glTexCoord2f(1,0) glVertex2f(1.0, -1.0) |
Examples: texturedSquare.py texturedSquare_PIL.py
Defining a texture transfers the image data to the graphics card
Texture objects let you do this once, and then use the texture again later by referring to its ID (its "name").
textureID1 = glGenTextures(1) glBindTexture(GL_TEXTURE_2D, textureID1) glTexImage2D(...) glBindTexture(GL_TEXTURE_2D, 0) ... glBindTexture(GL_TEXTURE_2D, textureID1) # Draw textured object
glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels)
target - GL_TEXTURE_2D
level - used in mipmapping; set to 0
internalFormat - usually the same as format;
can be used for optimization
width & height - size of the image, in pixels
border - normally 0; set to 1 when image data includes a border
format - GL_RGB for RGB images, or GL_LUMINANCE for greyscale
(there are other formats as well)
type - data type of the pixel data.
GL_UNSIGNED_BYTE is standard for 8-bit-per-channel images.
pixels - the actual array of image data.
Use the tostring() function with PIL images.
Note: Generally, width & height must be powers of 2 - i.e., 2, 4, 8, 16, 32, 64, 128, 256, 512, etc. (some times other sizes work, but not always)
Objects need texture coordinates to define how a texture is applied
Texture coordinates form a coordinate system on the texture image, ranging from 0 to 1 in each direction
They are referred to as S and T
(to distinguish them from X & Y geometric coordinates)
One texture coordinate should be assigned for each vertex
This defines what part of the texture should be used at that point
When a polygon is filled in, the vertices' texture coordinates are interpolated across its surface, to find the texture data for each pixel
A texture does not have to be evenly applied to a polygon.
The image can appear distorted, either as a result of the geometry or the texture coordinates used.
Texture coordinates outside the range 0 - 1 can be used to tile a texture
Tiling is controlled by the WRAP texture parameter:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
for no tiling:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
Textures provide color information, but so does glColor or lighting.
The texture environment controls how these colors interact.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode)
A "GL_REPLACE" environment uses just the texture color, and ignores everything
else.
Color = Ct
A "GL_MODULATE" environment combines the texture and other color, multiplying
them together.
Color = Ct * Cf
Example: texenv.py
Applying a texture involves sampling - for each pixel drawn on the screen, OpenGL must compute a color from the texture image.
Texels (texture pixels) rarely match up exactly 1-to-1 with the pixels on the screen .
Filtering modes select what to do when texels are larger than screen pixels (magnification), or when texels are smaller than screen pixels (minification).
glTexParameteri(GL_TEXTURE_2D, filter, mode)
If filter is GL_TEXTURE_MAG_FILTER, mode can be
If filter is GL_TEXTURE_MIN_FILTER, mode can be
Example: texfilter.py
Mipmapping uses versions of the texture at smaller & smaller sizes image, to effectively pre-compute the average of many texels.
As a texture gets more and more minified, many texels will correspond to a single screen pixel, and using a "nearest" or "linear" filter will not compute an accurate result. The texture will appear to flicker as the object moves.
A mipmapped texture avoids the flickering problem when minified. As a result, it can look a bit fuzzier.
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels)
Use gluBuild2DMipmaps in place of glTexImage2D.
It will automatically generate all the smaller versions of the texture.
Example: mipmap.py