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