Seeing Textures in Action

Let's write a script to demonstrate uploading a texture and using it when rendering an OpenGL primitive. We are going to draw a single textured quad, and to show that it isn't simply a sprite we will rotate it around the x axis.

In the init function of Listing 11-2 is a call to glEnable(GL_TEXTURE_2D), which enables OpenGL textures. If you ever have problems getting textures to work in OpenGL, check whether you have made this call.

Listing 11-2. Textures in Action (opengltex.py) SCREEN_SIZE = (800, 600)

from math import radians from OpenGL.GL import * from OpenGL.GLU import *

import pygame from pygame.locals import *

def resize(width, height):

glViewport(0, 0, width, height)

glMatrixMode(GL_PROJECTION)

glLoadIdentity()

gluPerspective(60.0, float(width)/height, .1, 1000.)

glMatrixMode(GL_MODELVIEW)

glLoadIdentity()

glEnable(GL_TEXTURE_2D) glClearColor(1, 1, 1, 1)

pygame.init()

screen = pygame.display.set_mode(SCREEN_SIZE, HWSURFACE|OPENGL|DOUBLEBUF)

resize(*SCREEN_SIZE) init()

# Load the textures texture_surface = pygame.image.load("sushitex.png")

# Retrieve the texture data texture_data = pygame.image.tostring(texture_surface, 'RGB', True)

# Generate a texture id texture_id = glGenTextures(1)

# Tell OpenGL we will be using this texture id for texture operations glBindTexture(GL_TEXTURE_2D, texture_id)

# Tell OpenGL how to scale images glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR )

# Tell OpenGL that data is aligned to byte boundries glPixelStorei(GL_UNPACK_ALIGNMENT, 1)

# Get the dimensions of the image width, height = texture_surface.get_rect().size

# Upload the image to OpenGL glTexImage2D( GL_TEXTURE_2D, 0, 3, width, height, 0,

GL_RGB,

GL_UNSIGNED_BYTE, texture_data)

clock = pygame.time.Clock()

tex_rotation = 0.0

while True:

for event in pygame.event.get(): if event.type == QUIT: return time_passed = clock.tick() time_passed_seconds = time_passed / 1000. tex_rotation += time_passed_seconds * 360.0 / 8.0

# Clear the screen (similar to fill) glClear(GL_COLOR_BUFFER_BIT)

# Clear the modelview matrix glLoadIdentity()

# Set the modelview matrix glTranslatef(0.0, 0.0, -600.0) glRotate(tex_rotation, 1, 0, 0)

# Draw a quad (4 vertices, 4 texture coords) glBegin(GL_QUADS)

glTexCoord2f(0, l)

glVertex3f(-300, 300, 0)

glTexCoord2f(l, l)

glVertex3f(300, 300, 0)

glTexCoord2f(l, 0)

glVertex3f(300, -300, 0)

glTexCoord2f(0, 0)

glEnd()

pygame.display.flip()

# Delete the texture when we are finished with it glDeleteTextures(texture_id)

The run function performs the five steps required to read in the sushitex.png image and upload the image data to OpenGL. It then draws a textured quad by sending OpenGL four texture coordinates and four vertices. Texture coordinates are sent with the glTexcoord2f function, which takes the s and t components as parameters. An alternative to glTexcoord2f is the glTexCoord2fv function, which takes a sequence (tuple, Vector2, etc.) rather than individual values.

The rotation is done with the glRotate function, which creates a rotation matrix about an axis and multiplies it by the current model-view matrix. It takes four parameters: the first parameter is the angle you want to rotate by (in degrees), followed by the x, y, and z component of the axis. For example, a call to glRotate(45, 1, 0, 0) would rotate 45 degrees around the xaxis, and a call to glRotate(-30, 0, 1, 0) would rotate negative 30 degrees (i.e., 30 degrees clockwise) around the y axis. You can also use this function to rotate around any axis, and not just the three basic axes.

When you run Listing 11-2, you will see something like Figure 11-2, with a large textured quad rotating around the x axis. Try experimenting with the texture coordinate values to see the effect they have on the quad.

Figure 11-2. opengltex.py

Was this article helpful?

0 0

Post a comment