CCDrawingPrimitives.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  1. /****************************************************************************
  2. Copyright (c) 2010-2012 cocos2d-x.org
  3. Copyright (c) 2008-2010 Ricardo Quesada
  4. Copyright (c) 2011 Zynga Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. /**
  23. * <p>
  24. * Drawing primitives Utility Class. this class is base class, it contain some render type version: Canvas, WebGL, DOM.<br/>
  25. * this class contain some primitive Drawing Method: <br/>
  26. * - drawPoint<br/>
  27. * - drawLine<br/>
  28. * - drawPoly<br/>
  29. * - drawCircle<br/>
  30. * - drawQuadBezier<br/>
  31. * - drawCubicBezier<br/>
  32. * You can change the color, width and other property by calling these WebGL API:<br/>
  33. * glColor4ub(), glLineWidth(), glPointSize().<br/>
  34. * </p>
  35. * @class
  36. * @extends cc.Class
  37. * @warning These functions draws the Line, Point, Polygon, immediately. They aren't batched. <br/>
  38. * If you are going to make a game that depends on these primitives, I suggest creating a batch.
  39. */
  40. cc.DrawingPrimitive = cc.Class.extend(/** @lends cc.DrawingPrimitive# */{
  41. _renderContext:null,
  42. /**
  43. * set render context of drawing primitive
  44. * @param context
  45. */
  46. setRenderContext:function (context) {
  47. this._renderContext = context;
  48. },
  49. /**
  50. * returns render context of drawing primitive
  51. * @return {CanvasRenderingContext2D}
  52. */
  53. getRenderContext:function () {
  54. return this._renderContext;
  55. },
  56. /**
  57. * Constructor
  58. * @param {CanvasRenderingContext2D} renderContext
  59. */
  60. ctor:function (renderContext) {
  61. this._renderContext = renderContext;
  62. },
  63. /**
  64. * draws a point given x and y coordinate measured in points
  65. * @param {cc.Point} point
  66. */
  67. drawPoint:function (point) {
  68. cc.log("DrawingPrimitive.drawPoint() not implement!");
  69. },
  70. /**
  71. * draws an array of points.
  72. * @param {Array} points point of array
  73. * @param {Number} numberOfPoints
  74. */
  75. drawPoints:function (points, numberOfPoints) {
  76. cc.log("DrawingPrimitive.drawPoints() not implement!");
  77. },
  78. /**
  79. * draws a line given the origin and destination point measured in points
  80. * @param {cc.Point} origin
  81. * @param {cc.Point} destination
  82. */
  83. drawLine:function (origin, destination) {
  84. cc.log("DrawingPrimitive.drawLine() not implement!");
  85. },
  86. /**
  87. * draws a rectangle given the origin and destination point measured in points.
  88. * @param {cc.Point} origin
  89. * @param {cc.Point} destination
  90. */
  91. drawRect:function (origin, destination) {
  92. cc.log("DrawingPrimitive.drawRect() not implement!");
  93. },
  94. /**
  95. * draws a solid rectangle given the origin and destination point measured in points.
  96. * @param {cc.Point} origin
  97. * @param {cc.Point} destination
  98. * @param {cc.Color4F} color
  99. */
  100. drawSolidRect:function (origin, destination, color) {
  101. cc.log("DrawingPrimitive.drawSolidRect() not implement!");
  102. },
  103. /**
  104. * draws a poligon given a pointer to cc.Point coordiantes and the number of vertices measured in points.
  105. * @param {Array} vertices a pointer to cc.Point coordiantes
  106. * @param {Number} numOfVertices the number of vertices measured in points
  107. * @param {Boolean} closePolygon The polygon can be closed or open
  108. * @param {Boolean} fill The polygon can be closed or open and optionally filled with current color
  109. */
  110. drawPoly:function (vertices, numOfVertices, closePolygon, fill) {
  111. cc.log("DrawingPrimitive.drawPoly() not implement!");
  112. },
  113. /**
  114. * draws a solid polygon given a pointer to CGPoint coordiantes, the number of vertices measured in points, and a color.
  115. * @param {Array} poli
  116. * @param {Number} numberOfPoints
  117. * @param {cc.Color4F} color
  118. */
  119. drawSolidPoly:function (poli, numberOfPoints, color) {
  120. cc.log("DrawingPrimitive.drawSolidPoly() not implement!");
  121. },
  122. /**
  123. * draws a circle given the center, radius and number of segments.
  124. * @param {cc.Point} center center of circle
  125. * @param {Number} radius
  126. * @param {Number} angle angle in radians
  127. * @param {Number} segments
  128. * @param {Boolean} drawLineToCenter
  129. */
  130. drawCircle:function (center, radius, angle, segments, drawLineToCenter) {
  131. cc.log("DrawingPrimitive.drawCircle() not implement!");
  132. },
  133. /**
  134. * draws a quad bezier path
  135. * @param {cc.Point} origin
  136. * @param {cc.Point} control
  137. * @param {cc.Point} destination
  138. * @param {Number} segments
  139. */
  140. drawQuadBezier:function (origin, control, destination, segments) {
  141. cc.log("DrawingPrimitive.drawQuadBezier() not implement!");
  142. },
  143. /**
  144. * draws a cubic bezier path
  145. * @param {cc.Point} origin
  146. * @param {cc.Point} control1
  147. * @param {cc.Point} control2
  148. * @param {cc.Point} destination
  149. * @param {Number} segments
  150. */
  151. drawCubicBezier:function (origin, control1, control2, destination, segments) {
  152. cc.log("DrawingPrimitive.drawCubicBezier() not implement!");
  153. },
  154. /**
  155. * draw a catmull rom line
  156. * @param {Array} points
  157. * @param {Number} segments
  158. */
  159. drawCatmullRom:function (points, segments) {
  160. cc.log("DrawingPrimitive.drawCardinalSpline() not implement!");
  161. },
  162. /**
  163. * draw a cardinal spline path
  164. * @param {Array} config
  165. * @param {Number} tension
  166. * @param {Number} segments
  167. */
  168. drawCardinalSpline:function (config, tension, segments) {
  169. cc.log("DrawingPrimitive.drawCardinalSpline() not implement!");
  170. }
  171. });
  172. /**
  173. * Canvas of DrawingPrimitive implement version
  174. * @class
  175. * @extends cc.DrawingPrimitive
  176. */
  177. cc.DrawingPrimitiveCanvas = cc.DrawingPrimitive.extend(/** @lends cc.DrawingPrimitiveCanvas# */{
  178. _cacheArray:[],
  179. /**
  180. * draws a point given x and y coordinate measured in points
  181. * @override
  182. * @param {cc.Point} point
  183. * @param {Number} size
  184. */
  185. drawPoint:function (point, size) {
  186. if (!size) {
  187. size = 1;
  188. }
  189. var locScaleX = cc.EGLView.getInstance().getScaleX(), locScaleY = cc.EGLView.getInstance().getScaleY();
  190. var newPoint = cc.p(point.x * locScaleX, point.y * locScaleY);
  191. this._renderContext.beginPath();
  192. this._renderContext.arc(newPoint.x, -newPoint.y, size * locScaleX, 0, Math.PI * 2, false);
  193. this._renderContext.closePath();
  194. this._renderContext.fill();
  195. },
  196. /**
  197. * draws an array of points.
  198. * @override
  199. * @param {Array} points point of array
  200. * @param {Number} numberOfPoints
  201. * @param {Number} size
  202. */
  203. drawPoints:function (points, numberOfPoints, size) {
  204. if (points == null) {
  205. return;
  206. }
  207. if (!size) {
  208. size = 1;
  209. }
  210. var locContext = this._renderContext,locScaleX = cc.EGLView.getInstance().getScaleX(), locScaleY = cc.EGLView.getInstance().getScaleY();
  211. locContext.beginPath();
  212. for (var i = 0, len = points.length; i < len; i++)
  213. locContext.arc(points[i].x * locScaleX, -points[i].y * locScaleY, size * locScaleX, 0, Math.PI * 2, false);
  214. locContext.closePath();
  215. locContext.fill();
  216. },
  217. /**
  218. * draws a line given the origin and destination point measured in points
  219. * @override
  220. * @param {cc.Point} origin
  221. * @param {cc.Point} destination
  222. */
  223. drawLine:function (origin, destination) {
  224. var locContext = this._renderContext, locScaleX = cc.EGLView.getInstance().getScaleX(), locScaleY = cc.EGLView.getInstance().getScaleY();
  225. locContext.beginPath();
  226. locContext.moveTo(origin.x * locScaleX, -origin.y * locScaleY);
  227. locContext.lineTo(destination.x * locScaleX, -destination.y * locScaleY);
  228. locContext.closePath();
  229. locContext.stroke();
  230. },
  231. /**
  232. * draws a rectangle given the origin and destination point measured in points.
  233. * @param {cc.Point} origin
  234. * @param {cc.Point} destination
  235. */
  236. drawRect:function (origin, destination) {
  237. this.drawLine(cc.p(origin.x, origin.y), cc.p(destination.x, origin.y));
  238. this.drawLine(cc.p(destination.x, origin.y), cc.p(destination.x, destination.y));
  239. this.drawLine(cc.p(destination.x, destination.y), cc.p(origin.x, destination.y));
  240. this.drawLine(cc.p(origin.x, destination.y), cc.p(origin.x, origin.y));
  241. },
  242. /**
  243. * draws a solid rectangle given the origin and destination point measured in points.
  244. * @param {cc.Point} origin
  245. * @param {cc.Point} destination
  246. * @param {cc.Color4F} color
  247. */
  248. drawSolidRect:function (origin, destination, color) {
  249. var vertices = [
  250. origin,
  251. cc.p(destination.x, origin.y),
  252. destination,
  253. cc.p(origin.x, destination.y)
  254. ];
  255. this.drawSolidPoly(vertices, 4, color);
  256. },
  257. /**
  258. * draws a polygon given a pointer to cc.Point coordinates and the number of vertices measured in points.
  259. * @override
  260. * @param {Array} vertices a pointer to cc.Point coordinates
  261. * @param {Number} numOfVertices the number of vertices measured in points
  262. * @param {Boolean} closePolygon The polygon can be closed or open
  263. * @param {Boolean} [fill=] The polygon can be closed or open and optionally filled with current color
  264. */
  265. drawPoly:function (vertices, numOfVertices, closePolygon, fill) {
  266. fill = fill || false;
  267. if (vertices == null)
  268. return;
  269. if (vertices.length < 3)
  270. throw new Error("Polygon's point must greater than 2");
  271. var firstPoint = vertices[0], locContext = this._renderContext;
  272. var locScaleX = cc.EGLView.getInstance().getScaleX(), locScaleY = cc.EGLView.getInstance().getScaleY();
  273. locContext.beginPath();
  274. locContext.moveTo(firstPoint.x * locScaleX, -firstPoint.y * locScaleY);
  275. for (var i = 1, len = vertices.length; i < len; i++)
  276. locContext.lineTo(vertices[i].x * locScaleX, -vertices[i].y * locScaleY);
  277. if (closePolygon)
  278. locContext.closePath();
  279. if (fill)
  280. locContext.fill();
  281. else
  282. locContext.stroke();
  283. },
  284. /**
  285. * draws a solid polygon given a pointer to CGPoint coordinates, the number of vertices measured in points, and a color.
  286. * @param {Array} polygons
  287. * @param {Number} numberOfPoints
  288. * @param {cc.Color4F} color
  289. */
  290. drawSolidPoly:function (polygons, numberOfPoints, color) {
  291. this.setDrawColor4F(color.r, color.g, color.b, color.a);
  292. this.drawPoly(polygons, numberOfPoints, true, true);
  293. },
  294. /**
  295. * draws a circle given the center, radius and number of segments.
  296. * @override
  297. * @param {cc.Point} center center of circle
  298. * @param {Number} radius
  299. * @param {Number} angle angle in radians
  300. * @param {Number} segments
  301. * @param {Boolean} [drawLineToCenter=]
  302. */
  303. drawCircle: function (center, radius, angle, segments, drawLineToCenter) {
  304. drawLineToCenter = drawLineToCenter || false;
  305. var locContext = this._renderContext;
  306. var locScaleX = cc.EGLView.getInstance().getScaleX(), locScaleY = cc.EGLView.getInstance().getScaleY();
  307. locContext.beginPath();
  308. var endAngle = angle - Math.PI * 2;
  309. locContext.arc(0 | (center.x * locScaleX), 0 | -(center.y * locScaleY), radius * locScaleX, -angle, -endAngle, false);
  310. if (drawLineToCenter) {
  311. locContext.lineTo(0 | (center.x * locScaleX), 0 | -(center.y * locScaleY));
  312. }
  313. locContext.stroke();
  314. },
  315. /**
  316. * draws a quad bezier path
  317. * @override
  318. * @param {cc.Point} origin
  319. * @param {cc.Point} control
  320. * @param {cc.Point} destination
  321. * @param {Number} segments
  322. */
  323. drawQuadBezier:function (origin, control, destination, segments) {
  324. //this is OpenGL Algorithm
  325. var vertices = this._cacheArray;
  326. vertices.length =0;
  327. var t = 0.0;
  328. for (var i = 0; i < segments; i++) {
  329. var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
  330. var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
  331. vertices.push(cc.p(x, y));
  332. t += 1.0 / segments;
  333. }
  334. vertices.push(cc.p(destination.x, destination.y));
  335. this.drawPoly(vertices, segments + 1, false, false);
  336. },
  337. /**
  338. * draws a cubic bezier path
  339. * @override
  340. * @param {cc.Point} origin
  341. * @param {cc.Point} control1
  342. * @param {cc.Point} control2
  343. * @param {cc.Point} destination
  344. * @param {Number} segments
  345. */
  346. drawCubicBezier:function (origin, control1, control2, destination, segments) {
  347. //this is OpenGL Algorithm
  348. var vertices = this._cacheArray;
  349. vertices.length =0;
  350. var t = 0;
  351. for (var i = 0; i < segments; i++) {
  352. var x = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x;
  353. var y = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y;
  354. vertices.push(cc.p(x , y ));
  355. t += 1.0 / segments;
  356. }
  357. vertices.push(cc.p(destination.x , destination.y));
  358. this.drawPoly(vertices, segments + 1, false, false);
  359. },
  360. /**
  361. * draw a CatmullRom curve
  362. * @override
  363. * @param {Array} points
  364. * @param {Number} segments
  365. */
  366. drawCatmullRom:function (points, segments) {
  367. this.drawCardinalSpline(points, 0.5, segments);
  368. },
  369. /**
  370. * draw a cardinal spline path
  371. * @override
  372. * @param {Array} config
  373. * @param {Number} tension
  374. * @param {Number} segments
  375. */
  376. drawCardinalSpline:function (config, tension, segments) {
  377. //lazy_init();
  378. cc.renderContext.strokeStyle = "rgba(255,255,255,1)";
  379. var points = this._cacheArray;
  380. points.length = 0;
  381. var p, lt;
  382. var deltaT = 1.0 / config.length;
  383. for (var i = 0; i < segments + 1; i++) {
  384. var dt = i / segments;
  385. // border
  386. if (dt == 1) {
  387. p = config.length - 1;
  388. lt = 1;
  389. } else {
  390. p = 0 | (dt / deltaT);
  391. lt = (dt - deltaT * p) / deltaT;
  392. }
  393. // Interpolate
  394. var newPos = cc.CardinalSplineAt(
  395. cc.getControlPointAt(config, p - 1),
  396. cc.getControlPointAt(config, p - 0),
  397. cc.getControlPointAt(config, p + 1),
  398. cc.getControlPointAt(config, p + 2),
  399. tension, lt);
  400. points.push(newPos);
  401. }
  402. this.drawPoly(points, segments + 1, false, false);
  403. },
  404. /**
  405. * draw an image
  406. * @override
  407. * @param {HTMLImageElement|HTMLCanvasElement} image
  408. * @param {cc.Point} sourcePoint
  409. * @param {cc.Size} sourceSize
  410. * @param {cc.Point} destPoint
  411. * @param {cc.Size} destSize
  412. */
  413. drawImage:function (image, sourcePoint, sourceSize, destPoint, destSize) {
  414. var len = arguments.length;
  415. switch (len) {
  416. case 2:
  417. var height = image.height;
  418. this._renderContext.drawImage(image, sourcePoint.x, -(sourcePoint.y + height));
  419. break;
  420. case 3:
  421. this._renderContext.drawImage(image, sourcePoint.x, -(sourcePoint.y + sourceSize.height), sourceSize.width, sourceSize.height);
  422. break;
  423. case 5:
  424. this._renderContext.drawImage(image, sourcePoint.x, sourcePoint.y, sourceSize.width, sourceSize.height, destPoint.x, -(destPoint.y + destSize.height),
  425. destSize.width, destSize.height);
  426. break;
  427. default:
  428. throw new Error("Argument must be non-nil");
  429. break;
  430. }
  431. },
  432. /**
  433. * draw a star
  434. * @param {CanvasRenderingContext2D} ctx canvas context
  435. * @param {Number} radius
  436. * @param {cc.Color3B|cc.Color4B|cc.Color4F} color
  437. */
  438. drawStar:function (ctx, radius, color) {
  439. var context = ctx || this._renderContext;
  440. radius *= cc.EGLView.getInstance().getScaleX();
  441. if (color instanceof cc.Color4F)
  442. color = new cc.Color3B(0 | (color.r * 255), 0 | (color.g * 255), 0 | (color.b * 255));
  443. var colorStr = "rgba(" + color.r + "," + color.g + "," + color.b;
  444. context.fillStyle = colorStr + ",1)";
  445. var subRadius = radius / 10;
  446. context.beginPath();
  447. context.moveTo(-radius, radius);
  448. context.lineTo(0, subRadius);
  449. context.lineTo(radius, radius);
  450. context.lineTo(subRadius, 0);
  451. context.lineTo(radius, -radius);
  452. context.lineTo(0, -subRadius);
  453. context.lineTo(-radius, -radius);
  454. context.lineTo(-subRadius, 0);
  455. context.lineTo(-radius, radius);
  456. context.closePath();
  457. context.fill();
  458. var g1 = context.createRadialGradient(0, 0, subRadius, 0, 0, radius);
  459. g1.addColorStop(0, colorStr + ", 1)");
  460. g1.addColorStop(0.3, colorStr + ", 0.8)");
  461. g1.addColorStop(1.0, colorStr + ", 0.0)");
  462. context.fillStyle = g1;
  463. context.beginPath();
  464. var startAngle_1 = 0;
  465. var endAngle_1 = cc.PI2;
  466. context.arc(0, 0, radius - subRadius, startAngle_1, endAngle_1, false);
  467. context.closePath();
  468. context.fill();
  469. },
  470. /**
  471. * draw a color ball
  472. * @param {CanvasRenderingContext2D} ctx canvas context
  473. * @param {Number} radius
  474. * @param {cc.Color3B|cc.Color4B|cc.Color4F} color
  475. */
  476. drawColorBall:function (ctx, radius, color) {
  477. var context = ctx || this._renderContext;
  478. radius *= cc.EGLView.getInstance().getScaleX();
  479. if (color instanceof cc.Color4F)
  480. color = new cc.Color3B(0 | (color.r * 255), 0 | (color.g * 255), 0 | (color.b * 255));
  481. var colorStr = "rgba(" + color.r + "," + color.g + "," + color.b;
  482. var subRadius = radius / 10;
  483. var g1 = context.createRadialGradient(0, 0, subRadius, 0, 0, radius);
  484. g1.addColorStop(0, colorStr + ", 1)");
  485. g1.addColorStop(0.3, colorStr + ", 0.8)");
  486. g1.addColorStop(0.6, colorStr + ", 0.4)");
  487. g1.addColorStop(1.0, colorStr + ", 0.0)");
  488. context.fillStyle = g1;
  489. context.beginPath();
  490. var startAngle_1 = 0;
  491. var endAngle_1 = cc.PI2;
  492. context.arc(0, 0, radius, startAngle_1, endAngle_1, false);
  493. context.closePath();
  494. context.fill();
  495. },
  496. /**
  497. * fill text
  498. * @param {String} strText
  499. * @param {Number} x
  500. * @param {Number} y
  501. */
  502. fillText:function (strText, x, y) {
  503. this._renderContext.fillText(strText, x, -y);
  504. },
  505. /**
  506. * set the drawing color with 4 unsigned bytes
  507. * @param {Number} r red value (0 to 255)
  508. * @param {Number} g green value (0 to 255)
  509. * @param {Number} b blue value (0 to 255)
  510. * @param {Number} a Alpha value (0 to 255)
  511. */
  512. setDrawColor4B:function (r, g, b, a) {
  513. this._renderContext.fillStyle = "rgba(" + r + "," + g + "," + b + "," + a / 255 + ")";
  514. this._renderContext.strokeStyle = "rgba(" + r + "," + g + "," + b + "," + a / 255 + ")";
  515. },
  516. /**
  517. * set the drawing color with 4 floats
  518. * @param {Number} r red value (0 to 1)
  519. * @param {Number} g green value (0 to 1)
  520. * @param {Number} b blue value (0 to 1)
  521. * @param {Number} a Alpha value (0 to 1)
  522. */
  523. setDrawColor4F:function (r, g, b, a) {
  524. this._renderContext.fillStyle = "rgba(" + (0 | (r * 255)) + "," + (0 | (g * 255)) + "," + (0 | (b * 255)) + "," + a + ")";
  525. this._renderContext.strokeStyle = "rgba(" + (0 | (r * 255)) + "," + (0 | (g * 255)) + "," + (0 | (b * 255)) + "," + a + ")";
  526. },
  527. /**
  528. * set the point size in points. Default 1.
  529. * @param {Number} pointSize
  530. */
  531. setPointSize:function (pointSize) {
  532. },
  533. /**
  534. * set the line width. Default 1.
  535. * @param {Number} width
  536. */
  537. setLineWidth:function (width) {
  538. this._renderContext.lineWidth = width * cc.EGLView.getInstance().getScaleX();
  539. }
  540. });
  541. /**
  542. * Canvas of DrawingPrimitive implement version
  543. * @class
  544. * @extends cc.DrawingPrimitive
  545. */
  546. cc.DrawingPrimitiveWebGL = cc.DrawingPrimitive.extend({
  547. _initialized:false,
  548. _shader: null,
  549. _colorLocation:-1,
  550. _color: null,
  551. _pointSizeLocation:-1,
  552. _pointSize:-1,
  553. ctor:function (ctx) {
  554. if (ctx == null)
  555. ctx = cc.renderContext;
  556. if (!ctx instanceof WebGLRenderingContext)
  557. throw "Can't initialise DrawingPrimitiveWebGL. context need is WebGLRenderingContext";
  558. cc.DrawingPrimitive.prototype.ctor.call(this, ctx);
  559. this._color = new cc.Color4F(1.0, 1.0, 1.0, 1.0);
  560. },
  561. lazy_init:function () {
  562. if (!this._initialized) {
  563. //
  564. // Position and 1 color passed as a uniform (to similate glColor4ub )
  565. //
  566. this._shader = cc.ShaderCache.getInstance().programForKey(cc.SHADER_POSITION_UCOLOR);
  567. this._colorLocation = this._renderContext.getUniformLocation(this._shader.getProgram(), "u_color");
  568. this._pointSizeLocation = this._renderContext.getUniformLocation(this._shader.getProgram(), "u_pointSize");
  569. //cc.CHECK_GL_ERROR_DEBUG();
  570. this._initialized = true;
  571. }
  572. },
  573. /**
  574. * initlialize context
  575. */
  576. drawInit:function () {
  577. this._initialized = false;
  578. },
  579. /**
  580. * draws a point given x and y coordinate measured in points
  581. * @param {cc.Point} point
  582. */
  583. drawPoint:function (point) {
  584. this.lazy_init();
  585. this._shader.use();
  586. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  587. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  588. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  589. this._shader.setUniformLocationWith1f(this._pointSizeLocation, this._pointSize);
  590. var glContext = this._renderContext;
  591. var pointBuffer = glContext.createBuffer();
  592. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  593. glContext.bufferData(glContext.ARRAY_BUFFER, new Float32Array([point.x, point.y]), glContext.STATIC_DRAW);
  594. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  595. glContext.drawArrays(glContext.POINTS, 0, 1);
  596. glContext.deleteBuffer(pointBuffer);
  597. cc.INCREMENT_GL_DRAWS(1);
  598. },
  599. /**
  600. * draws an array of points.
  601. * @param {Array} points point of array
  602. * @param {Number} numberOfPoints
  603. */
  604. drawPoints:function (points, numberOfPoints) {
  605. if (!points || points.length == 0)
  606. return;
  607. this.lazy_init();
  608. this._shader.use();
  609. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  610. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  611. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  612. this._shader.setUniformLocationWith1f(this._pointSizeLocation, this._pointSize);
  613. var glContext = this._renderContext;
  614. var pointBuffer = glContext.createBuffer();
  615. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  616. glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(points), glContext.STATIC_DRAW);
  617. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  618. glContext.drawArrays(glContext.POINTS, 0, points.length);
  619. glContext.deleteBuffer(pointBuffer);
  620. cc.INCREMENT_GL_DRAWS(1);
  621. },
  622. _pointsToTypeArray:function (points) {
  623. var typeArr = new Float32Array(points.length * 2);
  624. for (var i = 0; i < points.length; i++) {
  625. typeArr[i * 2] = points[i].x;
  626. typeArr[i * 2 + 1] = points[i].y;
  627. }
  628. return typeArr;
  629. },
  630. /**
  631. * draws a line given the origin and destination point measured in points
  632. * @param {cc.Point} origin
  633. * @param {cc.Point} destination
  634. */
  635. drawLine:function (origin, destination) {
  636. this.lazy_init();
  637. this._shader.use();
  638. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  639. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  640. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  641. var glContext = this._renderContext;
  642. var pointBuffer = glContext.createBuffer();
  643. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  644. glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray([origin, destination]), glContext.STATIC_DRAW);
  645. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  646. glContext.drawArrays(glContext.LINES, 0, 2);
  647. glContext.deleteBuffer(pointBuffer);
  648. cc.INCREMENT_GL_DRAWS(1);
  649. },
  650. /**
  651. * draws a rectangle given the origin and destination point measured in points.
  652. * @param {cc.Point} origin
  653. * @param {cc.Point} destination
  654. */
  655. drawRect:function (origin, destination) {
  656. this.drawLine(cc.p(origin.x, origin.y), cc.p(destination.x, origin.y));
  657. this.drawLine(cc.p(destination.x, origin.y), cc.p(destination.x, destination.y));
  658. this.drawLine(cc.p(destination.x, destination.y), cc.p(origin.x, destination.y));
  659. this.drawLine(cc.p(origin.x, destination.y), cc.p(origin.x, origin.y));
  660. },
  661. /**
  662. * draws a solid rectangle given the origin and destination point measured in points.
  663. * @param {cc.Point} origin
  664. * @param {cc.Point} destination
  665. * @param {cc.Color4F} color
  666. */
  667. drawSolidRect:function (origin, destination, color) {
  668. var vertices = [
  669. origin,
  670. cc.p(destination.x, origin.y),
  671. destination,
  672. cc.p(origin.x, destination.y)
  673. ];
  674. this.drawSolidPoly(vertices, 4, color);
  675. },
  676. /**
  677. * draws a polygon given a pointer to cc.Point coordiantes and the number of vertices measured in points.
  678. * @param {Array} vertices a pointer to cc.Point coordiantes
  679. * @param {Number} numOfVertices the number of vertices measured in points
  680. * @param {Boolean} closePolygon The polygon can be closed or open
  681. */
  682. drawPoly:function (vertices, numOfVertices, closePolygon) {
  683. this.lazy_init();
  684. this._shader.use();
  685. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  686. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  687. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  688. var glContext = this._renderContext;
  689. var pointBuffer = glContext.createBuffer();
  690. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  691. glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(vertices), glContext.STATIC_DRAW);
  692. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  693. if (closePolygon)
  694. glContext.drawArrays(glContext.LINE_LOOP, 0, vertices.length);
  695. else
  696. glContext.drawArrays(glContext.LINE_STRIP, 0, vertices.length);
  697. glContext.deleteBuffer(pointBuffer);
  698. cc.INCREMENT_GL_DRAWS(1);
  699. },
  700. /**
  701. * draws a solid polygon given a pointer to CGPoint coordiantes, the number of vertices measured in points, and a color.
  702. * @param {Array} poli
  703. * @param {Number} numberOfPoints
  704. * @param {cc.Color4F} color
  705. */
  706. drawSolidPoly:function (poli, numberOfPoints, color) {
  707. this.lazy_init();
  708. if (!color)
  709. color = this._color;
  710. this._shader.use();
  711. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  712. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  713. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(color._arrayBuffer,0,4), 1);
  714. var glContext = this._renderContext;
  715. var pointBuffer = glContext.createBuffer();
  716. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  717. glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(poli), glContext.STATIC_DRAW);
  718. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  719. glContext.drawArrays(glContext.TRIANGLE_FAN, 0, poli.length);
  720. glContext.deleteBuffer(pointBuffer);
  721. cc.INCREMENT_GL_DRAWS(1);
  722. },
  723. /**
  724. * draws a circle given the center, radius and number of segments.
  725. * @param {cc.Point} center center of circle
  726. * @param {Number} radius
  727. * @param {Number} angle angle in radians
  728. * @param {Number} segments
  729. * @param {Boolean} drawLineToCenter
  730. */
  731. drawCircle:function (center, radius, angle, segments, drawLineToCenter) {
  732. this.lazy_init();
  733. var additionalSegment = 1;
  734. if (drawLineToCenter)
  735. additionalSegment++;
  736. var coef = 2.0 * Math.PI / segments;
  737. var vertices = new Float32Array((segments + 2) * 2);
  738. if (!vertices)
  739. return;
  740. for (var i = 0; i <= segments; i++) {
  741. var rads = i * coef;
  742. var j = radius * Math.cos(rads + angle) + center.x;
  743. var k = radius * Math.sin(rads + angle) + center.y;
  744. vertices[i * 2] = j;
  745. vertices[i * 2 + 1] = k;
  746. }
  747. vertices[(segments + 1) * 2] = center.x;
  748. vertices[(segments + 1) * 2 + 1] = center.y;
  749. this._shader.use();
  750. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  751. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  752. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  753. var glContext = this._renderContext;
  754. var pointBuffer = glContext.createBuffer();
  755. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  756. glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
  757. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  758. glContext.drawArrays(glContext.LINE_STRIP, 0, segments + additionalSegment);
  759. glContext.deleteBuffer(pointBuffer);
  760. cc.INCREMENT_GL_DRAWS(1);
  761. },
  762. /**
  763. * draws a quad bezier path
  764. * @param {cc.Point} origin
  765. * @param {cc.Point} control
  766. * @param {cc.Point} destination
  767. * @param {Number} segments
  768. */
  769. drawQuadBezier:function (origin, control, destination, segments) {
  770. this.lazy_init();
  771. var vertices = new Float32Array((segments + 1) * 2);
  772. var t = 0.0;
  773. for (var i = 0; i < segments; i++) {
  774. vertices[i * 2] = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
  775. vertices[i * 2 + 1] = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
  776. t += 1.0 / segments;
  777. }
  778. vertices[segments * 2] = destination.x;
  779. vertices[segments * 2 + 1] = destination.y;
  780. this._shader.use();
  781. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  782. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  783. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  784. var glContext = this._renderContext;
  785. var pointBuffer = glContext.createBuffer();
  786. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  787. glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
  788. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  789. glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
  790. glContext.deleteBuffer(pointBuffer);
  791. cc.INCREMENT_GL_DRAWS(1);
  792. },
  793. /**
  794. * draws a cubic bezier path
  795. * @param {cc.Point} origin
  796. * @param {cc.Point} control1
  797. * @param {cc.Point} control2
  798. * @param {cc.Point} destination
  799. * @param {Number} segments
  800. */
  801. drawCubicBezier:function (origin, control1, control2, destination, segments) {
  802. this.lazy_init();
  803. var vertices = new Float32Array((segments + 1) * 2);
  804. var t = 0;
  805. for (var i = 0; i < segments; i++) {
  806. vertices[i * 2] = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x;
  807. vertices[i * 2 + 1] = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y;
  808. t += 1.0 / segments;
  809. }
  810. vertices[segments * 2] = destination.x;
  811. vertices[segments * 2 + 1] = destination.y;
  812. this._shader.use();
  813. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  814. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  815. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  816. var glContext = this._renderContext;
  817. var pointBuffer = glContext.createBuffer();
  818. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  819. glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
  820. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  821. glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
  822. glContext.deleteBuffer(pointBuffer);
  823. cc.INCREMENT_GL_DRAWS(1);
  824. },
  825. /**
  826. * draw a catmull rom line
  827. * @param {Array} points
  828. * @param {Number} segments
  829. */
  830. drawCatmullRom:function (points, segments) {
  831. this.drawCardinalSpline(points, 0.5, segments);
  832. },
  833. /**
  834. * draw a cardinal spline path
  835. * @param {Array} config
  836. * @param {Number} tension
  837. * @param {Number} segments
  838. */
  839. drawCardinalSpline:function (config, tension, segments) {
  840. this.lazy_init();
  841. var vertices = new Float32Array((segments + 1) * 2);
  842. var p, lt, deltaT = 1.0 / config.length;
  843. for (var i = 0; i < segments + 1; i++) {
  844. var dt = i / segments;
  845. // border
  846. if (dt == 1) {
  847. p = config.length - 1;
  848. lt = 1;
  849. } else {
  850. p = 0 | (dt / deltaT);
  851. lt = (dt - deltaT * p) / deltaT;
  852. }
  853. var newPos = cc.CardinalSplineAt(
  854. cc.getControlPointAt(config, p - 1),
  855. cc.getControlPointAt(config, p),
  856. cc.getControlPointAt(config, p + 1),
  857. cc.getControlPointAt(config, p + 2),
  858. tension, lt);
  859. // Interpolate
  860. vertices[i * 2] = newPos.x;
  861. vertices[i * 2 + 1] = newPos.y;
  862. }
  863. this._shader.use();
  864. this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
  865. cc.glEnableVertexAttribs(cc.VERTEX_ATTRIB_FLAG_POSITION);
  866. this._shader.setUniformLocationWith4fv(this._colorLocation, new Float32Array(this._color._arrayBuffer,0,4), 1);
  867. var glContext = this._renderContext;
  868. var pointBuffer = glContext.createBuffer();
  869. glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
  870. glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
  871. glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
  872. glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
  873. glContext.deleteBuffer(pointBuffer);
  874. cc.INCREMENT_GL_DRAWS(1);
  875. },
  876. /**
  877. * set the drawing color with 4 unsigned bytes
  878. * @param {Number} r red value (0 to 255)
  879. * @param {Number} g green value (0 to 255)
  880. * @param {Number} b blue value (0 to 255)
  881. * @param {Number} a Alpha value (0 to 255)
  882. */
  883. setDrawColor4B:function (r, g, b, a) {
  884. this._color.r = r / 255.0;
  885. this._color.g = g / 255.0;
  886. this._color.b = b / 255.0;
  887. this._color.a = a / 255.0;
  888. },
  889. /**
  890. * set the drawing color with 4 floats
  891. * @param {Number} r red value (0 to 1)
  892. * @param {Number} g green value (0 to 1)
  893. * @param {Number} b blue value (0 to 1)
  894. * @param {Number} a Alpha value (0 to 1)
  895. */
  896. setDrawColor4F:function (r, g, b, a) {
  897. this._color.r = r;
  898. this._color.g = g;
  899. this._color.b = b;
  900. this._color.a = a;
  901. },
  902. /**
  903. * set the point size in points. Default 1.
  904. * @param {Number} pointSize
  905. */
  906. setPointSize:function (pointSize) {
  907. this._pointSize = pointSize * cc.CONTENT_SCALE_FACTOR();
  908. },
  909. /**
  910. * set the line width. Default 1.
  911. * @param {Number} width
  912. */
  913. setLineWidth:function (width) {
  914. if(this._renderContext.lineWidth)
  915. this._renderContext.lineWidth(width);
  916. }
  917. });
  918. cc.PI2 = Math.PI * 2;