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.

441 lines
13 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. DM_TRIANGES = 4,
  13. };
  14. enum DATETYPE
  15. {
  16. DT_BYTE,
  17. DT_FLOAT,
  18. DT_DOUBLE,
  19. };
  20. struct DateElementDes
  21. {
  22. int _size;
  23. DATETYPE _type;
  24. int _stride;
  25. const void* _data;
  26. };
  27. class Span
  28. {
  29. public:
  30. int _xStart;
  31. int _xEnd;
  32. Rgba _colorStart;
  33. Rgba _colorEnd;
  34. float2 _uvStart;
  35. float2 _uvEnd;
  36. int _y;
  37. public:
  38. Span(int xStart,int xEnd,int y,Rgba colorStart,Rgba colorEnd,float2 uvStart,float2 uvEnd)
  39. {
  40. if (xStart < xEnd)
  41. {
  42. _xStart = xStart;
  43. _xEnd = xEnd;
  44. _colorStart = colorStart;
  45. _colorEnd = colorEnd;
  46. _uvStart = uvStart;
  47. _uvEnd = uvEnd;
  48. _y = y;
  49. }
  50. else
  51. {
  52. _xStart = xEnd;
  53. _xEnd = xStart;
  54. _colorStart = colorEnd;
  55. _colorEnd = colorStart;
  56. _uvStart = uvEnd;
  57. _uvEnd = uvStart;
  58. _y = y;
  59. }
  60. }
  61. };
  62. class Ege
  63. {
  64. public:
  65. int _x1;
  66. int _y1;
  67. float2 _uv1;
  68. Rgba _color1;
  69. int _x2;
  70. int _y2;
  71. float2 _uv2;
  72. Rgba _color2;
  73. Ege(int x1,int y1,Rgba color1,float2 uv1,int x2,int y2,Rgba color2,float2 uv2)
  74. {
  75. if (y1 < y2)
  76. {
  77. _x1 = x1;
  78. _y1 = y1;
  79. _uv1 = uv1;
  80. _color1 = color1;
  81. _x2 = x2;
  82. _y2 = y2;
  83. _uv2 = uv2;
  84. _color2 = color2;
  85. }
  86. else
  87. {
  88. _x1 = x2;
  89. _y1 = y2;
  90. _uv1 = uv2;
  91. _color1 = color2;
  92. _x2 = x1;
  93. _y2 = y1;
  94. _uv2 = uv1;
  95. _color2 = color1;
  96. }
  97. }
  98. };
  99. class Raster
  100. {
  101. public:
  102. uint* _buffer;
  103. int _width;
  104. int _height;
  105. Rgba _color;
  106. Image* _texture;
  107. matrix4 _matModel;
  108. DateElementDes _poitionPointer;
  109. DateElementDes _colorPointer;
  110. DateElementDes _uvPointer;
  111. DateElementDes _defaultColorPointer;
  112. DateElementDes _defaultUVPointer;
  113. Rgba _defaultColorArray[3];
  114. float2 _detaultUVArray[3];
  115. public:
  116. Raster(int w,int h,void* buffer);
  117. ~Raster(void);
  118. void clear();
  119. struct Vertex
  120. {
  121. int2 p0;
  122. float2 uv0;
  123. Rgba c0;
  124. int2 p1;
  125. float2 uv1;
  126. Rgba c1;
  127. int2 p2;
  128. float2 uv2;
  129. Rgba c2;
  130. };
  131. void drawImage(int startX,int startY,const Image* image)
  132. {
  133. int left = tmax<int>(startX,0);
  134. int top = tmax<int>(startY,0);
  135. int right = tmin<int>(startX + image->width(),_width);
  136. int bottom = tmin<int>(startY + image->height(),_height);
  137. for (int x = left ; x < right ; ++ x)
  138. {
  139. for (int y = top ; y < bottom ; ++ y)
  140. {
  141. Rgba color = image->pixelAt(x - left,y - top);
  142. setPixelEx(x,y,color);
  143. }
  144. }
  145. }
  146. public:
  147. /**
  148. *
  149. */
  150. void loadMatrix(const CELL::matrix4& mat)
  151. {
  152. _matModel = mat;
  153. }
  154. void loadIdentity()
  155. {
  156. _matModel = CELL::matrix4(1);
  157. }
  158. void vertexPointer(int size,DATETYPE type,int stride,const void* data)
  159. {
  160. _poitionPointer._size = size;
  161. _poitionPointer._type = type;
  162. _poitionPointer._stride = stride;
  163. _poitionPointer._data = data;
  164. }
  165. void colorPointer(int size,DATETYPE type,int stride,const void* data)
  166. {
  167. _colorPointer._size = size;
  168. _colorPointer._type = type;
  169. _colorPointer._stride = stride;
  170. _colorPointer._data = data;
  171. }
  172. void textureCoordPointer(int size,DATETYPE type,int stride,const void* data)
  173. {
  174. _uvPointer._size = size;
  175. _uvPointer._type = type;
  176. _uvPointer._stride = stride;
  177. _uvPointer._data = data;
  178. }
  179. void bindTexture(Image* image)
  180. {
  181. _texture = image;
  182. }
  183. void drawArrays(DRAWMODE pri,int start,int count)
  184. {
  185. if (_poitionPointer._data == 0)
  186. {
  187. return;
  188. }
  189. DateElementDes colorPointerdesc = _colorPointer;
  190. DateElementDes uvPointerdesc = _uvPointer;
  191. if (colorPointerdesc._data == 0)
  192. {
  193. colorPointerdesc = _defaultColorPointer;
  194. }
  195. if (uvPointerdesc._data == 0)
  196. {
  197. uvPointerdesc = _defaultUVPointer;
  198. }
  199. char* posData = (char*)_poitionPointer._data;
  200. char* cData = (char*)colorPointerdesc._data;
  201. char* uvData = (char*)uvPointerdesc._data;
  202. for(int i = start ;i < start + count; i += 3)
  203. {
  204. float* fData = (float*)posData;
  205. float4 p01 (fData[0],fData[1],fData[2],1);
  206. posData += _poitionPointer._stride;
  207. fData = (float*)(posData);
  208. p01 = _matModel * p01;
  209. float4 p11 (fData[0],fData[1],fData[2],1);
  210. posData += _poitionPointer._stride;
  211. fData = (float*)(posData);
  212. p11 = _matModel * p11;
  213. float4 p21 (fData[0],fData[1],fData[2],1);
  214. posData += _poitionPointer._stride;
  215. p21 = _matModel * p21;
  216. //! ת��Ϊ��Ļ����
  217. int2 p0(p01.x,p01.y);
  218. int2 p1(p11.x,p11.y);
  219. int2 p2(p21.x,p21.y);
  220. Rgba* pColor = (Rgba*)cData;
  221. Rgba c0 (*pColor);
  222. cData += _colorPointer._stride;
  223. Rgba c1 (*pColor);
  224. cData += _colorPointer._stride;
  225. Rgba c2 (*pColor);
  226. cData += _colorPointer._stride;
  227. float* pUV = (float*)uvData;
  228. float2 uv0 (pUV[0],pUV[1]);
  229. uvData += _uvPointer._stride;
  230. pUV = (float*)uvData;
  231. float2 uv1(pUV[0],pUV[1]);
  232. uvData += _uvPointer._stride;
  233. pUV = (float*)uvData;
  234. float2 uv2(pUV[0],pUV[1]);
  235. uvData += _uvPointer._stride;
  236. Ege eges[3] =
  237. {
  238. Ege(p0.x,p0.y,c0, uv0, p1.x,p1.y,c1, uv1),
  239. Ege(p1.x,p1.y,c1, uv1, p2.x,p2.y,c2, uv2),
  240. Ege(p2.x,p2.y,c2, uv2, p0.x,p0.y,c0, uv0),
  241. };
  242. drawTrianle(eges);
  243. if (_colorPointer._data == 0)
  244. {
  245. cData = (char*)colorPointerdesc._data;
  246. }
  247. if (_uvPointer._data == 0 )
  248. {
  249. uvData = (char*)uvPointerdesc._data;
  250. }
  251. }
  252. }
  253. void drawTrianle(Ege eges[3])
  254. {
  255. int iMax = 0;
  256. int length = eges[0]._y2 - eges[0]._y1;
  257. for (int i = 1 ;i < 3 ; ++ i)
  258. {
  259. int len = eges[i]._y2 - eges[i]._y1;
  260. if (len > length)
  261. {
  262. length = len;
  263. iMax = i;
  264. }
  265. }
  266. int iShort1 = (iMax + 1)%3;
  267. int iShort2 = (iMax + 2)%3;
  268. drawEge(eges[iMax],eges[iShort1],_texture);
  269. drawEge(eges[iMax],eges[iShort2],_texture);
  270. }
  271. void drawTriangle(const Vertex& vertex,Image* image)
  272. {
  273. Ege eges[3] =
  274. {
  275. Ege(vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0, vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1),
  276. Ege(vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1, vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2),
  277. Ege(vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2, vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0),
  278. };
  279. int iMax = 0;
  280. int length = eges[0]._y2 - eges[0]._y1;
  281. for (int i = 1 ;i < 3 ; ++ i)
  282. {
  283. int len = eges[i]._y2 - eges[i]._y1;
  284. if (len > length)
  285. {
  286. length = len;
  287. iMax = i;
  288. }
  289. }
  290. int iShort1 = (iMax + 1)%3;
  291. int iShort2 = (iMax + 2)%3;
  292. drawEge(eges[iMax],eges[iShort1],image);
  293. drawEge(eges[iMax],eges[iShort2],image);
  294. }
  295. void drawEge(const Ege& e1,const Ege& e2,Image* image)
  296. {
  297. float yOffset1 = e1._y2 - e1._y1;
  298. if (yOffset1 == 0)
  299. {
  300. return;
  301. }
  302. float yOffset = e2._y2 - e2._y1;
  303. if (yOffset == 0)
  304. {
  305. return;
  306. }
  307. float xOffset = e2._x2 - e2._x1;
  308. float scale = 0;
  309. float step = 1.0f/yOffset;
  310. float xOffset1 = e1._x2 - e1._x1;
  311. float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
  312. float step1 = 1.0f/yOffset1;
  313. for (int y = e2._y1 ; y < e2._y2 ; ++ y)
  314. {
  315. int x1 = e1._x1 + (int)(scale1 * xOffset1);
  316. int x2 = e2._x1 + (int)(scale * xOffset);
  317. Rgba color2 = colorLerp(e2._color1,e2._color2,scale);
  318. Rgba color1 = colorLerp(e1._color1,e1._color2,scale1);
  319. float2 uvStart = uvLerp(e1._uv1,e1._uv2,scale1);
  320. float2 uvEnd = uvLerp(e2._uv1,e2._uv2,scale);
  321. Span span(x1,x2,y,color1,color2,uvStart,uvEnd);
  322. drawSpan(span,image);
  323. scale += step;
  324. scale1 += step1;
  325. }
  326. }
  327. void drawSpan(const Span& span,Image* image)
  328. {
  329. float length = span._xEnd - span._xStart;
  330. float scale = 0;
  331. float step = 1.0f/length;
  332. for (int x = span._xStart ; x < span._xEnd; ++ x)
  333. {
  334. //Rgba color = colorLerp(span._colorStart,span._colorEnd,scale);
  335. float2 uv = uvLerp(span._uvStart,span._uvEnd,scale);
  336. Rgba pixel = image->pixelUV(uv.x,uv.y);
  337. //Rgba dst = color + pixel;
  338. scale += step;
  339. setPixel(x,span._y,pixel);
  340. }
  341. }
  342. void drawLine(float2 pt1,float2 pt2,Rgba color1,Rgba color2);
  343. void drawPoints(float2 pt1,Rgba4Byte color)
  344. {
  345. }
  346. inline void setPixelEx(unsigned x,unsigned y,Rgba color)
  347. {
  348. _buffer[y * _width + x] = color._color;
  349. }
  350. inline Rgba getPixel(unsigned x,unsigned y)
  351. {
  352. return Rgba(_buffer[y * _width + x]);
  353. }
  354. inline void setPixel(unsigned x,unsigned y,Rgba color)
  355. {
  356. if (x >= _width || y >= _height)
  357. {
  358. return;
  359. }
  360. _buffer[y * _width + x] = color._color;
  361. }
  362. };
  363. }