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. RefClipper::__CLIP_NAME(RDClipVertex **inv, RDClipVertex **outv, int count)
  30. {
  31. int i;
  32. int out_count = 0;
  33. RDClipVertex *curr, *prev;
  34. D3DVALUE curr_inside;
  35. D3DVALUE prev_inside;
  36. prev = inv[count-1];
  37. curr = *inv++;
  38. #ifdef __CLIP_GUARDBAND
  39. prev_inside = __CLIP_SIGN(prev->m_clip_w * __CLIP_GBCOEF -
  40. prev->__CLIP_COORD);
  41. #else
  42. #ifdef __CLIP_W
  43. prev_inside = prev->m_clip_w - prev->__CLIP_COORD;
  44. #else
  45. prev_inside = prev->__CLIP_COORD;
  46. #endif
  47. #endif
  48. for (i = count; i; i--)
  49. {
  50. #ifdef __CLIP_GUARDBAND
  51. curr_inside = __CLIP_SIGN(curr->m_clip_w * __CLIP_GBCOEF -
  52. curr->__CLIP_COORD);
  53. #else
  54. #ifdef __CLIP_W
  55. curr_inside = curr->m_clip_w - curr->__CLIP_COORD;
  56. #else
  57. curr_inside = curr->__CLIP_COORD;
  58. #endif
  59. #endif
  60. // We interpolate always from the inside vertex to the outside vertex
  61. // to reduce precision problems
  62. if (FLOAT_LTZ(prev_inside))
  63. { // first point is outside
  64. if (FLOAT_GEZ(curr_inside))
  65. { // second point is inside
  66. // Find intersection and insert in into the output buffer
  67. outv[out_count] = GET_NEW_CLIP_VERTEX;
  68. outv[out_count]->m_qwFVF = prev->m_qwFVF;
  69. Interpolate(outv[out_count],
  70. curr, prev,
  71. (prev->m_clip & CLIPPED_ENABLE) | __CLIP_FLAG,
  72. curr_inside, curr_inside - prev_inside);
  73. out_count++;
  74. }
  75. }
  76. else
  77. { // first point is inside - put it to the output buffer first
  78. outv[out_count++] = prev;
  79. if (FLOAT_LTZ(curr_inside))
  80. { // second point is outside
  81. // Find intersection and put it to the output buffer
  82. outv[out_count] = GET_NEW_CLIP_VERTEX;
  83. outv[out_count]->m_qwFVF = prev->m_qwFVF;
  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. RefClipper::__CLIP_LINE_NAME(RDCLIPTRIANGLE *line)
  104. {
  105. D3DVALUE in1, in2;
  106. RDClipVertex outv;
  107. #ifdef __CLIP_GUARDBAND
  108. in1 = __CLIP_SIGN(line->v[0]->m_clip_w * __CLIP_GBCOEF -
  109. line->v[0]->__CLIP_COORD);
  110. in2 = __CLIP_SIGN(line->v[1]->m_clip_w * __CLIP_GBCOEF -
  111. line->v[1]->__CLIP_COORD);
  112. #else
  113. #ifdef __CLIP_W
  114. in1 = line->v[0]->m_clip_w - line->v[0]->__CLIP_COORD;
  115. in2 = line->v[1]->m_clip_w - 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