void render_smoke_trail_polygon ( vertex *poly, screen *texture, int additive ) { int outcode; vertex *tmp; tmp = poly; outcode = 0; while ( tmp ) { outcode |= tmp->outcode; tmp = tmp->next_vertex; } if ( outcode ) { clip_3d_coord = 0; if ( outcode & CLIP_HITHER ) { poly = hither_clip_3d_polygon ( poly, &outcode ); if ( !poly ) { outcode = 0; } } if ( outcode ) { apply_perspective_to_polygon_texture ( poly ); poly = clip_3d_polygon ( poly, outcode ); if ( poly ) { remove_perspective_from_polygon_texture ( poly ); } } } if ( poly ) { // d3d_fog_intensity = RGBA_MAKE ( 0, 0, 0, 255 ); // // Set the required renderstates // set_d3d_int_state ( D3DRENDERSTATE_SPECULARENABLE, FALSE ); // set_d3d_int_state ( D3DRENDERSTATE_CULLMODE, D3DCULL_NONE ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); 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_NONE ); if ( additive ) { set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); set_d3d_gouraud_shaded_textured_renderstate ( texture ); draw_wbuffered_gouraud_shaded_textured_polygon ( poly ); } else { set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ); set_d3d_gouraud_shaded_textured_renderstate ( texture ); draw_wbuffered_gouraud_shaded_textured_polygon ( poly ); } // set_d3d_int_state ( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); } }
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 ); } }
void draw_terrain_line ( int index1, int index2 ) { int outcode, outcode2; vertex *line; polygon_3d_vertices[0].x = transformed_3d_3d_points[index1].x; polygon_3d_vertices[0].y = transformed_3d_3d_points[index1].y; polygon_3d_vertices[0].z = transformed_3d_2d_points[index1].z; polygon_3d_vertices[0].i = transformed_3d_2d_points[index1].i; polygon_3d_vertices[0].j = transformed_3d_2d_points[index1].j; polygon_3d_vertices[0].q = transformed_3d_2d_points[index1].q; polygon_3d_vertices[0].outcode = transformed_3d_point_outcodes[index1]; polygon_3d_vertices[0].next_vertex = &polygon_3d_vertices[1]; polygon_3d_vertices[1].x = transformed_3d_3d_points[index2].x; polygon_3d_vertices[1].y = transformed_3d_3d_points[index2].y; polygon_3d_vertices[1].z = transformed_3d_2d_points[index2].z; polygon_3d_vertices[1].i = transformed_3d_2d_points[index2].i; polygon_3d_vertices[1].j = transformed_3d_2d_points[index2].j; polygon_3d_vertices[1].q = transformed_3d_2d_points[index2].q; polygon_3d_vertices[1].outcode = transformed_3d_point_outcodes[index2]; polygon_3d_vertices[1].next_vertex = NULL; line = polygon_3d_vertices; outcode = line->outcode; outcode2 = line->outcode; outcode |= line->next_vertex->outcode; outcode2 &= line->next_vertex->outcode; if ( outcode2 == 0 ) { vertex *line; line = polygon_3d_vertices; clip_3d_coord = 0; if ( outcode & CLIP_HITHER ) { line = hither_clip_3d_polygon ( line, &outcode ); } if ( line ) { if ( outcode ) { line = clip_3d_polygon ( line, outcode ); } if ( line ) { real_colour colour; colour.red = 0; colour.green = 0; colour.blue = 0; colour.alpha = 0; d3d_fog_intensity = RGBA_MAKE ( 0, 0, 0, 255 ); draw_wbuffered_plain_line ( line, colour ); } } } }
vertex * construct_sun_polygon ( matrix3x3 sun_matrix, vertex *sun_quad, float sun_width, float sun_height, float sun_depth ) { vertex *sun_polygon, *vert; int outcode, outcode2, count; sun_quad[0].next_vertex = &sun_quad[1]; sun_quad[1].next_vertex = &sun_quad[2]; sun_quad[2].next_vertex = &sun_quad[3]; sun_quad[3].next_vertex = NULL; sun_quad[0].x = -sun_width/2; sun_quad[0].y = sun_height/2; sun_quad[0].z = sun_depth; sun_quad[0].u = 0; sun_quad[0].v = 0; sun_quad[1].x = sun_width/2; sun_quad[1].y = sun_height/2; sun_quad[1].z = sun_depth; sun_quad[1].u = 1; sun_quad[1].v = 0; sun_quad[2].x = sun_width/2; sun_quad[2].y = -sun_height/2; sun_quad[2].z = sun_depth; sun_quad[2].u = 1; sun_quad[2].v = 1; sun_quad[3].x = -sun_width/2; sun_quad[3].y = -sun_height/2; sun_quad[3].z = sun_depth; sun_quad[3].u = 0; sun_quad[3].v = 1; for ( count = 0; count < 4; count++ ) { float x, y, z; x = sun_quad[count].x * sun_matrix[0][0] + sun_quad[count].y * sun_matrix[1][0] + sun_quad[count].z * sun_matrix[2][0]; y = sun_quad[count].x * sun_matrix[0][1] + sun_quad[count].y * sun_matrix[1][1] + sun_quad[count].z * sun_matrix[2][1]; z = sun_quad[count].x * sun_matrix[0][2] + sun_quad[count].y * sun_matrix[1][2] + sun_quad[count].z * sun_matrix[2][2]; sun_quad[count].x = x; sun_quad[count].y = y; sun_quad[count].z = z; } // // Clip the sun to the horizon // clip_3d_coord = 0; sun_polygon = horizon_clip_3d_polygon ( sun_quad ); if ( sun_polygon ) { // // Rotate the polygon around to the users viewpoint // vert = sun_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 ( NULL ); } if ( outcode & CLIP_HITHER ) { sun_polygon = hither_clip_3d_polygon ( sun_polygon, &outcode ); if ( !sun_polygon ) { return ( NULL ); } } if ( outcode ) { apply_perspective_to_polygon_texture ( sun_polygon ); sun_polygon = clip_3d_polygon ( sun_polygon, outcode ); if ( !sun_polygon ) { return ( NULL ); } remove_perspective_from_polygon_texture ( sun_polygon ); } if ( sun_polygon ) { vertex *p; p = sun_polygon; while ( p ) { if ( p->q < clip_yonder_reciprocal ) { p->q = clip_yonder_reciprocal; } p = p->next_vertex; } } return ( sun_polygon ); } else { return ( NULL ); } }
void render_cloud_polygon ( int number_of_points, cloud_3d_textured_reference *point_references, vertex *transformed_points, cloud_3d_point *source_points, float alpha_blend, screen *texture ) { int count, alpha, first_point, this_point, previous_point, outcode, outcode2; vertex *polygon; first_point = point_references->point; this_point = first_point; outcode = transformed_points[this_point].outcode; outcode2 = transformed_points[this_point].outcode; convert_float_to_int ( ( source_points[this_point].a * alpha_blend * 255 ), &alpha ); transformed_points[this_point].u = point_references->u; transformed_points[this_point].v = point_references->v; transformed_points[this_point].alpha = alpha; point_references++; for ( count = 1; count < number_of_points; count++ ) { previous_point = this_point; this_point = point_references->point; outcode |= transformed_points[this_point].outcode; outcode2 &= transformed_points[this_point].outcode; convert_float_to_int ( ( source_points[this_point].a * alpha_blend * 255 ), &alpha ); transformed_points[this_point].u = point_references->u; transformed_points[this_point].v = point_references->v; transformed_points[this_point].alpha = alpha; cloud_transformed_3d_points[previous_point].next_vertex = &cloud_transformed_3d_points[this_point]; point_references++; } cloud_transformed_3d_points[this_point].next_vertex = NULL; if ( !outcode2 ) { polygon = &cloud_transformed_3d_points[first_point]; clip_3d_coord = 0; if ( outcode & CLIP_HITHER ) { polygon = hither_clip_3d_polygon ( polygon, &outcode ); if ( !polygon ) { return; } } if ( outcode ) { apply_perspective_to_polygon_texture ( polygon ); polygon = clip_3d_polygon ( polygon, outcode ); if ( !polygon ) { return; } remove_perspective_from_polygon_texture ( polygon ); } if ( polygon ) { set_d3d_int_state ( D3DRENDERSTATE_SPECULARENABLE, FALSE ); set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ); set_d3d_gouraud_shaded_textured_renderstate ( texture ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP ); set_d3d_texture_stage_state ( 0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP ); set_d3d_texture_stage_state ( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); set_d3d_texture_stage_state ( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); { int number_of_vertices; vertex *vert; LPD3DTLVERTEX vertices, vptr; vert = polygon; vertices = get_d3d_vertices_address ( polygon, &number_of_vertices ); vptr = vertices; while ( vert ) { real_colour specular; specular.colour = d3d_fog_intensity; specular.red = vert->specular; specular.green = vert->specular; specular.blue = vert->specular; *( ( int * ) &vptr->sx ) = *( ( int * ) &vert->i ); *( ( int * ) &vptr->sy ) = *( ( int * ) &vert->j ); *( ( int * ) &vptr->tu ) = *( ( int * ) &vert->u ); *( ( int * ) &vptr->tv ) = *( ( int * ) &vert->v ); *( ( int * ) &vptr->rhw ) = *( ( int * ) &vert->q ); vptr->sz = ( vert->q * zbuffer_factor ) + zbuffer_constant; vptr->r = vert->red; vptr->g = vert->green; vptr->b = vert->blue; vptr->a = vert->alpha; vptr->color = vert->colour; vptr->specular = specular.colour; if ( vptr->sz >= 1.0 ) { vptr->sz = 0.999; } vptr++; vert = vert->next_vertex; } draw_fan_primitive ( number_of_vertices, vertices ); } // draw_wbuffered_gouraud_shaded_textured_polygon ( polygon ); } } }
void draw_3d_lightning_cloud_burst ( lightning_strike *strike ) { vertex *polygon, *vert, quad[4]; float width, depth, intensity; vec3d relative_position; int int_intensity, outcode, outcode2; screen *texture; texture = system_textures[lightning_cloud_texture]; width = 30000; depth = 30000; if ( !strike->current_frame_number ) { intensity = 0.5; } else { intensity = 1.0 / ( ( float ) strike->current_frame_number ); } intensity /= 3; quad[0].next_vertex = &quad[1]; quad[1].next_vertex = &quad[2]; quad[2].next_vertex = &quad[3]; quad[3].next_vertex = NULL; quad[0].x = -width/2; quad[0].y = 0; quad[0].z = -depth/2; quad[0].u = 0; quad[0].v = 0; quad[1].x = width/2; quad[1].y = 0; quad[1].z = -depth/2; quad[1].u = 1; quad[1].v = 0; quad[2].x = width/2; quad[2].y = 0; quad[2].z = depth/2; quad[2].u = 1; quad[2].v = 1; quad[3].x = -width/2; quad[3].y = 0; quad[3].z = depth/2; quad[3].u = 0; quad[3].v = 1; polygon = quad; // // Calculate the relative position of the lightning strike // relative_position.x = ( ( strike->position.x - visual_3d_vp->x ) * visual_3d_vp->xv.x + ( strike->position.y - visual_3d_vp->y ) * visual_3d_vp->xv.y + ( strike->position.z - visual_3d_vp->z ) * visual_3d_vp->xv.z ); relative_position.y = ( ( strike->position.x - visual_3d_vp->x ) * visual_3d_vp->yv.x + ( strike->position.y - visual_3d_vp->y ) * visual_3d_vp->yv.y + ( strike->position.z - visual_3d_vp->z ) * visual_3d_vp->yv.z ); relative_position.z = ( ( strike->position.x - visual_3d_vp->x ) * visual_3d_vp->zv.x + ( strike->position.y - visual_3d_vp->y ) * visual_3d_vp->zv.y + ( strike->position.z - visual_3d_vp->z ) * visual_3d_vp->zv.z ); { // // Rotate the polygon around to the users viewpoint // vert = 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; clip_3d_coord = 0; 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] + relative_position.x; y = vert->x * rotation_3d[0][1] + vert->y * rotation_3d[1][1] + vert->z * rotation_3d[2][1] + relative_position.y; z = vert->x * rotation_3d[0][2] + vert->y * rotation_3d[1][2] + vert->z * rotation_3d[2][2] + relative_position.z; 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 ) { polygon = hither_clip_3d_polygon ( polygon, &outcode ); if ( !polygon ) { return; } } if ( outcode ) { apply_perspective_to_polygon_texture ( polygon ); polygon = clip_3d_polygon ( polygon, outcode ); if ( !polygon ) { return; } remove_perspective_from_polygon_texture ( polygon ); } { real_colour colour, specular; set_d3d_alpha_fog_zbuffer ( TRUE, FALSE, TRUE, FALSE ); convert_float_to_int ( intensity * 255, &int_intensity ); colour.red = int_intensity; colour.green = int_intensity; colour.blue = int_intensity; colour.alpha = int_intensity; set_d3d_texture ( 0, texture ); set_d3d_texture_stage_state ( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); set_d3d_texture_stage_state ( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); set_d3d_int_state ( D3DRENDERSTATE_SRCBLEND, D3DBLEND_ONE ); set_d3d_int_state ( D3DRENDERSTATE_DESTBLEND, D3DBLEND_ONE ); 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_MIPFILTER, D3DTFP_POINT ); specular.colour = 0; draw_wbuffered_flat_shaded_textured_polygon ( polygon, colour, specular ); } } }
void draw_3d_polyline ( struct OBJECT_3D_POLYLINE *polyline ) { int segment, outcode; float average_distance; polyline_point *points; vertex *line; real_colour colour; // // Connect the two vertices up // points = polyline->polyline->points; segment = polyline->segment; points[segment].transformed_point.next_vertex = &points[segment+1].transformed_point; points[segment+1].transformed_point.next_vertex = NULL; outcode = points[segment].transformed_point.outcode; outcode |= points[segment+1].transformed_point.outcode; // // Calculate the average distance of the polyline // average_distance = ( points[segment].transformed_point.z + points[segment+1].transformed_point.z ) / 2.0; // // Set the fog value for this polyline // { float fog_intensity; int ifog_intensity; fog_intensity = get_fog_distance_value ( average_distance ); convert_float_to_int ( fog_intensity, &ifog_intensity ); set_d3d_fog_face_intensity ( ifog_intensity ); } // // Calculate the lighting if required // if ( polyline->polyline->lit ) { vec3d point1, point2, plane_normal, line_normal; float red, green, blue, ndotn, ndotp1, ndotcamera, direction_factor; light_3d_source *this_light; int ired, igreen, iblue; // // This bit is a work of a genius matey! // point1 = points[segment].world_point; point2 = points[segment+1].world_point; point1.x = ( ( point2.x - point1.x ) / 2 ) + point1.x; point1.y = ( ( point2.y - point1.y ) / 2 ) + point1.y; point1.z = ( ( point2.z - point1.z ) / 2 ) + point1.z; plane_normal.x = point2.x - point1.x; plane_normal.y = point2.y - point1.y; plane_normal.z = point2.z - point1.z; ndotn = ( ( plane_normal.x * plane_normal.x ) + ( plane_normal.y * plane_normal.y ) + ( plane_normal.z * plane_normal.z ) ); ndotp1 = ( ( point1.x * plane_normal.x ) + ( point1.y * plane_normal.y ) + ( point1.z * plane_normal.z ) ); ndotcamera = ( ( visual_3d_vp->x * plane_normal.x ) + ( visual_3d_vp->y * plane_normal.y ) + ( visual_3d_vp->z * plane_normal.z ) ); direction_factor = ( ( ndotp1 - ndotcamera ) / ndotn ); line_normal.x = visual_3d_vp->x + direction_factor * ( plane_normal.x ); line_normal.y = visual_3d_vp->y + direction_factor * ( plane_normal.y ); line_normal.z = visual_3d_vp->z + direction_factor * ( plane_normal.z ); line_normal.x = line_normal.x - point1.x; line_normal.y = line_normal.y - point1.y; line_normal.z = line_normal.z - point1.z; normalise_any_3d_vector ( &line_normal ); this_light = current_3d_lights; red = ambient_3d_light.colour.red; green = ambient_3d_light.colour.green; blue = ambient_3d_light.colour.blue; while ( this_light ) { float intensity; intensity = ( ( line_normal.x * this_light->lx ) + ( line_normal.y * this_light->ly ) + ( line_normal.z * this_light->lz ) ); if ( ( *( int * ) &intensity ) > ( *( int * ) &float_value_zero ) ) { red += intensity * this_light->colour.red; green += intensity * this_light->colour.green; blue += intensity * this_light->colour.blue; } this_light = this_light->succ; } red = bound ( red, 0, 1 ); green = bound ( green, 0, 1 ); blue = bound ( blue, 0, 1 ); red *= polyline->polyline->colour.red; green *= polyline->polyline->colour.green; blue *= polyline->polyline->colour.blue; red += FLOAT_FLOAT_FACTOR; green += FLOAT_FLOAT_FACTOR; blue += FLOAT_FLOAT_FACTOR; ired = ( *( int * ) &red ) - INTEGER_FLOAT_FACTOR; igreen = ( *( int * ) &green ) - INTEGER_FLOAT_FACTOR; iblue = ( *( int * ) &blue ) - INTEGER_FLOAT_FACTOR; colour.red = ired; colour.green = igreen; colour.blue = iblue; colour.alpha = 0; } else { colour = polyline->polyline->colour; } // // Go through all the vertices, creating lines to draw, then render them. // line = &points[segment].transformed_point; clip_3d_coord = 0; if ( outcode & CLIP_HITHER ) { line = hither_clip_3d_polygon ( line, &outcode ); } if ( line ) { if ( outcode ) { line = clip_3d_polygon ( line, outcode ); } if ( line ) { set_d3d_plain_renderstate (); draw_wbuffered_plain_line ( line, 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 ); } }
void render_clipped_3d_terrain_tree_gouraud_textured_diffuse_lit_polygon ( object_3d_face *this_face, struct OBJECT_3D_INFO *object_base ) { int triangle_count, outcode; vertex *poly; texture_map *texture; texture = &system_textures[current_object_3d_surface->texture_index]; for ( triangle_count = 0; triangle_count < ( this_face->number_of_points - 2 ); triangle_count++ ) { poly = NULL; /*construct_3d_vertex_gouraud_coloured_textured_triangle_fan ( triangle_count, current_object_3d_point_list, current_object_3d_gouraud_list, current_object_3d_texture_list, object_base->points_base, &outcode, current_tree_colour_red, current_tree_colour_green, current_tree_colour_blue, current_tree_colour_alpha ); */ if ( poly ) { if ( outcode ) { clip_3d_coord = 0; if ( outcode & CLIP_HITHER ) { poly = hither_clip_3d_polygon ( poly, &outcode ); if ( !poly ) { continue; } } if ( outcode ) { apply_perspective_to_polygon_texture ( poly ); poly = clip_3d_polygon ( poly, outcode ); if ( !poly ) { continue; } remove_perspective_from_polygon_texture ( poly ); } } // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREMAG, current_object_3d_texture_filter ); // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREMIN, current_object_3d_texture_mipmap ); // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREADDRESS, current_object_3d_texture_address ); // draw_d3d_gouraud_shaded_textured_polygon ( poly, texture ); } } }
void render_clipped_3d_terrain_tree_textured_diffuse_lit_polygon ( object_3d_face *this_face, struct OBJECT_3D_INFO *object_base ) { vertex *poly; texture_map *texture; texture = &system_textures[current_object_3d_surface->texture_index]; { real_colour colour; float red, green, blue; int ired, igreen, iblue; // // Look up the colour of the face normal // red = current_object_3d_transformed_normals[current_object_3d_face_normal_list->point].r; green = current_object_3d_transformed_normals[current_object_3d_face_normal_list->point].g; blue = current_object_3d_transformed_normals[current_object_3d_face_normal_list->point].b; red *= current_tree_colour_red; green *= current_tree_colour_green; blue *= current_tree_colour_blue; convert_float_to_int ( red, &ired ); convert_float_to_int ( green, &igreen ); convert_float_to_int ( blue, &iblue ); colour.red = ired; colour.green = igreen; colour.blue = iblue; colour.alpha = 255; poly = NULL; /*construct_3d_vertex_textured_polygon ( this_face->number_of_points, current_object_3d_point_list, current_object_3d_texture_list, object_base->points_base ); */ clip_3d_coord = 0; if ( current_object_3d_outcode & CLIP_HITHER ) { poly = hither_clip_3d_polygon ( poly, ¤t_object_3d_outcode ); if ( !poly ) { return; } } if ( current_object_3d_outcode ) { apply_perspective_to_polygon_texture ( poly ); poly = clip_3d_polygon ( poly, current_object_3d_outcode ); if ( !poly ) { return; } remove_perspective_from_polygon_texture ( poly ); } // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREMAG, current_object_3d_texture_filter ); // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREMIN, current_object_3d_texture_mipmap ); // set_d3d_int_state ( D3DRENDERSTATE_TEXTUREADDRESS, current_object_3d_texture_address ); // draw_d3d_flat_shaded_textured_polygon ( poly, texture, colour ); } }