Skip to content

Commit

Permalink
feat: WebGL render mode support view's tint property
Browse files Browse the repository at this point in the history
  • Loading branch information
06wj committed Jun 20, 2016
1 parent bb7fde9 commit 00da91a
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 44 deletions.
101 changes: 101 additions & 0 deletions examples/tint.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, minimum-scale=1, maximum-scale=1" />
<title>tint - Hilo Example</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="../build/standalone/hilo-standalone.min.js"></script>
<script type="text/javascript" src="../build/flash/hilo-flash.min.js" data-auto="true"></script>
<img src="images/fish.png" alt="" id="fish" style="display:none">
<style>
canvas{
background: #fff;
}
</style>
</head>
<body onload="init();">
<header>
<h1>view.tint</h1>
<p>tint</p>
</header>
<div id="game-container"></div>
<script type="text/javascript" src="js/demo.js"></script>
<script type="text/javascript">
function init(){
//init stage
var stage = new Hilo.Stage({
renderType:renderType,
container: gameContainer,
width: stageWidth,
height: stageHeight
});

//start stage ticker
var ticker = new Hilo.Ticker(60);
ticker.addTick(stage);
ticker.start();

//init texture atlas
var atlas = new Hilo.TextureAtlas({
image: 'images/fish.png',
width: 174,
height: 1512,
frames: {
frameWidth: 174,
frameHeight: 126,
numFrames: 12
},
sprites: {
fish: {from:0, to:7}
}
});

//create a fish sprite
var maxX = stageWidth + 174;
var maxY = stageHeight + 126;
var minX = -174;
var minY = -126;

var num = 30;
while(num--){
var fish = new Hilo.Sprite({
frames: atlas.getSprite('fish'),
x: Math.random()*stageWidth,
y: Math.random()*stageHeight,
interval: 6,
timeBased: false,
loop: true,
alpha:1,
tint:Math.random()*0xffffff,
pivotX:87,
pivotY:63,
onUpdate: function(){
if(this.x > maxX){
this.x = minX;
}
else if(this.x < minX){
this.x = maxX;
}

if(this.y > maxY){
this.y = minY;
}
else if(this.y < minY){
this.y = maxY;
}

this.x += this.vx;
this.y += this.vy;
}
}).addTo(stage);

var speed = 2;
fish.rotation = Math.random()*360;
fish.vy = Math.sin(fish.rotation*Math.PI/180) * speed;
fish.vx = Math.cos(fish.rotation*Math.PI/180) * speed;
}
}
</script>
</body>
</html>
85 changes: 45 additions & 40 deletions src/renderer/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@ var WebGLRenderer = Class.create(/** @lends WebGLRenderer.prototype */{
this.positionStride = WebGLRenderer.ATTRIBUTE_NUM * 4;
var vertexNum = this.maxBatchNum * WebGLRenderer.ATTRIBUTE_NUM * 4;
var indexNum = this.maxBatchNum * 6;
this.positions = new Float32Array(vertexNum);
this.arrayBuffer = new ArrayBuffer(vertexNum * 4);
this.float32Array = new Float32Array(this.arrayBuffer);
this.uint32Array = new Uint32Array(this.arrayBuffer);
this.indexs = new Uint16Array(indexNum);
for (var i=0, j=0; i < indexNum; i += 6, j += 4)
{
Expand Down Expand Up @@ -110,11 +112,11 @@ var WebGLRenderer = Class.create(/** @lends WebGLRenderer.prototype */{
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indexs, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, this.positions, gl.DYNAMIC_DRAW);
gl.bufferData(gl.ARRAY_BUFFER, this.arrayBuffer, gl.DYNAMIC_DRAW);

gl.vertexAttribPointer(this.a_position, 2, gl.FLOAT, false, this.positionStride, 0);//x, y
gl.vertexAttribPointer(this.a_TexCoord, 2, gl.FLOAT, false, this.positionStride, 2 * 4);//x, y
gl.vertexAttribPointer(this.a_alpha, 1, gl.FLOAT, false, this.positionStride, 4 * 4);//alpha
gl.vertexAttribPointer(this.a_tint, 4, gl.UNSIGNED_BYTE, true, this.positionStride, 4 * 4);//alpha
},

context: null,
Expand Down Expand Up @@ -163,39 +165,42 @@ var WebGLRenderer = Class.create(/** @lends WebGLRenderer.prototype */{

var vertexs = this._createVertexs(image, rect[0], rect[1], sw, sh, 0, 0, w, h);
var index = this.batchIndex * this.positionStride;
var positions = this.positions;
var alpha = target.__webglRenderAlpha;
positions[index + 0] = vertexs[0];//x
positions[index + 1] = vertexs[1];//y
positions[index + 2] = vertexs[2];//uvx
positions[index + 3] = vertexs[3];//uvy
positions[index + 4] = alpha;//alpha

positions[index + 5] = vertexs[4];
positions[index + 6] = vertexs[5];
positions[index + 7] = vertexs[6];
positions[index + 8] = vertexs[7];
positions[index + 9] = alpha;

positions[index + 10] = vertexs[8]
positions[index + 11] = vertexs[9]
positions[index + 12] = vertexs[10]
positions[index + 13] = vertexs[11]
positions[index + 14] = alpha;

positions[index + 15] = vertexs[12]
positions[index + 16] = vertexs[13]
positions[index + 17] = vertexs[14]
positions[index + 18] = vertexs[15]
positions[index + 19] = alpha;
var float32Array = this.float32Array;
var uint32Array = this.uint32Array;

var tint = (target.tint >> 16) + (target.tint & 0xff00) + ((target.tint & 0xff) << 16) + (target.__webglRenderAlpha * 255 << 24);

float32Array[index + 0] = vertexs[0];//x
float32Array[index + 1] = vertexs[1];//y
float32Array[index + 2] = vertexs[2];//uvx
float32Array[index + 3] = vertexs[3];//uvy
uint32Array[index + 4] = tint;//tint

float32Array[index + 5] = vertexs[4];
float32Array[index + 6] = vertexs[5];
float32Array[index + 7] = vertexs[6];
float32Array[index + 8] = vertexs[7];
uint32Array[index + 9] = tint;

float32Array[index + 10] = vertexs[8]
float32Array[index + 11] = vertexs[9]
float32Array[index + 12] = vertexs[10]
float32Array[index + 13] = vertexs[11]
uint32Array[index + 14] = tint;

float32Array[index + 15] = vertexs[12]
float32Array[index + 16] = vertexs[13]
float32Array[index + 17] = vertexs[14]
float32Array[index + 18] = vertexs[15]
uint32Array[index + 19] = tint;

var matrix = target.__webglWorldMatrix;
for(var i = 0;i < 4;i ++){
var x = positions[index + i*5];
var y = positions[index + i*5 + 1];
var x = float32Array[index + i*5];
var y = float32Array[index + i*5 + 1];

positions[index + i*5] = matrix.a*x+matrix.c*y + matrix.tx;
positions[index + i*5 + 1] = matrix.b*x+matrix.d*y + matrix.ty;
float32Array[index + i*5] = matrix.a*x+matrix.c*y + matrix.tx;
float32Array[index + i*5 + 1] = matrix.b*x+matrix.d*y + matrix.ty;
}

target.texture = image.texture;
Expand Down Expand Up @@ -312,7 +317,7 @@ var WebGLRenderer = Class.create(/** @lends WebGLRenderer.prototype */{
},
_renderBatches:function(){
var gl = this.gl;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.positions.subarray(0, this.batchIndex * this.positionStride));
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uint32Array.subarray(0, this.batchIndex * this.positionStride));
var startIndex = 0;
var batchNum = 0;
var preTexture = null;
Expand Down Expand Up @@ -351,33 +356,33 @@ var WebGLRenderer = Class.create(/** @lends WebGLRenderer.prototype */{
var VSHADER_SOURCE ='\
attribute vec2 a_position;\n\
attribute vec2 a_TexCoord;\n\
attribute float a_alpha;\n\
attribute vec4 a_tint;\n\
uniform mat3 u_projectionTransform;\n\
varying vec2 v_TexCoord;\n\
varying float v_alpha;\n\
varying vec4 v_tint;\n\
void main(){\n\
gl_Position = vec4((u_projectionTransform * vec3(a_position, 1.0)).xy, 1.0, 1.0);\n\
v_TexCoord = a_TexCoord;\n\
v_alpha = a_alpha;\n\
v_tint = vec4(a_tint.rgb * a_tint.a, a_tint.a);\n\
}\n\
';

var FSHADER_SOURCE = '\n\
precision mediump float;\n\
uniform sampler2D u_Sampler;\n\
varying vec2 v_TexCoord;\n\
varying float v_alpha;\n\
varying vec4 v_tint;\n\
void main(){\n\
gl_FragColor = texture2D(u_Sampler, v_TexCoord) * v_alpha;\n\
gl_FragColor = texture2D(u_Sampler, v_TexCoord) * v_tint;\n\
}\n\
';

this.defaultShader = new Shader(this, {
v:VSHADER_SOURCE,
f:FSHADER_SOURCE
},{
attributes:["a_position", "a_TexCoord", "a_alpha"],
uniforms:["u_projectionTransform", "u_Alpha", "u_Sampler"]
attributes:["a_position", "a_TexCoord", "a_tint"],
uniforms:["u_projectionTransform", "u_Sampler"]
});
},
_createVertexs:function(img, tx, ty, tw, th, x, y, w, h){
Expand Down
11 changes: 7 additions & 4 deletions src/view/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
* @property {Number} scaleY The y axis scale factor of the view, default value is 1.
* @property {Boolean} pointerEnabled Is the view can receive DOM events, default value is true.
* @property {Object} background The background style to fill the view, can be css color, gradient or pattern of canvas
* @property {Graphics} mask Sets a mask for the view. A mask is an object that limits the visibility of an object to the shape of the mask applied to it. A regular mask must be a Hilo.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping. To remove a mask, set this property to null.
* @property {Graphics} mask Sets a mask for the view. A mask is an object that limits the visibility of an object to the shape of the mask applied to it. A regular mask must be a Hilo.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping. To remove a mask, set this property to null.
* @property {Number} tint The tint applied to the view,default is 0xFFFFFF.Only support in WebGL mode.
* @property {String|Function} align The alignment of the view, the value must be one of Hilo.align enum.
* @property {Container} parent The parent view of this view, readonly!
* @property {Number} depth The z index of the view, readonly!
Expand Down Expand Up @@ -58,6 +59,7 @@
* @property {Boolean} pointerEnabled 可视对象是否接受交互事件。默认为接受交互事件,即true。
* @property {Object} background 可视对象的背景样式。可以是CSS颜色值、canvas的gradient或pattern填充。
* @property {Graphics} mask 可视对象的遮罩图形。
* @property {Number} tint 可视对象的附加颜色,默认0xFFFFFF,只支持WebGL模式。
* @property {String|Function} align 可视对象相对于父容器的对齐方式。取值可查看Hilo.align枚举对象。
* @property {Container} parent 可视对象的父容器。只读属性。
* @property {Number} depth 可视对象的深度,也即z轴的序号。只读属性。
Expand All @@ -74,6 +76,7 @@ return Class.create(/** @lends View.prototype */{
Hilo.copy(this, properties, true);
},

tint:0xffffff,
id: null,
x: 0,
y: 0,
Expand Down Expand Up @@ -338,7 +341,7 @@ return Class.create(/** @lends View.prototype */{
},
/**
* @language=en
* Mouse event
* Mouse event
*/
/**
* @language=zh
Expand Down Expand Up @@ -379,7 +382,7 @@ return Class.create(/** @lends View.prototype */{

/**
* @language=en
* This method will call while the view need update(usually caused by ticker update). This method can return a Boolean value, if return false, the view will not be drawn.
* This method will call while the view need update(usually caused by ticker update). This method can return a Boolean value, if return false, the view will not be drawn.
* Limit: If you change the index in it's parent, it will not be drawn correct in current frame but next frame is correct.
* @type Function
* @default null
Expand All @@ -395,7 +398,7 @@ return Class.create(/** @lends View.prototype */{

/**
* @language=en
* The render method of current view. The subclass can implement it's own render logic by rewrite this function.
* The render method of current view. The subclass can implement it's own render logic by rewrite this function.
* @param {Renderer} renderer Renderer object.
* @param {Number} delta The delta time of render.
*/
Expand Down

0 comments on commit 00da91a

Please sign in to comment.