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.

149 lines
4.8 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. {
  34. int i;
  35. int out_count = 0;
  36. ClipVertex *curr, *prev;
  37. D3DVALUE curr_inside;
  38. D3DVALUE prev_inside;
  39. prev = inv[count-1];
  40. curr = *inv++;
  41. #ifdef __CLIP_GUARDBAND
  42. prev_inside = __CLIP_SIGN(prev->hw * pv->vcache.__CLIP_GBCOEF -
  43. prev->__CLIP_COORD);
  44. #else
  45. #ifdef __CLIP_W
  46. prev_inside = prev->hw - prev->__CLIP_COORD;
  47. #else
  48. prev_inside = prev->__CLIP_COORD;
  49. #endif
  50. #endif
  51. for (i = count; i; i--)
  52. {
  53. #ifdef __CLIP_GUARDBAND
  54. curr_inside = __CLIP_SIGN(curr->hw * pv->vcache.__CLIP_GBCOEF -
  55. curr->__CLIP_COORD);
  56. #else
  57. #ifdef __CLIP_W
  58. curr_inside = curr->hw - curr->__CLIP_COORD;
  59. #else
  60. curr_inside = curr->__CLIP_COORD;
  61. #endif
  62. #endif
  63. // We interpolate always from the inside vertex to the outside vertex
  64. // to reduce precision problems
  65. if (FLOAT_LTZ(prev_inside))
  66. { // first point is outside
  67. if (FLOAT_GEZ(curr_inside))
  68. { // second point is inside
  69. // Find intersection and insert in into the output buffer
  70. outv[out_count] = GET_NEW_CLIP_VERTEX;
  71. Interpolate(pv,
  72. outv[out_count],
  73. curr, prev,
  74. (prev->clip & CLIPPED_ENABLE) | __CLIP_FLAG,
  75. curr_inside, curr_inside - prev_inside);
  76. out_count++;
  77. }
  78. } else
  79. { // first point is inside - put it to the output buffer first
  80. outv[out_count++] = prev;
  81. if (FLOAT_LTZ(curr_inside))
  82. { // second point is outside
  83. // Find intersection and put it to the output buffer
  84. outv[out_count] = GET_NEW_CLIP_VERTEX;
  85. Interpolate(pv,
  86. outv[out_count],
  87. prev, curr,
  88. __CLIP_FLAG,
  89. prev_inside, prev_inside - curr_inside);
  90. out_count++;
  91. }
  92. }
  93. prev = curr;
  94. curr = *inv++;
  95. prev_inside = curr_inside;
  96. }
  97. return out_count;
  98. }
  99. //-------------------------------------------------------------------------
  100. // Clipping for lines
  101. //
  102. // Returns 1 if the line is outside the frustum, 0 otherwise
  103. //
  104. int __CLIP_LINE_NAME(D3DFE_PROCESSVERTICES *pv, ClipTriangle *line)
  105. {
  106. D3DVALUE in1, in2;
  107. ClipVertex outv;
  108. #ifdef __CLIP_GUARDBAND
  109. in1 = __CLIP_SIGN(line->v[0]->hw * pv->vcache.__CLIP_GBCOEF -
  110. line->v[0]->__CLIP_COORD);
  111. in2 = __CLIP_SIGN(line->v[1]->hw * pv->vcache.__CLIP_GBCOEF -
  112. line->v[1]->__CLIP_COORD);
  113. #else
  114. #ifdef __CLIP_W
  115. in1 = line->v[0]->hw - line->v[0]->__CLIP_COORD;
  116. in2 = line->v[1]->hw - line->v[1]->__CLIP_COORD;
  117. #else
  118. in1 = line->v[0]->__CLIP_COORD;
  119. in2 = line->v[1]->__CLIP_COORD;
  120. #endif
  121. #endif
  122. if (in1 < 0)
  123. {
  124. if (in2 < 0)
  125. return 1;
  126. Interpolate(pv, &outv, line->v[0], line->v[1],
  127. __CLIP_FLAG, in1, in1 - in2);
  128. *line->v[0] = outv;
  129. }
  130. else
  131. {
  132. if (in2 < 0)
  133. {
  134. Interpolate(pv, &outv, line->v[0], line->v[1],
  135. __CLIP_FLAG, in1, in1 - in2);
  136. *line->v[1] = outv;
  137. }
  138. }
  139. return 0;
  140. }
  141. #undef __CLIP_FLAG
  142. #undef __CLIP_COORD
  143. #undef __CLIP_NAME
  144. #undef __CLIP_LINE_NAME
  145. #undef __CLIP_W
  146. #undef __CLIP_SIGN
  147. #undef __CLIP_GBCOEF