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