Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: examples/js/cube.js

Issue 788863003: Restore the JS Spinning Cube demo (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Removed spurious includes Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!mojo:js_content_handler
Aaron Boodman 2014/12/09 20:24:53 copyright header
hansmuller 2014/12/09 20:43:21 Done.
2
3 define("main", [
4 "console",
5 "mojo/services/public/js/application",
6 "mojo/services/public/interfaces/gpu/command_buffer.mojom",
7 "mojo/services/public/interfaces/geometry/geometry.mojom",
8 "mojo/services/public/interfaces/gpu/gpu.mojom",
9 "mojo/services/public/interfaces/native_viewport/native_viewport.mojom",
10 "mojo/services/public/interfaces/gpu/viewport_parameter_listener.mojom",
11 "mojo/public/js/core",
12 "services/js/modules/gl",
13 "services/js/modules/clock",
14 "timer",
15 ], function(console,
16 appModule,
17 cbModule,
18 geoModule,
19 gpuModule,
20 nvModule,
21 vplModule,
22 coreModule,
23 glModule,
24 clockModule,
25 timerModule) {
26
27 const VERTEX_SHADER_SOURCE = [
28 'uniform mat4 u_mvpMatrix;',
29 'attribute vec4 a_position;',
30 'void main()',
31 '{',
32 ' gl_Position = u_mvpMatrix * a_position;',
33 '}'
34 ].join('\n');
35
36 const FRAGMENT_SHADER_SOURCE = [
37 'precision mediump float;',
38 'void main()',
39 '{',
40 ' gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );',
41 '}'
42 ].join('\n');
43
44 class ESMatrix {
45 constructor() {
46 this.m = new Float32Array(16);
47 }
48
49 getIndex(x, y) {
50 return x * 4 + y;
51 }
52
53 set(x, y, v) {
54 this.m[this.getIndex(x, y)] = v;
55 }
56
57 get(x, y) {
58 return this.m[this.getIndex(x, y)];
59 }
60
61 loadZero() {
62 for (var i = 0; i < this.m.length; i++) {
63 this.m[i] = 0;
64 }
65 }
66
67 loadIdentity() {
68 this.loadZero();
69 for (var i = 0; i < 4; i++) {
70 this.set(i, i, 1);
71 }
72 }
73
74 multiply(a, b) {
75 var result = new ESMatrix();
76 for (var i = 0; i < 4; i++) {
77 result.set(i, 0,
78 (a.get(i, 0) * b.get(0, 0)) +
79 (a.get(i, 1) * b.get(1, 0)) +
80 (a.get(i, 2) * b.get(2, 0)) +
81 (a.get(i, 3) * b.get(3, 0)));
82
83 result.set(i, 1,
84 (a.get(i, 0) * b.get(0, 1)) +
85 (a.get(i, 1) * b.get(1, 1)) +
86 (a.get(i, 2) * b.get(2, 1)) +
87 (a.get(i, 3) * b.get(3, 1)));
88
89 result.set(i, 2,
90 (a.get(i, 0) * b.get(0, 2)) +
91 (a.get(i, 1) * b.get(1, 2)) +
92 (a.get(i, 2) * b.get(2, 2)) +
93 (a.get(i, 3) * b.get(3, 2)));
94
95 result.set(i, 3,
96 (a.get(i, 0) * b.get(0, 3)) +
97 (a.get(i, 1) * b.get(1, 3)) +
98 (a.get(i, 2) * b.get(2, 3)) +
99 (a.get(i, 3) * b.get(3, 3)));
100 }
101 for (var i = 0; i < result.m.length; i++) {
102 this.m[i] = result.m[i];
103 }
104 }
105
106 frustrum(left, right, bottom, top, nearZ, farZ) {
107 var deltaX = right - left;
108 var deltaY = top - bottom;
109 var deltaZ = farZ - nearZ;
110
111 if (nearZ < 0 || farZ < 0 || deltaZ < 0 || deltaY < 0 || deltaX < 0) {
112 return;
113 }
114
115 var frust = new ESMatrix();
116 frust.set(0, 0, 2 * nearZ / deltaX);
117
118 frust.set(1, 1, 2 * nearZ / deltaY);
119
120 frust.set(2, 0, (right + left) / deltaX);
121 frust.set(2, 1, (top + bottom) / deltaY);
122 frust.set(2, 2, -(nearZ + farZ) / deltaZ);
123 frust.set(2, 3, -1);
124
125 frust.set(3, 2, -2 * nearZ * farZ / deltaZ);
126
127 this.multiply(frust, this);
128 }
129
130 perspective(fovY, aspect, nearZ, farZ) {
131 var frustrumH = Math.tan(fovY / 360 * Math.PI) * nearZ;
132 var frustrumW = frustrumH * aspect;
133 this.frustrum(-frustrumW, frustrumW, -frustrumH, frustrumH, nearZ, farZ);
134 }
135
136 translate(tx, ty, tz) {
137 this.set(3, 0, this.get(3, 0) + this.get(0, 0) *
138 tx + this.get(1, 0) * ty + this.get(2, 0) * tz);
139 this.set(3, 1, this.get(3, 1) + this.get(0, 1) *
140 tx + this.get(1, 1) * ty + this.get(2, 1) * tz);
141 this.set(3, 2, this.get(3, 2) + this.get(0, 2) *
142 tx + this.get(1, 2) * ty + this.get(2, 2) * tz);
143 this.set(3, 3, this.get(3, 3) + this.get(0, 3) *
144 tx + this.get(1, 3) * ty + this.get(2, 3) * tz);
145 }
146
147 rotate(angle, x, y, z) {
148 var mag = Math.sqrt(x * x + y * y + z * z);
149 var sinAngle = Math.sin(angle * Math.PI / 180);
150 var cosAngle = Math.cos(angle * Math.PI / 180);
151 if (mag <= 0) {
152 return;
153 }
154
155 var xx, yy, zz, xy, yz, zx, xs, ys, zs, oneMinusCos;
156 var rotation = new ESMatrix();
157
158 x /= mag;
159 y /= mag;
160 z /= mag;
161
162 xx = x * x;
163 yy = y * y;
164 zz = z * z;
165 xy = x * y;
166 yz = y * z;
167 zx = z * x;
168 xs = x * sinAngle;
169 ys = y * sinAngle;
170 zs = z * sinAngle;
171 oneMinusCos = 1 - cosAngle;
172
173 rotation.set(0, 0, (oneMinusCos * xx) + cosAngle);
174 rotation.set(0, 1, (oneMinusCos * xy) - zs);
175 rotation.set(0, 2, (oneMinusCos * zx) + ys);
176 rotation.set(0, 3, 0);
177
178 rotation.set(1, 0, (oneMinusCos * xy) + zs);
179 rotation.set(1, 1, (oneMinusCos * yy) + cosAngle);
180 rotation.set(1, 2, (oneMinusCos * yz) - xs);
181 rotation.set(1, 3, 0);
182
183 rotation.set(2, 0, (oneMinusCos * zx) - ys);
184 rotation.set(2, 1, (oneMinusCos * yz) + xs);
185 rotation.set(2, 2, (oneMinusCos * zz) + cosAngle);
186 rotation.set(2, 3, 0);
187
188 rotation.set(3, 0, 0);
189 rotation.set(3, 1, 0);
190 rotation.set(3, 2, 0);
191 rotation.set(3, 3, 1);
192
193 this.multiply(rotation, this);
194 }
195 }
196
197 function loadProgram(gl) {
198 var vertexShader = gl.createShader(gl.VERTEX_SHADER);
199 gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE);
200 gl.compileShader(vertexShader);
201
202 var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
203 gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);
204 gl.compileShader(fragmentShader);
205
206 var program = gl.createProgram();
207 gl.attachShader(program, vertexShader);
208 gl.attachShader(program, fragmentShader);
209
210 gl.linkProgram(program);
211 // TODO(aa): Check for errors using getProgramiv and LINK_STATUS.
212
213 gl.deleteShader(vertexShader);
214 gl.deleteShader(fragmentShader);
215
216 return program;
217 }
218
219 var vboVertices;
220 var vboIndices;
221 function generateCube(gl) {
222 var numVertices = 24 * 3;
223 var numIndices = 12 * 3;
224
225 var cubeVertices = new Float32Array([
226 -0.5, -0.5, -0.5,
227 -0.5, -0.5, 0.5,
228 0.5, -0.5, 0.5,
229 0.5, -0.5, -0.5,
230 -0.5, 0.5, -0.5,
231 -0.5, 0.5, 0.5,
232 0.5, 0.5, 0.5,
233 0.5, 0.5, -0.5,
234 -0.5, -0.5, -0.5,
235 -0.5, 0.5, -0.5,
236 0.5, 0.5, -0.5,
237 0.5, -0.5, -0.5,
238 -0.5, -0.5, 0.5,
239 -0.5, 0.5, 0.5,
240 0.5, 0.5, 0.5,
241 0.5, -0.5, 0.5,
242 -0.5, -0.5, -0.5,
243 -0.5, -0.5, 0.5,
244 -0.5, 0.5, 0.5,
245 -0.5, 0.5, -0.5,
246 0.5, -0.5, -0.5,
247 0.5, -0.5, 0.5,
248 0.5, 0.5, 0.5,
249 0.5, 0.5, -0.5
250 ]);
251
252 var cubeIndices = new Uint16Array([
253 0, 2, 1,
254 0, 3, 2,
255 4, 5, 6,
256 4, 6, 7,
257 8, 9, 10,
258 8, 10, 11,
259 12, 15, 14,
260 12, 14, 13,
261 16, 17, 18,
262 16, 18, 19,
263 20, 23, 22,
264 20, 22, 21
265 ]);
266
267 // TODO(aa): The C++ program branches here on whether the pointer is
268 // non-NULL.
269 vboVertices = gl.createBuffer();
270 gl.bindBuffer(gl.ARRAY_BUFFER, vboVertices);
271 gl.bufferData(gl.ARRAY_BUFFER, cubeVertices, gl.STATIC_DRAW);
272 gl.bindBuffer(gl.ARRAY_BUFFER, 0);
273
274 vboIndices = gl.createBuffer();
275 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vboIndices);
276 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, cubeIndices, gl.STATIC_DRAW);
277 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0);
278
279 return cubeIndices.length;
280 }
281
282 class GLES2ClientImpl {
283 constructor (remotePipe, size) {
284 this.gl_ = new glModule.Context(remotePipe, this.contextLost.bind(this));
285 this.lastTime_ = clockModule.seconds();
286 this.angle_ = 45;
287
288 this.program_ = loadProgram(this.gl_);
289 this.positionLocation_ =
290 this.gl_.getAttribLocation(this.program_, 'a_position');
291 this.mvpLocation_ =
292 this.gl_.getUniformLocation(this.program_, 'u_mvpMatrix');
293 this.numIndices_ = generateCube(this.gl_);
294 this.mvpMatrix_ = new ESMatrix();
295 this.mvpMatrix_.loadIdentity();
296
297 this.gl_.clearColor(0, 0, 0, 0);
298 this.setDimensions(size);
299 this.timer_ =
300 timerModule.createRepeating(16, this.handleTimer.bind(this));
301 }
302
303 setDimensions(size) {
304 this.width_ = size.width;
305 this.height_ = size.height;
306 this.gl_.resize(size.width, size.height, 1);
307 }
308
309 drawCube() {
310 this.gl_.viewport(0, 0, this.width_, this.height_);
311 this.gl_.clear(this.gl_.COLOR_BUFFER_BIT);
312 this.gl_.useProgram(this.program_);
313 this.gl_.bindBuffer(this.gl_.ARRAY_BUFFER, vboVertices);
314 this.gl_.bindBuffer(this.gl_.ELEMENT_ARRAY_BUFFER, vboIndices);
315 this.gl_.vertexAttribPointer(this.positionLocation_, 3, this.gl_.FLOAT,
316 false, 12, 0);
317 this.gl_.enableVertexAttribArray(this.positionLocation_);
318 this.gl_.uniformMatrix4fv(this.mvpLocation_, false, this.mvpMatrix_.m);
319 this.gl_.drawElements(this.gl_.TRIANGLES, this.numIndices_,
320 this.gl_.UNSIGNED_SHORT, 0);
321 this.gl_.swapBuffers();
322 };
323
324 handleTimer() {
325 var now = clockModule.seconds();
326 var secondsDelta = now - this.lastTime_;
327 this.lastTime_ = now;
328
329 this.angle_ += this.getRotationForTimeDelta(secondsDelta);
330 this.angle_ = this.angle_ % 360;
331
332 var aspect = this.width_ / this.height_;
333
334 var perspective = new ESMatrix();
335 perspective.loadIdentity();
336 perspective.perspective(60, aspect, 1, 20);
337
338 var modelView = new ESMatrix();
339 modelView.loadIdentity();
340 modelView.translate(0, 0, -2);
341 modelView.rotate(this.angle_, 1, 0, 1);
342
343 this.mvpMatrix_.multiply(modelView, perspective);
344
345 this.drawCube();
346 };
347
348 getRotationForTimeDelta(secondsDelta) {
349 return secondsDelta * 40;
350 };
351
352 contextLost() {
353 console.log('GLES2ClientImpl.prototype.contextLost');
354 };
355
356 quit() {
357 if (this.timer_) {
358 console.log("CANCEL");
359 this.timer_.cancel();
360 this.timer_ = null;
361 }
362 }
363 }
364
365 class CubeDemo extends appModule.Application {
366 initialize(args) {
367 this.viewport = this.shell.connectToService(
368 "mojo:native_viewport_service", nvModule.NativeViewport, this);
369
370 this.gpu = this.shell.connectToService(
371 "mojo:native_viewport_service", gpuModule.Gpu);
372
373 var app = this;
374 var viewportSize = new geoModule.Size({width: 800, height: 600});
375 this.viewport.create(viewportSize).then(
376 function(result) {
377 app.onViewportCreated(result.native_viewport_id, viewportSize);
378 });
379
380 this.eventDispatcher =
381 new nvModule.NativeViewportEventDispatcher.stubClass(this);
382 this.viewport.setEventDispatcher(this.eventDispatcher);
383 this.viewport.show();
384 }
385
386 onViewportCreated(id, size) {
387 this.vpl = new vplModule.ViewportParameterListener.stubClass({
388 onVSyncParametersUpdated: function(timebase, interval) {
389 console.log("onVSyncParametersUpdated");
390 }
391 });
392 var pipe = coreModule.createMessagePipe();
393 this.gpu.createOnscreenGLES2Context(id, size, pipe.handle1, this.vpl);
394 this.gles2_ = new GLES2ClientImpl(pipe.handle0, size);
395 }
396
397 onEvent(event) {
398 return Promise.resolve(); // This just gates the next event delivery
399 }
400
401 onSizeChanged(size) {
402 if (this.gles2_)
403 this.gles2_.setDimensions(size);
404 }
405
406 onDestroyed() {
407 this.quit();
408 }
409 }
410
411 return CubeDemo;
412 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698