Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.0 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: clip.h
  6. * Content: Template for functions to clip by a frustum side
  7. *
  8. * The following symbol should be defined before included this file:
  9. * __CLIP_NAME - name for a function to clip triangles
  10. * __CLIP_LINE_NAME - name for a function to clip lines
  11. * __CLIP_W - if this functions are for Coord <= W. Otherwise they
  12. * are for 0 < Coord
  13. * __CLIP_COORD - should be hx, hy or hz
  14. * __CLIP_FLAG - clipping flag to set
  15. * __CLIP_GUARDBAND - defined when clipping by guardband window
  16. * __CLIP_SIGN - "-" if clipping by left or bottom sides of guard band
  17. * window
  18. * __CLIP_GBCOEF - coefficient to multiply W when clipping by guard band
  19. * window
  20. *
  21. * All these symbols are undefined at the end of this file
  22. ***************************************************************************/
  23. //
  24. // Clipping for triangle
  25. //
  26. // Returns number of vertices in the clipped triangle
  27. //
  28. int
  29. __CLIP_NAME(D3DFE_PROCESSVERTICES *pv,
  30. ClipVertex **inv,
  31. ClipVertex **outv,
  32. int count,
  33. int interpolate)
  34. {
  35. int i;
  36. int out_count = 0;
  37. ClipVertex *curr, *prev;
  38. D3DVALUE curr_inside;
  39. D3DVALUE prev_inside;
  40. prev = inv[count-1];
  41. curr = *inv++;
  42. #ifdef __CLIP_GUARDBAND
  43. prev_inside = __CLIP_SIGN(prev->hw * pv->vcache.__CLIP_GBCOEF -
  44. prev->__CLIP_COORD);
  45. #else
  46. #ifdef __CLIP_W
  47. prev_inside = prev->hw - prev->__CLIP_COORD;
  48. #else
  49. prev_inside = prev->__CLIP_COORD;
  50. #endif
  51. #endif
  52. for (i = count; i; i--)
  53. {
  54. #ifdef __CLIP_GUARDBAND
  55. curr_inside = __CLIP_SIGN(curr->hw * pv->vcache.__CLIP_GBCOEF -
  56. curr->__CLIP_COORD);
  57. #else
  58. #ifdef __CLIP_W
  59. curr_inside = curr->hw - curr->__CLIP_COORD;
  60. #else
  61. curr_inside = curr->__CLIP_COORD;
  62. #endif
  63. #endif
  64. // We interpolate always from the inside vertex to the outside vertex
  65. // to reduce precision problems
  66. if (FLOAT_LTZ(prev_inside))
  67. { // first point is outside
  68. if (FLOAT_GEZ(curr_inside))
  69. { // second point is inside
  70. // Find intersection and insert in into the output buffer
  71. outv[out_count] = GET_NEW_CLIP_VERTEX;
  72. Interpolate(pv,
  73. outv[out_count],
  74. curr, prev,
  75. (prev->clip & CLIPPED_ENABLE) | __CLIP_FLAG,
  76. interpolate,
  77. curr_inside, curr_inside - prev_inside);
  78. out_count++;
  79. }
  80. } else
  81. { // first point is inside - put it to the output buffer first
  82. outv[out_count++] = prev;
  83. if (FLOAT_LTZ(curr_inside))
  84. { // second point is outside
  85. // Find intersection and put it to the output buffer
  86. outv[out_count] = GET_NEW_CLIP_VERTEX;
  87. Interpolate(pv,
  88. outv[out_count],
  89. prev, curr,
  90. __CLIP_FLAG,
  91. interpolate,
  92. prev_inside, prev_inside - curr_inside);
  93. out_count++;
  94. }
  95. }
  96. prev = curr;
  97. curr = *inv++;
  98. prev_inside = curr_inside;
  99. }
  100. return out_count;
  101. }
  102. //-------------------------------------------------------------------------
  103. // Clipping for lines
  104. //
  105. // Returns 1 if the line is outside the frustum, 0 otherwise
  106. //
  107. int __CLIP_LINE_NAME(D3DFE_PROCESSVERTICES *pv, ClipTriangle *line,
  108. int interpolate)
  109. {
  110. D3DVALUE in1, in2;
  111. ClipVertex outv;
  112. #ifdef __CLIP_GUARDBAND
  113. in1 = __CLIP_SIGN(line->v[0]->hw * pv->vcache.__CLIP_GBCOEF -
  114. line->v[0]->__CLIP_COORD);
  115. in2 = __CLIP_SIGN(line->v[1]->hw * pv->vcache.__CLIP_GBCOEF -
  116. line->v[1]->__CLIP_COORD);
  117. #else
  118. #ifdef __CLIP_W
  119. in1 = line->v[0]->hw - line->v[0]->__CLIP_COORD;
  120. in2 = line->v[1]->hw - line->v[1]->__CLIP_COORD;
  121. #else
  122. in1 = line->v[0]->__CLIP_COORD;
  123. in2 = line->v[1]->__CLIP_COORD;
  124. #endif
  125. #endif
  126. if (in1 < 0)
  127. {
  128. if (in2 < 0)
  129. return 1;
  130. Interpolate(pv, &outv, line->v[0], line->v[1],
  131. __CLIP_FLAG, interpolate, in1, in1 - in2);
  132. *line->v[0] = outv;
  133. }
  134. else
  135. {
  136. if (in2 < 0)
  137. {
  138. Interpolate(pv, &outv, line->v[0], line->v[1],
  139. __CLIP_FLAG, interpolate, in1, in1 - in2);
  140. *line->v[1] = outv;
  141. }
  142. }
  143. return 0;
  144. }
  145. #undef __CLIP_FLAG
  146. #undef __CLIP_COORD
  147. #undef __CLIP_NAME
  148. #undef __CLIP_LINE_NAME
  149. #undef __CLIP_W
  150. #undef __CLIP_SIGN
  151. #undef __CLIP_GBCOEF