示例#1
0
文件: 3dpixel.c 项目: Comanche93/eech
void set_3d_pixel ( float x, float y, float z, rgb_colour colour )
{

	if ( z >= clip_hither )
	{

		float
			i,
			j,
			q,
			oxmax,
			oxmin,
			oymax,
			oymin;
	
		int
			inti,
			intj,
			ixmax,
			ixmin,
			iymax,
			iymin,
			outcode;
	
		q = 1.0 / z;
	
		i = ( active_3d_environment->screen_i_scale * x * q );
	
		j = ( active_3d_environment->screen_j_scale * y * q );
	
		j = active_3d_environment->y_origin - j;
	
		i = active_3d_environment->x_origin + i;
	
		oxmax = active_viewport.x_max - i;
		oxmin = i - active_viewport.x_min;
		oymax = active_viewport.y_max - j;
		oymin = j - active_viewport.y_min;
	
		ixmax = *( ( int * ) &oxmax );
		ixmin = *( ( int * ) &oxmin );
		iymax = *( ( int * ) &oymax );
		iymin = *( ( int * ) &oymin );
	
		outcode = generate_lookup_outcode ( ixmin, iymin, ixmax, iymax );
	
		if ( !outcode )
		{

			asm_convert_float_to_int ( i, &inti );

			asm_convert_float_to_int ( j, &intj );

			set_pixel ( inti, intj, colour );
		}
	}
}
示例#2
0
int get_int_fog_distance_value ( float z )
{

//	float
//		value;

	int
		ivalue;

	asm_convert_float_to_int ( ( ( d3d_fog_constant - z ) * d3d_fog_factor ), &ivalue );

//	ivalue = bound ( ivalue, 0, 255 );

	return ( ivalue );
/*



	value = d3d_fog_constant - z;

	if ( *( ( int * ) &value ) < *( ( int * ) &float_value_zero ) )
	{

		return ( 0 );
	}
	else
	{

		value *= d3d_fog_factor;

		if ( *( ( int * ) &value ) > *( ( int * ) &float_value_255 ) )
		{

			return ( 255 );
		}
		else
		{

			int
				int_value;

			convert_float_to_int ( value, &int_value );

			return ( int_value );
		}
	}
	*/
}
示例#3
0
real_colour light_smoke_colour ( real_colour colour, int additive )
{

	real_colour
		result;

	float
		r,
		g,
		b,
		intensity;

	int
		ir,
		ig,
		ib;

	result.colour = colour.colour;

	if ( additive )
	{

		if (active_3d_environment->render_filter != RENDER_CLEAR )
		{

			//
			// Colour the additive to the light colour
			//

			r = colour.red;
			g = colour.green;
			b = colour.blue;

			intensity = ( 0.3 * r ) + ( 0.59 * g ) + ( 0.11 * b );

			r = intensity * ambient_3d_light.colour.red;
			g = intensity * ambient_3d_light.colour.green;
			b = intensity * ambient_3d_light.colour.blue;

			asm_convert_float_to_int ( r, &ir );
			asm_convert_float_to_int ( g, &ig );
			asm_convert_float_to_int ( b, &ib );

			result.red = ir;
			result.green = ig;
			result.blue = ib;
		}
		else
		{

			result = colour;
		}
	}
	else
	{

		r = colour.red;
		g = colour.green;
		b = colour.blue;

		r *= ambient_3d_light.colour.red * 1.866666;		//2.8;
		g *= ambient_3d_light.colour.green * 1.866666;	//2.8;
		b *= ambient_3d_light.colour.blue * 1.866666;	//2.8;

		asm_convert_float_to_int ( r, &ir );
		asm_convert_float_to_int ( g, &ig );
		asm_convert_float_to_int ( b, &ib );

		ir = bound ( ir, 0, 255 );
		ig = bound ( ig, 0, 255 );
		ib = bound ( ib, 0, 255 );

		result.red = ir;
		result.green = ig;
		result.blue = ib;
	}

	return ( result );
}
示例#4
0
void draw_3d_moon ( void )
{


	vertex
		*moon_polygon,
		*vert,
		moon_quad[4];

	int
		outcode,
		outcode2,
		count;

	float
		moon_width,
		moon_height,
		moon_depth;

	matrix3x3
		moon_matrix;

	int
		moon_red,
		moon_green,
		moon_blue;

	real_colour
		colour,
		specular;

	moon_polygon = moon_quad;

	moon_width = 12000;
	moon_height = 12000;
	moon_depth = 100000;

	moon_quad[0].next_vertex = &moon_quad[1];
	moon_quad[1].next_vertex = &moon_quad[2];
	moon_quad[2].next_vertex = &moon_quad[3];
	moon_quad[3].next_vertex = NULL;

	moon_quad[0].x = -moon_width/2;
	moon_quad[0].y = moon_height/2;
	moon_quad[0].z = moon_depth;
	moon_quad[0].u = 0;
	moon_quad[0].v = 0;

	moon_quad[1].x = moon_width/2;
	moon_quad[1].y = moon_height/2;
	moon_quad[1].z = moon_depth;
	moon_quad[1].u = 1;
	moon_quad[1].v = 0;

	moon_quad[2].x = moon_width/2;
	moon_quad[2].y = -moon_height/2;
	moon_quad[2].z = moon_depth;
	moon_quad[2].u = 1;
	moon_quad[2].v = 1;

	moon_quad[3].x = -moon_width/2;
	moon_quad[3].y = -moon_height/2;
	moon_quad[3].z = moon_depth;
	moon_quad[3].u = 0;
	moon_quad[3].v = 1;

	//
	// Rotate the moon into position
	//

	get_3d_transformation_matrix ( moon_matrix, moon_3d_heading, moon_3d_pitch, 0 );

	for ( count = 0; count < 4; count++ )
	{

		float
			x,
			y,
			z;


		x = moon_quad[count].x * moon_matrix[0][0] + moon_quad[count].y * moon_matrix[1][0] + moon_quad[count].z * moon_matrix[2][0];
		y = moon_quad[count].x * moon_matrix[0][1] + moon_quad[count].y * moon_matrix[1][1] + moon_quad[count].z * moon_matrix[2][1];
		z = moon_quad[count].x * moon_matrix[0][2] + moon_quad[count].y * moon_matrix[1][2] + moon_quad[count].z * moon_matrix[2][2];

		moon_quad[count].x = x;
		moon_quad[count].y = y;
		moon_quad[count].z = z;
	}

	//
	// Clip the moon to the horizon
	//

	clip_3d_coord = 0;

	moon_polygon = horizon_clip_3d_polygon ( moon_quad );

	if ( moon_polygon )
	{

		//
		// Rotate the polygon around to the users viewpoint
		//

		vert = moon_polygon;

		rotation_3d[0][0] = ( visual_3d_vp->xv.x );
		rotation_3d[0][1] = ( visual_3d_vp->yv.x );
		rotation_3d[0][2] = ( visual_3d_vp->zv.x );

		rotation_3d[1][0] = ( visual_3d_vp->xv.y );
		rotation_3d[1][1] = ( visual_3d_vp->yv.y );
		rotation_3d[1][2] = ( visual_3d_vp->zv.y );

		rotation_3d[2][0] = ( visual_3d_vp->xv.z );
		rotation_3d[2][1] = ( visual_3d_vp->yv.z );
		rotation_3d[2][2] = ( visual_3d_vp->zv.z );

		outcode = 0;

		outcode2 = CLIP_LEFT | CLIP_RIGHT | CLIP_TOP | CLIP_BOTTOM | CLIP_HITHER | CLIP_YONDER;

		while ( vert )
		{

			float
				x,
				y,
				z;

			x = vert->x * rotation_3d[0][0] + vert->y * rotation_3d[1][0] + vert->z * rotation_3d[2][0];
			y = vert->x * rotation_3d[0][1] + vert->y * rotation_3d[1][1] + vert->z * rotation_3d[2][1];
			z = vert->x * rotation_3d[0][2] + vert->y * rotation_3d[1][2] + vert->z * rotation_3d[2][2];

			x *= active_3d_environment->screen_i_scale;
			y *= active_3d_environment->screen_j_scale;

			if ( *( ( int * ) &z ) >= *( ( int * ) &clip_hither ) )
			{

				float
					q,
					i,
					j;

				float
					oxmax,
					oxmin,
					oymax,
					oymin;

				int
					ixmax,
					ixmin,
					iymax,
					iymin;

				q = 1.0 / z;

				vert->x = x;
				vert->y = y;
				vert->z = z;
				vert->q = q;

				i = ( x * q );
				j = ( y * q );

				vert->j = active_3d_environment->y_origin - j;
				vert->i = active_3d_environment->x_origin + i;

				oxmax = active_viewport.x_max - vert->i;
				oxmin = vert->i - active_viewport.x_min;
				oymax = active_viewport.y_max - vert->j;
				oymin = vert->j - active_viewport.y_min;

				ixmax = *( ( int * ) &oxmax );
				ixmin = *( ( int * ) &oxmin );
				iymax = *( ( int * ) &oymax );
				iymin = *( ( int * ) &oymin );

				vert->outcode = generate_lookup_outcode ( ixmin, iymin, ixmax, iymax );

				outcode |= vert->outcode;
				outcode2 &= vert->outcode;
			}
			else
			{

				vert->outcode = CLIP_HITHER;
				vert->z = z;
				vert->x = x;
				vert->y = y;

				outcode |= vert->outcode;
				outcode2 &= vert->outcode;
			}

			vert = vert->next_vertex;
		}

		if ( outcode2 )
		{

			return;
		}


		if ( outcode & CLIP_HITHER )
		{

			moon_polygon = hither_clip_3d_polygon ( moon_polygon, &outcode );

			if ( !moon_polygon )
			{

				return;
			}
		}

		if ( outcode )
		{

			apply_perspective_to_polygon_texture ( moon_polygon );

			moon_polygon = clip_3d_polygon ( moon_polygon, outcode );

			if ( !moon_polygon )
			{

				return;
			}

			remove_perspective_from_polygon_texture ( moon_polygon );
		}

		asm_convert_float_to_int ( ( moon_colour.red * 255 ), &moon_red );
		asm_convert_float_to_int ( ( moon_colour.green * 255 ), &moon_green );
		asm_convert_float_to_int ( ( moon_colour.blue * 255 ), &moon_blue );

		colour.red = moon_red;
		colour.green = moon_green;
		colour.blue = moon_blue;

		specular.colour = 0;

		set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS );
		set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE );

		suspend_d3d_fog ();

		set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD );
		set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND );
		set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND );

		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
		set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );

        set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
        set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

		set_d3d_texture ( 0, load_hardware_texture_map ( moon_texture ) );

		draw_wbuffered_flat_shaded_textured_polygon ( moon_polygon, colour, specular );

		set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );

		set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
		set_d3d_texture ( 0, NULL );

		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

		reinstate_d3d_fog ();

		set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, zbuffer_default_comparison );
		set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
	}
}
示例#5
0
void draw_3d_sun ( void )
{

	vertex
		*sun_polygon,
		sun_quad[4];

	matrix3x3
		sun_matrix;

	float
		flare_intensity;

	int
		sun_red,
		sun_green,
		sun_blue;

	real_colour
		colour,
		specular;

	//
	// Draw the main sun object
	//

	get_3d_transformation_matrix ( sun_matrix, sun_3d_heading, sun_3d_pitch, 0 );

	sun_polygon = construct_sun_polygon ( sun_matrix, sun_quad, 32000 * sun_3d_scale, 32000 * sun_3d_scale, 100000 );

	specular.colour = 0;

	if ( sun_polygon )
	{

		asm_convert_float_to_int ( ( sun_3d_colour.red * 255 ), &sun_red );
		asm_convert_float_to_int ( ( sun_3d_colour.green * 255 ), &sun_green );
		asm_convert_float_to_int ( ( sun_3d_colour.blue * 255 ), &sun_blue );

		colour.red = sun_red;
		colour.green = sun_green;
		colour.blue = sun_blue;

		set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS );
		set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE );

		suspend_d3d_fog ();

		set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT );
		set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND );
		set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND );

		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
		set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );

		set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

		set_d3d_texture ( 0, load_hardware_texture_map ( sun_texture ) );

		draw_wbuffered_flat_shaded_textured_polygon ( sun_polygon, colour, specular );
	}

	//
	// Now render the flare around the sun, if it is indeed there.
	//

	//
	// Calculate the intensity of the sun flare
	//

	flare_intensity = (	( sun_matrix[2][0] * visual_3d_vp->zv.x ) +
							 	( sun_matrix[2][1] * visual_3d_vp->zv.y ) +
							 	( sun_matrix[2][2] * visual_3d_vp->zv.z ) );

	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;
	flare_intensity *= flare_intensity;

	flare_intensity *= sun_3d_intensity;
	flare_intensity *= sun_3d_intensity;
	flare_intensity *= sun_3d_intensity;

	flare_intensity *= 255;

	sun_polygon = construct_sun_polygon ( sun_matrix, sun_quad, 144000, 69750, 100000 );

	if ( sun_polygon )
	{

		asm_convert_float_to_int ( ( ( 74.0 / 255.0 ) * flare_intensity ), &sun_red );
		asm_convert_float_to_int ( ( ( 177.0 / 255.0 ) * flare_intensity ), &sun_green );
		asm_convert_float_to_int ( ( ( 248.0 / 255.0 ) * flare_intensity ), &sun_blue );
//		asm_convert_float_to_int ( ( sun_3d_colour.red * flare_intensity ), &sun_red );
//		asm_convert_float_to_int ( ( sun_3d_colour.green * flare_intensity ), &sun_green );
//		asm_convert_float_to_int ( ( sun_3d_colour.blue * flare_intensity ), &sun_blue );

		colour.red = sun_red;
		colour.green = sun_green;
		colour.blue = sun_blue;

		set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, D3DCMP_ALWAYS );
		set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, FALSE );

		suspend_d3d_fog ();

		set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_FLAT );
		set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
		set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, ADDITIVE_SOURCE_BLEND );
		set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, ADDITIVE_DESTINATION_BLEND );

		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
		set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
		set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );

		set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

		set_d3d_texture ( 0, load_hardware_texture_map ( sun_flare_texture ) );

		draw_wbuffered_flat_shaded_textured_polygon ( sun_polygon, colour, specular );
	}

	set_d3d_int_state ( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE );

	set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
	set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	set_d3d_texture_stage_state ( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
	set_d3d_texture ( 0, NULL );

	set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
	set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );

	reinstate_d3d_fog ();

	set_d3d_int_state ( D3DRENDERSTATE_ZFUNC, zbuffer_default_comparison );
	set_d3d_int_state ( D3DRENDERSTATE_ZWRITEENABLE, TRUE );
}
示例#6
0
void draw_z_sorted_3d_object ( object_3d_instance *obj )
{

    int
    object_number,
    draw_sub_objects,
    count,
    temp,
    num_faces;

    object_3d_face
    *faces;

    light_3d_source
    *this_light,
    *prev_light,
    *light_ptr,
    *light;

    vec3d
    *pos;

    vec3d
    object_pos,
    object_unit_pos;

    polygon_buffer
    *translucent_buffer;

    object_3d_scene_database_entry
    *scene;

    //
    // Set the scene pointer
    //

    scene = &objects_3d_scene_database[obj->object_number];

    //
    // Set up the texture animations for this object.
    //

    initialise_object_texture_animations ( obj );

    //
    // Set up the object drawing global variables
    //

    object_3d_points_current_base = 0;

    object_3d_object_current_base = 0;

    object_3d_light_3d_current_base = 0;


    //
    // Set the object dissolve variables
    //

    current_object_3d_dissolve_factor = 1.0;
    current_object_3d_dissolve_value = 255;

    //
    // Turn lightmaps off
    //

    current_object_3d_light_maps_enabled = FALSE;

    //
    // Calculate the object's position relative to the view.
    //

    pos = &obj->view_position;

    {

        float
        fog_intensity;

        int
        ifog_intensity;

        fog_intensity = get_fog_distance_value ( pos->z );

        asm_convert_float_to_int ( fog_intensity, &ifog_intensity );

        set_d3d_fog_face_intensity ( ifog_intensity );
    }

    //
    // Set the main objects' scaling values
    //

    object_3d_scale.x = obj->relative_scale.x;
    object_3d_scale.y = obj->relative_scale.y;
    object_3d_scale.z = obj->relative_scale.z;

    //
    // Calculate the object's rotation matrix, to transform its 3d points relative to the view.
    //

    rotation_3d[0][0] = ( obj->vp.xv.x * visual_3d_vp->xv.x + obj->vp.xv.y * visual_3d_vp->xv.y + obj->vp.xv.z * visual_3d_vp->xv.z );
    rotation_3d[0][1] = ( obj->vp.xv.x * visual_3d_vp->yv.x + obj->vp.xv.y * visual_3d_vp->yv.y + obj->vp.xv.z * visual_3d_vp->yv.z );
    rotation_3d[0][2] = ( obj->vp.xv.x * visual_3d_vp->zv.x + obj->vp.xv.y * visual_3d_vp->zv.y + obj->vp.xv.z * visual_3d_vp->zv.z );

    rotation_3d[1][0] = ( obj->vp.yv.x * visual_3d_vp->xv.x + obj->vp.yv.y * visual_3d_vp->xv.y + obj->vp.yv.z * visual_3d_vp->xv.z );
    rotation_3d[1][1] = ( obj->vp.yv.x * visual_3d_vp->yv.x + obj->vp.yv.y * visual_3d_vp->yv.y + obj->vp.yv.z * visual_3d_vp->yv.z );
    rotation_3d[1][2] = ( obj->vp.yv.x * visual_3d_vp->zv.x + obj->vp.yv.y * visual_3d_vp->zv.y + obj->vp.yv.z * visual_3d_vp->zv.z );

    rotation_3d[2][0] = ( obj->vp.zv.x * visual_3d_vp->xv.x + obj->vp.zv.y * visual_3d_vp->xv.y + obj->vp.zv.z * visual_3d_vp->xv.z );
    rotation_3d[2][1] = ( obj->vp.zv.x * visual_3d_vp->yv.x + obj->vp.zv.y * visual_3d_vp->yv.y + obj->vp.zv.z * visual_3d_vp->yv.z );
    rotation_3d[2][2] = ( obj->vp.zv.x * visual_3d_vp->zv.x + obj->vp.zv.y * visual_3d_vp->zv.y + obj->vp.zv.z * visual_3d_vp->zv.z );

    rotation_3d[0][0] *= object_3d_scale.x;
    rotation_3d[1][0] *= object_3d_scale.y;
    rotation_3d[2][0] *= object_3d_scale.z;

    rotation_3d[0][1] *= object_3d_scale.x;
    rotation_3d[1][1] *= object_3d_scale.y;
    rotation_3d[2][1] *= object_3d_scale.z;

    rotation_3d[0][2] *= object_3d_scale.x;
    rotation_3d[1][2] *= object_3d_scale.y;
    rotation_3d[2][2] *= object_3d_scale.z;

    //
    // Calculate the vector from the object to the viewpoint, in the object's view system
    //

    {

        float
        x,
        y,
        z;

        x = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.xv.x );
        x += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.xv.y );
        x += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.xv.z );

        y = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.yv.x );
        y += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.yv.y );
        y += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.yv.z );

        z = ( ( visual_3d_vp->x - obj->vp.x ) * obj->vp.zv.x );
        z += ( ( visual_3d_vp->y - obj->vp.y ) *  obj->vp.zv.y );
        z += ( ( visual_3d_vp->z - obj->vp.z ) *  obj->vp.zv.z );

        object_pos.x = x;
        object_pos.y = y;
        object_pos.z = z;

        object_unit_pos.x = -object_pos.x;
        object_unit_pos.y = -object_pos.y;
        object_unit_pos.z = -object_pos.z;

        normalise_any_3d_vector ( &object_unit_pos );
    }

    //
    // Get the object number
    //

    object_number = get_object_approximation_number ( obj->object_number, pos->z, &draw_sub_objects );

    //
    // Rotate the light source vector to be relative to the object.
    //

    light_ptr = current_3d_lights;

    prev_light = NULL;

    light = NULL;

    if ( light_ptr )
    {

        light = &light_3d_array[object_3d_light_3d_current_base];

        while ( light_ptr )
        {

            float
            lx,
            ly,
            lz;

            if ( light_ptr->type == LIGHT_3D_TYPE_POINT )
            {

                vec3d
                vector;

                float
                distance;

                //
                // Work out the distance from object to light source
                //

                vector.x = - light_ptr->light_position.x + obj->vp.x;
                vector.y = - light_ptr->light_position.y + obj->vp.y;
                vector.z = - light_ptr->light_position.z + obj->vp.z;

                lx = vector.x * vector.x;
                ly = vector.y * vector.y;
                lz = vector.z * vector.z;

                distance = ( lx + ly + lz );

                if ( distance < light_ptr->radius )
                {

                    distance = 1 - ( distance / light_ptr->radius );

                    this_light = &light_3d_array[object_3d_light_3d_current_base];

                    object_3d_light_3d_current_base++;

                    if ( prev_light )
                    {

                        prev_light->succ = this_light;
                    }

                    this_light->pred = prev_light;
                    this_light->succ = NULL;


                    this_light->colour.red = light_ptr->colour.red * distance;
                    this_light->colour.green = light_ptr->colour.green * distance;
                    this_light->colour.blue = light_ptr->colour.blue * distance;
//					this_light->colour.intensity = light_ptr->colour.intensity * distance;

                    normalise_any_3d_vector ( &vector );

                    lx = ( vector.x * obj->vp.attitude[0][0] );
                    lx += ( vector.y * obj->vp.attitude[0][1] );
                    lx += ( vector.z * obj->vp.attitude[0][2] );

                    ly = ( vector.x * obj->vp.attitude[1][0] );
                    ly += ( vector.y * obj->vp.attitude[1][1] );
                    ly += ( vector.z * obj->vp.attitude[1][2] );

                    lz = ( vector.x * obj->vp.attitude[2][0] );
                    lz += ( vector.y * obj->vp.attitude[2][1] );
                    lz += ( vector.z * obj->vp.attitude[2][2] );

                    this_light->lx = lx;
                    this_light->ly = ly;
                    this_light->lz = lz;

                    //
                    // Generate a highlight vector
                    //

                    this_light->highlight_vector.x = ( lx - object_unit_pos.x );
                    this_light->highlight_vector.y = ( ly - object_unit_pos.y );
                    this_light->highlight_vector.z = ( lz - object_unit_pos.z );

                    normalise_any_3d_vector ( &this_light->highlight_vector );

                    prev_light = this_light;
                }
            }
            else
            {

                this_light = &light_3d_array[object_3d_light_3d_current_base];

                object_3d_light_3d_current_base++;

                if ( prev_light )
                {

                    prev_light->succ = this_light;
                }

                this_light->pred = prev_light;
                this_light->succ = NULL;

                this_light->colour.red = light_ptr->colour.red;
                this_light->colour.green = light_ptr->colour.green;
                this_light->colour.blue = light_ptr->colour.blue;
//				this_light->colour.intensity = light_ptr->colour.intensity;

                lx = ( light_ptr->lx * obj->vp.attitude[0][0] );
                lx +=  ( light_ptr->ly * obj->vp.attitude[0][1] );
                lx += ( light_ptr->lz * obj->vp.attitude[0][2] );

                ly = ( light_ptr->lx * obj->vp.attitude[1][0] );
                ly += ( light_ptr->ly * obj->vp.attitude[1][1] );
                ly += ( light_ptr->lz * obj->vp.attitude[1][2] );


                lz = ( light_ptr->lx * obj->vp.attitude[2][0] );
                lz += ( light_ptr->ly * obj->vp.attitude[2][1] );
                lz += ( light_ptr->lz * obj->vp.attitude[2][2] );

                this_light->lx = lx;
                this_light->ly = ly;
                this_light->lz = lz;

                //
                // Generate a highlight vector
                //

                this_light->highlight_vector.x = ( lx - object_unit_pos.x );
                this_light->highlight_vector.y = ( ly - object_unit_pos.y );
                this_light->highlight_vector.z = ( lz - object_unit_pos.z );

                normalise_any_3d_vector ( &this_light->highlight_vector );

                prev_light = this_light;
            }

            light_ptr = light_ptr->succ;
        }
    }

    //
    //	Set up this objects' object info structure
    //

    object_3d_object_base[object_3d_object_current_base].lights = light;

    object_3d_object_base[object_3d_object_current_base].points_base = object_3d_points_current_base;

    object_3d_object_base[object_3d_object_current_base].object_number = object_number;

    current_object_3d_object_base = &object_3d_object_base[object_3d_object_current_base];

    //
    // Set up the face sorting variables
    //

    num_faces = objects_3d_data[object_number].number_of_faces;

    reset_3d_face_sorting ();

    //
    // Insert this objects' faces into the sorted list.
    //

    faces = objects_3d_data[object_number].faces;

    if ( objects_3d_data[object_number].number_of_points )
    {

        object_short_3d_point
        *object_points;

        point_3d_plain_reference
        *plain_point_list;

        face_surface_description
        *surfaces;

        int
        surface,
        surface_face_count,
        point_reference_index,
        gouraud_point_index,
        face_normal_index,
        texture_point_index;

        surface = 0;
        point_reference_index = 0;
        gouraud_point_index = 0;
        face_normal_index = 0;
        texture_point_index = 0;

        object_points = objects_3d_data[object_number].points;

        plain_point_list = NULL;	//objects_3d_data[object_number].object_faces_point_plain_list;

        surfaces = objects_3d_data[object_number].surfaces;

        surface_face_count = surfaces[surface].number_of_faces;

        for ( count = num_faces; count > 0; count-- )
        {

            if ( surface_face_count == 0 )
            {

                surface++;

                surface_face_count = surfaces[surface].number_of_faces;
            }

            if ( faces->number_of_points > 2 )
            {

                float
                tmp;

                vec3d
                true_depth_point;

                {

                    point_3d_plain_reference
                    *point_list;

                    point_list = &plain_point_list[point_reference_index];

                    true_depth_point.x = object_points[point_list[0].point].x;
                    true_depth_point.y = object_points[point_list[0].point].y;
                    true_depth_point.z = object_points[point_list[0].point].z;

                    true_depth_point.x += object_points[point_list[1].point].x;
                    true_depth_point.y += object_points[point_list[1].point].y;
                    true_depth_point.z += object_points[point_list[1].point].z;

                    true_depth_point.x += object_points[point_list[2].point].x;
                    true_depth_point.y += object_points[point_list[2].point].y;
                    true_depth_point.z += object_points[point_list[2].point].z;

                    point_list += 3;

                    for ( temp = faces->number_of_points; temp > 3; temp-- )
                    {

                        true_depth_point.x += object_points[point_list->point].x;
                        true_depth_point.y += object_points[point_list->point].y;
                        true_depth_point.z += object_points[point_list->point].z;

                        point_list++;
                    }

                    tmp = true_depth_point.x * rotation_3d[0][2];
                    tmp += true_depth_point.y * rotation_3d[1][2];
                    tmp += true_depth_point.z * rotation_3d[2][2];
                    tmp *= one_over_table[faces->number_of_points];
                    tmp += pos->z;

                    //
                    // Just use the binary representation of the float z value for z-sorting
                    //

                    insert_z_sorted_3d_face ( faces, *( ( int * ) &tmp ), surface, point_reference_index, gouraud_point_index, face_normal_index, texture_point_index, current_object_3d_object_base );
//					insert_z_sorted_3d_face ( faces, *( ( int * ) &tmp ), surface, point_reference_index, gouraud_point_index, 0, texture_point_index, this_object_3d_info );
                }
            }
            else
            {
                /*
                			float
                				tmp;

                			point_3d_plain_reference
                				*point_list;

                			point_list = &plain_point_list[faces->point_reference_index];

                			depth_point = &object_points[point_list->point];

                			tmp = pos->z;

                			point_list++;

                			tmp += depth_point->x * rotation_3d[0][2];

                			tmp += depth_point->y * rotation_3d[1][2];

                			tmp += depth_point->z * rotation_3d[2][2];

                			//
                			// Just use the binary representation of the float z value for z-sorting
                			//

                			insert_z_sorted_3d_face ( faces, * ( ( int * ) &tmp ), this_object_3d_info );
                		*/
            }

            point_reference_index += faces->number_of_points;

            if ( surfaces[surface].textured )
            {

                texture_point_index += faces->number_of_points;
            }

            if ( surfaces[surface].smoothed )
            {

                gouraud_point_index += faces->number_of_points;
            }

            if ( faces->number_of_points >= 3 )
            {

                face_normal_index++;
            }

            faces++;

            surface_face_count--;
        }
    }

    faces = objects_3d_data[object_number].faces;

    //
    // Transform the object's shape data
    //

    if ( objects_3d_data[object_number].number_of_points )
    {

        illuminate_3d_object ( &objects_3d_data[object_number], pos, light, NULL, object_3d_points_current_base );

        transform_3d_object ( &objects_3d_data[object_number], pos, light, NULL, object_3d_points_current_base);
    }

    //
    // Adjust the memory pointers for any sub objects
    //

    object_3d_object_current_base ++;

    object_3d_points_current_base += objects_3d_data[object_number].number_of_points;

    //
    // Recurse down any sub objects
    //

    if ( ( draw_sub_objects ) && ( scene->number_of_sub_objects != 0 ) )
    {

        for ( count = ( scene->number_of_sub_objects -1 ); count >= 0; count-- )
        {

            if ( obj->sub_objects[count].visible_object )
            {

                draw_z_sorted_sub_object ( &obj->sub_objects[count], &scene->sub_objects[count], &obj->vp, current_object_3d_object_base->lights, pos );
            }
        }
    }

    //
    // Start sorting the translucent polygons
    //

    translucent_buffer = get_translucent_sorted_polygon_buffer ();

    //
    //	Ok, now we're ready to draw the actual faces.
    //

    render_3d_object_faces ();

    if ( finalise_translucent_sorted_polygon_buffer ( translucent_buffer ) )
    {

//		set_d3d_transparency_on ();

        draw_polygon_buffer ( translucent_buffer );

//		set_d3d_transparency_off ();
    }
}