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

Side by Side Diff: examples/sample_app/spinning_cube.cc

Issue 967563002: Rename sample_app -> spinning_cube. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Rebase. Created 5 years, 9 months 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/sample_app/spinning_cube.h ('k') | examples/spinning_cube/BUILD.gn » ('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 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // This example program is based on Simple_VertexShader.c from:
6
7 //
8 // Book: OpenGL(R) ES 2.0 Programming Guide
9 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10 // ISBN-10: 0321502795
11 // ISBN-13: 9780321502797
12 // Publisher: Addison-Wesley Professional
13 // URLs: http://safari.informit.com/9780321563835
14 // http://www.opengles-book.com
15 //
16
17 #include "examples/sample_app/spinning_cube.h"
18
19 #include <GLES2/gl2.h>
20 #include <GLES2/gl2ext.h>
21 #include <math.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "mojo/common/common_type_converters.h"
26 #include "mojo/public/cpp/environment/logging.h"
27
28 namespace examples {
29
30 namespace {
31
32 const float kPi = 3.14159265359f;
33 const int kNumVertices = 24;
34
35 int GenerateCube(GLuint *vbo_vertices,
36 GLuint *vbo_indices) {
37 const int num_indices = 36;
38
39 const GLfloat cube_vertices[kNumVertices * 3] = {
40 // -Y side.
41 -0.5f, -0.5f, -0.5f,
42 -0.5f, -0.5f, 0.5f,
43 0.5f, -0.5f, 0.5f,
44 0.5f, -0.5f, -0.5f,
45
46 // +Y side.
47 -0.5f, 0.5f, -0.5f,
48 -0.5f, 0.5f, 0.5f,
49 0.5f, 0.5f, 0.5f,
50 0.5f, 0.5f, -0.5f,
51
52 // -Z side.
53 -0.5f, -0.5f, -0.5f,
54 -0.5f, 0.5f, -0.5f,
55 0.5f, 0.5f, -0.5f,
56 0.5f, -0.5f, -0.5f,
57
58 // +Z side.
59 -0.5f, -0.5f, 0.5f,
60 -0.5f, 0.5f, 0.5f,
61 0.5f, 0.5f, 0.5f,
62 0.5f, -0.5f, 0.5f,
63
64 // -X side.
65 -0.5f, -0.5f, -0.5f,
66 -0.5f, -0.5f, 0.5f,
67 -0.5f, 0.5f, 0.5f,
68 -0.5f, 0.5f, -0.5f,
69
70 // +X side.
71 0.5f, -0.5f, -0.5f,
72 0.5f, -0.5f, 0.5f,
73 0.5f, 0.5f, 0.5f,
74 0.5f, 0.5f, -0.5f,
75 };
76
77 const GLfloat vertex_normals[kNumVertices * 3] = {
78 // -Y side.
79 0.0f, -1.0f, 0.0f,
80 0.0f, -1.0f, 0.0f,
81 0.0f, -1.0f, 0.0f,
82 0.0f, -1.0f, 0.0f,
83
84 // +Y side.
85 0.0f, 1.0f, 0.0f,
86 0.0f, 1.0f, 0.0f,
87 0.0f, 1.0f, 0.0f,
88 0.0f, 1.0f, 0.0f,
89
90 // -Z side.
91 0.0f, 0.0f, -1.0f,
92 0.0f, 0.0f, -1.0f,
93 0.0f, 0.0f, -1.0f,
94 0.0f, 0.0f, -1.0f,
95
96 // +Z side.
97 0.0f, 0.0f, 1.0f,
98 0.0f, 0.0f, 1.0f,
99 0.0f, 0.0f, 1.0f,
100 0.0f, 0.0f, 1.0f,
101
102 // -X side.
103 -1.0f, 0.0f, 0.0f,
104 -1.0f, 0.0f, 0.0f,
105 -1.0f, 0.0f, 0.0f,
106 -1.0f, 0.0f, 0.0f,
107
108 // +X side.
109 1.0f, 0.0f, 0.0f,
110 1.0f, 0.0f, 0.0f,
111 1.0f, 0.0f, 0.0f,
112 1.0f, 0.0f, 0.0f,
113 };
114
115 const GLushort cube_indices[] = {
116 // -Y side.
117 0, 2, 1,
118 0, 3, 2,
119
120 // +Y side.
121 4, 5, 6,
122 4, 6, 7,
123
124 // -Z side.
125 8, 9, 10,
126 8, 10, 11,
127
128 // +Z side.
129 12, 15, 14,
130 12, 14, 13,
131
132 // -X side.
133 16, 17, 18,
134 16, 18, 19,
135
136 // +X side.
137 20, 23, 22,
138 20, 22, 21
139 };
140
141 if (vbo_vertices) {
142 glGenBuffers(1, vbo_vertices);
143 glBindBuffer(GL_ARRAY_BUFFER, *vbo_vertices);
144 glBufferData(GL_ARRAY_BUFFER,
145 sizeof(cube_vertices) + sizeof(vertex_normals),
146 nullptr,
147 GL_STATIC_DRAW);
148 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(cube_vertices), cube_vertices);
149 glBufferSubData(GL_ARRAY_BUFFER, sizeof(cube_vertices),
150 sizeof(vertex_normals), vertex_normals);
151 glBindBuffer(GL_ARRAY_BUFFER, 0);
152 }
153
154 if (vbo_indices) {
155 glGenBuffers(1, vbo_indices);
156 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *vbo_indices);
157 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
158 sizeof(cube_indices),
159 cube_indices,
160 GL_STATIC_DRAW);
161 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
162 }
163
164 return num_indices;
165 }
166
167 GLuint LoadShader(GLenum type,
168 const char* shader_source) {
169 GLuint shader = glCreateShader(type);
170 glShaderSource(shader, 1, &shader_source, NULL);
171 glCompileShader(shader);
172
173 GLint compiled = 0;
174 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
175
176 if (!compiled) {
177 GLsizei expected_length = 0;
178 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &expected_length);
179 std::string log;
180 log.resize(expected_length); // Includes null terminator.
181 GLsizei actual_length = 0;
182 glGetShaderInfoLog(shader, expected_length, &actual_length, &log[0]);
183 log.resize(actual_length); // Excludes null terminator.
184 MOJO_LOG(FATAL) << "Compilation of shader failed: " << log;
185 glDeleteShader(shader);
186 return 0;
187 }
188
189 return shader;
190 }
191
192 GLuint LoadProgram(const char* vertex_shader_source,
193 const char* fragment_shader_source) {
194 GLuint vertex_shader = LoadShader(GL_VERTEX_SHADER,
195 vertex_shader_source);
196 if (!vertex_shader)
197 return 0;
198
199 GLuint fragment_shader = LoadShader(GL_FRAGMENT_SHADER,
200 fragment_shader_source);
201 if (!fragment_shader) {
202 glDeleteShader(vertex_shader);
203 return 0;
204 }
205
206 GLuint program_object = glCreateProgram();
207 glAttachShader(program_object, vertex_shader);
208 glAttachShader(program_object, fragment_shader);
209 glLinkProgram(program_object);
210 glDeleteShader(vertex_shader);
211 glDeleteShader(fragment_shader);
212
213 GLint linked = 0;
214 glGetProgramiv(program_object, GL_LINK_STATUS, &linked);
215 if (!linked) {
216 GLsizei expected_length = 0;
217 glGetProgramiv(program_object, GL_INFO_LOG_LENGTH, &expected_length);
218 std::string log;
219 log.resize(expected_length); // Includes null terminator.
220 GLsizei actual_length = 0;
221 glGetProgramInfoLog(program_object, expected_length, &actual_length,
222 &log[0]);
223 log.resize(actual_length); // Excludes null terminator.
224 MOJO_LOG(FATAL) << "Linking program failed: " << log;
225 glDeleteProgram(program_object);
226 return 0;
227 }
228
229 return program_object;
230 }
231
232 class ESMatrix {
233 public:
234 GLfloat m[4][4];
235
236 ESMatrix() {
237 LoadZero();
238 }
239
240 void LoadZero() {
241 memset(this, 0x0, sizeof(ESMatrix));
242 }
243
244 void LoadIdentity() {
245 LoadZero();
246 m[0][0] = 1.0f;
247 m[1][1] = 1.0f;
248 m[2][2] = 1.0f;
249 m[3][3] = 1.0f;
250 }
251
252 void Multiply(ESMatrix* a, ESMatrix* b) {
253 ESMatrix result;
254 for (int i = 0; i < 4; ++i) {
255 result.m[i][0] = (a->m[i][0] * b->m[0][0]) +
256 (a->m[i][1] * b->m[1][0]) +
257 (a->m[i][2] * b->m[2][0]) +
258 (a->m[i][3] * b->m[3][0]);
259
260 result.m[i][1] = (a->m[i][0] * b->m[0][1]) +
261 (a->m[i][1] * b->m[1][1]) +
262 (a->m[i][2] * b->m[2][1]) +
263 (a->m[i][3] * b->m[3][1]);
264
265 result.m[i][2] = (a->m[i][0] * b->m[0][2]) +
266 (a->m[i][1] * b->m[1][2]) +
267 (a->m[i][2] * b->m[2][2]) +
268 (a->m[i][3] * b->m[3][2]);
269
270 result.m[i][3] = (a->m[i][0] * b->m[0][3]) +
271 (a->m[i][1] * b->m[1][3]) +
272 (a->m[i][2] * b->m[2][3]) +
273 (a->m[i][3] * b->m[3][3]);
274 }
275 *this = result;
276 }
277
278 void Frustum(float left,
279 float right,
280 float bottom,
281 float top,
282 float near_z,
283 float far_z) {
284 float delta_x = right - left;
285 float delta_y = top - bottom;
286 float delta_z = far_z - near_z;
287
288 if ((near_z <= 0.0f) ||
289 (far_z <= 0.0f) ||
290 (delta_z <= 0.0f) ||
291 (delta_y <= 0.0f) ||
292 (delta_y <= 0.0f))
293 return;
294
295 ESMatrix frust;
296 frust.m[0][0] = 2.0f * near_z / delta_x;
297 frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
298
299 frust.m[1][1] = 2.0f * near_z / delta_y;
300 frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
301
302 frust.m[2][0] = (right + left) / delta_x;
303 frust.m[2][1] = (top + bottom) / delta_y;
304 frust.m[2][2] = -(near_z + far_z) / delta_z;
305 frust.m[2][3] = -1.0f;
306
307 frust.m[3][2] = -2.0f * near_z * far_z / delta_z;
308 frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
309
310 Multiply(&frust, this);
311 }
312
313 void Perspective(float fov_y, float aspect, float near_z, float far_z) {
314 GLfloat frustum_h = tanf(fov_y / 360.0f * kPi) * near_z;
315 GLfloat frustum_w = frustum_h * aspect;
316 Frustum(-frustum_w, frustum_w, -frustum_h, frustum_h, near_z, far_z);
317 }
318
319 void Translate(GLfloat tx, GLfloat ty, GLfloat tz) {
320 m[3][0] += m[0][0] * tx + m[1][0] * ty + m[2][0] * tz;
321 m[3][1] += m[0][1] * tx + m[1][1] * ty + m[2][1] * tz;
322 m[3][2] += m[0][2] * tx + m[1][2] * ty + m[2][2] * tz;
323 m[3][3] += m[0][3] * tx + m[1][3] * ty + m[2][3] * tz;
324 }
325
326 void Rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
327 GLfloat mag = sqrtf(x * x + y * y + z * z);
328
329 GLfloat sin_angle = sinf(angle * kPi / 180.0f);
330 GLfloat cos_angle = cosf(angle * kPi / 180.0f);
331 if (mag > 0.0f) {
332 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs;
333 GLfloat one_minus_cos;
334 ESMatrix rotation;
335
336 x /= mag;
337 y /= mag;
338 z /= mag;
339
340 xx = x * x;
341 yy = y * y;
342 zz = z * z;
343 xy = x * y;
344 yz = y * z;
345 zx = z * x;
346 xs = x * sin_angle;
347 ys = y * sin_angle;
348 zs = z * sin_angle;
349 one_minus_cos = 1.0f - cos_angle;
350
351 rotation.m[0][0] = (one_minus_cos * xx) + cos_angle;
352 rotation.m[0][1] = (one_minus_cos * xy) - zs;
353 rotation.m[0][2] = (one_minus_cos * zx) + ys;
354 rotation.m[0][3] = 0.0F;
355
356 rotation.m[1][0] = (one_minus_cos * xy) + zs;
357 rotation.m[1][1] = (one_minus_cos * yy) + cos_angle;
358 rotation.m[1][2] = (one_minus_cos * yz) - xs;
359 rotation.m[1][3] = 0.0F;
360
361 rotation.m[2][0] = (one_minus_cos * zx) - ys;
362 rotation.m[2][1] = (one_minus_cos * yz) + xs;
363 rotation.m[2][2] = (one_minus_cos * zz) + cos_angle;
364 rotation.m[2][3] = 0.0F;
365
366 rotation.m[3][0] = 0.0F;
367 rotation.m[3][1] = 0.0F;
368 rotation.m[3][2] = 0.0F;
369 rotation.m[3][3] = 1.0F;
370
371 Multiply(&rotation, this);
372 }
373 }
374 };
375
376 float RotationForTimeDelta(float delta_time) {
377 return delta_time * 40.0f;
378 }
379
380 float RotationForDragDistance(float drag_distance) {
381 return drag_distance / 5; // Arbitrary damping.
382 }
383
384 } // namespace
385
386 class SpinningCube::GLState {
387 public:
388 GLState();
389
390 void OnGLContextLost();
391
392 GLfloat angle_; // Survives losing the GL context.
393
394 GLuint program_object_;
395 GLint position_location_;
396 GLint normal_location_;
397 GLint mvp_location_;
398 GLuint vbo_vertices_;
399 GLuint vbo_indices_;
400 int num_indices_;
401 ESMatrix mvp_matrix_;
402 };
403
404 SpinningCube::GLState::GLState()
405 : angle_(0) {
406 OnGLContextLost();
407 }
408
409 void SpinningCube::GLState::OnGLContextLost() {
410 program_object_ = 0;
411 position_location_ = 0;
412 normal_location_ = 0;
413 mvp_location_ = 0;
414 vbo_vertices_ = 0;
415 vbo_indices_ = 0;
416 num_indices_ = 0;
417 }
418
419 SpinningCube::SpinningCube()
420 : initialized_(false),
421 width_(0),
422 height_(0),
423 state_(new GLState()),
424 fling_multiplier_(1.0f),
425 direction_(1),
426 color_() {
427 state_->angle_ = 45.0f;
428 set_color(0.0, 1.0, 0.0);
429 }
430
431 SpinningCube::~SpinningCube() {
432 if (!initialized_)
433 return;
434 if (state_->vbo_vertices_)
435 glDeleteBuffers(1, &state_->vbo_vertices_);
436 if (state_->vbo_indices_)
437 glDeleteBuffers(1, &state_->vbo_indices_);
438 if (state_->program_object_)
439 glDeleteProgram(state_->program_object_);
440 }
441
442 void SpinningCube::Init(uint32_t width, uint32_t height) {
443 width_ = width;
444 height_ = height;
445
446 const char vertex_shader_source[] =
447 "uniform mat4 u_mvpMatrix; \n"
448 "attribute vec4 a_position; \n"
449 "attribute vec4 a_normal; \n"
450 "varying vec4 v_color; \n"
451 "void main() \n"
452 "{ \n"
453 " gl_Position = u_mvpMatrix * a_position; \n"
454 " vec4 rotated_normal = u_mvpMatrix * a_normal; \n"
455 " vec4 light_direction = normalize(vec4(0.0, 1.0, -1.0, 0.0)); \n"
456 " float directional_capture = \n"
457 " clamp(dot(rotated_normal, light_direction), 0.0, 1.0); \n"
458 " float light_intensity = 0.6 * directional_capture + 0.4; \n"
459 " vec3 base_color = a_position.xyz + 0.5; \n"
460 " v_color = vec4(base_color * light_intensity, 1.0); \n"
461 "} \n";
462
463 const char fragment_shader_source[] =
464 "precision mediump float; \n"
465 "varying vec4 v_color; \n"
466 "void main() \n"
467 "{ \n"
468 " gl_FragColor = v_color; \n"
469 "} \n";
470
471 state_->program_object_ = LoadProgram(
472 vertex_shader_source, fragment_shader_source);
473 state_->position_location_ = glGetAttribLocation(
474 state_->program_object_, "a_position");
475 state_->normal_location_ = glGetAttribLocation(
476 state_->program_object_, "a_normal");
477 state_->mvp_location_ = glGetUniformLocation(
478 state_->program_object_, "u_mvpMatrix");
479 state_->num_indices_ = GenerateCube(
480 &state_->vbo_vertices_, &state_->vbo_indices_);
481
482 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
483 glEnable(GL_DEPTH_TEST);
484 initialized_ = true;
485 }
486
487 void SpinningCube::OnGLContextLost() {
488 initialized_ = false;
489 height_ = 0;
490 width_ = 0;
491 state_->OnGLContextLost();
492 }
493
494 void SpinningCube::SetFlingMultiplier(float drag_distance,
495 float drag_time) {
496 fling_multiplier_ = RotationForDragDistance(drag_distance) /
497 RotationForTimeDelta(drag_time);
498
499 }
500
501 void SpinningCube::UpdateForTimeDelta(float delta_time) {
502 state_->angle_ += RotationForTimeDelta(delta_time) * fling_multiplier_;
503 if (state_->angle_ >= 360.0f)
504 state_->angle_ -= 360.0f;
505
506 // Arbitrary 50-step linear reduction in spin speed.
507 if (fling_multiplier_ > 1.0f) {
508 fling_multiplier_ =
509 std::max(1.0f, fling_multiplier_ - (fling_multiplier_ - 1.0f) / 50);
510 }
511
512 Update();
513 }
514
515 void SpinningCube::UpdateForDragDistance(float distance) {
516 state_->angle_ += RotationForDragDistance(distance);
517 if (state_->angle_ >= 360.0f )
518 state_->angle_ -= 360.0f;
519
520 Update();
521 }
522
523 void SpinningCube::Draw() {
524 glViewport(0, 0, width_, height_);
525 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
526 glUseProgram(state_->program_object_);
527 glBindBuffer(GL_ARRAY_BUFFER, state_->vbo_vertices_);
528 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state_->vbo_indices_);
529 glVertexAttribPointer(state_->position_location_, 3, GL_FLOAT, GL_FALSE,
530 3 * sizeof(GLfloat), 0);
531 glVertexAttribPointer(state_->normal_location_, 3, GL_FLOAT, GL_FALSE,
532 3 * sizeof(GLfloat),
533 reinterpret_cast<void*>(3 * sizeof(GLfloat) *
534 kNumVertices));
535 glEnableVertexAttribArray(state_->position_location_);
536 glEnableVertexAttribArray(state_->normal_location_);
537 glUniformMatrix4fv(state_->mvp_location_, 1, GL_FALSE,
538 static_cast<GLfloat*>(&state_->mvp_matrix_.m[0][0]));
539 glDrawElements(GL_TRIANGLES, state_->num_indices_, GL_UNSIGNED_SHORT, 0);
540 }
541
542 void SpinningCube::Update() {
543 float aspect = static_cast<GLfloat>(width_) / static_cast<GLfloat>(height_);
544
545 ESMatrix perspective;
546 perspective.LoadIdentity();
547 perspective.Perspective(60.0f, aspect, 1.0f, 20.0f );
548
549 ESMatrix modelview;
550 modelview.LoadIdentity();
551 modelview.Translate(0.0, 0.0, -2.0);
552 modelview.Rotate(state_->angle_ * direction_, 1.0, 0.0, 1.0);
553
554 state_->mvp_matrix_.Multiply(&modelview, &perspective);
555 }
556
557 } // namespace examples
OLDNEW
« no previous file with comments | « examples/sample_app/spinning_cube.h ('k') | examples/spinning_cube/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698