📄 d3dfixedfuncshaders.fx
字号:
| 1 - completely inside (no clipping - p_num_new_vertices set| to num_vertices, new_vertices set to vertices, all| plane id's set to PGL_ID_NULL);| 2 - partially inside (clipped - new_vertices differs from| vertices)| p_num_new_vertices address to place number of vertices of the resulting| clipped polygon. If the entire original polygon is clipped| away, this number is set to zero and the rest of the output| arguments are unreliable. Otherwise, it is at least 3.| p_new_vertices[] address of the first _PglClipvertex structure in an| array of such structures that specify each of the vertices of| the clipped polygon.| The ordering matches the original ordering only in terms of the| original CW or CCW sense relative to the normal to the plane of| the polygon.| Array must have size greater than or equal to| (num_vertices+num_planes) structure elements.| CAUTION - some new edges may have zero length. |\*----------------------------------------------------------------------------*/int ClipTriangleByPlanes (uint oa_data_mask){/* "bld" refers to clipped polygon under construction (other polygon is implicitly the current polygon); "this" refers to current vertex on the perimeter of current polygon; "prev" refers to vertex preceding current vertex of current polygon*/ int i; uint vi, pi; /* free indices to vertices of current polygon, planes */ uint vi_prev; /* index of previous vertex of current polygon */ bool prev_vertex_is_neg; /* TRUE if previous vertex of current polygon is on negative side of plane */ uint vi_first_pos; /* index of first vertex of current polygon that lies on positive side of current plane */ uint num_v, num_v_bld; /* number of vertices in current and bld polygons */ uint num_v_pos; /* number of vertices of current polygon on positive side of plane */ float displ, displ_pos, displ_neg; /* signed displacements */ float dist_perp; /* absolute value of perp component of displacement */ float n_len, n_len_sq; float displacement_from_plane[9]; float4 plane; float4 position; float3 normal;#if 0/* TODO - temporary block because cannot easily furnish zone_mask */ uint plane_negative_zone, plane_negative_mask = 0x1000;#endif num_v = 3; for (pi=0; pi<NumSectionPlanes; pi++) {#if 0/* TODO - temporary block because cannot easily furnish zone_mask */ plane_negative_zone = plane_negative_mask & zone_mask; plane_negative_mask <<= 2; if (!plane_negative_zone) { /* Portion of zone_mask for this clip plane indicates that all vertices are on positive side or that software clipping for the corresponding plane is not wanted. */ continue; }#endif plane = SectionPlanes[pi]; num_v_pos = 0; for (vi=0; vi<num_v; ++vi) { position = v_str_array[vi].position; /* Compute signed displacement of vertex from current clip plane */// TODO - make sure dot works with 4D displacement_from_plane[vi] = displ = dot (position, plane); if (0.0 <= displ) { /* This vertex is on positive side of current clip plane */ if (num_v_pos == 0) { /* Capture first vertex on positive side */ vi_first_pos = vi; } ++num_v_pos; } } if (num_v_pos == 0) { /* No vertices computed to be on positive side of this clip plane */ return (0); } if (num_v_pos == num_v) { /* All vertices computed to be on positive side of this plane */ continue; } /* At least one vertex is on negative side of this clip plane */ /* Create next clipped polygon by starting with first vertex that was on positive side and move along perimeter of current polygon, creating new vertices at intersections with clip plane and at least one new edge, and eliminating vertices that are on negative side */ /* If edge from V' to V" crosses clip plane, intersection with plane is: V = V' + dist_V'_plane * (V" - V') / dist_perp_V'_V" where all distances are absolute values and dist_perp_V'_V" is defined as the absolute value of the component of the displacement between the two vertices that is perpendicular to the plane: dist_perp_V'_V" = (dist_V'_plane + dist_V"_plane) V = V' * (dist_perp_V'_V" - dist_V'_plane) / dist_perp_V'_V" + V" * dist_V'_plane / dist_perp_V'_V" = V' * dist_V"_plane / dist_perp_V'_V" + V" * dist_V'_plane / dist_perp_V'_V" */ /* First new vertex of next polygon is the first positive vertex */ mod_v_str_array[0] = v_str_array[vi_first_pos]; num_v_bld = 1; prev_vertex_is_neg = 0/*FALSE*/; for (i=1; i<num_v; i++) { vi = (vi_first_pos + i) % num_v; displ = displacement_from_plane[vi]; if (displ < 0.0) { /* this vertex is on negative side of plane */ if (!prev_vertex_is_neg) { /* Edge goes from positive side to negative side, so new vertex of next polygon is at intersection with plane */ vi_prev = (vi_first_pos + i - 1) % num_v; displ_neg = displ; displ_pos = displacement_from_plane[vi_prev]; dist_perp = displ_pos - displ_neg; if (0.0001/*PGL_EPSILON_LENGTH_1*/ < dist_perp) { displ_pos /= dist_perp; displ_neg /= dist_perp; } else { /* Use prev */ displ_pos = 0.0; displ_neg = -1.0; } construct_new_vertex (oa_data_mask, displ_neg, displ_pos, num_v_bld, vi_prev, vi);#if 0/* TODO - Temporarily removed and replaced by call to construct_new_vertex ()to reduce size of code to try to make it compile */ mod_v_str_array[num_v_bld].position = - displ_neg*v_str_array[vi_prev].position + displ_pos*v_str_array[vi].position;/* Can continue to use oa_data_mask, but only one tex is sent to VS, soconvention is used herein that it is tracked by OAMB_VERTEX_UV_FRONT bit */#if 0 if (oa_data_mask & OAMB_VERTEX_UV_FRONT) { mod_v_str_array[num_v_bld].tex = - displ_neg*v_str_array[vi_prev].tex + displ_pos*v_str_array[vi].tex; }#endif if (oa_data_mask & OAMB_VERTEX_ECOLOR) { mod_v_str_array[num_v_bld].rgba_front = - displ_neg*v_str_array[vi_prev].rgba_front + displ_pos*v_str_array[vi].rgba_front; } if (oa_data_mask & OAMB_VERTEX_ECOLOR_BACK) { mod_v_str_array[num_v_bld].rgba_back = - displ_neg*v_str_array[vi_prev].rgba_back + displ_pos*v_str_array[vi].rgba_back; }#if 0 if (oa_data_mask & OAMB_VERTEX_AND_NORMAL) { normal = mod_v_str_array[num_v_bld].normal = - displ_neg*v_str_array[vi_prev].normal + displ_pos*v_str_array[vi].normal; n_len_sq = normal.x * normal.x + normal.y*normal.y + normal.z*normal.z; if (0.00000001/*PGL_EPSILON_LENGTH_2*/ < n_len_sq) { /* Normalize */ n_len = sqrt (n_len_sq); mod_v_str_array[num_v_bld].normal /= n_len; } else { /* Use nearest normal */ if (0.5 < displ_pos) { mod_v_str_array[num_v_bld].normal = v_str_array[vi].normal; } else { mod_v_str_array[num_v_bld].normal = v_str_array[vi_prev].normal; } } }#endif#endif prev_vertex_is_neg = 1/*TRUE*/; ++num_v_bld; } /* END if (!prev_vertex_is_neg) */ /* (else, previous vertex is also on negative side and this edge generates no new vertices for next polygon) */ } /* END this vertex is on negative side of plane */ else { /* this vertex is on positive side of plane */ if (prev_vertex_is_neg) { /* Edge goes from negative side to positive side, so there are two new vertices of next polygon: intersection with plane; and this vertex (which is copied below) */ vi_prev = (vi_first_pos + i - 1) % num_v; displ_pos = displ; displ_neg = displacement_from_plane[vi_prev]; dist_perp = displ_pos - displ_neg; if (0.0001/*PGL_EPSILON_LENGTH_1*/ < dist_perp) { displ_pos /= dist_perp; displ_neg /= dist_perp; } else { /* Use this */ displ_pos = 0.0; displ_neg = -1.0; } construct_new_vertex (oa_data_mask, displ_neg, displ_pos, num_v_bld, vi, vi_prev);#if 0/* TODO - Temporarily removed and replaced by call to construct_new_vertex ()to reduce size of code to try to make it compile */ mod_v_str_array[num_v_bld].position = displ_pos*v_str_array[vi_prev].position - displ_neg*v_str_array[vi].position;/* Can continue to use oa_data_mask, but only one tex is sent to VS, soconvention is used that it is tracked by OAMB_VERTEX_UV_FRONT bit */#if 0 if (oa_data_mask & OAMB_VERTEX_UV_FRONT) { mod_v_str_array[num_v_bld].tex = displ_pos*v_str_array[vi_prev].tex - displ_neg*v_str_array[vi].tex; }#endif if (oa_data_mask & OAMB_VERTEX_ECOLOR) { mod_v_str_array[num_v_bld].rgba_front = displ_pos*v_str_array[vi_prev].rgba_front - displ_neg*v_str_array[vi].rgba_front; } if (oa_data_mask & OAMB_VERTEX_ECOLOR_BACK) { mod_v_str_array[num_v_bld].rgba_back = displ_pos*v_str_array[vi_prev].rgba_back - displ_neg*v_str_array[vi].rgba_back; }#if 0 if (oa_data_mask & OAMB_VERTEX_AND_NORMAL) { normal = mod_v_str_array[num_v_bld].normal = displ_pos*v_str_array[vi_prev].normal - displ_neg*v_str_array[vi].normal; n_len_sq = normal.x * normal.x + normal.y*normal.y + normal.z*normal.z; if (0.00000001/*PGL_EPSILON_LENGTH_2*/ < n_len_sq) { /* Normalize */ n_len = sqrt (n_len_sq); mod_v_str_array[num_v_bld].normal /= n_len; } else { /* Use nearest normal */ if (0.5 < displ_pos) { mod_v_str_array[num_v_bld].normal = v_str_array[vi_prev].normal; } else { mod_v_str_array[num_v_bld].normal = v_str_array[vi].normal; } } }#endif#endif prev_vertex_is_neg = 0/*FALSE*/; ++num_v_bld; } /* END if (prev_vertex_is_neg) */ /* (else, previous vertex is already in next polygon) */ /* Add this vertex to next polygon */ mod_v_str_array[num_v_bld] = v_str_array[vi]; ++num_v_bld; } /* END this vertex is on positive side of plane */ } /* END for (i=1; i<num_v; ++i) */ /* Have landed on every vertex of current polygon once. There may be one final new vertex */ if (prev_vertex_is_neg) { /* Edge ending at first positive vertex goes from negative side to positive side, so intersection with plane is final new vertex of next polygon */; vi_prev = (vi_first_pos + num_v - 1) % num_v; displ_neg = displacement_from_plane[vi_prev]; displ_pos = displacement_from_plane[vi_first_pos]; dist_perp = displ_pos - displ_neg; if (0.0001/*PGL_EPSILON_LENGTH_1*/ < dist_perp) { displ_pos /= dist_perp; displ_neg /= dist_perp; } else { /* Use vi_first_pos */ displ_pos = 0.0; displ_neg = -1.0; } construct_new_vertex (oa_data_mask, displ_neg, displ_pos, num_v_bld, vi_first_pos, vi_prev);#if 0/* TODO - Temporarily removed and replaced by call to construct_new_vertex ()to reduce size of code to try to make it compile */ mod_v_str_array[num_v_bld].position = displ_pos*v_str_array[vi_prev].position - displ_neg*v_str_array[vi_first_pos].position;/* Can continue to use oa_data_mask, but only one tex is sent to VS, soconvention is used that it is tracked by OAMB_VERTEX_UV_FRONT bit */#if 0 if (oa_data_mask & OAMB_VERTEX_UV_FRONT) { mod_v_str_array[num_v_bld].tex = displ_pos*v_str_array[vi_prev].tex - displ_neg*v_str_array[vi_first_pos].tex; }#endif if (oa_data_mask & OAMB_VERTEX_ECOLOR) { mod_v_str_array[num_v_bld].rgba_front = displ_pos*v_str_array[vi_prev].rgba_front - displ_neg*v_str_array[vi_first_pos].rgba_front; } if (oa_data_mask & OAMB_VERTEX_ECOLOR_BACK) { mod_v_str_array[num_v_bld].rgba_back = displ_pos*v_str_array[vi_prev].rgba_back - displ_neg*v_str_array[vi_first_pos].rgba_back; }#if 0 if (oa_data_mask & OAMB_VERTEX_AND_NORMAL) { normal = mod_v_str_array[num_v_bld].normal =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -