Figure The flat plane becomes a full rotating cube

Let's say you wanted to speed up and twist your rotating cube around a bit more. It's easy to fiddle with MatrixMode, especially since you've thought ahead and included a number of variables with which to do it:

# Now we use all of these

# x,y, and z rots are the rotations on each axis xrot = yrot = zrot = 0.0

These variables, xrot, yrot, and zrot, can be used to rotate the cube in a new way on the x-, y-, and x-axes. Do so by adding a few lines to the top of drawgraphics:

global xrot, yrot, zrot glclear(GL_cOLOR_BUFFER_BiT|GL_DEPTH_BUFFER_BiT) glLoadidentity() glTranslatef(0.0, 0.0, -5.0)

global rquad # not used for now glRotatef(xrot,1.0,0.0,0.0) glRotatef(yrot,0.0,1.0,0.0) glRotatef(zrot,0.0,0.0,1.0)

And then add a few lines to the end of drawgraphics:

# Use XYZ to rotate - speed it up a bit xrot = xrot + 0.9 yrot = yrot + 0.9 zrot = zrot + 0.9

This will cause your cube to rotate quicker and also spin on aother axis. Adding Textures

In your final PyOpenGL tutorial you'll open and use a local texture image instead of having PyOpenGL simply color the cube; this is illustrated in Figure 4.21. The full code is listed in openGL_5. py in the Chapter 4 code section on the CD.

First you will make use of import os .A texture will then have to be loaded from outside of Python, and your program will need to understand how to navigate through different directories and pull files from its native operating system.

You will also finally be using the texture variables you initialized early on:

# textures for loading the .bmp image textures = [0,0]

You will be using textures [ ] for loading the .bmp you will be using for texture. The first thing you need is a new function that opens up the .bmp file:

# New function to find, load, and use the texture def loadtextures () :

# Need to find and load the texture point to file = os.path.join('dtcfe.bmp')

texture surface = pygame.image.load(point to file)

texture buffer = pygame.image.tostring(texture surface, "RGBX", 1

First, point_to_f ile uses the os module's os . path. j oin to point to the .bmp you want to use—in this case it is the dtcfe.bmp file found on the CD with the code samples. The next two commands use Pygame methods to load the .bmp image to a new surface ( texture_surf ace) and then copy the image into a larger string buffer ( texture_buff er). Specifying RGBX tells Pygame that the texture should be 32-bit padded RGB data. This turns the .bmp image into an actual texture.

Pyopengl Glrotatef Spin
Figure 4.21. A textured cube spins around each axis

With Pygame, your textures must be at least 64x64 pixels, and shouldn't be more than 256x256 pixels. Textures need to be sized in height and width to the power of 2 (if the textures are 64x64, 128x128, or 256x256, they do not need to be resized, otherwise they do). These are of course the standard defaults for textures and are changeable, but not without more advanced programming.

Now that Pygame has the texture, you hand it over to OpenGL. First you need to specify that the texture is two-dimensional with gl_texture_2d, and then you need to bind it to a texture [ ] array that will hold any and all textures your program needs:

glBindTexture(GL_TEXTURE_2D, textures[0] )

giTextimage2D is a PyOpenGL command that specifies a two-dimensional texture. You feed it several values, including the texture surface, width, and height (using the get_width ( ) and get_height ( ) methods). Then you specify that the texture is two-dimensional with gl_texture_2d, explain how the color format is organized with gl_rgba, define the data format used to store the texture data with gl_unsigned_byte, and finally, you give giTextimage2D ( ) the actual data of the texture itself, texture_buff er, which you defined with Pygame:

glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, texture surface.get width(), texture sur-face.get height(), 0,

_ GL_RGBA, GL_UNSIGNED_BYTE, texture_buffer );

Whew—that's our longest one-liner yet. The last step in loading a texture is to tell PyOpenGL what filtering to use when the image is stretched or altered on the screen. To do so, use PyOpenGL's built-in glTexParameterf ( ), which simply defines the options to use when texture mapping. The min and mag filters specify texture magnification, and gl_nearest asks PyOpenGL to grab the nearest pixel when redrawing the gl_texture_2d image:

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

Now that you can load the .bmp image and turn it into a texture, you need to make PyOpenGL use the texture on each side of the cube instead of filling in the sides with glColor3f() .

Drawing a textured cube is quite a bit different from drawing colored cubes. Most of the gl functions are the same but the glBindTexture command we used to load textures sets the texture we want to use, much like glColor3f ( ) set the pen to a specific color:

glBindTexture(GL_TEXTURE_2D, textures[0])

To map the texture correctly into a specific side of the texture, you need to make sure the top-right of the texture is mapped to the top-right of the side; same with the bottom-left. Each corner needs to be mapped using the giTexCoord2f(), command like so:

glTexCoord2f(0.0, 0.0); glVertex3f(-l.0, -1.0, 1.0)

The giTexCoord2 f command is designed to map out textures in two dimensions. Once you get the hang of using the command it is as easy to use as gicoior, there isjust an added complexity to each of the cube's mapped points:

glBegin(GL_QUADS

# Front Face

glTexCoord2 f

0

0

glTexCoord2 f

1

0

glTexCoord2 f

1

0

glTexCoord2 f

0

0

# Back Face

glTexCoord2 f

1

0

glTexCoord2 f

1

0

glTexCoord2 f

0

0

glTexCoord2 f

0

0

# Top Face

glTexCoord2 f

0

0

glTexCoord2 f

0

0

glTexCoord2 f

1

0

glTexCoord2 f

1

0

# Bottom Face

glTexCoord2 f

1

0

glTexCoord2 f

0

0

glTexCoord2 f

0

0

glTexCoord2 f

1

0

# Right face

glTexCoord2 f

1

0

glTexCoord2 f

1

0

glTexCoord2 f

0

0

glTexCoord2 f

0

0

# Left Face

glTexCoord2 f

0

0

glTexCoord2 f

1

0

glTexCoord2 f

1

0

glTexCoord2 f

0

0

glEnd();

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

1.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

0.0); glVertex3f

1.0); glVertex3f

-1.

,0,

-1.

0,

1.

0

1.

,0,

-1.

0,

1.

0

1.

,0,

1.

0,

1.

0

-1.

,0,

1.

0,

1.

0

-1.

,0,

-1.

0,

-1

0

-1.

0,

1.

0,

-1

0

1.

0,

1.

0,

-1

0

1.

0,

-1.

0,

-1

0

-1.

0,

1.

0,

-1

0

-1.

0,

1.

0,

1.

0

1.

0,

1.

0,

1.

0

1.

0,

1.

0,

-1

0

-1.

0,

-1.

0,

-1

0

1.

0,

-1.

0,

-1

0

1.

0,

-1.

0,

1.

0

-1.

0,

-1.

0,

1.

0

1.

0,

-1.

0,

-1

0

1.

0,

1.

0,

-1

0

1.

0,

1.

0,

1.

0

1.

0,

-1.

0,

1.

0

-1.

0,

-1.

0,

-1

0

-1.

0,

-1.

0,

1.

0

-1.

0,

1.

0,

1.

0

-1.

0,

1.

0,

-1

0

The result of this code (OpenGL_5.py) is illustratedinFigure 4.21.

0 0

Post a comment

  • Receive news updates via email from this site