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.

373 lines
10 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. matrix4 _matView;
  109. matrix4 _matProj;
  110. matrix4 _mvp;
  111. float2 _viewPort;
  112. Frustum _frust;
  113. DateElementDes _poitionPointer;
  114. DateElementDes _colorPointer;
  115. DateElementDes _uvPointer;
  116. DateElementDes _defaultColorPointer;
  117. DateElementDes _defaultUVPointer;
  118. Rgba _defaultColorArray[3];
  119. float2 _detaultUVArray[3];
  120. public:
  121. Raster(int w,int h,void* buffer);
  122. ~Raster(void);
  123. void clear();
  124. struct Vertex
  125. {
  126. int2 p0;
  127. float2 uv0;
  128. Rgba c0;
  129. int2 p1;
  130. float2 uv1;
  131. Rgba c1;
  132. int2 p2;
  133. float2 uv2;
  134. Rgba c2;
  135. };
  136. void drawImage(int startX,int startY,const Image* image);
  137. public:
  138. void loadViewMatrix(const CELL::matrix4& mat);
  139. void loadViewIdentity(const CELL::matrix4& mat);
  140. void loadProjMatrix(const CELL::matrix4& mat);
  141. void loadProjIdentity(const CELL::matrix4& mat);
  142. /**
  143. * ͶӰ
  144. */
  145. void setPerspective(float fovy, float aspect, float zNear, float zFar);
  146. /**
  147. * ɹ۲
  148. */
  149. void lookat(float3 const & eye,float3 const & center,float3 const & up);
  150. void setViewPort(int x,int y,int w,int h);
  151. /**
  152. * ģ;
  153. */
  154. void loadMatrix(const CELL::matrix4& mat);
  155. void loadIdentity();
  156. void vertexPointer(int size,DATETYPE type,int stride,const void* data);
  157. void colorPointer(int size,DATETYPE type,int stride,const void* data);
  158. void textureCoordPointer(int size,DATETYPE type,int stride,const void* data);
  159. void bindTexture(Image* image);
  160. void drawArrays(DRAWMODE pri,int start,int count);
  161. protected:
  162. float3 piplineTransform(float3 pos)
  163. {
  164. float4 world(pos.x,pos.y,pos.z,0);
  165. float4 screen = (_mvp) * world;
  166. if (screen.w == 0.0f)
  167. {
  168. return float3(0,0,0);
  169. }
  170. screen.x /= screen.w;
  171. screen.y /= screen.w;
  172. screen.z /= screen.w;
  173. // map to range 0 - 1
  174. screen.x = screen.x * 0.5f + 0.5f;
  175. screen.y = screen.y * 0.5f + 0.5f;
  176. screen.z = screen.z * 0.5f + 0.5f;
  177. // map to viewport
  178. screen.x = screen.x * _viewPort.x;
  179. //screen.y = screen.y * _viewPort.y;
  180. screen.y = _viewPort.y - (screen.y * _viewPort.y);
  181. return float3(screen.x,screen.y,screen.z);
  182. }
  183. void drawTrianle(Ege eges[3])
  184. {
  185. int iMax = 0;
  186. int length = eges[0]._y2 - eges[0]._y1;
  187. for (int i = 1 ;i < 3 ; ++ i)
  188. {
  189. int len = eges[i]._y2 - eges[i]._y1;
  190. if (len > length)
  191. {
  192. length = len;
  193. iMax = i;
  194. }
  195. }
  196. int iShort1 = (iMax + 1)%3;
  197. int iShort2 = (iMax + 2)%3;
  198. drawEge(eges[iMax],eges[iShort1],_texture);
  199. drawEge(eges[iMax],eges[iShort2],_texture);
  200. }
  201. void drawTriangle(const Vertex& vertex,Image* image)
  202. {
  203. Ege eges[3] =
  204. {
  205. Ege(vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0, vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1),
  206. Ege(vertex.p1.x,vertex.p1.y,vertex.c1, vertex.uv1, vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2),
  207. Ege(vertex.p2.x,vertex.p2.y,vertex.c2, vertex.uv2, vertex.p0.x,vertex.p0.y,vertex.c0, vertex.uv0),
  208. };
  209. int iMax = 0;
  210. int length = eges[0]._y2 - eges[0]._y1;
  211. for (int i = 1 ;i < 3 ; ++ i)
  212. {
  213. int len = eges[i]._y2 - eges[i]._y1;
  214. if (len > length)
  215. {
  216. length = len;
  217. iMax = i;
  218. }
  219. }
  220. int iShort1 = (iMax + 1)%3;
  221. int iShort2 = (iMax + 2)%3;
  222. drawEge(eges[iMax],eges[iShort1],image);
  223. drawEge(eges[iMax],eges[iShort2],image);
  224. }
  225. void drawEge(const Ege& e1,const Ege& e2,Image* image)
  226. {
  227. float yOffset1 = e1._y2 - e1._y1;
  228. if (yOffset1 == 0)
  229. {
  230. return;
  231. }
  232. float yOffset = e2._y2 - e2._y1;
  233. if (yOffset == 0)
  234. {
  235. return;
  236. }
  237. float xOffset = e2._x2 - e2._x1;
  238. float scale = 0;
  239. float step = 1.0f/yOffset;
  240. int startY = tmax<int>(0,e2._y1);
  241. int endY = tmin<int>(_height,e2._y2);
  242. float pp = (startY -e2._y1)/yOffset;
  243. scale += pp;
  244. float xOffset1 = e1._x2 - e1._x1;
  245. float scale1 = (float)(e2._y1 - e1._y1)/yOffset1;
  246. float step1 = 1.0f/yOffset1;
  247. int startY1 = tmax<int>(0,e1._y1);
  248. int endY1 = tmin<int>(_height,e1._y2);
  249. float pp1 = (startY1 - e1._y1)/yOffset1;
  250. scale1 += pp1;
  251. for (int y = startY ; y < endY ; ++ y)
  252. {
  253. int x1 = e1._x1 + (int)(scale1 * xOffset1);
  254. int x2 = e2._x1 + (int)(scale * xOffset);
  255. Rgba color2 = colorLerp(e2._color1,e2._color2,scale);
  256. Rgba color1 = colorLerp(e1._color1,e1._color2,scale1);
  257. float2 uvStart = uvLerp(e1._uv1,e1._uv2,scale1);
  258. float2 uvEnd = uvLerp(e2._uv1,e2._uv2,scale);
  259. Span span(x1,x2,y,color1,color2,uvStart,uvEnd);
  260. drawSpan(span,image);
  261. scale += step;
  262. scale1 += step1;
  263. }
  264. }
  265. void drawSpan(const Span& span,Image* image)
  266. {
  267. float length = span._xEnd - span._xStart;
  268. float scale = 0;
  269. float step = 1.0f/length;
  270. for (int x = span._xStart ; x < span._xEnd; ++ x)
  271. {
  272. Rgba color = colorLerp(span._colorStart,span._colorEnd,scale);
  273. float2 uv = uvLerp(span._uvStart,span._uvEnd,scale);
  274. Rgba pixel = image->pixelUV(uv.x,uv.y);
  275. //Rgba dst = color + pixel;
  276. scale += step;
  277. setPixel(x,span._y,color);
  278. }
  279. }
  280. void drawLine(float2 pt1,float2 pt2,Rgba color1,Rgba color2);
  281. void drawPoints(float2 pt1,Rgba4Byte color)
  282. {
  283. }
  284. inline void setPixelEx(unsigned x,unsigned y,Rgba color)
  285. {
  286. _buffer[y * _width + x] = color._color;
  287. }
  288. inline Rgba getPixel(unsigned x,unsigned y)
  289. {
  290. return Rgba(_buffer[y * _width + x]);
  291. }
  292. inline void setPixel(unsigned x,unsigned y,Rgba color)
  293. {
  294. if (x >= _width || y >= _height)
  295. {
  296. return;
  297. }
  298. _buffer[y * _width + x] = color._color;
  299. }
  300. };
  301. }