- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / data / third_party / spaceport / js / sprites / renderers / webGLBatchDraw.js
1 define([ 'util/ensureCallback', 'sprites/canvas', 'sprites/webGL' ], function (ensureCallback, canvas, webGL) {
2     var FLOATS_PER_VERT = 4;
3     var VERTS_PER_SPRITE = 6;
4     var FLOATS_PER_SPRITE = VERTS_PER_SPRITE * FLOATS_PER_VERT;
5
6     function RenderContext(sourceData, frameData) {
7         this.sourceData = sourceData;
8         this.frameData = frameData;
9
10         this.canvas = canvas();
11         var gl = webGL.getContext(this.canvas);
12         this.context = gl;
13
14         this.program = webGL.shaders.batchSprite(gl);
15
16         // Buffer data is interleaved:
17         //
18         // struct bufferUnit {
19         //   vec2 aCoord;
20         //   vec2 aTexCoord;  -- Constant
21         // };
22         //
23         // sizeof(bufferUnit) == sizeof(float) * 4 == 16
24         //
25         // There are six of these structs per sprite
26         // (one for each corner of the each triangle,
27         // and two triangles per square).
28
29         var maxSprites = Math.max.apply(Math, frameData.map(function (arr) {
30             return arr.length;
31         }));
32
33         var bufferData = new Float32Array(maxSprites * FLOATS_PER_SPRITE);
34         for (var i = 0, j = 0; i < maxSprites; ++i, j += FLOATS_PER_SPRITE) {
35             // p0
36             bufferData[j + 0*4 + 2] = 0;
37             bufferData[j + 0*4 + 3] = 0;
38
39             // p1
40             bufferData[j + 1*4 + 2] = 1;
41             bufferData[j + 1*4 + 3] = 0;
42
43             // p2
44             bufferData[j + 2*4 + 2] = 0;
45             bufferData[j + 2*4 + 3] = 1;
46
47             // p3
48             bufferData[j + 3*4 + 2] = 1;
49             bufferData[j + 3*4 + 3] = 0;
50
51             // p4
52             bufferData[j + 4*4 + 2] = 0;
53             bufferData[j + 4*4 + 3] = 1;
54
55             // p5
56             bufferData[j + 5*4 + 2] = 1;
57             bufferData[j + 5*4 + 3] = 1;
58         }
59
60         this.bufferData = bufferData;
61
62         var buffer = gl.createBuffer();
63         gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
64         gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.DYNAMIC_DRAW);
65         gl.bindBuffer(gl.ARRAY_BUFFER, null);
66
67         this.buffer = buffer;
68
69         this.texture = webGL.makeTexture(gl, this.sourceData.img);
70
71         gl.enable(gl.BLEND);
72         gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
73         gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.SRC_ALPHA, gl.ONE);
74     }
75
76     RenderContext.prototype.load = function load(callback) {
77         callback = ensureCallback(callback);
78
79         document.body.appendChild(this.canvas);
80
81         this.clear();
82
83         callback(null);
84     };
85
86     RenderContext.prototype.unload = function unload() {
87         if (this.canvas.parentNode) {
88             this.canvas.parentNode.removeChild(this.canvas);
89         }
90         
91         var gl = this.context;
92         gl.deleteTexture(this.texture);
93         this.texture = null;
94         
95         gl.deleteProgram(this.program);
96         this.program = null;
97         
98         gl.deleteBuffer(this.buffer);
99         this.buffer = null;
100         this.bufferData = null;
101     };
102
103     RenderContext.prototype.clear = function clear() {
104         var gl = this.context;
105         gl.viewport(0, 0, this.canvas.width, this.canvas.height);
106         gl.clearColor(255, 255, 255, 255);
107         gl.clear(gl.COLOR_BUFFER_BIT);
108     };
109
110     RenderContext.prototype.renderFrame = function renderFrame(frameIndex) {
111         var gl = this.context;
112         var sourceData = this.sourceData;
113
114         var img = sourceData.img;
115         var imgWidth = img.width;
116         var imgHeight = img.height;
117
118         var transforms = this.frameData[frameIndex];
119         var count = transforms.length;
120
121         var bufferData = this.bufferData;
122
123         var i, j;
124         for (i = 0, j = 0; i < count; ++i, j += FLOATS_PER_SPRITE) {
125             var t = transforms[i];
126             t.transformPointInto(0,        0,         bufferData, j + 0);
127             t.transformPointInto(imgWidth, 0,         bufferData, j + 4);
128             t.transformPointInto(0,        imgHeight, bufferData, j + 8);
129
130             bufferData[j + 12] = bufferData[j + 4];
131             bufferData[j + 13] = bufferData[j + 5];
132
133             bufferData[j + 16] = bufferData[j + 8];
134             bufferData[j + 17] = bufferData[j + 9];
135
136             t.transformPointInto(imgWidth, imgHeight, bufferData, j + 20);
137         }
138
139         this.clear();
140
141         var program = this.program;
142         gl.useProgram(program);
143
144         gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
145         gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.DYNAMIC_DRAW);
146
147         gl.vertexAttribPointer(program.attr.coord, 2, gl.FLOAT, false, 16, 0);
148         gl.vertexAttribPointer(program.attr.texCoord, 2, gl.FLOAT, false, 16, 8);
149         gl.enableVertexAttribArray(program.attr.coord);
150         gl.enableVertexAttribArray(program.attr.texCoord);
151
152         gl.activeTexture(gl.TEXTURE0);
153         gl.bindTexture(gl.TEXTURE_2D, this.texture);
154         gl.uniform1i(program.uni.sampler, 0);
155
156         gl.drawArrays(gl.TRIANGLES, 0, count * VERTS_PER_SPRITE);
157
158         // Cleanup
159         gl.disableVertexAttribArray(program.attr.coord);
160         gl.disableVertexAttribArray(program.attr.texCoord);
161         gl.bindBuffer(gl.ARRAY_BUFFER, null);
162
163         gl.useProgram(null);
164     };
165
166     return function (element, frameData) {
167         return new RenderContext(element, frameData);
168     };
169 });