mirror of
https://github.com/tiennm99/fbird.git
synced 2026-06-13 10:10:50 +00:00
465 lines
18 KiB
JavaScript
Vendored
465 lines
18 KiB
JavaScript
Vendored
/****************************************************************************
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
|
Copyright (c) 2011-2012 cocos2d-x.org
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
/**
|
|
* Canvas of DrawingPrimitive implement version use for WebGlMode
|
|
* @class
|
|
* @extends cc.Class
|
|
*/
|
|
cc.DrawingPrimitiveWebGL = cc.Class.extend(/** @lends cc.DrawingPrimitiveWebGL# */{
|
|
_renderContext:null,
|
|
_initialized:false,
|
|
_shader: null,
|
|
_colorLocation: "u_color",
|
|
_colorArray: null,
|
|
_pointSizeLocation: "u_pointSize",
|
|
_pointSize:-1,
|
|
/**
|
|
* contructor of cc.DrawingPrimitiveWebGL
|
|
* @param ctx rendercontext
|
|
*/
|
|
ctor:function (ctx) {
|
|
if (ctx == null)
|
|
ctx = cc._renderContext;
|
|
|
|
if (!ctx instanceof WebGLRenderingContext)
|
|
throw new Error("Can't initialise DrawingPrimitiveWebGL. context need is WebGLRenderingContext");
|
|
|
|
this._renderContext = ctx;
|
|
this._colorArray = new Float32Array([1.0, 1.0, 1.0, 1.0]);
|
|
},
|
|
|
|
lazy_init:function () {
|
|
var _t = this;
|
|
if (!_t._initialized) {
|
|
//
|
|
// Position and 1 color passed as a uniform (to similate glColor4ub )
|
|
//
|
|
_t._shader = cc.shaderCache.programForKey(cc.SHADER_POSITION_UCOLOR);
|
|
_t._shader._addUniformLocation(this._colorLocation);
|
|
_t._shader._addUniformLocation(this._pointSizeLocation);
|
|
_t._glProgramState = cc.GLProgramState.getOrCreateWithGLProgram(_t._shader);
|
|
|
|
_t._initialized = true;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* initlialize context
|
|
*/
|
|
drawInit:function () {
|
|
this._initialized = false;
|
|
},
|
|
|
|
/**
|
|
* draws a point given x and y coordinate measured in points
|
|
* @param {cc.Point} point
|
|
*/
|
|
drawPoint:function (point) {
|
|
this.lazy_init();
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
this._shader.setUniformLocationWith1f(this._pointSizeLocation, this._pointSize);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, new Float32Array([point.x, point.y]), glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
glContext.drawArrays(glContext.POINTS, 0, 1);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws an array of points.
|
|
* @param {Array} points point of array
|
|
* @param {Number} numberOfPoints
|
|
*/
|
|
drawPoints:function (points, numberOfPoints) {
|
|
if (!points || points.length === 0)
|
|
return;
|
|
|
|
this.lazy_init();
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
this._shader.setUniformLocationWith1f(this._pointSizeLocation, this._pointSize);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(points), glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
glContext.drawArrays(glContext.POINTS, 0, points.length);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
_pointsToTypeArray:function (points) {
|
|
var typeArr = new Float32Array(points.length * 2);
|
|
for (var i = 0; i < points.length; i++) {
|
|
typeArr[i * 2] = points[i].x;
|
|
typeArr[i * 2 + 1] = points[i].y;
|
|
}
|
|
return typeArr;
|
|
},
|
|
|
|
/**
|
|
* draws a line given the origin and destination point measured in points
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
*/
|
|
drawLine:function (origin, destination) {
|
|
this.lazy_init();
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray([origin, destination]), glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
glContext.drawArrays(glContext.LINES, 0, 2);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws a rectangle given the origin and destination point measured in points.
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
*/
|
|
drawRect:function (origin, destination) {
|
|
this.drawLine(cc.p(origin.x, origin.y), cc.p(destination.x, origin.y));
|
|
this.drawLine(cc.p(destination.x, origin.y), cc.p(destination.x, destination.y));
|
|
this.drawLine(cc.p(destination.x, destination.y), cc.p(origin.x, destination.y));
|
|
this.drawLine(cc.p(origin.x, destination.y), cc.p(origin.x, origin.y));
|
|
},
|
|
|
|
/**
|
|
* draws a solid rectangle given the origin and destination point measured in points.
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawSolidRect:function (origin, destination, color) {
|
|
var vertices = [
|
|
origin,
|
|
cc.p(destination.x, origin.y),
|
|
destination,
|
|
cc.p(origin.x, destination.y)
|
|
];
|
|
|
|
this.drawSolidPoly(vertices, 4, color);
|
|
},
|
|
|
|
/**
|
|
* draws a polygon given a pointer to cc.Point coordiantes and the number of vertices measured in points.
|
|
* @param {Array} vertices a pointer to cc.Point coordiantes
|
|
* @param {Number} numOfVertices the number of vertices measured in points
|
|
* @param {Boolean} closePolygon The polygon can be closed or open
|
|
*/
|
|
drawPoly:function (vertices, numOfVertices, closePolygon) {
|
|
this.lazy_init();
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(vertices), glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
if (closePolygon)
|
|
glContext.drawArrays(glContext.LINE_LOOP, 0, vertices.length);
|
|
else
|
|
glContext.drawArrays(glContext.LINE_STRIP, 0, vertices.length);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws a solid polygon given a pointer to CGPoint coordiantes, the number of vertices measured in points, and a color.
|
|
* @param {Array} poli
|
|
* @param {Number} numberOfPoints
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawSolidPoly:function (poli, numberOfPoints, color) {
|
|
this.lazy_init();
|
|
if (color)
|
|
this.setDrawColor(color.r, color.g, color.b, color.a);
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, this._pointsToTypeArray(poli), glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
glContext.drawArrays(glContext.TRIANGLE_FAN, 0, poli.length);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws a circle given the center, radius and number of segments.
|
|
* @param {cc.Point} center center of circle
|
|
* @param {Number} radius
|
|
* @param {Number} angle angle in radians
|
|
* @param {Number} segments
|
|
* @param {Boolean} drawLineToCenter
|
|
*/
|
|
drawCircle:function (center, radius, angle, segments, drawLineToCenter) {
|
|
this.lazy_init();
|
|
|
|
var additionalSegment = 1;
|
|
if (drawLineToCenter)
|
|
additionalSegment++;
|
|
|
|
var coef = 2.0 * Math.PI / segments;
|
|
|
|
var vertices = new Float32Array((segments + 2) * 2);
|
|
if (!vertices)
|
|
return;
|
|
|
|
for (var i = 0; i <= segments; i++) {
|
|
var rads = i * coef;
|
|
var j = radius * Math.cos(rads + angle) + center.x;
|
|
var k = radius * Math.sin(rads + angle) + center.y;
|
|
|
|
vertices[i * 2] = j;
|
|
vertices[i * 2 + 1] = k;
|
|
}
|
|
vertices[(segments + 1) * 2] = center.x;
|
|
vertices[(segments + 1) * 2 + 1] = center.y;
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
glContext.drawArrays(glContext.LINE_STRIP, 0, segments + additionalSegment);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws a quad bezier path
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} control
|
|
* @param {cc.Point} destination
|
|
* @param {Number} segments
|
|
*/
|
|
drawQuadBezier:function (origin, control, destination, segments) {
|
|
this.lazy_init();
|
|
|
|
var vertices = new Float32Array((segments + 1) * 2);
|
|
|
|
var t = 0.0;
|
|
for (var i = 0; i < segments; i++) {
|
|
vertices[i * 2] = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
|
|
vertices[i * 2 + 1] = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
|
|
t += 1.0 / segments;
|
|
}
|
|
vertices[segments * 2] = destination.x;
|
|
vertices[segments * 2 + 1] = destination.y;
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
|
|
glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draws a cubic bezier path
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} control1
|
|
* @param {cc.Point} control2
|
|
* @param {cc.Point} destination
|
|
* @param {Number} segments
|
|
*/
|
|
drawCubicBezier:function (origin, control1, control2, destination, segments) {
|
|
this.lazy_init();
|
|
|
|
var vertices = new Float32Array((segments + 1) * 2);
|
|
|
|
var t = 0;
|
|
for (var i = 0; i < segments; i++) {
|
|
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;
|
|
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;
|
|
t += 1.0 / segments;
|
|
}
|
|
vertices[segments * 2] = destination.x;
|
|
vertices[segments * 2 + 1] = destination.y;
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* draw a catmull rom line
|
|
* @param {Array} points
|
|
* @param {Number} segments
|
|
*/
|
|
drawCatmullRom:function (points, segments) {
|
|
this.drawCardinalSpline(points, 0.5, segments);
|
|
},
|
|
|
|
/**
|
|
* draw a cardinal spline path
|
|
* @param {Array} config
|
|
* @param {Number} tension
|
|
* @param {Number} segments
|
|
*/
|
|
drawCardinalSpline:function (config, tension, segments) {
|
|
this.lazy_init();
|
|
|
|
var vertices = new Float32Array((segments + 1) * 2);
|
|
var p, lt, deltaT = 1.0 / config.length;
|
|
for (var i = 0; i < segments + 1; i++) {
|
|
var dt = i / segments;
|
|
|
|
// border
|
|
if (dt === 1) {
|
|
p = config.length - 1;
|
|
lt = 1;
|
|
} else {
|
|
p = 0 | (dt / deltaT);
|
|
lt = (dt - deltaT * p) / deltaT;
|
|
}
|
|
|
|
var newPos = cc.cardinalSplineAt(
|
|
cc.getControlPointAt(config, p - 1),
|
|
cc.getControlPointAt(config, p),
|
|
cc.getControlPointAt(config, p + 1),
|
|
cc.getControlPointAt(config, p + 2),
|
|
tension, lt);
|
|
// Interpolate
|
|
|
|
vertices[i * 2] = newPos.x;
|
|
vertices[i * 2 + 1] = newPos.y;
|
|
}
|
|
|
|
var glContext = this._renderContext;
|
|
this._glProgramState.apply();
|
|
this._shader.setUniformForModelViewAndProjectionMatrixWithMat4();
|
|
glContext.enableVertexAttribArray(cc.VERTEX_ATTRIB_POSITION);
|
|
this._shader.setUniformLocationWith4fv(this._colorLocation, this._colorArray);
|
|
|
|
var pointBuffer = glContext.createBuffer();
|
|
glContext.bindBuffer(glContext.ARRAY_BUFFER, pointBuffer);
|
|
glContext.bufferData(glContext.ARRAY_BUFFER, vertices, glContext.STATIC_DRAW);
|
|
glContext.vertexAttribPointer(cc.VERTEX_ATTRIB_POSITION, 2, glContext.FLOAT, false, 0, 0);
|
|
glContext.drawArrays(glContext.LINE_STRIP, 0, segments + 1);
|
|
glContext.deleteBuffer(pointBuffer);
|
|
|
|
cc.incrementGLDraws(1);
|
|
},
|
|
|
|
/**
|
|
* set the drawing color with 4 unsigned bytes
|
|
* @param {Number} r red value (0 to 255)
|
|
* @param {Number} g green value (0 to 255)
|
|
* @param {Number} b blue value (0 to 255)
|
|
* @param {Number} a Alpha value (0 to 255)
|
|
*/
|
|
setDrawColor:function (r, g, b, a) {
|
|
this._colorArray[0] = r / 255.0;
|
|
this._colorArray[1] = g / 255.0;
|
|
this._colorArray[2] = b / 255.0;
|
|
this._colorArray[3] = a / 255.0;
|
|
},
|
|
|
|
/**
|
|
* set the point size in points. Default 1.
|
|
* @param {Number} pointSize
|
|
*/
|
|
setPointSize:function (pointSize) {
|
|
this._pointSize = pointSize * cc.contentScaleFactor();
|
|
},
|
|
|
|
/**
|
|
* set the line width. Default 1.
|
|
* @param {Number} width
|
|
*/
|
|
setLineWidth:function (width) {
|
|
if(this._renderContext.lineWidth)
|
|
this._renderContext.lineWidth(width);
|
|
}
|
|
}); |