OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AstcTextures.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2014-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include <jni.h>
22 #include <GLES3/gl3.h>
23 
24 #include <cstdlib>
25 #include <cmath>
26 #include <string>
27 
28 #include "Text.h"
29 #include "AstcTextures.h"
30 #include "Timer.h"
31 #include "SolidSphere.h"
32 
33 using namespace AstcTextures;
34 using namespace std;
35 
36 /* Instance of Timer used to measure texture switch time. */
38 
39 /* Instance of Timer used to determine current time. */
41 
42 /* Instance of text renderer used to display name of the compressed texture internalformat,
43  in which textures used for rendering are stored. */
45 
46 /* Instance of SolidSphere which provides mesh data for the globe. */
48 
49 /* Place where all asset files are located. */
50 const string resource_directory("/data/data/com.arm.malideveloper.openglessdk.astctextures/files/");
51 
52 /* Window resolution. */
53 int window_width = 0;
54 int window_height = 0;
55 
56 /* Field of view in y-direction set up to 60 deg., expressed in radians. */
57 const float field_of_view = M_PI * 60.0f / 180.0f;
58 
59 /* Aspect ratio of perspective frustrum. */
60 float x_to_y_ratio = 0;
61 
62 /* Distances between camera and near/far plane of clipping frustrum. */
63 const float z_near = 0.01f;
64 const float z_far = 100.0f;
65 
66 /* Sampler locations. */
70 
71 /* Uniform locations. */
72 GLint mv_location = 0;
73 GLint mvp_location = 0;
74 
75 /* Attribute locations. */
76 GLint normal_location = 0;
79 
80 /* Buffer object ID. */
82 
83 /* Vertex and fragment shader IDs. */
86 
87 /* Program object ID. */
89 
90 /* Vertex array object ID. */
92 
93 /* Initial angles around x, y and z axes. */
94 float angle_x = 0;
95 float angle_y = 0;
96 float angle_z = 0;
97 
98 /* Time value for rotation and translation calculations. */
99 float current_time = 0;
100 
101 /* Model-view transform matrix. */
103 
104 /* Model-view-perspective transform matrix. */
106 
107 /* Perspective projection matrix. */
109 
110 /* Rotation matrix. */
112 
113 /* Indicates which texture set is to be bound to texture units. */
114 unsigned int current_texture_set_id = 0;
115 
117 unsigned short* sphere_indices = NULL;
118 
119 /* Array containing information about all texture sets. */
121 {
122  /* Compression type. Path to cloud texture. Path to day texture. Path to night texture. Name of compression algorithm. */
123  GL_COMPRESSED_RGBA_ASTC_4x4_KHR, "CloudAndGloss4x4.astc", "Earth-Color4x4.astc", "Earth-Night4x4.astc", "4x4 ASTC",
124  GL_COMPRESSED_RGBA_ASTC_5x4_KHR, "CloudAndGloss5x4.astc", "Earth-Color5x4.astc", "Earth-Night5x4.astc", "5x4 ASTC",
125  GL_COMPRESSED_RGBA_ASTC_5x5_KHR, "CloudAndGloss5x5.astc", "Earth-Color5x5.astc", "Earth-Night5x5.astc", "5x5 ASTC",
126  GL_COMPRESSED_RGBA_ASTC_6x5_KHR, "CloudAndGloss6x5.astc", "Earth-Color6x5.astc", "Earth-Night6x5.astc", "6x5 ASTC",
127  GL_COMPRESSED_RGBA_ASTC_6x6_KHR, "CloudAndGloss6x6.astc", "Earth-Color6x6.astc", "Earth-Night6x6.astc", "6x6 ASTC",
128  GL_COMPRESSED_RGBA_ASTC_8x5_KHR, "CloudAndGloss8x5.astc", "Earth-Color8x5.astc", "Earth-Night8x5.astc", "8x5 ASTC",
129  GL_COMPRESSED_RGBA_ASTC_8x6_KHR, "CloudAndGloss8x6.astc", "Earth-Color8x6.astc", "Earth-Night8x6.astc", "8x6 ASTC",
130  GL_COMPRESSED_RGBA_ASTC_8x8_KHR, "CloudAndGloss8x8.astc", "Earth-Color8x8.astc", "Earth-Night8x8.astc", "8x8 ASTC",
131  GL_COMPRESSED_RGBA_ASTC_10x5_KHR, "CloudAndGloss10x5.astc", "Earth-Color10x5.astc", "Earth-Night10x5.astc", "10x5 ASTC",
132  GL_COMPRESSED_RGBA_ASTC_10x6_KHR, "CloudAndGloss10x6.astc", "Earth-Color10x6.astc", "Earth-Night10x6.astc", "10x6 ASTC",
133  GL_COMPRESSED_RGBA_ASTC_10x8_KHR, "CloudAndGloss10x8.astc", "Earth-Color10x8.astc", "Earth-Night10x8.astc", "10x8 ASTC",
134  GL_COMPRESSED_RGBA_ASTC_10x10_KHR, "CloudAndGloss10x10.astc", "Earth-Color10x10.astc", "Earth-Night10x10.astc", "10x10 ASTC",
135  GL_COMPRESSED_RGBA_ASTC_12x10_KHR, "CloudAndGloss12x10.astc", "Earth-Color12x10.astc", "Earth-Night12x10.astc", "12x10 ASTC",
136  GL_COMPRESSED_RGBA_ASTC_12x12_KHR, "CloudAndGloss12x12.astc", "Earth-Color12x12.astc", "Earth-Night12x12.astc", "12x12 ASTC",
137  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, "CloudAndGloss4x4.astc", "Earth-Color4x4.astc", "Earth-Night4x4.astc", "4x4 SRGB ASTC",
138  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, "CloudAndGloss5x4.astc", "Earth-Color5x4.astc", "Earth-Night5x4.astc", "5x4 SRGB ASTC",
139  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, "CloudAndGloss5x5.astc", "Earth-Color5x5.astc", "Earth-Night5x5.astc", "5x5 SRGB ASTC",
140  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, "CloudAndGloss6x5.astc", "Earth-Color6x5.astc", "Earth-Night6x5.astc", "6x5 SRGB ASTC",
141  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, "CloudAndGloss6x6.astc", "Earth-Color6x6.astc", "Earth-Night6x6.astc", "6x6 SRGB ASTC",
142  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, "CloudAndGloss8x5.astc", "Earth-Color8x5.astc", "Earth-Night8x5.astc", "8x5 SRGB ASTC",
143  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, "CloudAndGloss8x6.astc", "Earth-Color8x6.astc", "Earth-Night8x6.astc", "8x6 SRGB ASTC",
144  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, "CloudAndGloss8x8.astc", "Earth-Color8x8.astc", "Earth-Night8x8.astc", "8x8 SRGB ASTC",
145  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, "CloudAndGloss10x5.astc", "Earth-Color10x5.astc", "Earth-Night10x5.astc", "10x5 SRGB ASTC",
146  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, "CloudAndGloss10x6.astc", "Earth-Color10x6.astc", "Earth-Night10x6.astc", "10x6 SRGB ASTC",
147  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, "CloudAndGloss10x8.astc", "Earth-Color10x8.astc", "Earth-Night10x8.astc", "10x8 SRGB ASTC",
148  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, "CloudAndGloss10x10.astc", "Earth-Color10x10.astc", "Earth-Night10x10.astc", "10x10 SRGB ASTC",
149  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, "CloudAndGloss12x10.astc", "Earth-Color12x10.astc", "Earth-Night12x10.astc", "12x10 SRGB ASTC",
150  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, "CloudAndGloss12x12.astc", "Earth-Color12x12.astc", "Earth-Night12x12.astc", "12x12 SRGB ASTC"
151 };
152 
153 /* Number of texture sets. */
154 const int n_texture_ids = sizeof(texture_sets_info) / sizeof(texture_sets_info[0]);
155 
156 /* Array storing texture bindings. */
158 
159 /* Please see header for specification. */
160 GLint get_and_check_attrib_location(GLuint program, const GLchar* attrib_name)
161 {
162  GLint attrib_location = GL_CHECK(glGetAttribLocation(program, attrib_name));
163 
164  if (attrib_location == -1)
165  {
166  LOGE("Cannot retrieve location of %s attribute.\n", attrib_name);
167  exit(EXIT_FAILURE);
168  }
169 
170  return attrib_location;
171 }
172 
173 /* Please see header for specification. */
174 GLint get_and_check_uniform_location(GLuint program, const GLchar* uniform_name)
175 {
176  GLint uniform_location = GL_CHECK(glGetUniformLocation(program, uniform_name));
177 
178  if (uniform_location == -1)
179  {
180  LOGE("Cannot retrieve location of %s uniform.\n", uniform_name);
181  exit(EXIT_FAILURE);
182  }
183 
184  return uniform_location;
185 }
186 
187 /* Please see header for specification. */
188 GLuint load_shader(GLenum shader_type, const char* shader_source)
189 {
190  GLuint shader = GL_CHECK(glCreateShader(shader_type));
191 
192  if (shader != 0)
193  {
194  GL_CHECK(glShaderSource(shader, 1, &shader_source, NULL));
195  GL_CHECK(glCompileShader(shader));
196 
197  GLint compiled = 0;
198 
199  GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
200 
201  if (compiled != GL_TRUE)
202  {
203  GLint info_len = 0;
204 
205  GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len));
206 
207  if (info_len > 0)
208  {
209  char* log_buffer = NULL;
210 
211  MALLOC_CHECK(char*, log_buffer, info_len);
212 
213  GL_CHECK(glGetShaderInfoLog(shader, info_len, NULL, log_buffer));
214  LOGE("Could not compile shader 0x%x:\n%s\n", shader_type, log_buffer);
215  FREE_CHECK(log_buffer);
216 
217  GL_CHECK(glDeleteShader(shader));
218  shader = 0;
219 
220  exit(EXIT_FAILURE);
221  }
222  }
223  }
224 
225  return shader;
226 }
227 
228 /* Please see header for specification. */
229 GLuint create_program(const char* vertex_source, const char* fragment_source)
230 {
231  GLuint vertexShader = load_shader(GL_VERTEX_SHADER, vertex_source);
232  GLuint fragmentShader = load_shader(GL_FRAGMENT_SHADER, fragment_source);
233  GLuint program = GL_CHECK(glCreateProgram());
234 
235  if (program != 0)
236  {
237  GL_CHECK(glAttachShader(program, vertexShader));
238  GL_CHECK(glAttachShader(program, fragmentShader));
239  GL_CHECK(glLinkProgram(program));
240 
241  GLint linkStatus = GL_FALSE;
242 
243  GL_CHECK(glGetProgramiv(program, GL_LINK_STATUS, &linkStatus));
244 
245  if (linkStatus != GL_TRUE)
246  {
247  GLint buf_length = 0;
248 
249  GL_CHECK(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &buf_length));
250 
251  if (buf_length > 0)
252  {
253  char* log_buffer = NULL;
254 
255  MALLOC_CHECK(char*, log_buffer, buf_length);
256  GL_CHECK(glGetProgramInfoLog(program, buf_length, NULL, log_buffer));
257  LOGE("Could not link program:\n%s\n", log_buffer);
258  FREE_CHECK(log_buffer);
259  }
260 
261  GL_CHECK(glDeleteProgram(program));
262  program = 0;
263 
264  exit(EXIT_FAILURE);
265  }
266  }
267  else
268  {
269  LOGE("Error creating program object.");
270  exit(EXIT_FAILURE);
271  }
272 
273  return program;
274 }
275 
282 void update_texture_bindings(bool force_switch_texture)
283 {
284  if (timer.getTime() >= ASTC_TEXTURE_SWITCH_INTERVAL || force_switch_texture)
285  {
286  /* If the current texture set is to be changed, reset timer to start counting time again. */
287  timer.reset();
288 
289  /* Clear current text. */
291 
292  if (!force_switch_texture)
293  {
295  {
297  }
298  else
299  {
301  }
302  }
303 
304  /* Change displayed text. */
308  255, /* Red channel. */
309  255, /* Green channel. */
310  0, /* Blue channel. */
311  255); /* Alpha channel. */
312  }
313 
314  /* Update texture units with new bindings. */
315  GL_CHECK(glActiveTexture(GL_TEXTURE0));
316  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].cloud_and_gloss_texture_id));
317  GL_CHECK(glActiveTexture(GL_TEXTURE1));
318  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].earth_color_texture_id));
319  GL_CHECK(glActiveTexture(GL_TEXTURE2));
320  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].earth_night_texture_id));
321 }
322 
329 GLuint load_texture(const char* file_name, GLenum compressed_data_internal_format)
330 {
331  unsigned char* compressed_data = NULL;
332  unsigned char* input_data = NULL;
333 
334  long file_size = 0;
335  unsigned int n_bytes_to_read = 0;
336  size_t result = 0;
337  GLuint to_id = 0;
338 
339  /* Number of blocks in the x, y and z direction. */
340  int xblocks = 0;
341  int yblocks = 0;
342  int zblocks = 0;
343 
344  /* Number of bytes for each dimension. */
345  int xsize = 0;
346  int ysize = 0;
347  int zsize = 0;
348 
349  FILE* compressed_data_file = fopen(file_name, "rb");
350 
351  if (compressed_data_file == NULL)
352  {
353  LOGE("Could not open a file.\n");
354  exit(EXIT_FAILURE);
355  }
356 
357  LOGI("Loading texture [%s]\n", file_name);
358 
359  /* Obtain file size. */
360  fseek(compressed_data_file, 0, SEEK_END);
361  file_size = ftell(compressed_data_file);
362  rewind(compressed_data_file);
363 
364  /* Allocate memory to contain the whole file. */
365  MALLOC_CHECK(unsigned char*, input_data, sizeof(unsigned char) * file_size);
366 
367  /* Copy the file into the buffer. */
368  result = fread(input_data, 1, file_size, compressed_data_file);
369 
370  if (result != file_size)
371  {
372  LOGE("Reading error [%s] ... FILE: %s LINE: %i\n", file_name, __FILE__, __LINE__);
373  exit(EXIT_FAILURE);
374  }
375 
376  /* Traverse the file structure. */
377  astc_header* astc_data_ptr = (astc_header*) input_data;
378 
379  /* Merge x,y,z-sizes from 3 chars into one integer value. */
380  xsize = astc_data_ptr->xsize[0] + (astc_data_ptr->xsize[1] << 8) + (astc_data_ptr->xsize[2] << 16);
381  ysize = astc_data_ptr->ysize[0] + (astc_data_ptr->ysize[1] << 8) + (astc_data_ptr->ysize[2] << 16);
382  zsize = astc_data_ptr->zsize[0] + (astc_data_ptr->zsize[1] << 8) + (astc_data_ptr->zsize[2] << 16);
383 
384  /* Compute number of blocks in each direction. */
385  xblocks = (xsize + astc_data_ptr->blockdim_x - 1) / astc_data_ptr->blockdim_x;
386  yblocks = (ysize + astc_data_ptr->blockdim_y - 1) / astc_data_ptr->blockdim_y;
387  zblocks = (zsize + astc_data_ptr->blockdim_z - 1) / astc_data_ptr->blockdim_z;
388 
389  /* Each block is encoded on 16 bytes, so calculate total compressed image data size. */
390  n_bytes_to_read = xblocks * yblocks * zblocks << 4;
391 
392  /* We now have file contents in memory so let's fill a texture object with the data. */
393  GL_CHECK(glGenTextures(1, &to_id));
394  GL_CHECK(glBindTexture(GL_TEXTURE_2D, to_id));
395 
396  /* Upload texture data to ES. */
397  GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D,
398  0,
399  compressed_data_internal_format,
400  xsize,
401  ysize,
402  0,
403  n_bytes_to_read,
404  (const GLvoid*)&astc_data_ptr[1]));
405 
406  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
407  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
408  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
409  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
410 
411  /* Unbind texture from target. */
412  GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
413 
414  /* Terminate file operations. */
415  fclose(compressed_data_file);
416  FREE_CHECK(input_data);
417 
418  return to_id;
419 }
420 
424 void load_textures(void)
425 {
426  /* Paths to texture images. */
427  string cloud_and_gloss_texture_file_path;
428  string earth_color_texture_file_path;
429  string earth_night_texture_file_path;
430 
431  for (int i = 0; i < n_texture_ids; i++)
432  {
433  cloud_and_gloss_texture_file_path = resource_directory + texture_sets_info[i].cloud_and_gloss_texture_file_path;
434  earth_color_texture_file_path = resource_directory + texture_sets_info[i].earth_color_texture_file_path;
435  earth_night_texture_file_path = resource_directory + texture_sets_info[i].earth_night_texture_file_path;
436 
441  }
442 
443  /* Configure texture set. */
445 }
446 
451 void setup_program(void)
452 {
453  /* Create program object and initialize it. */
455 
456  /* Get attribute locations of attributes vertex position,cd normal and texture coordinates. */
460 
461  /* Get uniform locations. */
467 
468  /* Activate program object. */
469  GL_CHECK(glUseProgram(program_id));
470 }
471 
476 {
477  const float sphere_radius = 1.0f;
478 
479  /* Number of pararells and meridians the sphere should consists of. */
480  const unsigned int n_sectors = 64;
481  const unsigned int n_rings = 64;
482 
483  /* New instance of sphere. */
484  solid_sphere = new SolidSphere(sphere_radius, n_rings, n_sectors);
485 
486  /* Obtain sizes of the several subbuffers. */
487  GLsizei sphere_vertices_size = 0;
488  GLsizei sphere_normals_size = 0;
489  GLsizei sphere_texcoords_size = 0;
490  GLsizei buffer_offset = 0;
491 
492  /* Load generated mesh data from SolidSphere object. */
493  float* sphere_vertices = solid_sphere->getSphereVertexData(&sphere_vertices_size);
494  float* sphere_normals = solid_sphere->getSphereNormalData(&sphere_normals_size);
495  float* sphere_texcoords = solid_sphere->getSphereTexcoords(&sphere_texcoords_size);
496 
497  /* Size of the entire buffer. */
498  GLsizei buffer_total_size = sphere_vertices_size + sphere_normals_size + sphere_texcoords_size;
499 
500  /* Create buffer object to hold all mesh data. */
501  GL_CHECK(glGenBuffers(1, &bo_id));
502  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bo_id));
503  GL_CHECK(glBufferData(GL_ARRAY_BUFFER, buffer_total_size, NULL, GL_STATIC_DRAW));
504 
505  /* Upload subsets of mesh data to buffer object. */
506  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_vertices_size, sphere_vertices));
507 
508  buffer_offset += sphere_vertices_size;
509 
510  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_normals_size, sphere_normals));
511 
512  buffer_offset += sphere_normals_size;
513 
514  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_texcoords_size, sphere_texcoords));
515 
516  /* Release resources. */
517  FREE_CHECK(sphere_vertices);
518  FREE_CHECK(sphere_normals);
519  FREE_CHECK(sphere_texcoords);
520 
521  /* Configure vertex attribute arrays, so that position/normals/texture coordinate data is available to the vertex shader. */
522  GL_CHECK(glGenVertexArrays(1, &vao_id));
523  GL_CHECK(glBindVertexArray(vao_id));
524  GL_CHECK(glEnableVertexAttribArray(position_location));
525  GL_CHECK(glEnableVertexAttribArray(normal_location));
526  GL_CHECK(glEnableVertexAttribArray(texture_coords_location));
527 
528  buffer_offset = 0;
529 
530  /* Populate attribute for position. */
531  GL_CHECK(glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
532 
533  buffer_offset += sphere_vertices_size;
534 
535  /* Populate attribute for normals. */
536  GL_CHECK(glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
537 
538  buffer_offset += sphere_normals_size;
539 
540  /* Populate attribute for texture coordinates. */
541  GL_CHECK(glVertexAttribPointer(texture_coords_location, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
542 
543  /* Bind texture units to texture samplers. */
544  GL_CHECK(glUniform1i(cloud_texture_location, 0));
545  GL_CHECK(glUniform1i(daytime_texture_location, 1));
546  GL_CHECK(glUniform1i(nighttime_texture_location, 2));
547 
548  /* Load generated indices from SolidSphere object. */
550 }
551 
553 {
556 
558 
560 
561  /* Make sure the required ASTC extension is present. */
562  const GLubyte* extensions = GL_CHECK(glGetString(GL_EXTENSIONS));
563 
564  if (strstr((const char*) extensions, "GL_KHR_texture_compression_astc_ldr") == NULL)
565  {
566  LOGI("OpenGL ES 3.0 implementation does not support GL_KHR_texture_compression_astc_ldr extension.\n");
567  exit(EXIT_SUCCESS);
568  }
569 
570  /* Enable culling and depth testing. */
571  GL_CHECK(glEnable(GL_CULL_FACE));
572  GL_CHECK(glEnable(GL_DEPTH_TEST));
573 
574  /* Enable blending and specify pixel arihmetic.
575  Transparency is implemented using blend function with primitives sorted from the farthest to the nearest. */
576  GL_CHECK(glEnable(GL_BLEND));
577  GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
578 
580 
581  /* Create texture objects and fill them with texture data. */
582  load_textures();
583 
584  /* Set up shader objects.
585  Rerieve uniform and attribute locations. */
586  setup_program();
587 
588  /* Prepare buffer objects that will hold mesh data. */
590 
591  /* Start counting time. */
592  timer.reset();
593  fps_timer.reset();
594 }
595 
599 void render_frame(void)
600 {
601  /* Prepare rotation matrices and use them to set up model+view matrix. */
606  model_view_matrix = rotate_matrix * model_view_matrix;
607 
608  /* Pull the camera back from the cube - move back and forth as time goes by.
609  To achieve it scale with time translational part of model matrix for z-direction. */
610  model_view_matrix[14] -= 2.5f + sinf(current_time / 5.0f) * 0.5f;
611 
612  /* Upload view matrix. */
613  GL_CHECK(glUniformMatrix4fv(mv_location, 1, GL_FALSE, &model_view_matrix[0]));
614 
615  /* Bring model from camera space into Normalized Device Coordinates (NDC). */
617 
618  /* Upload complete Model Space->World Space->Camera(Eye) Space->NDC transformation by updating relevant MVP uniform.
619  Vertex shader will then use this matrix to transform all input vertices from model space to screen space. */
620  GL_CHECK(glUniformMatrix4fv(mvp_location, 1, GL_FALSE, &mvp_matrix[0]));
621 
622  /* Get the current time. */
624 
625  /* Obtain angular rates around X, Y, Z axes. */
629 
630  /* Clear buffers. */
631  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
632 
633  /* Draw the sphere from array data. */
634  GL_CHECK(glDrawElements(GL_TRIANGLES, sphere_indices_size, GL_UNSIGNED_SHORT, sphere_indices));
635 
636  /* Also don't forget to show name of the compression algorithm in action. */
637  text_displayer->draw();
638 
639  /* Switch the texture set if more than 5 seconds has passed since the last switch event. */
641 }
642 
647 {
648  /* Delete all used textures. */
649  for (int i = 0; i < n_texture_ids; i++)
650  {
651  GL_CHECK(glDeleteTextures(1, &texture_ids[i].cloud_and_gloss_texture_id));
652  GL_CHECK(glDeleteTextures(1, &texture_ids[i].earth_color_texture_id));
653  GL_CHECK(glDeleteTextures(1, &texture_ids[i].earth_night_texture_id));
654  }
655 
656  /* Cleanup shaders. */
657  GL_CHECK(glUseProgram(0));
658  GL_CHECK(glDeleteShader(vert_shader_id));
659  GL_CHECK(glDeleteShader(frag_shader_id));
660  GL_CHECK(glDeleteProgram(program_id));
661 
662  /* Delete vertex array object. */
663  GL_CHECK(glDisableVertexAttribArray(position_location));
664  GL_CHECK(glDisableVertexAttribArray(normal_location));
665  GL_CHECK(glDisableVertexAttribArray(texture_coords_location));
666  GL_CHECK(glDeleteVertexArrays(1, &vao_id));
667 
668  /* Free buffer object memory. */
669  GL_CHECK(glDeleteBuffers(1, &bo_id));
670 
671  /* Free indices buffer. */
673 
674  /* Release memory for Text and SolidSphere instances. */
675  delete text_displayer;
676  delete solid_sphere;
677 }
678 
679 extern "C"
680 {
681  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_init(JNIEnv*, jobject, jint width, jint height);
682  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_step(JNIEnv*, jobject);
683  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_uninit(JNIEnv*, jobject);
684 };
685 
686 JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_init(JNIEnv*, jobject, jint width, jint height)
687 {
688  setup_graphics(width, height);
689 }
690 
692 {
693  render_frame();
694 }
695 
697 {
699 }
GLint normal_location
int sphere_indices_size
GLuint create_program(const char *vertex_source, const char *fragment_source)
Create program object, attach vertex and fragment shader to it. Link program object and check whether...
Matrix mvp_matrix
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
Definition: AstcTextures.h:85
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR
Definition: AstcTextures.h:83
#define MALLOC_CHECK(ptr_type, ptr, size)
Definition: AstcTextures.h:33
uniform float sphere_radius
Definition: generate.cs:28
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
Definition: AstcTextures.h:96
void setup_program(void)
This function sets up a program object that will be used for rendering, as well as retrieves attribut...
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
Definition: AstcTextures.h:97
static Matrix createRotationY(float angle)
Create and return a rotation matrix around the y-axis matrix.
Definition: Matrix.cpp:135
#define LOGI(...)
Definition: AstcTextures.h:29
GLint get_and_check_attrib_location(GLuint program, const GLchar *attrib_name)
Invoke glGetAttribLocation(), if it has returned a positive value. Otherwise, print a message and exi...
const float z_far
Functions for drawing text in OpenGL ES.
Definition: Text.h:89
const char * cloud_and_gloss_texture_file_path
Definition: AstcTextures.h:213
const char earth_fragment_shader_source[]
Definition: AstcTextures.h:133
float angle_x
GLint nighttime_texture_location
#define ASTC_TEXTURE_SWITCH_INTERVAL
Definition: AstcTextures.h:101
GLint mvp_location
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
static const int textureCharacterHeight
The height (in pixels) of the characters in the text texture.
Definition: Text.h:131
void clear(void)
Removes the current string from the class.
Definition: Text.cpp:142
GLint cloud_texture_location
unsigned char blockdim_z
Definition: AstcTextures.h:187
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR
Definition: AstcTextures.h:76
float current_time
float angle_z
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_uninit(JNIEnv *, jobject)
const string resource_directory("/data/data/com.arm.malideveloper.openglessdk.astctextures/files/")
GLuint earth_night_texture_id
Definition: AstcTextures.h:199
unsigned short * getSphereIndices(int *n_indices)
Returns sphere indices.
GLuint earth_color_texture_id
Definition: AstcTextures.h:198
GLuint vert_shader_id
Functions for manipulating matrices.
Definition: Matrix.h:29
GLint get_and_check_uniform_location(GLuint program, const GLchar *uniform_name)
Invoke glGetUniformLocation, if it has returned a positive value. Otherwise, print a message and exit...
Timer fps_timer
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
Definition: AstcTextures.h:93
Matrix perspective_matrix
GLuint load_shader(GLenum shader_type, const char *shader_source)
Create shader object and compile its source code.
const char * name
Definition: AstcTextures.h:202
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR
Definition: AstcTextures.h:82
unsigned int current_texture_set_id
float * getSphereNormalData(int *normal_data_size)
Returns normal coordinates.
const char * earth_color_texture_file_path
Definition: AstcTextures.h:214
Provides a platform independent high resolution timer.
Definition: Timer.h:33
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
Definition: AstcTextures.h:98
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR
Definition: AstcTextures.h:72
float * getSphereTexcoords(int *texcoords_size)
Returns texture coordinates.
const char * earth_night_texture_file_path
Definition: AstcTextures.h:215
texture_set texture_ids[n_texture_ids]
unsigned char zsize[3]
Definition: AstcTextures.h:190
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
Definition: AstcTextures.h:87
GLint position_location
float angle_y
const float field_of_view
unsigned char blockdim_y
Definition: AstcTextures.h:186
GLuint vao_id
static const int textureCharacterWidth
The width (in pixels) of the characters in the text texture.
Definition: Text.h:125
int window_width
const char * compressed_texture_format_name
Definition: AstcTextures.h:218
#define Z_ROTATION_SPEED
Definition: AstcTextures.h:106
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR
Definition: AstcTextures.h:79
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
Definition: AstcTextures.h:91
const int n_texture_ids
GLint daytime_texture_location
void render_frame(void)
Renders a single frame.
GLuint bo_id
GLfloat GLfloat f
Definition: gl2ext.h:2707
unsigned char xsize[3]
Definition: AstcTextures.h:188
GLuint frag_shader_id
void load_textures(void)
Define 32 texture sets that the demo will switch between every 5 seconds.
float * getSphereVertexData(int *vertex_data_size)
Returns sphere vertices.
Definition: SolidSphere.cpp:98
GLint mv_location
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR
Definition: AstcTextures.h:77
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
Definition: AstcTextures.h:94
#define M_PI
The value of pi.
Definition: Mathematics.h:37
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
Definition: AstcTextures.h:86
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
Definition: AstcTextures.h:90
#define GL_CHECK(x)
Definition: AstcTextures.h:59
SolidSphere * solid_sphere
GLuint program_id
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_init(JNIEnv *, jobject, jint width, jint height)
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR
Definition: AstcTextures.h:81
#define X_ROTATION_SPEED
Definition: AstcTextures.h:104
const float z_near
static Matrix createRotationX(float angle)
Create and return a rotation matrix around the x-axis matrix.
Definition: Matrix.cpp:121
Matrix rotate_matrix
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR
Definition: AstcTextures.h:84
void cleanup_graphics(void)
Perform graphics clean-up actions.
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR
Definition: AstcTextures.h:78
GLuint name
Definition: gl2ext.h:139
void update_texture_bindings(bool force_switch_texture)
Update texture bindings and text presented by text renderer.
const GLenum compressed_data_internal_format
Definition: AstcTextures.h:210
float x_to_y_ratio
texture_set_info texture_sets_info[]
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR
Definition: AstcTextures.h:75
Timer timer
GLint texture_coords_location
const char earth_vertex_shader_source[]
Definition: AstcTextures.h:109
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR
Definition: AstcTextures.h:74
float getTime()
Returns the time passed since object creation or since reset() was last called.
Definition: Timer.cpp:55
unsigned char ysize[3]
Definition: AstcTextures.h:189
void reset()
Resets the timer to 0.0f.
Definition: Timer.cpp:45
unsigned char blockdim_x
Definition: AstcTextures.h:185
void setup_graphics(int width, int height)
#define LOGE(...)
Definition: AstcTextures.h:30
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR
Definition: AstcTextures.h:73
precision highp float
Definition: hiz_cull.cs:37
GLint GLsizei width
Definition: gl2ext.h:179
void load_buffer_data(void)
Sets up a buffer object that will hold mesh data (vertex positions, normal vectors, textures UV coordinates).
static Matrix createRotationZ(float angle)
Create and return a rotation matrix around the z-axis matrix.
Definition: Matrix.cpp:149
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR
Definition: AstcTextures.h:80
#define FREE_CHECK(ptr)
Definition: AstcTextures.h:53
static T * buffer_offset(T *buffer, size_t offset)
Definition: GroundMesh.cpp:462
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
#define Y_ROTATION_SPEED
Definition: AstcTextures.h:105
GLuint program
Definition: gl2ext.h:1475
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
Definition: AstcTextures.h:89
int window_height
Matrix model_view_matrix
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
Definition: AstcTextures.h:92
void draw(void)
Draw the text to the screen.
Definition: Text.cpp:257
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
Definition: AstcTextures.h:95
GLuint load_texture(const char *file_name, GLenum compressed_data_internal_format)
Define and retrieve compressed texture image.
Text * text_displayer
static Matrix matrixPerspective(float FOV, float ratio, float zNear, float zFar)
Create and return a perspective projection matrix.
Definition: Matrix.cpp:104
unsigned short * sphere_indices
GLuint cloud_and_gloss_texture_id
Definition: AstcTextures.h:197
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR
Definition: AstcTextures.h:71
void addString(int xPosition, int yPosition, const char *string, int red, int green, int blue, int alpha)
Add a std::string to be drawn to the screen.
Definition: Text.cpp:153
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
Definition: AstcTextures.h:88
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextures_NativeLibrary_step(JNIEnv *, jobject)