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.

260 lines
7.2 KiB

5 years ago
  1. #pragma once
  2. #include "CELLMath.hpp"
  3. #include "Image.hpp"
  4. namespace CELL
  5. {
  6. enum DRAWMODE
  7. {
  8. DM_POINTS = 0,
  9. DM_LINES = 1,
  10. DM_LINE_LOOP = 2,
  11. DM_LINE_STRIP = 3,
  12. };
  13. class Span
  14. {
  15. public:
  16. int _xStart;
  17. int _xEnd;
  18. Rgba _colorStart;
  19. Rgba _colorEnd;
  20. float2 _uvStart;
  21. float2 _uvEnd;
  22. int _y;
  23. public:
  24. Span(int xStart,int xEnd,int y,Rgba colorStart,Rgba colorEnd,float2 uvStart,float2 uvEnd)
  25. {
  26. if (xStart < xEnd)
  27. {
  28. _xStart = xStart;
  29. _xEnd = xEnd;
  30. _colorStart = colorStart;
  31. _colorEnd = colorEnd;
  32. _uvStart = uvStart;
  33. _uvEnd = uvEnd;
  34. _y = y;
  35. }
  36. else
  37. {
  38. _xStart = xEnd;
  39. _xEnd = xStart;
  40. _colorStart = colorEnd;
  41. _colorEnd = colorStart;
  42. _uvStart = uvEnd;
  43. _uvEnd = uvStart;
  44. _y = y;
  45. }
  46. }
  47. };
  48. class Ege
  49. {
  50. public:
  51. int _x1;
  52. int _y1;
  53. float2 _uv1;
  54. Rgba _color1;
  55. int _x2;
  56. int _y2;
  57. float2 _uv2;
  58. Rgba _color2;
  59. Ege(int x1,int y1,Rgba color1,float2 uv1,int x2,int y2,Rgba color2,float2 uv2)
  60. {
  61. if (y1 < y2)
  62. {
  63. _x1 = x1;
  64. _y1 = y1;
  65. _uv1 = uv1;
  66. _color1 = color1;
  67. _x2 = x2;
  68. _y2 = y2;
  69. _uv2 = uv2;
  70. _color2 = color2;
  71. }
  72. else
  73. {
  74. _x1 = x2;
  75. _y1 = y2;
  76. _uv1 = uv2;
  77. _color1 = color2;
  78. _x2 = x1;
  79. _y2 = y1;
  80. _uv2 = uv1;
  81. _color2 = color1;
  82. }
  83. }
  84. };
  85. class Raster
  86. {
  87. public:
  88. uint* _buffer;
  89. int _width;
  90. int _height;
  91. Rgba _color;
  92. public:
  93. Raster(int w,int h,void* buffer);
  94. ~Raster(void);
  95. void clear();
  96. struct Vertex
  97. {
  98. int2 p0;
  99. float2 uv0;
  100. Rgba c0;
  101. int2 p1;
  102. float2 uv1;
  103. Rgba c1;
  104. int2 p2;
  105. float2 uv2;
  106. Rgba c2;
  107. };
  108. void drawImage(int startX,int startY,const Image* image)
  109. {
  110. int left = tmax<int>(startX,0);
  111. int top = tmax<int>(startY,0);
  112. int right = tmin<int>(startX + image->width(),_width);
  113. int bottom = tmin<int>(startY + image->height(),_height);
  114. for (int x = left ; x < right ; ++ x)
  115. {
  116. for (int y = top ; y < bottom ; ++ y)
  117. {
  118. Rgba color = image->pixelAt(x - left,y - top);
  119. setPixelEx(x,y,color);
  120. }
  121. }
  122. }
  123. public:
  124. void drawTriangle(const Vertex& vertex,Image* image)
  125. {
  126. Ege eges[3] =
  127. {
  128. Ege(vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0, vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1),
  129. Ege(vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1, vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2),
  130. Ege(vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2, vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0),
  131. };
  132. int iMax = 0;
  133. int length = eges[0]._y2 - eges[0]._y1;
  134. for (int i = 1 ;i < 3 ; ++ i)
  135. {
  136. int len = eges[i]._y2 - eges[i]._y1;
  137. if (len > length)
  138. {
  139. length = len;
  140. iMax = i;
  141. }
  142. }
  143. int iShort1 = (iMax + 1)%3;
  144. int iShort2 = (iMax + 2)%3;
  145. drawEge(eges[iMax],eges[iShort1],image);
  146. drawEge(eges[iMax],eges[iShort2],image);
  147. }
  148. void drawEge(const Ege& e1,const Ege& e2,Image* image)
  149. {
  150. float yOffset1 = e1._y2 - e1._y1;
  151. if (yOffset1 == 0)
  152. {
  153. return;
  154. }
  155. float yOffset = e2._y2 - e2._y1;
  156. if (yOffset == 0)
  157. {
  158. return;
  159. }
  160. float xOffset = e2._x2 - e2._x1;
  161. float scale = 0;
  162. float step = 1.0f/yOffset;
  163. float xOffset1 = e1._x2 - e1._x1;
  164. float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
  165. float step1 = 1.0f/yOffset1;
  166. for (int y = e2._y1 ; y < e2._y2 ; ++ y)
  167. {
  168. int x1 = e1._x1 + (int)(scale1 * xOffset1);
  169. int x2 = e2._x1 + (int)(scale * xOffset);
  170. Rgba color2 = colorLerp(e2._color1,e2._color2,scale);
  171. Rgba color1 = colorLerp(e1._color1,e1._color2,scale1);
  172. float2 uvStart = uvLerp(e1._uv1,e1._uv2,scale1);
  173. float2 uvEnd = uvLerp(e2._uv1,e2._uv2,scale);
  174. Span span(x1,x2,y,color1,color2,uvStart,uvEnd);
  175. drawSpan(span,image);
  176. scale += step;
  177. scale1 += step1;
  178. }
  179. }
  180. void drawSpan(const Span& span,Image* image)
  181. {
  182. float length = span._xEnd - span._xStart;
  183. float scale = 0;
  184. float step = 1.0f/length;
  185. for (int x = span._xStart ; x < span._xEnd; ++ x)
  186. {
  187. Rgba color = colorLerp(span._colorStart,span._colorEnd,scale);
  188. float2 uv = uvLerp(span._uvStart,span._uvEnd,scale);
  189. Rgba pixel = image->pixelUV(uv.x,uv.y);
  190. Rgba dst = color + pixel;
  191. scale += step;
  192. setPixel(x,span._y,dst);
  193. }
  194. }
  195. void drawLine(float2 pt1,float2 pt2,Rgba color1,Rgba color2);
  196. void drawPoints(float2 pt1,Rgba4Byte color)
  197. {
  198. }
  199. inline void setPixelEx(unsigned x,unsigned y,Rgba color)
  200. {
  201. _buffer[y * _width + x] = color._color;
  202. }
  203. inline Rgba getPixel(unsigned x,unsigned y)
  204. {
  205. return Rgba(_buffer[y * _width + x]);
  206. }
  207. inline void setPixel(unsigned x,unsigned y,Rgba color)
  208. {
  209. if (x >= _width || y >= _height)
  210. {
  211. return;
  212. }
  213. _buffer[y * _width + x] = color._color;
  214. }
  215. };
  216. }