## Note It may seem a little odd but when you move a camera about in a D world you are actually transforming the world and not the camera

Figure 9-10. Cube world

Listing 9-8. Flying Around Cube World! (firstopengl.py) SCREEN_SIZE = (800, 600)

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

import pygame from pygame.locals import *

from gameobjects.matrix44 import * from gameobjects.vector3 import *

def resize(width, height):

glViewport(0, 0, width, height)

glMatrixMode(GL_PROJECTION)

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

glMatrixMode(GL_MODELVIEW)

glEnable(GL_DEPTH_TEST)

glEnable(GL_COLOR_MATERIAL)

glEnable(GL_LIGHTING) glEnable(GL_LIGHT0)

class Cube(object):

def _init_(self, position, color):

self.position = position self.color = color

# Cube information num faces = 6

vertices = [ (0.0, 0.0, 1.0 (1.0, 0.0, 1.0 (1.0, 1.0, 1.0 (0.0, 1.0, 1.0 (0.0, 0.0, 0.0 (1.0, 0.0, 0.0 (1.0, 1.0, 0.0 (0.0, 1.0, 0.0

(0.0, 0.0, -1.0 (+1.0, 0.0, 0.0 (-1.0, 0.0, 0.0 (0.0, +1.0, 0.0 (0.0, -1.0, 0.0

] # bottom vertex_indices = [ (0, 1, 2, 3), # front

# Set the cube color, applies to all vertices till next call glColor( self.color )

# Adjust all the vertices so that the cube is at self.position vertices = []

for v in self.vertices:

vertices.append( tuple(Vector3(v)+ self.position) )

# Draw all 6 faces of the cube glBegin(GL_OUADS)

for face_no in xrange(self.num_faces):

glNormal3dv( self.normals[face_no] )

glVertex( vertices[vl] )

glVertex( vertices[v2] )

glVertex( vertices[v3] )

glVertex( vertices[v4] )

glEnd()

class Map(object):

# Create a cube for every non-white pixel for y in range(h):

gl_col = (r/255.0, g/255.0, b/255.0) position = (float(x), 0.0, float(y)) cube = Cube( position, gl_col ) self.cubes.append(cube)

map_surface.unlock() self.display_list = None def render(self):

if self.display_list is None:

# Create a display list self.display_list = glGenLists(l) glNewList(self.display_list, GL_COMPILE)

# Draw the cubes for cube in self.cubes: cube.render()

# End the display list glEndList()

else:

# Render the display list glCallList(self.display_list)

pygame.init()

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

resize(*SCREEN_SIZE) init()

clock = pygame.time.Clock()

# Camera transform matrix camera_matrix = Matrix44() camera_matrix.translate = (10.0, .6, 10.0)

# Initialize speeds and directions rotation_direction = Vector3() rotation_speed = radians(90.0) movement_direction = Vector3() movement_speed = 5.0

while True:

for event in pygame.event.get(): if event.type == QUIT: return if event.type == KEYUP and event.key == K_ESCAPE: return

# Clear the screen, and z-buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

time_passed = clock.tick() time_passed_seconds = time_passed / 1000.

pressed = pygame.key.get_pressed()

# Reset rotation and movement directions rotation_direction.set(0.0, 0.0, 0.0) movement_direction.set(0.0, 0.0, 0.0)

# Modify direction vectors for key presses if pressed[K_LEFT]:

rotation_direction.y = +1.0 elif pressed[K_RIGHT]:

rotation_direction.y = -1.0 if pressed[K_UP]:

rotation_direction.x = -1.0 elif pressed[K_DOWN]:

rotation_direction.x = +1.0 if pressed[K_z]:

rotation_direction.z = -1.0 elif pressed[K_x]:

rotation_direction.z = +1.0 if pressed[K_q]:

movement_direction.z = -1.0 elif pressed[K_a]:

movement direction.z = +1.0

# Calculate rotation matrix and multiply by camera matrix rotation = rotation_direction * rotation_speed * time_passed_seconds rotation_matrix = Matrix44.xyz_rotation(*rotation) camera_matrix *= rotation_matrix

# Calculate movement and add it to camera matrix translate heading = Vector3(camera_matrix.forward)

movement = heading * movement_direction.z * movement_speed camera_matrix.translate += movement * time_passed_seconds