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.

246 lines
6.8 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. int _y;
  21. public:
  22. Span(int xStart,int xEnd,int y,Rgba colorStart,Rgba colorEnd)
  23. {
  24. if (xStart < xEnd)
  25. {
  26. _xStart = xStart;
  27. _xEnd = xEnd;
  28. _colorStart = colorStart;
  29. _colorEnd = colorEnd;
  30. _y = y;
  31. }
  32. else
  33. {
  34. _xStart = _xEnd;
  35. _xEnd = _xStart;
  36. _colorStart = colorEnd;
  37. _colorEnd = colorStart;
  38. _y = y;
  39. }
  40. }
  41. };
  42. class Ege
  43. {
  44. public:
  45. int _x1;
  46. int _y1;
  47. Rgba _color1;
  48. int _x2;
  49. int _y2;
  50. Rgba _color2;
  51. Ege(int x1,int y1,Rgba color1,int x2,int y2,Rgba color2)
  52. {
  53. if (y1 < y2)
  54. {
  55. _x1 = x1;
  56. _y1 = y1;
  57. _color1 = color1;
  58. _x2 = x2;
  59. _y2 = y2;
  60. _color2 = color2;
  61. }
  62. else
  63. {
  64. _x1 = x2;
  65. _y1 = y2;
  66. _color1 = color2;
  67. _x2 = x1;
  68. _y2 = y1;
  69. _color2 = color1;
  70. }
  71. }
  72. };
  73. class Raster
  74. {
  75. public:
  76. uint* _buffer;
  77. int _width;
  78. int _height;
  79. Rgba _color;
  80. public:
  81. Raster(int w,int h,void* buffer);
  82. ~Raster(void);
  83. void clear();
  84. void drawPoint(int x,int y, Rgba color,int ptSize);
  85. void drawArrays(DRAWMODE mode,const float2* points,int count);
  86. void drawFilleRect(int startX,int startY,int w,int h);
  87. void drawRect(const int2* points,const Rgba* colors);
  88. void drawImage(int startX,int startY,const Image* image);
  89. void drawImageWidthColorKey(int startX,int startY,const Image* image,Rgba key);
  90. void drawImageAlphaTest(int startX,int startY,const Image* image,byte alpha);
  91. void drawImageAlphaBlend(int startX,int startY,const Image* image,float alpha);
  92. void drawImageAlpha( int startX,int startY,const Image* image,float alpha );
  93. void drawImage(int startX,int startY,const Image* image,int x1,int y1,int w,int h);
  94. void drawImageScale(int dstX,int dstY,int dstW,int dstH,const Image* image)
  95. {
  96. float xScale = (float)image->width()/(float)dstW;
  97. float yScale = (float)image->height()/(float)dstH;
  98. for (int x = dstX ;x <dstX + dstW ; ++ x )
  99. {
  100. for (int y = dstY ;y <dstY + dstH ; ++ y )
  101. {
  102. float xx = (x - dstX) * xScale;
  103. float yy = (y - dstY) * yScale;
  104. Rgba srcColor = image->pixelAt(xx,yy);
  105. setPixelEx(x,y,srcColor);
  106. }
  107. }
  108. }
  109. public:
  110. void drawTriangle(int2 p0,int2 p1,int2 p2,Rgba c0,Rgba c1,Rgba c2)
  111. {
  112. Ege eges[3] =
  113. {
  114. Ege(p0.x,p0.y,c0, p1.x,p1.y,c1),
  115. Ege(p1.x,p1.y,c1, p2.x,p2.y,c2),
  116. Ege(p2.x,p2.y,c2, p0.x,p0.y,c0),
  117. };
  118. int iMax = 0;
  119. int length = eges[0]._y2 - eges[0]._y1;
  120. for (int i = 1 ;i < 3 ; ++ i)
  121. {
  122. int len = eges[i]._y2 - eges[i]._y1;
  123. if (len > length)
  124. {
  125. length = i;
  126. }
  127. }
  128. int iShort1 = (iMax + 1)%3;
  129. int iShort2 = (iMax + 2)%3;
  130. drawEge(eges[iMax],eges[iShort1]);
  131. drawEge(eges[iMax],eges[iShort2]);
  132. }
  133. void drawEge(const Ege& e1,const Ege& e2)
  134. {
  135. float yOffset1 = e1._y2 - e1._y1;
  136. if (yOffset1 == 0)
  137. {
  138. return;
  139. }
  140. float yOffset = e2._y2 - e2._y1;
  141. if (yOffset == 0)
  142. {
  143. return;
  144. }
  145. float xOffset = e2._x2 - e2._x1;
  146. float scale = 0;
  147. float step = 1.0f/yOffset;
  148. float xOffset1 = e1._x2 - e1._x1;
  149. float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
  150. float step1 = 1.0f/yOffset1;
  151. for (int y = e2._y1 ; y < e2._y2 ; ++ y)
  152. {
  153. int x1 = e1._x1 + (int)(scale1 * xOffset1);
  154. int x2 = e2._x1 + (int)(scale * xOffset);
  155. Rgba color2 = colorLerp(e2._color1,e2._color2,scale);
  156. Rgba color1 = colorLerp(e1._color1,e1._color2,scale1);
  157. Span span(x1,x2,y,color1,color2);
  158. drawSpan(span);
  159. scale += step;
  160. scale1 += step1;
  161. }
  162. }
  163. void drawSpan(const Span& span)
  164. {
  165. float length = span._xEnd - span._xStart;
  166. float scale = 0;
  167. float step = 1.0f/length;
  168. for (int x = span._xStart ; x < span._xEnd; ++ x)
  169. {
  170. Rgba color = colorLerp(
  171. span._colorStart
  172. ,span._colorEnd
  173. ,scale
  174. );
  175. scale += step;
  176. setPixel(x,span._y,color);
  177. }
  178. }
  179. void drawLine(float2 pt1,float2 pt2,Rgba color1,Rgba color2);
  180. void drawPoints(float2 pt1,Rgba4Byte color)
  181. {
  182. }
  183. inline void setPixelEx(unsigned x,unsigned y,Rgba color)
  184. {
  185. _buffer[y * _width + x] = color._color;
  186. }
  187. inline Rgba getPixel(unsigned x,unsigned y)
  188. {
  189. return Rgba(_buffer[y * _width + x]);
  190. }
  191. inline void setPixel(unsigned x,unsigned y,Rgba color)
  192. {
  193. if (x >= _width || y >= _height)
  194. {
  195. return;
  196. }
  197. _buffer[y * _width + x] = color._color;
  198. }
  199. };
  200. }