Example #1
0
void draw_3d_sprite ( object_3d_sprite *sprite )
{

	float
		x,
		y,
		z,
		q,
		i,
		j,
		radius,
		roll,
		sin_roll,
		cos_roll,
		width,
		height;

	vertex
		*poly,
		sprite_quad[4];

	vec2d
		point1,
		point2,
		point3,
		point4;

	int
		outcode;

	number_of_sprites_in_3d_scene++;

	x = sprite->position.x;
	y = sprite->position.y;
	z = sprite->position.z;

	radius = sprite->radius;

	roll = sprite->roll;
	sin_roll = sin ( roll );
	cos_roll = cos ( roll );

	point1.x = ( -0.5 * ( +cos_roll ) ) + ( +0.5 * ( +sin_roll ) );
	point1.y = ( -0.5 * ( -sin_roll ) ) + ( +0.5 * ( +cos_roll ) );

	point2.x = ( -0.5 * ( +cos_roll ) ) + ( -0.5 * ( +sin_roll ) );
	point2.y = ( -0.5 * ( -sin_roll ) ) + ( -0.5 * ( +cos_roll ) );

	point3.x = ( +0.5 * ( +cos_roll ) ) + ( -0.5 * ( +sin_roll ) );
	point3.y = ( +0.5 * ( -sin_roll ) ) + ( -0.5 * ( +cos_roll ) );

	point4.x = ( +0.5 * ( +cos_roll ) ) + ( +0.5 * ( +sin_roll ) );
	point4.y = ( +0.5 * ( -sin_roll ) ) + ( +0.5 * ( +cos_roll ) );
	
	q = 1.0 / z;

	i = ( active_3d_environment->screen_i_scale * x * q );
	j = ( active_3d_environment->screen_j_scale * y * q );
	
	i = active_3d_environment->x_origin + i;
	j = active_3d_environment->y_origin - j;
	
	width = active_3d_environment->screen_i_scale * radius * q;
	height = active_3d_environment->screen_j_scale * radius * q;

	sprite_quad[0].q = q;
	sprite_quad[0].i = i + ( point1.x * width );
	sprite_quad[0].j = j + ( point1.y * height );
	sprite_quad[0].u = 0;
	sprite_quad[0].v = 0;
	sprite_quad[0].outcode = generate_3d_outcode ( sprite_quad[0].i, sprite_quad[0].j );
	sprite_quad[0].next_vertex = &sprite_quad[1];

	sprite_quad[1].q = q;
	sprite_quad[1].i = i + ( point2.x * width );
	sprite_quad[1].j = j + ( point2.y * height );
	sprite_quad[1].u = 1;
	sprite_quad[1].v = 0;
	sprite_quad[1].outcode = generate_3d_outcode ( sprite_quad[1].i, sprite_quad[1].j );
	sprite_quad[1].next_vertex = &sprite_quad[2];

	sprite_quad[2].q = q;
	sprite_quad[2].i = i + ( point3.x * width );
	sprite_quad[2].j = j + ( point3.y * height );
	sprite_quad[2].u = 1;
	sprite_quad[2].v = 1;
	sprite_quad[2].outcode = generate_3d_outcode ( sprite_quad[2].i, sprite_quad[2].j );
	sprite_quad[2].next_vertex = &sprite_quad[3];

	sprite_quad[3].q = q;
	sprite_quad[3].i = i + ( point4.x * width );
	sprite_quad[3].j = j + ( point4.y * height );
	sprite_quad[3].u = 0;
	sprite_quad[3].v = 1;
	sprite_quad[3].outcode = generate_3d_outcode ( sprite_quad[3].i, sprite_quad[3].j );
	sprite_quad[3].next_vertex = NULL;

	outcode = sprite_quad[0].outcode;
	outcode |= sprite_quad[1].outcode;
	outcode |= sprite_quad[2].outcode;
	outcode |= sprite_quad[3].outcode;

	poly = sprite_quad;

	if ( outcode )
	{

		clip_3d_coord = 0;

		poly = clip_3d_polygon ( poly, outcode );
	}

	if ( poly )
	{

		real_colour
			specular_colour;

		specular_colour.colour = 0;
		specular_colour.alpha = 255;

		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_MIPFILTER, D3DTFP_POINT );

		if (active_3d_environment->render_filter != RENDER_CLEAR )
		{

			float
				r,
				g,
				b,
				intensity;

			int
				ir,
				ig,
				ib;

			real_colour
				colour;

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

			colour.colour = sprite->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;

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

			colour.colour = sprite->colour;
			colour.red = ir;
			colour.green = ig;
			colour.blue = ib;

			sprite->colour = colour.colour;
		}

		if ( sprite->additive )
		{

			set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE );
			set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE );

			set_d3d_flat_shaded_textured_renderstate ( sprite->texture );

			draw_wbuffered_flat_shaded_textured_polygon ( poly, *( ( real_colour * ) &sprite->colour ), specular_colour );
		}
		else
		{



			set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
			set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );

			set_d3d_flat_shaded_textured_renderstate ( sprite->texture );

			draw_wbuffered_flat_shaded_textured_polygon ( poly, *( ( real_colour * ) &sprite->colour ), specular_colour );
		}
	}
}
Example #2
0
void draw_3d_rain ( void )
{

	point_3d_plain_reference
		rain_point_references[2];

	int
		count,
		outcode;

	//
	// Calculate the rotation matrix, to transform rain drops relative to the view.
	//

	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 );

	if ( rain_3d_raindrops_valid )
	{

		int
			number_of_valid_raindrops;

		float
			rain_intensity;

		int
			rain_whiteness;


		rain_intensity = ambient_3d_light.colour.red * 0.3 + ambient_3d_light.colour.green * 0.59 * ambient_3d_light.colour.blue * 0.11;

		rain_intensity *= 4;

		rain_intensity *= 255;

		rain_intensity = bound ( rain_intensity, 0, 255 );

		rain_whiteness = rain_intensity;

		//
		// Remeber the number of valid raindrops
		//

		number_of_valid_raindrops = rain_3d_raindrops_valid;

		//
		// Rotate the rain - putting the results in transformed_3d_points
		//

		transform_3d_rain ();

		//
		// Go through pairing up the transformed points, drawing lines between them.
		//

		rain_point_references[0].point = 0;
		rain_point_references[1].point = 1;

		set_d3d_alpha_fog_zbuffer ( TRUE, FALSE, TRUE, FALSE );

		set_d3d_int_state ( D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD );

		set_d3d_texture ( 0, NULL );

		set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_DISABLE );
		set_d3d_texture_stage_state ( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

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

			vertex
				*line;

			//
			// Construct the 3d line
			//

			clip_3d_coord = 0;

			line = construct_3d_line ( rain_point_references, ( count * 2 ), &outcode );

			if ( line )
			{

				line->red = rain_whiteness;
				line->green = rain_whiteness;
				line->blue = rain_whiteness;
				line->alpha = 32;

				line->next_vertex->red = rain_whiteness;
				line->next_vertex->green = rain_whiteness;
				line->next_vertex->blue = rain_whiteness;
				line->next_vertex->alpha = 192;

				if ( outcode & CLIP_HITHER )
				{

					line = hither_clip_3d_polygon ( line, &outcode );
				}

				if ( line )
				{

					if ( outcode )
					{

						line = clip_3d_polygon ( line, outcode );
					}

					if ( line )
					{

						vertex
							*point1,
							*point2;

						LPD3DTLVERTEX
							vertices,
							vptr;

						vertices = get_d3d_line_vertices_points_address ();

						vptr = vertices;

						point2 = line;

						point1 = line->next_vertex;

						*( ( int * ) &vptr->sx ) = *( ( int * ) &point1->i );
						*( ( int * ) &vptr->sy ) = *( ( int * ) &point1->j );
						*( ( int * ) &vptr->rhw ) = *( ( int * ) &point1->q );
						vptr->sz = ( point1->q * zbuffer_factor ) + zbuffer_constant;

                        vptr->r = point1->red;
                        vptr->g = point1->green;
                        vptr->b = point1->blue;
                        vptr->a = point1->alpha;
						vptr->color = point1->colour;
						vptr->specular = d3d_fog_intensity;

						vptr++;

						*( ( int * ) &vptr->sx ) = *( ( int * ) &point2->i );
						*( ( int * ) &vptr->sy ) = *( ( int * ) &point2->j );
						*( ( int * ) &vptr->rhw ) = *( ( int * ) &point2->q );
						vptr->sz = ( point2->q * zbuffer_factor ) + zbuffer_constant;

                        vptr->r = point2->red;
                        vptr->g = point2->green;
                        vptr->b = point2->blue;
                        vptr->a = point2->alpha;
						vptr->color = point2->colour;
						vptr->specular = d3d_fog_intensity;

						draw_line_primitive ( vertices );
					}
				}
			}
		}

		flush_line_primitives ();

		set_d3d_alpha_fog_zbuffer ( FALSE, TRUE, TRUE, TRUE );
	}

	if ( rain_3d_snowdrops_valid )
	{

		real_colour
			snow_specular,
			snow_colour;

		//
		// Rotate the rain - putting the results in transformed_3d_points
		//

		transform_3d_snow ();

		set_d3d_alpha_fog_zbuffer ( TRUE, FALSE, FALSE, FALSE );

		//
		// First, set the snow texture
		//

		set_d3d_texture ( 0, load_hardware_texture_map ( snow_3d_texture ) );

		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 );

		snow_colour.red = 255;
		snow_colour.green = 255;
		snow_colour.blue = 255;
		snow_colour.alpha = 255;

		snow_specular.colour = d3d_fog_intensity;

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

			vertex
				*poly,
				snow_quad[4];

			if ( !transformed_3d_points[count].outcode )
			{

				float
					width,
					height;

				int
					outcode;

				//
				// We know the raindrop is on the screen ( to a certain extent )
				//

				width = active_3d_environment->screen_i_scale * snow_particle_radius * transformed_3d_points[count].q;
				height = active_3d_environment->screen_j_scale * snow_particle_radius * transformed_3d_points[count].q;

				snow_quad[0].q = transformed_3d_points[count].q;
				snow_quad[0].i = transformed_3d_points[count].i - ( width / 2 );
				snow_quad[0].j = transformed_3d_points[count].j - ( height / 2 );
				snow_quad[0].u = 0;
				snow_quad[0].v = 0;
				snow_quad[0].outcode = generate_3d_outcode ( snow_quad[0].i, snow_quad[0].j );
				snow_quad[0].next_vertex = &snow_quad[1];

				snow_quad[1].q = transformed_3d_points[count].q;
				snow_quad[1].i = transformed_3d_points[count].i + ( width / 2 );
				snow_quad[1].j = transformed_3d_points[count].j - ( height / 2 );
				snow_quad[1].u = 1;
				snow_quad[1].v = 0;
				snow_quad[1].outcode = generate_3d_outcode ( snow_quad[1].i, snow_quad[1].j );
				snow_quad[1].next_vertex = &snow_quad[2];

				snow_quad[2].q = transformed_3d_points[count].q;
				snow_quad[2].i = transformed_3d_points[count].i + ( width / 2 );
				snow_quad[2].j = transformed_3d_points[count].j + ( height / 2 );
				snow_quad[2].u = 1;
				snow_quad[2].v = 1;
				snow_quad[2].outcode = generate_3d_outcode ( snow_quad[2].i, snow_quad[2].j );
				snow_quad[2].next_vertex = &snow_quad[3];

				snow_quad[3].q = transformed_3d_points[count].q;
				snow_quad[3].i = transformed_3d_points[count].i - ( width / 2 );
				snow_quad[3].j = transformed_3d_points[count].j + ( height / 2 );
				snow_quad[3].u = 0;
				snow_quad[3].v = 1;
				snow_quad[3].outcode = generate_3d_outcode ( snow_quad[3].i, snow_quad[3].j );
				snow_quad[3].next_vertex = NULL;

				outcode = snow_quad[0].outcode;
				outcode |= snow_quad[1].outcode;
				outcode |= snow_quad[2].outcode;
				outcode |= snow_quad[3].outcode;

				poly = snow_quad;

				if ( outcode )
				{

					clip_3d_coord = 0;

					poly = clip_3d_polygon ( poly, outcode );
				}

				if ( poly )
				{

					draw_wbuffered_flat_shaded_textured_polygon ( poly, snow_colour, snow_specular );
				}
			}
		}

		set_d3d_alpha_fog_zbuffer ( FALSE, TRUE, TRUE, TRUE );
	}
}