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)
gluPerspective(60.0, float(width)/height, .1, 1000.)
glEnable(GL_TEXTURE_2D) glClearColor(1, 1, 1, 1)
screen = pygame.display.set_mode(SCREEN_SIZE, HWSURFACE|OPENGL|DOUBLEBUF)
# 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,
clock = pygame.time.Clock()
tex_rotation = 0.0
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)
glVertex3f(-300, 300, 0)
glVertex3f(300, 300, 0)
glVertex3f(300, -300, 0)
# 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?