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.

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