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

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

Powered by Google App Engine
This is Rietveld 408576698