agg_span_gouraud.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //----------------------------------------------------------------------------
  2. // Anti-Grain Geometry - Version 2.4
  3. // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
  4. //
  5. // Permission to copy, use, modify, sell and distribute this software
  6. // is granted provided this copyright notice appears in all copies.
  7. // This software is provided "as is" without express or implied
  8. // warranty, and with no claim as to its suitability for any purpose.
  9. //
  10. //----------------------------------------------------------------------------
  11. // Contact: mcseem@antigrain.com
  12. // mcseemagg@yahoo.com
  13. // http://www.antigrain.com
  14. //----------------------------------------------------------------------------
  15. #ifndef AGG_SPAN_GOURAUD_INCLUDED
  16. #define AGG_SPAN_GOURAUD_INCLUDED
  17. #include "agg_basics.h"
  18. #include "agg_math.h"
  19. namespace agg
  20. {
  21. //============================================================span_gouraud
  22. template<class ColorT> class span_gouraud
  23. {
  24. public:
  25. typedef ColorT color_type;
  26. struct coord_type
  27. {
  28. double x;
  29. double y;
  30. color_type color;
  31. };
  32. //--------------------------------------------------------------------
  33. span_gouraud() :
  34. m_vertex(0)
  35. {
  36. m_cmd[0] = path_cmd_stop;
  37. }
  38. //--------------------------------------------------------------------
  39. span_gouraud(const color_type& c1,
  40. const color_type& c2,
  41. const color_type& c3,
  42. double x1, double y1,
  43. double x2, double y2,
  44. double x3, double y3,
  45. double d) :
  46. m_vertex(0)
  47. {
  48. colors(c1, c2, c3);
  49. triangle(x1, y1, x2, y2, x3, y3, d);
  50. }
  51. //--------------------------------------------------------------------
  52. void colors(ColorT c1, ColorT c2, ColorT c3)
  53. {
  54. m_coord[0].color = c1;
  55. m_coord[1].color = c2;
  56. m_coord[2].color = c3;
  57. }
  58. //--------------------------------------------------------------------
  59. // Sets the triangle and dilates it if needed.
  60. // The trick here is to calculate beveled joins in the vertices of the
  61. // triangle and render it as a 6-vertex polygon.
  62. // It's necessary to achieve numerical stability.
  63. // However, the coordinates to interpolate colors are calculated
  64. // as miter joins (calc_intersection).
  65. void triangle(double x1, double y1,
  66. double x2, double y2,
  67. double x3, double y3,
  68. double d)
  69. {
  70. m_coord[0].x = m_x[0] = x1;
  71. m_coord[0].y = m_y[0] = y1;
  72. m_coord[1].x = m_x[1] = x2;
  73. m_coord[1].y = m_y[1] = y2;
  74. m_coord[2].x = m_x[2] = x3;
  75. m_coord[2].y = m_y[2] = y3;
  76. m_cmd[0] = path_cmd_move_to;
  77. m_cmd[1] = path_cmd_line_to;
  78. m_cmd[2] = path_cmd_line_to;
  79. m_cmd[3] = path_cmd_stop;
  80. if(d != 0.0)
  81. {
  82. dilate_triangle(m_coord[0].x, m_coord[0].y,
  83. m_coord[1].x, m_coord[1].y,
  84. m_coord[2].x, m_coord[2].y,
  85. m_x, m_y, d);
  86. calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5],
  87. m_x[0], m_y[0], m_x[1], m_y[1],
  88. &m_coord[0].x, &m_coord[0].y);
  89. calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1],
  90. m_x[2], m_y[2], m_x[3], m_y[3],
  91. &m_coord[1].x, &m_coord[1].y);
  92. calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3],
  93. m_x[4], m_y[4], m_x[5], m_y[5],
  94. &m_coord[2].x, &m_coord[2].y);
  95. m_cmd[3] = path_cmd_line_to;
  96. m_cmd[4] = path_cmd_line_to;
  97. m_cmd[5] = path_cmd_line_to;
  98. m_cmd[6] = path_cmd_stop;
  99. }
  100. }
  101. //--------------------------------------------------------------------
  102. // Vertex Source Interface to feed the coordinates to the rasterizer
  103. void rewind(unsigned)
  104. {
  105. m_vertex = 0;
  106. }
  107. //--------------------------------------------------------------------
  108. unsigned vertex(double* x, double* y)
  109. {
  110. *x = m_x[m_vertex];
  111. *y = m_y[m_vertex];
  112. return m_cmd[m_vertex++];
  113. }
  114. protected:
  115. //--------------------------------------------------------------------
  116. void arrange_vertices(coord_type* coord) const
  117. {
  118. coord[0] = m_coord[0];
  119. coord[1] = m_coord[1];
  120. coord[2] = m_coord[2];
  121. if(m_coord[0].y > m_coord[2].y)
  122. {
  123. coord[0] = m_coord[2];
  124. coord[2] = m_coord[0];
  125. }
  126. coord_type tmp;
  127. if(coord[0].y > coord[1].y)
  128. {
  129. tmp = coord[1];
  130. coord[1] = coord[0];
  131. coord[0] = tmp;
  132. }
  133. if(coord[1].y > coord[2].y)
  134. {
  135. tmp = coord[2];
  136. coord[2] = coord[1];
  137. coord[1] = tmp;
  138. }
  139. }
  140. private:
  141. //--------------------------------------------------------------------
  142. coord_type m_coord[3];
  143. double m_x[8];
  144. double m_y[8];
  145. unsigned m_cmd[8];
  146. unsigned m_vertex;
  147. };
  148. }
  149. #endif