コード例 #1
0
ファイル: templateApp.cpp プロジェクト: crlarsen/gamelibrary
void templateAppDraw( void ) {

	glClearColor( 0.5f, 0.5f, 0.5f, 1.0f );
	glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );


	GFX_set_matrix_mode( PROJECTION_MATRIX );
	GFX_load_identity();
	
	
	GFX_set_perspective( 80.0f,
						 ( float )viewport_matrix[ 2 ] / ( float )viewport_matrix[ 3 ],
						 1.0f,
						 1000.0f,
						 -90.0f );

	if( game_over == 2 ) {

		templateAppExit();

		load_game();

		game_over = 0;
	}


	GFX_set_matrix_mode( MODELVIEW_MATRIX );
	GFX_load_identity();


	if( view_delta.x || view_delta.y ) { 

		if( view_delta.y ) next_rotz -= view_delta.y;

		if( view_delta.x ) { 
			next_rotx -= view_delta.x;
			next_rotx = CLAMP( next_rotx, 0.0f, 90.0f ); 
		}
		
		view_delta.x =
		view_delta.y = 0.0f;
	}

	rotx = rotx * 0.9f + next_rotx * 0.1f;
	rotz = rotz * 0.9f + next_rotz * 0.1f;



	eye.x = center.x + 
			distance * 
			cosf( rotx * DEG_TO_RAD ) * 
			sinf( rotz * DEG_TO_RAD );
	
	eye.y = center.y - 
			distance *
			cosf( rotx * DEG_TO_RAD ) *
			cosf( rotz * DEG_TO_RAD );
	
	
	eye.z = center.z +
			distance *
			sinf( rotx * DEG_TO_RAD );
			
			
	rotx = rotx * 0.9f + next_rotx * 0.1f;
	rotz = rotz * 0.9f + next_rotz * 0.1f;


	center.x = maze->location.x;
	center.y = maze->location.y;
	center.z = maze->location.z;


	GFX_look_at( &eye,
				 &center,
				 &up );


	if( double_tap ) { 
		
		vec3 location;
		
		if( GFX_unproject( view_location.x,
						   viewport_matrix[ 3 ] - view_location.y,
						   1.0f,
						   GFX_get_modelview_matrix(),
						   GFX_get_projection_matrix(),
						   viewport_matrix,
						   &location.x,
						   &location.y,
						   &location.z  ) ) {

			btVector3 ray_from( eye.x,
							    eye.y,
							    eye.z ),

					  ray_to( location.x + eye.x,
							  location.y + eye.y,
							  location.z + eye.z );

			btCollisionWorld::ClosestRayResultCallback collision_ray( ray_from,
																	  ray_to );
			
			dynamicsworld->rayTest( ray_from,
									ray_to,
									collision_ray );
			
			if( collision_ray.hasHit() &&
				collision_ray.m_collisionObject == maze->btrigidbody ) { 

				collision_ray.m_hitNormalWorld.normalize();

				if( collision_ray.m_hitNormalWorld.z() == 1.0f ) {
			
					navigationpath_player.start_location.x = player->location.x;
					navigationpath_player.start_location.y = player->location.y;
					navigationpath_player.start_location.z = player->location.z;

					navigationpath_player.end_location.x = collision_ray.m_hitPointWorld.x();
					navigationpath_player.end_location.y = collision_ray.m_hitPointWorld.y();
					navigationpath_player.end_location.z = collision_ray.m_hitPointWorld.z();
				
					if( NAVIGATION_get_path( navigation,
											&navigationpath_player,
											&navigationpathdata_player ) ) {
						
						player_next_point = 1;

						unsigned int i = 0;
						
						while( i != navigationpathdata_player.path_point_count + 1 ) { 
						
							console_print( "%d: %f %f %f\n",
										   i,
										   navigationpathdata_player.path_point_array[ i ].x,
										   navigationpathdata_player.path_point_array[ i ].y,
										   navigationpathdata_player.path_point_array[ i ].z );
							++i; 
						}
						
						printf( "\n" );
					}
				}
			}
		}

		double_tap = 0;
	}
	
	
	if( navigationpathdata_player.path_point_count ) {

		vec3 color = { 0.0f, 0.0f, 1.0f };

		draw_navigation_points( &navigationpathdata_player, &color );
   
		move_entity( player,
					 &navigationpathdata_player,
					 &player_next_point,
					 3.0f );
	}	
	
	
	static unsigned int start_time = get_milli_time();

	if( get_milli_time() - start_time > 1000 ) { 

		navigationpath_enemy.start_location.x = enemy->location.x;
		navigationpath_enemy.start_location.y = enemy->location.y;
		navigationpath_enemy.start_location.z = enemy->location.z;

		navigationpath_enemy.end_location.x = player->location.x;
		navigationpath_enemy.end_location.y = player->location.y;
		navigationpath_enemy.end_location.z = player->location.z;

		NAVIGATION_get_path( navigation,
							&navigationpath_enemy, 
							&navigationpathdata_enemy );

		enemy_next_point = 1;

		start_time = get_milli_time();
	}	
	
	
	if( navigationpathdata_enemy.path_point_count ) { 
	
		vec3 color = { 1.0f, 0.0f, 0.0f };

		move_entity( enemy,
					&navigationpathdata_enemy,
					&enemy_next_point,
					4.0f );

		draw_navigation_points( &navigationpathdata_enemy, &color );
	}
	
	
	PROGRAM_draw( program );

	glUniform1i( PROGRAM_get_uniform_location( program, ( char * )"DIFFUSE" ), 1 );

	unsigned int i = 0;

	while( i != obj->n_objmesh ) {

		OBJMESH *objmesh = &obj->objmesh[ i ];

		GFX_push_matrix();

		mat4 mat;

		objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat );

		memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) );

		GFX_multiply_matrix( &mat );

		glUniformMatrix4fv( PROGRAM_get_uniform_location( program, ( char * )"MODELVIEWPROJECTIONMATRIX" ),
							1,
							GL_FALSE,
							( float * )GFX_get_modelview_projection_matrix() );

		OBJ_draw_mesh( obj, i );

		GFX_pop_matrix();

		++i;
	}
	
	
	if( !game_over ) dynamicsworld->stepSimulation( 1.0f / 60.0f );

	else { 

	  GFX_set_matrix_mode( PROJECTION_MATRIX );
	  GFX_load_identity();

	  float half_width  =
			( float )viewport_matrix[ 2 ] * 0.5f,
			half_height =
			( float )viewport_matrix[ 3 ] * 0.5f;

	  GFX_set_orthographic_2d( -half_width,
								half_width,
							   -half_height,
								half_height );

	  GFX_rotate( -90.0f, 0.0f, 0.0f, 1.0f );

	  GFX_translate( -half_height, -half_width, 0.0f );

	  GFX_set_matrix_mode( MODELVIEW_MATRIX );

	  GFX_load_identity();

	  vec4 color = { 0.0f, 0.0f, 0.0f, 1.0f };

	  char msg[ MAX_CHAR ] = {"GAME OVER!"};

	  if( !font ) {

		 font = FONT_init( ( char * )"foo.ttf" );

		 FONT_load( font,
					font->name,
					1,
					64.0f,
					512,
					512,
					32,
					96 );
	  }

	  float posx = ( viewport_matrix[ 3 ] * 0.5f ) -
				   ( FONT_length( font, msg ) * 0.5f ),

			posy = viewport_matrix[ 2 ] - font->font_size;

	  FONT_print( font,
				  posx + 4.0f,
				  posy - 4.0f,
				  msg,
				  &color );

	  color.y = 1.0f;

	  FONT_print( font,
			   posx,
			   posy,
			   msg,
			   &color );
	}
}
コード例 #2
0
ファイル: templateApp.cpp プロジェクト: mitoi/_chapter9-4
void templateAppDraw( void ) {

	if( game_state == 2 ) {

		free_level();
		load_level();
	}
   
	glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
	glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

	GFX_set_matrix_mode( PROJECTION_MATRIX );
	GFX_load_identity();
	
	GFX_set_perspective( 80.0f,
						 ( float )viewport_matrix[ 2 ] / ( float )viewport_matrix[ 3 ],
						 0.1f,
						 50.0f,
						 -90.0f );

	GFX_set_matrix_mode( MODELVIEW_MATRIX );
	GFX_load_identity();

	/* Linearly interpolate the accelerometer values to get a smooth transition. */
	next_accelerometer.x = accelerometer.x * 0.1f + next_accelerometer.x * 0.9f;
	next_accelerometer.y = accelerometer.y * 0.1f + next_accelerometer.y * 0.9f;

	/* Assign the current Y rotation of the accelerometer to the Z rotation of the camera,
	 * multiplied by the accelerometer sensitivity factor. */
	rotz += next_accelerometer.y * sensitivity;

	/* The forward vector of the ball. */
	vec3 forward = { 0.0f, 1.0f, 0.0f },
			/* The current direction vector of the ball. Basically, this is the
			forward vector rotated by the cameraÕs Z rotation. */
		 direction;

	/* If the game is running, let the user move the ball. */
	if( !game_state ) {
		/* Pre-calculate a few variables before rotating the forward vector by the cameraÕs Z rotation. */
		float r = rotz * DEG_TO_RAD,
			  c = cosf( r ),
			  s = sinf( r );

		/* Rotate the forward vector and store the result into the
		direction variable. Because both vectors are already normalized,
		thereÕs no need to re-normalize them again. */
		direction.x = c * forward.y - s * forward.x;
		direction.y = s * forward.y + c * forward.x;

		float speed = CLAMP( ( -next_accelerometer.x * sensitivity ) * ball_speed,
							   -ball_speed,
							    ball_speed );

		/* Assign the direction vector multiplied by the current speed to the
		angular velocity of the ball. */
		player->btrigidbody->setAngularVelocity( btVector3( direction.x * speed,
															direction.y * speed,
														    0.0f ) );
		/* Activate the rigid body to make sure that the angular velocity
		will be applied. */
		player->btrigidbody->setActivationState( ACTIVE_TAG );
	}

	next_eye.x = player->location.x + 
				 distance * 
				 cosf( rotx * DEG_TO_RAD ) * 
				 sinf( rotz * DEG_TO_RAD );

	next_eye.y = player->location.y - 
				 distance *
				 cosf( rotx * DEG_TO_RAD ) *
				 cosf( rotz * DEG_TO_RAD );

	next_eye.z = player->location.z +
				 distance *
				 sinf( rotx * DEG_TO_RAD );

	player->location.z += player->dimension.z;

	btVector3 p1( player->location.x,
				  player->location.y,
				  player->location.z ),

			  p2( next_eye.x,
				  next_eye.y,
				  next_eye.z );

	ClosestNotMeRayResultCallback back_ray( player->btrigidbody,
											p1,
											p2 );

	dynamicsworld->rayTest( p1,
							p2,
							back_ray );

	if( back_ray.hasHit() ) { 

		back_ray.m_hitNormalWorld.normalize();

		next_eye.x =  back_ray.m_hitPointWorld.x() +
					( back_ray.m_hitNormalWorld.x() * 0.1f );

		next_eye.y =  back_ray.m_hitPointWorld.y() +
					( back_ray.m_hitNormalWorld.y() * 0.1f );

		next_eye.z =  back_ray.m_hitPointWorld.z() +
					( back_ray.m_hitNormalWorld.z()* 0.1f );
	}

	eye.x = next_eye.x * 0.05f + eye.x * 0.95f;
	eye.y = next_eye.y * 0.05f + eye.y * 0.95f;
	eye.z = next_eye.z * 0.05f + eye.z * 0.95f;

	/* Calculate the direction vector from the player to the current eye location. */
	vec3_diff( &direction, &player->location, &eye );
	/* Normalize the direction vector. */
	vec3_normalize( &direction, &direction );

	AUDIO_set_listener( &eye, &direction, &up );


	GFX_look_at( &eye,
				 &player->location,
				 &up );
	
	build_frustum( frustum,
				  GFX_get_modelview_matrix(),
				  GFX_get_projection_matrix() );	


	unsigned int i = 0;

	while( i != obj->n_objmesh ) {

		OBJMESH *objmesh = &obj->objmesh[ i ];

		objmesh->distance = sphere_distance_in_frustum( frustum, 
														&objmesh->location,
														objmesh->radius );

		if( objmesh->distance && objmesh->visible )
		{
			GFX_push_matrix();
			/* Check if the current objmesh name contains Ògem.Ó
			 * If yes, donÕt ask Bullet for the transformation matrix and handle the position and
			 * rotation manually. */
			if( strstr( objmesh->name, "gem" ) ) {

				GFX_translate( objmesh->location.x, 
							   objmesh->location.y, 
							   objmesh->location.z );
				
				objmesh->rotation.z += 1.0f;

				GFX_rotate( objmesh->rotation.z, 0.0f, 0.0f, 1.0f );
			}
			
			else if( objmesh->btrigidbody )
			{
				mat4 mat;

				objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat );
				
				memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) );

				GFX_multiply_matrix( &mat );				
			}
			else
			{
				GFX_translate( objmesh->location.x, 
							   objmesh->location.y, 
							   objmesh->location.z );
			}

			OBJ_draw_mesh( obj, i );

			GFX_pop_matrix();
		}
		
		++i;
	}
	
	dynamicsworld->stepSimulation( 1.0f / 60.0f );

	
	GFX_set_matrix_mode( PROJECTION_MATRIX );
	GFX_load_identity();

	float half_width  = ( float )viewport_matrix[ 2 ] * 0.5f,
		  half_height = ( float )viewport_matrix[ 3 ] * 0.5f;

	GFX_set_orthographic_2d( -half_width,
							  half_width,
						     -half_height,
							  half_height );

	GFX_rotate( -90.0f, 0.0f, 0.0f, 1.0f );

	GFX_translate( -half_height, -half_width, 0.0f );

	GFX_set_matrix_mode( MODELVIEW_MATRIX );

	GFX_load_identity();
	
	vec4 font_color = { 0.0f, 0.0f, 0.0f, 1.0f };

	char gem_str  [ MAX_CHAR ] = {""},
		 time_str [ MAX_CHAR ] = {""},
		 level_str[ MAX_CHAR ] = {""};

	if( game_state ) { 
	
		sprintf( level_str, "Level Clear!" );

		FONT_print( font_big,
					viewport_matrix[ 3 ] * 0.5f - FONT_length( font_big, level_str ) * 0.5f + 4.0f,
					viewport_matrix[ 2 ] - font_big->font_size * 1.5f - 4.0f,
					level_str,
					&font_color );

		/* Yellow. */
		font_color.x = 1.0f;
		font_color.y = 1.0f;
		font_color.z = 0.0f;

		FONT_print( font_big,
					viewport_matrix[ 3 ] * 0.5f - FONT_length( font_big, level_str ) * 0.5f,
					viewport_matrix[ 2 ] - font_big->font_size * 1.5f,
		level_str,
		&font_color );   
	}

	font_color.x = 0.0f;
	font_color.y = 0.0f;
	font_color.z = 0.0f;

	sprintf( gem_str, "Gem Points:%02d", gem_points );
	sprintf( time_str, "Game Time:%02.2f", game_time * 0.1f );

	FONT_print( font_small,
				viewport_matrix[ 3 ] - FONT_length( font_small, gem_str ) - 6.0f,
				( font_small->font_size * 0.5f ),
				gem_str,
				&font_color );
	
	FONT_print( font_small,
				8.0f,
				( font_small->font_size * 0.5f ),
				time_str,
				&font_color );

	font_color.x = 1.0f;
	font_color.y = 1.0f;
	font_color.z = 0.0f;

	FONT_print( font_small,
				viewport_matrix[ 3 ] - FONT_length( font_small, gem_str ) - 8.0f,
				( font_small->font_size * 0.5f ),
				gem_str,
				&font_color );
	
	FONT_print( font_small,
				6.0f,
				( font_small->font_size * 0.5f ),
				time_str,
				&font_color );

	if( !game_state ) game_time += SOUND_get_time( background_sound );
}
コード例 #3
0
ファイル: templateApp.cpp プロジェクト: psstoyanov/EICG699
void templateAppDraw( void ) {

	if( game_state == 2 ) {

		free_level();
		load_level();
	}
   
	glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
	glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

	GFX_set_matrix_mode( PROJECTION_MATRIX );
	GFX_load_identity();
	
	GFX_set_perspective( 80.0f,
						 ( float )viewport_matrix[ 2 ] / ( float )viewport_matrix[ 3 ],
						 0.1f,
						 50.0f,
						 0.0f );

	GFX_set_matrix_mode( MODELVIEW_MATRIX );
	GFX_load_identity();


	if(turn_left())
		{
			next_rotz+=1.2;

		}
	if(turn_right())

	{
	         next_rotz-=1.2;
	}

	vec3 forward = { 0.0f, 1.0f, 0.0f },direction;

	if( !game_state )
	{
		//Pre-calculate a few variables before rotating the forward vector by the camera's Z rotation.
		float r = rotz * DEG_TO_RAD, c = cosf( r ), s = sinf( r );

		//Rotate the forward vector and store the result into the direction variable. Because
		//both vectors are already normalized, there's no need to re-normalize them one more time.

		direction.x = c * forward.y - s * forward.x;
		direction.y = s * forward.y + c * forward.x;


		//Calculate the current angular velocity that is relevant to the
		//accelerometer value that we are using as the force factor.
		//Then clamp the result to make sure that the speed is between the minimum and
		//maximum ball speed thresholds.
		float speed = CLAMP(   -maximum_speed,
		                       -maximum_speed,
								maximum_speed );



			player->btrigidbody->setAngularVelocity( btVector3( direction.x * speed,direction.y * speed,0.0f ) );


			//Activate the rigid body to make sure that the angular velocity will be applied.
			player->btrigidbody->setActivationState( ACTIVE_TAG );
		}
	/*
	if( view_delta.x || view_delta.y )
	{

		if( view_delta.x ) next_rotz -= view_delta.x;

		if( view_delta.y )
		{
			next_roty += view_delta.y;
			next_roty = CLAMP( next_roty, -180.0f, -90.0f );
		}

		view_delta.x =
		view_delta.y = 0.0f;
	}


	if( move_delta.z )
	{
		vec3 direction;

		float r = rotz * DEG_TO_RAD,
				      c = cosf( r ),
				      s = sinf( r );

		direction.x =  s * move_delta.y + c * move_delta.x;
		direction.y =  c * move_delta.y - s * move_delta.x;

		player->btrigidbody->setAngularVelocity( 2*btVector3( -direction.y * ( move_delta.z * 6.7f ),
															  -direction.x * ( move_delta.z * 6.7f ),
															  0.0f ) );


		player->btrigidbody->setActivationState( ACTIVE_TAG );
	}*/

	//console_print("player_x: %3.f player_y: %3.f\n",player->location.x,player->location.y);

	next_eye.x = player->location.x +
					 distance *
					 cosf( roty * DEG_TO_RAD ) *
					 sinf( rotz * DEG_TO_RAD );

	next_eye.y = player->location.y -
					 distance *
					 cosf( roty * DEG_TO_RAD ) *
					 cosf( rotz * DEG_TO_RAD );


	next_eye.z = player->location.z +
					       distance *
					      sinf( roty * DEG_TO_RAD );
		

	btVector3 p1(   player->location.x,
					 player->location.y,
					 player->location.z ),

			     p2( next_eye.x,
					 next_eye.y,
					 next_eye.z );

	ClosestNotMeRayResultCallback back_ray( player->btrigidbody,
											   p1,
											   p2 );
	dynamicsworld->rayTest( p1,
							p2,
							back_ray );

	if( back_ray.hasHit() )
	{

		back_ray.m_hitNormalWorld.normalize();

		next_eye.x =   back_ray.m_hitPointWorld.x() +
					   ( back_ray.m_hitNormalWorld.x() * 0.1f );

		next_eye.y =   back_ray.m_hitPointWorld.y() +
					   ( back_ray.m_hitNormalWorld.y()* 0.1f );

		next_eye.z =   back_ray.m_hitPointWorld.z() +
					   ( back_ray.m_hitNormalWorld.z()* 0.1f );
	}



	roty = roty * 0.9f + next_roty * 0.1f;
	rotz = rotz * 0.9f + next_rotz * 0.1f;

	eye.x = eye.x * 0.95f + next_eye.x * 0.05f;
	eye.y = eye.y * 0.95f + next_eye.y * 0.05f;
	eye.z = eye.z * 0.95f + next_eye.z * 0.05f;

	player->location.z += player->dimension.z * 0.5f;

	/*
	 * needed for directional audio
	 */
	vec3 player_location={player->location.x,player->location.y,player->location.z};
	AUDIO_set_listener( &eye, &player_location, &up );


	GFX_look_at( &eye,
				 &player->location,
				 &up );
	
	build_frustum( frustum,
				  GFX_get_modelview_matrix(),
				  GFX_get_projection_matrix() );	


	unsigned int i = 0;

	while( i != obj->n_objmesh ) {

		OBJMESH *objmesh = &obj->objmesh[ i ];

		objmesh->distance = sphere_distance_in_frustum( frustum, 
														&objmesh->location,
														objmesh->radius );

		if( objmesh->distance && objmesh->visible )
		{
			GFX_push_matrix();

			if( strstr( objmesh->name, "gem" ) ) {

				GFX_translate( objmesh->location.x, 
							   objmesh->location.y, 
							   objmesh->location.z );
				
				objmesh->rotation.z += 1.0f;

				GFX_rotate( objmesh->rotation.z, 0.0f, 0.0f, 1.0f );
			}
			
			else if( objmesh->btrigidbody )
			{
				mat4 mat;

				objmesh->btrigidbody->getWorldTransform().getOpenGLMatrix( ( float * )&mat );
				
				memcpy( &objmesh->location, ( vec3 * )&mat.m[ 3 ], sizeof( vec3 ) );

				GFX_multiply_matrix( &mat );				
			}
			else
			{
				GFX_translate( objmesh->location.x, 
							   objmesh->location.y, 
							   objmesh->location.z );
			}

			OBJ_draw_mesh( obj, i );

			GFX_pop_matrix();
		}
		
		++i;
	}
	if(!game_state )
	{
	dynamicsworld->stepSimulation( 1.0f / 60.0f );
	}
	
	GFX_set_matrix_mode( PROJECTION_MATRIX );
	GFX_load_identity();

	float half_width  = ( float )viewport_matrix[ 2 ] * 0.5f,
		  half_height = ( float )viewport_matrix[ 3 ] * 0.5f;
	GFX_set_orthographic_2d( -half_width,
			                  half_width,
						     -half_height,
						      half_height );

	GFX_rotate( 0.0f, 0.0f, 0.0f, 1.0f );

	GFX_translate( -half_width, -half_height, 0.0f );



	GFX_set_matrix_mode( MODELVIEW_MATRIX );

	GFX_load_identity();
	
	vec4 font_color = { 0.0f, 0.0f, 0.0f, 1.0f };

	char gem_str  [ MAX_CHAR ] = {""},
		 time_str [ MAX_CHAR ] = {""},
		 level_str[ MAX_CHAR ] = {""},
		 pause_str [ MAX_CHAR ] = {""};

	if( game_state == 3 )
	{
		sprintf( pause_str, "Touch to Resume" );

				FONT_print( font_big,
							viewport_matrix[ 2 ] * 0.5f - FONT_length( font_big, pause_str ) * 0.5f + 4.0f,
							viewport_matrix[ 3 ] * 0.7f - font_big->font_size * 1.5f - 4.0f,
							pause_str,
							&font_color );

				/* Yellow. */
				font_color.x = 1.0f;
				font_color.y = 1.0f;
				font_color.z = 0.0f;

				FONT_print( font_big,
							viewport_matrix[ 2 ] * 0.5f - FONT_length( font_big, pause_str ) * 0.5f,
							viewport_matrix[ 3 ] * 0.7f - font_big->font_size * 1.5f,
							pause_str,
							&font_color );
	}
	if( game_state == 1 )
	{
	
		sprintf( level_str, "Level Clear!" );

		FONT_print( font_big,
					viewport_matrix[ 2 ] * 0.5f - FONT_length( font_big, level_str ) * 0.5f + 4.0f,
					viewport_matrix[ 3 ] - font_big->font_size * 1.5f - 4.0f,
					level_str,
					&font_color );

		/* Yellow. */
		font_color.x = 1.0f;
		font_color.y = 1.0f;
		font_color.z = 0.0f;

		FONT_print( font_big,
					viewport_matrix[ 2 ] * 0.5f - FONT_length( font_big, level_str ) * 0.5f,
					viewport_matrix[ 3 ] - font_big->font_size * 1.5f,
					level_str,
					&font_color );

	}

	font_color.x = 0.0f;
	font_color.y = 0.0f;
	font_color.z = 0.0f;

	sprintf( gem_str, "Gem Points:%02d", gem_points );
	sprintf( time_str, "Game Time:%02.2f", game_time * 0.1f );

	FONT_print( font_small,
				viewport_matrix[ 2 ] - FONT_length( font_small, gem_str ) - 6.0f,
				( font_small->font_size * 0.5f ),
				gem_str,
				&font_color );

	FONT_print( font_small,
				8.0f,
				( font_small->font_size * 0.5f ),
				time_str,
				&font_color );

	font_color.x = 1.0f;
	font_color.y = 1.0f;
	font_color.z = 0.0f;

	FONT_print( font_small,
				viewport_matrix[ 2 ] - FONT_length( font_small, gem_str ) - 8.0f,
				( font_small->font_size * 0.5f ),
				gem_str,
				&font_color );
	
	FONT_print( font_small,
				6.0f,
				( font_small->font_size * 0.5f ),
				time_str,
				&font_color );


	if( !game_state ) game_time += SOUND_get_time( background_sound );

}