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.astctextureslowprecision/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 static bool astc_decode_mode_supported = false;
121 
122 /* Array containing information about all texture sets. */
124 {
125  /* Compression type. Decode format. Path to cloud texture. Decode format. Path to day texture. Decode format. Path to night texture. Name of compression algorithm. */
126  GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_RGBA8, "CloudAndGloss4x4.astc", GL_RGB9_E5, "Earth-Color4x4.astc", GL_RGB9_E5, "Earth-Night4x4.astc", "4x4 ASTC",
127  GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_RGBA8, "CloudAndGloss5x4.astc", GL_RGB9_E5, "Earth-Color5x4.astc", GL_RGB9_E5, "Earth-Night5x4.astc", "5x4 ASTC",
128  GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_RGBA8, "CloudAndGloss5x5.astc", GL_RGB9_E5, "Earth-Color5x5.astc", GL_RGB9_E5, "Earth-Night5x5.astc", "5x5 ASTC",
129  GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_RGBA8, "CloudAndGloss6x5.astc", GL_RGB9_E5, "Earth-Color6x5.astc", GL_RGB9_E5, "Earth-Night6x5.astc", "6x5 ASTC",
130  GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_RGBA8, "CloudAndGloss6x6.astc", GL_RGB9_E5, "Earth-Color6x6.astc", GL_RGB9_E5, "Earth-Night6x6.astc", "6x6 ASTC",
131  GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_RGBA8, "CloudAndGloss8x5.astc", GL_RGB9_E5, "Earth-Color8x5.astc", GL_RGB9_E5, "Earth-Night8x5.astc", "8x5 ASTC",
132  GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_RGBA8, "CloudAndGloss8x6.astc", GL_RGB9_E5, "Earth-Color8x6.astc", GL_RGB9_E5, "Earth-Night8x6.astc", "8x6 ASTC",
133  GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_RGBA8, "CloudAndGloss8x8.astc", GL_RGB9_E5, "Earth-Color8x8.astc", GL_RGB9_E5, "Earth-Night8x8.astc", "8x8 ASTC",
134  GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_RGBA8, "CloudAndGloss10x5.astc", GL_RGB9_E5, "Earth-Color10x5.astc", GL_RGB9_E5, "Earth-Night10x5.astc", "10x5 ASTC",
135  GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_RGBA8, "CloudAndGloss10x6.astc", GL_RGB9_E5, "Earth-Color10x6.astc", GL_RGB9_E5, "Earth-Night10x6.astc", "10x6 ASTC",
136  GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_RGBA8, "CloudAndGloss10x8.astc", GL_RGB9_E5, "Earth-Color10x8.astc", GL_RGB9_E5, "Earth-Night10x8.astc", "10x8 ASTC",
137  GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_RGBA8, "CloudAndGloss10x10.astc", GL_RGB9_E5, "Earth-Color10x10.astc", GL_RGB9_E5, "Earth-Night10x10.astc", "10x10 ASTC",
138  GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_RGBA8, "CloudAndGloss12x10.astc", GL_RGB9_E5, "Earth-Color12x10.astc", GL_RGB9_E5, "Earth-Night12x10.astc", "12x10 ASTC",
139  GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_RGBA8, "CloudAndGloss12x12.astc", GL_RGB9_E5, "Earth-Color12x12.astc", GL_RGB9_E5, "Earth-Night12x12.astc", "12x12 ASTC",
140  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_RGBA8, "CloudAndGloss4x4.astc", GL_RGB9_E5, "Earth-Color4x4.astc", GL_RGB9_E5, "Earth-Night4x4.astc", "4x4 SRGB ASTC",
141  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_RGBA8, "CloudAndGloss5x4.astc", GL_RGB9_E5, "Earth-Color5x4.astc", GL_RGB9_E5, "Earth-Night5x4.astc", "5x4 SRGB ASTC",
142  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_RGBA8, "CloudAndGloss5x5.astc", GL_RGB9_E5, "Earth-Color5x5.astc", GL_RGB9_E5, "Earth-Night5x5.astc", "5x5 SRGB ASTC",
143  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_RGBA8, "CloudAndGloss6x5.astc", GL_RGB9_E5, "Earth-Color6x5.astc", GL_RGB9_E5, "Earth-Night6x5.astc", "6x5 SRGB ASTC",
144  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_RGBA8, "CloudAndGloss6x6.astc", GL_RGB9_E5, "Earth-Color6x6.astc", GL_RGB9_E5, "Earth-Night6x6.astc", "6x6 SRGB ASTC",
145  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_RGBA8, "CloudAndGloss8x5.astc", GL_RGB9_E5, "Earth-Color8x5.astc", GL_RGB9_E5, "Earth-Night8x5.astc", "8x5 SRGB ASTC",
146  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_RGBA8, "CloudAndGloss8x6.astc", GL_RGB9_E5, "Earth-Color8x6.astc", GL_RGB9_E5, "Earth-Night8x6.astc", "8x6 SRGB ASTC",
147  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_RGBA8, "CloudAndGloss8x8.astc", GL_RGB9_E5, "Earth-Color8x8.astc", GL_RGB9_E5, "Earth-Night8x8.astc", "8x8 SRGB ASTC",
148  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_RGBA8, "CloudAndGloss10x5.astc", GL_RGB9_E5, "Earth-Color10x5.astc", GL_RGB9_E5, "Earth-Night10x5.astc", "10x5 SRGB ASTC",
149  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_RGBA8, "CloudAndGloss10x6.astc", GL_RGB9_E5, "Earth-Color10x6.astc", GL_RGB9_E5, "Earth-Night10x6.astc", "10x6 SRGB ASTC",
150  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_RGBA8, "CloudAndGloss10x8.astc", GL_RGB9_E5, "Earth-Color10x8.astc", GL_RGB9_E5, "Earth-Night10x8.astc", "10x8 SRGB ASTC",
151  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_RGBA8, "CloudAndGloss10x10.astc", GL_RGB9_E5, "Earth-Color10x10.astc", GL_RGB9_E5, "Earth-Night10x10.astc", "10x10 SRGB ASTC",
152  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_RGBA8, "CloudAndGloss12x10.astc", GL_RGB9_E5, "Earth-Color12x10.astc", GL_RGB9_E5, "Earth-Night12x10.astc", "12x10 SRGB ASTC",
153  GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_RGBA8, "CloudAndGloss12x12.astc", GL_RGB9_E5, "Earth-Color12x12.astc", GL_RGB9_E5, "Earth-Night12x12.astc", "12x12 SRGB ASTC"
154 };
155 
156 /* Number of texture sets. */
157 const int n_texture_ids = sizeof(texture_sets_info) / sizeof(texture_sets_info[0]);
158 
159 /* Array storing texture bindings. */
161 
162 /* Please see header for specification. */
163 GLint get_and_check_attrib_location(GLuint program, const GLchar* attrib_name)
164 {
165  GLint attrib_location = GL_CHECK(glGetAttribLocation(program, attrib_name));
166 
167  if (attrib_location == -1)
168  {
169  LOGE("Cannot retrieve location of %s attribute.\n", attrib_name);
170  exit(EXIT_FAILURE);
171  }
172 
173  return attrib_location;
174 }
175 
176 /* Please see header for specification. */
177 GLint get_and_check_uniform_location(GLuint program, const GLchar* uniform_name)
178 {
179  GLint uniform_location = GL_CHECK(glGetUniformLocation(program, uniform_name));
180 
181  if (uniform_location == -1)
182  {
183  LOGE("Cannot retrieve location of %s uniform.\n", uniform_name);
184  exit(EXIT_FAILURE);
185  }
186 
187  return uniform_location;
188 }
189 
190 /* Please see header for specification. */
191 GLuint load_shader(GLenum shader_type, const char* shader_source)
192 {
193  GLuint shader = GL_CHECK(glCreateShader(shader_type));
194 
195  if (shader != 0)
196  {
197  GL_CHECK(glShaderSource(shader, 1, &shader_source, NULL));
198  GL_CHECK(glCompileShader(shader));
199 
200  GLint compiled = 0;
201 
202  GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled));
203 
204  if (compiled != GL_TRUE)
205  {
206  GLint info_len = 0;
207 
208  GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len));
209 
210  if (info_len > 0)
211  {
212  char* log_buffer = NULL;
213 
214  MALLOC_CHECK(char*, log_buffer, info_len);
215 
216  GL_CHECK(glGetShaderInfoLog(shader, info_len, NULL, log_buffer));
217  LOGE("Could not compile shader 0x%x:\n%s\n", shader_type, log_buffer);
218  FREE_CHECK(log_buffer);
219 
220  GL_CHECK(glDeleteShader(shader));
221  shader = 0;
222 
223  exit(EXIT_FAILURE);
224  }
225  }
226  }
227 
228  return shader;
229 }
230 
231 /* Please see header for specification. */
232 GLuint create_program(const char* vertex_source, const char* fragment_source)
233 {
234  GLuint vertexShader = load_shader(GL_VERTEX_SHADER, vertex_source);
235  GLuint fragmentShader = load_shader(GL_FRAGMENT_SHADER, fragment_source);
236  GLuint program = GL_CHECK(glCreateProgram());
237 
238  if (program != 0)
239  {
240  GL_CHECK(glAttachShader(program, vertexShader));
241  GL_CHECK(glAttachShader(program, fragmentShader));
242  GL_CHECK(glLinkProgram(program));
243 
244  GLint linkStatus = GL_FALSE;
245 
246  GL_CHECK(glGetProgramiv(program, GL_LINK_STATUS, &linkStatus));
247 
248  if (linkStatus != GL_TRUE)
249  {
250  GLint buf_length = 0;
251 
252  GL_CHECK(glGetProgramiv(program, GL_INFO_LOG_LENGTH, &buf_length));
253 
254  if (buf_length > 0)
255  {
256  char* log_buffer = NULL;
257 
258  MALLOC_CHECK(char*, log_buffer, buf_length);
259  GL_CHECK(glGetProgramInfoLog(program, buf_length, NULL, log_buffer));
260  LOGE("Could not link program:\n%s\n", log_buffer);
261  FREE_CHECK(log_buffer);
262  }
263 
264  GL_CHECK(glDeleteProgram(program));
265  program = 0;
266 
267  exit(EXIT_FAILURE);
268  }
269  }
270  else
271  {
272  LOGE("Error creating program object.");
273  exit(EXIT_FAILURE);
274  }
275 
276  return program;
277 }
278 
285 void update_texture_bindings(bool force_switch_texture)
286 {
287  if (timer.getTime() >= ASTC_TEXTURE_SWITCH_INTERVAL || force_switch_texture)
288  {
289  /* If the current texture set is to be changed, reset timer to start counting time again. */
290  timer.reset();
291 
292  /* Clear current text. */
294 
295  if (!force_switch_texture)
296  {
298  {
300  }
301  else
302  {
304  }
305  }
306 
307  /* Change displayed text. */
311  255, /* Red channel. */
312  255, /* Green channel. */
313  0, /* Blue channel. */
314  255); /* Alpha channel. */
315  }
316 
317  /* Update texture units with new bindings. */
318  GL_CHECK(glActiveTexture(GL_TEXTURE0));
319  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].cloud_and_gloss_texture_id));
320  GL_CHECK(glActiveTexture(GL_TEXTURE1));
321  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].earth_color_texture_id));
322  GL_CHECK(glActiveTexture(GL_TEXTURE2));
323  GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture_ids[current_texture_set_id].earth_night_texture_id));
324 }
325 
333 GLuint load_texture(const char* file_name, GLenum decode_format, GLenum compressed_data_internal_format)
334 {
335  unsigned char* compressed_data = NULL;
336  unsigned char* input_data = NULL;
337 
338  long file_size = 0;
339  unsigned int n_bytes_to_read = 0;
340  size_t result = 0;
341  GLuint to_id = 0;
342 
343  /* Number of blocks in the x, y and z direction. */
344  int xblocks = 0;
345  int yblocks = 0;
346  int zblocks = 0;
347 
348  /* Number of bytes for each dimension. */
349  int xsize = 0;
350  int ysize = 0;
351  int zsize = 0;
352 
353  FILE* compressed_data_file = fopen(file_name, "rb");
354 
355  if (compressed_data_file == NULL)
356  {
357  LOGE("Could not open a file.\n");
358  exit(EXIT_FAILURE);
359  }
360 
361  LOGI("Loading texture [%s]\n", file_name);
362 
363  /* Obtain file size. */
364  fseek(compressed_data_file, 0, SEEK_END);
365  file_size = ftell(compressed_data_file);
366  rewind(compressed_data_file);
367 
368  /* Allocate memory to contain the whole file. */
369  MALLOC_CHECK(unsigned char*, input_data, sizeof(unsigned char) * file_size);
370 
371  /* Copy the file into the buffer. */
372  result = fread(input_data, 1, file_size, compressed_data_file);
373 
374  if (result != file_size)
375  {
376  LOGE("Reading error [%s] ... FILE: %s LINE: %i\n", file_name, __FILE__, __LINE__);
377  exit(EXIT_FAILURE);
378  }
379 
380  /* Traverse the file structure. */
381  astc_header* astc_data_ptr = (astc_header*) input_data;
382 
383  /* Merge x,y,z-sizes from 3 chars into one integer value. */
384  xsize = astc_data_ptr->xsize[0] + (astc_data_ptr->xsize[1] << 8) + (astc_data_ptr->xsize[2] << 16);
385  ysize = astc_data_ptr->ysize[0] + (astc_data_ptr->ysize[1] << 8) + (astc_data_ptr->ysize[2] << 16);
386  zsize = astc_data_ptr->zsize[0] + (astc_data_ptr->zsize[1] << 8) + (astc_data_ptr->zsize[2] << 16);
387 
388  /* Compute number of blocks in each direction. */
389  xblocks = (xsize + astc_data_ptr->blockdim_x - 1) / astc_data_ptr->blockdim_x;
390  yblocks = (ysize + astc_data_ptr->blockdim_y - 1) / astc_data_ptr->blockdim_y;
391  zblocks = (zsize + astc_data_ptr->blockdim_z - 1) / astc_data_ptr->blockdim_z;
392 
393  /* Each block is encoded on 16 bytes, so calculate total compressed image data size. */
394  n_bytes_to_read = xblocks * yblocks * zblocks << 4;
395 
396  /* We now have file contents in memory so let's fill a texture object with the data. */
397  GL_CHECK(glGenTextures(1, &to_id));
398  GL_CHECK(glBindTexture(GL_TEXTURE_2D, to_id));
399 
400  /* Upload texture data to ES. */
401  GL_CHECK(glCompressedTexImage2D(GL_TEXTURE_2D,
402  0,
403  compressed_data_internal_format,
404  xsize,
405  ysize,
406  0,
407  n_bytes_to_read,
408  (const GLvoid*)&astc_data_ptr[1]));
409 
410  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
411  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
412  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
413  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT));
414 
416  {
417  if ((decode_format == GL_RGB9_E5) && !astc_decode_mode_rgb9e5_supported)
418  {
419  /* Fallback to RGBA16F if RGB9_E5 decode mode is not supported */
420  decode_format = GL_RGBA16F;
421  }
422  GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ASTC_DECODE_PRECISION_EXT, decode_format));
423  }
424 
425  /* Unbind texture from target. */
426  GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
427 
428  /* Terminate file operations. */
429  fclose(compressed_data_file);
430  FREE_CHECK(input_data);
431 
432  return to_id;
433 }
434 
438 void load_textures(void)
439 {
440  /* Paths to texture images. */
441  string cloud_and_gloss_texture_file_path;
442  string earth_color_texture_file_path;
443  string earth_night_texture_file_path;
444 
445  for (int i = 0; i < n_texture_ids; i++)
446  {
447  cloud_and_gloss_texture_file_path = resource_directory + texture_sets_info[i].cloud_and_gloss_texture_file_path;
448  earth_color_texture_file_path = resource_directory + texture_sets_info[i].earth_color_texture_file_path;
449  earth_night_texture_file_path = resource_directory + texture_sets_info[i].earth_night_texture_file_path;
450 
455  }
456 
457  /* Configure texture set. */
459 }
460 
465 void setup_program(void)
466 {
467  /* Create program object and initialize it. */
469 
470  /* Get attribute locations of attributes vertex position,cd normal and texture coordinates. */
474 
475  /* Get uniform locations. */
481 
482  /* Activate program object. */
483  GL_CHECK(glUseProgram(program_id));
484 }
485 
490 {
491  const float sphere_radius = 1.0f;
492 
493  /* Number of pararells and meridians the sphere should consists of. */
494  const unsigned int n_sectors = 64;
495  const unsigned int n_rings = 64;
496 
497  /* New instance of sphere. */
498  solid_sphere = new SolidSphere(sphere_radius, n_rings, n_sectors);
499 
500  /* Obtain sizes of the several subbuffers. */
501  GLsizei sphere_vertices_size = 0;
502  GLsizei sphere_normals_size = 0;
503  GLsizei sphere_texcoords_size = 0;
504  GLsizei buffer_offset = 0;
505 
506  /* Load generated mesh data from SolidSphere object. */
507  float* sphere_vertices = solid_sphere->getSphereVertexData(&sphere_vertices_size);
508  float* sphere_normals = solid_sphere->getSphereNormalData(&sphere_normals_size);
509  float* sphere_texcoords = solid_sphere->getSphereTexcoords(&sphere_texcoords_size);
510 
511  /* Size of the entire buffer. */
512  GLsizei buffer_total_size = sphere_vertices_size + sphere_normals_size + sphere_texcoords_size;
513 
514  /* Create buffer object to hold all mesh data. */
515  GL_CHECK(glGenBuffers(1, &bo_id));
516  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, bo_id));
517  GL_CHECK(glBufferData(GL_ARRAY_BUFFER, buffer_total_size, NULL, GL_STATIC_DRAW));
518 
519  /* Upload subsets of mesh data to buffer object. */
520  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_vertices_size, sphere_vertices));
521 
522  buffer_offset += sphere_vertices_size;
523 
524  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_normals_size, sphere_normals));
525 
526  buffer_offset += sphere_normals_size;
527 
528  GL_CHECK(glBufferSubData(GL_ARRAY_BUFFER, buffer_offset, sphere_texcoords_size, sphere_texcoords));
529 
530  /* Release resources. */
531  FREE_CHECK(sphere_vertices);
532  FREE_CHECK(sphere_normals);
533  FREE_CHECK(sphere_texcoords);
534 
535  /* Configure vertex attribute arrays, so that position/normals/texture coordinate data is available to the vertex shader. */
536  GL_CHECK(glGenVertexArrays(1, &vao_id));
537  GL_CHECK(glBindVertexArray(vao_id));
538  GL_CHECK(glEnableVertexAttribArray(position_location));
539  GL_CHECK(glEnableVertexAttribArray(normal_location));
540  GL_CHECK(glEnableVertexAttribArray(texture_coords_location));
541 
542  buffer_offset = 0;
543 
544  /* Populate attribute for position. */
545  GL_CHECK(glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
546 
547  buffer_offset += sphere_vertices_size;
548 
549  /* Populate attribute for normals. */
550  GL_CHECK(glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
551 
552  buffer_offset += sphere_normals_size;
553 
554  /* Populate attribute for texture coordinates. */
555  GL_CHECK(glVertexAttribPointer(texture_coords_location, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) buffer_offset));
556 
557  /* Bind texture units to texture samplers. */
558  GL_CHECK(glUniform1i(cloud_texture_location, 0));
559  GL_CHECK(glUniform1i(daytime_texture_location, 1));
560  GL_CHECK(glUniform1i(nighttime_texture_location, 2));
561 
562  /* Load generated indices from SolidSphere object. */
564 }
565 
567 {
570 
572 
574 
575  /* Make sure the required ASTC extension is present. */
576  const GLubyte* extensions = GL_CHECK(glGetString(GL_EXTENSIONS));
577 
578  if (strstr((const char*) extensions, "GL_KHR_texture_compression_astc_ldr") == NULL)
579  {
580  LOGI("OpenGL ES 3.0 implementation does not support GL_KHR_texture_compression_astc_ldr extension.\n");
581  exit(EXIT_SUCCESS);
582  }
583 
584  if (strstr((const char*) extensions, "GL_EXT_texture_compression_astc_decode_mode") == NULL)
585  {
587  LOGI("OpenGL ES 3.0 implementation does not support GL_EXT_texture_compression_astc_decode_mode extension.\n");
588  }
589  else
591 
592  if (strstr((const char*) extensions, "GL_EXT_texture_compression_astc_decode_mode_rgb9e5") == NULL)
593  {
595  LOGI("OpenGL ES 3.0 implementation does not support GL_EXT_texture_compression_astc_decode_mode_rgb9e5 extension.\n");
596  }
597  else
599 
600  /* Enable culling and depth testing. */
601  GL_CHECK(glEnable(GL_CULL_FACE));
602  GL_CHECK(glEnable(GL_DEPTH_TEST));
603 
604  /* Enable blending and specify pixel arihmetic.
605  Transparency is implemented using blend function with primitives sorted from the farthest to the nearest. */
606  GL_CHECK(glEnable(GL_BLEND));
607  GL_CHECK(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
608 
610 
611  /* Create texture objects and fill them with texture data. */
612  load_textures();
613 
614  /* Set up shader objects.
615  Rerieve uniform and attribute locations. */
616  setup_program();
617 
618  /* Prepare buffer objects that will hold mesh data. */
620 
621  /* Start counting time. */
622  timer.reset();
623  fps_timer.reset();
624 }
625 
629 void render_frame(void)
630 {
631  /* Prepare rotation matrices and use them to set up model+view matrix. */
636  model_view_matrix = rotate_matrix * model_view_matrix;
637 
638  /* Pull the camera back from the cube - move back and forth as time goes by.
639  To achieve it scale with time translational part of model matrix for z-direction. */
640  model_view_matrix[14] -= 2.5f + sinf(current_time / 5.0f) * 0.5f;
641 
642  /* Upload view matrix. */
643  GL_CHECK(glUniformMatrix4fv(mv_location, 1, GL_FALSE, &model_view_matrix[0]));
644 
645  /* Bring model from camera space into Normalized Device Coordinates (NDC). */
647 
648  /* Upload complete Model Space->World Space->Camera(Eye) Space->NDC transformation by updating relevant MVP uniform.
649  Vertex shader will then use this matrix to transform all input vertices from model space to screen space. */
650  GL_CHECK(glUniformMatrix4fv(mvp_location, 1, GL_FALSE, &mvp_matrix[0]));
651 
652  /* Get the current time. */
654 
655  /* Obtain angular rates around X, Y, Z axes. */
659 
660  /* Clear buffers. */
661  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
662 
663  /* Draw the sphere from array data. */
664  GL_CHECK(glDrawElements(GL_TRIANGLES, sphere_indices_size, GL_UNSIGNED_SHORT, sphere_indices));
665 
666  /* Also don't forget to show name of the compression algorithm in action. */
667  text_displayer->draw();
668 
669  /* Switch the texture set if more than 5 seconds has passed since the last switch event. */
671 }
672 
677 {
678  /* Delete all used textures. */
679  for (int i = 0; i < n_texture_ids; i++)
680  {
681  GL_CHECK(glDeleteTextures(1, &texture_ids[i].cloud_and_gloss_texture_id));
682  GL_CHECK(glDeleteTextures(1, &texture_ids[i].earth_color_texture_id));
683  GL_CHECK(glDeleteTextures(1, &texture_ids[i].earth_night_texture_id));
684  }
685 
686  /* Cleanup shaders. */
687  GL_CHECK(glUseProgram(0));
688  GL_CHECK(glDeleteShader(vert_shader_id));
689  GL_CHECK(glDeleteShader(frag_shader_id));
690  GL_CHECK(glDeleteProgram(program_id));
691 
692  /* Delete vertex array object. */
693  GL_CHECK(glDisableVertexAttribArray(position_location));
694  GL_CHECK(glDisableVertexAttribArray(normal_location));
695  GL_CHECK(glDisableVertexAttribArray(texture_coords_location));
696  GL_CHECK(glDeleteVertexArrays(1, &vao_id));
697 
698  /* Free buffer object memory. */
699  GL_CHECK(glDeleteBuffers(1, &bo_id));
700 
701  /* Free indices buffer. */
703 
704  /* Release memory for Text and SolidSphere instances. */
705  delete text_displayer;
706  delete solid_sphere;
707 }
708 
709 extern "C"
710 {
711  JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextureslowprecision_NativeLibrary_init(JNIEnv*, jobject, jint width, jint height);
714 };
715 
717 {
718  setup_graphics(width, height);
719 }
720 
722 {
723  render_frame();
724 }
725 
727 {
729 }
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
static bool astc_decode_mode_rgb9e5_supported
#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
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextureslowprecision_NativeLibrary_step(JNIEnv *, jobject)
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 GLenum earth_color_decode_format
Definition: AstcTextures.h:220
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
JNIEXPORT void JNICALL Java_com_arm_malideveloper_openglessdk_astctextureslowprecision_NativeLibrary_init(JNIEnv *, jobject, jint width, jint height)
#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
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_astctextureslowprecision_NativeLibrary_uninit(JNIEnv *, jobject)
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR
Definition: AstcTextures.h:81
#define X_ROTATION_SPEED
Definition: AstcTextures.h:104
const GLenum earth_night_decode_format
Definition: AstcTextures.h:223
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
const GLenum cloud_and_gloss_decode_format
Definition: AstcTextures.h:217
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
static bool astc_decode_mode_supported
#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT
Definition: AstcTextures.h:101