OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
loader.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2015-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 // This file holds functions for loading textures from images,
22 // as well as loading and compiling shader programs from file.
23 // You must define HEIGHTMAP_PATH, DIFFUSEMAP_PATH and
24 // SHADER_PATH that take in asset names and return the
25 // correct full asset path.
26 
27 #define STB_IMAGE_IMPLEMENTATION
28 #include "stb_image.h"
29 
30 GLuint load_packed_cubemap(const char *filename)
31 {
32  int width, height, channels;
33  unsigned char *pixels = stbi_load(filename, &width, &height, &channels, 4);
34  if (!pixels)
35  {
36  LOGE("Failed to load texture %s\n", filename);
37  exit(1);
38  }
39 
40  if (width != height)
41  {
42  LOGE("Cubemap dimensions must match %s\n", filename);
43  exit(1);
44  }
45 
46  // The cubemap is layed out in the following format
47  // Each face has dimensions (width / 4) x (height / 4)
48  // . . . .
49  // . +Y . .
50  // -X +Z +X -Z
51  // . -Y . .
52 
53  int s = width / 4;
54  GLuint texture = 0;
55  glActiveTexture(GL_TEXTURE0);
56  glGenTextures(1, &texture);
57  glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
58 
59  glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
60 
61  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*0);
62  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*2);
63  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
64 
65  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*2);
66  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*2);
67  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
68 
69  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*1);
70  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*3);
71  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
72 
73  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*1);
74  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*1);
75  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
76 
77  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*3);
78  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*2);
79  glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
80 
81  glPixelStorei(GL_UNPACK_SKIP_PIXELS, s*1);
82  glPixelStorei(GL_UNPACK_SKIP_ROWS, s*2);
83  glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, s, s, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
84 
85  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
86  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
87  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
88  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
89  glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
90  glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
91 
92  stbi_image_free(pixels);
93  return texture;
94 }
95 
96 char *read_file(const char *filename)
97 {
98  FILE *file = fopen(filename, "rb");
99  if (!file)
100  {
101  LOGE("Failed to open file %s\n", filename);
102  exit (1);
103  }
104  fseek(file, 0, SEEK_END);
105  long length = ftell(file);
106  fseek(file, 0, SEEK_SET);
107  char *data = (char *)calloc(length + 1, sizeof(char));
108  if (!data)
109  {
110  LOGE("Failed to allocate memory for file data %s\n", filename);
111  exit(1);
112  }
113  size_t read = fread(data, sizeof(char), length, file);
114  if (read != length)
115  {
116  LOGE("Failed to read whole file %s\n", filename);
117  exit(1);
118  }
119  data[length] = '\0';
120  fclose(file);
121  return data;
122 }
123 
125 {
126  GLuint result = glCreateShader(type);
127  glShaderSource(result, 1, (const GLchar**)&source, NULL);
128  glCompileShader(result);
129  GLint status;
130  glGetShaderiv(result, GL_COMPILE_STATUS, &status);
131  if (status == GL_FALSE) {
132  GLint length;
133  glGetShaderiv(result, GL_INFO_LOG_LENGTH, &length);
134  GLchar *info = new GLchar[length];
135  glGetShaderInfoLog(result, length, NULL, info);
136  LOGE("[COMPILE] %s\n", info);
137  delete[] info;
138  exit(1);
139  }
140  return result;
141 }
142 
144 {
145  GLuint program = glCreateProgram();
146  for (int i = 0; i < count; ++i)
147  glAttachShader(program, shaders[i]);
148 
149  glLinkProgram(program);
150 
151  for (int i = 0; i < count; ++i)
152  glDetachShader(program, shaders[i]);
153 
154  GLint status;
155  glGetProgramiv(program, GL_LINK_STATUS, &status);
156  if (status == GL_FALSE) {
157  GLint length;
158  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
159  GLchar *info = new GLchar[length];
160  glGetProgramInfoLog(program, length, NULL, info);
161  LOGE("[LINK] %s\n", info);
162  delete[] info;
163  exit(1);
164  }
165  return program;
166 }
167 
169 {
170  char *vs_src = read_file(SHADER_PATH("shader.vs"));
171  char *fs_src = read_file(SHADER_PATH("shader.fs"));
172  char *tc_src = read_file(SHADER_PATH("shader.tcs"));
173  char *te_src = read_file(SHADER_PATH("shader.tes"));
174 
175  GLuint shaders[4];
176  shaders[0] = compile_shader(vs_src, GL_VERTEX_SHADER);
177  shaders[1] = compile_shader(fs_src, GL_FRAGMENT_SHADER);
178  shaders[2] = compile_shader(tc_src, GL_TESS_CONTROL_SHADER);
179  shaders[3] = compile_shader(te_src, GL_TESS_EVALUATION_SHADER);
180  app->program_mapping = link_program(shaders, 4);
181 
182  free(vs_src);
183  free(fs_src);
184  free(tc_src);
185  free(te_src);
186 }
187 
189 {
190  char *vs_src = read_file(SHADER_PATH("backdrop.vs"));
191  char *fs_src = read_file(SHADER_PATH("backdrop.fs"));
192 
193  GLuint shaders[2];
194  shaders[0] = compile_shader(vs_src, GL_VERTEX_SHADER);
195  shaders[1] = compile_shader(fs_src, GL_FRAGMENT_SHADER);
196  app->program_backdrop = link_program(shaders, 2);
197 
198  free(vs_src);
199  free(fs_src);
200 }
201 
203 {
204  load_mapping_shader(app);
206 
207  app->scenes[0].heightmap = load_packed_cubemap(HEIGHTMAP_PATH("magicmoon"));
208  app->scenes[0].diffusemap = load_packed_cubemap(DIFFUSEMAP_PATH("magicmoon"));
209  app->scenes[0].sun_dir = normalize(vec3(1.0f, 1.0f, -0.5f));
210  app->scenes[0].use_mip = true;
211  app->scenes[0].max_lod_coverage = 150.0f;
212  app->scenes[0].height_scale = 0.2f;
213  app->scenes[0].fov = PI / 4.0f;
214  app->scenes[0].z_near = 0.1f;
215  app->scenes[0].z_far = 16.0f;
216 
217  app->scenes[1].heightmap = load_packed_cubemap(HEIGHTMAP_PATH("swirly"));
219  app->scenes[1].sun_dir = normalize(vec3(0.5f, 0.2f, -0.2f));
220  app->scenes[1].use_mip = true;
221  app->scenes[1].max_lod_coverage = 150.0f;
222  app->scenes[1].height_scale = 0.2f;
223  app->scenes[1].fov = PI / 4.0f;
224  app->scenes[1].z_near = 0.1f;
225  app->scenes[1].z_far = 16.0f;
226 
227  app->scenes[2].heightmap = load_packed_cubemap(HEIGHTMAP_PATH("voronoi_env"));
228  app->scenes[2].diffusemap = load_packed_cubemap(DIFFUSEMAP_PATH("voronoi_env"));
229  app->scenes[2].sun_dir = normalize(vec3(0.8f, 0.2f, -0.2f));
230  app->scenes[2].use_mip = true;
231  app->scenes[2].max_lod_coverage = 350.0f;
232  app->scenes[2].height_scale = 0.2f;
233  app->scenes[2].fov = PI / 4.0f;
234  app->scenes[2].z_near = 0.1f;
235  app->scenes[2].z_far = 16.0f;
236 
237  app->scenes[3].heightmap = load_packed_cubemap(HEIGHTMAP_PATH("voronoi_sharp"));
238  app->scenes[3].diffusemap = load_packed_cubemap(DIFFUSEMAP_PATH("voronoi_sharp"));
239  app->scenes[3].sun_dir = normalize(vec3(0.3f, 1.0f, 0.3f));
240  app->scenes[3].use_mip = true;
241  app->scenes[3].max_lod_coverage = 250.0f;
242  app->scenes[3].height_scale = 0.2f;
243  app->scenes[3].fov = PI / 4.0f;
244  app->scenes[3].z_near = 0.1f;
245  app->scenes[3].z_far = 16.0f;
246 
249  app->scenes[4].sun_dir = normalize(vec3(0.8f, 0.2f, -0.2f));
250  app->scenes[4].use_mip = true;
251  app->scenes[4].max_lod_coverage = 115.0f;
252  app->scenes[4].height_scale = 0.2f;
253  app->scenes[4].fov = PI / 4.0f;
254  app->scenes[4].z_near = 0.1f;
255  app->scenes[4].z_far = 16.0f;
256 }
void load_assets(App *app)
Definition: loader.cpp:175
GLuint diffusemap
Definition: tessellation.h:30
float height_scale
Definition: tessellation.h:34
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const void * pixels
Definition: gl2ext.h:572
#define DIFFUSEMAP_PATH(name)
Definition: main.cpp:50
#define SHADER_PATH(name)
Definition: main.cpp:40
char * read_file(const char *filename)
Definition: loader.cpp:48
Definition: matrix.h:51
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
GLuint program_backdrop
Definition: geometry.h:65
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
Definition: gl2ext.h:179
GLenum GLenum GLsizei count
Definition: gl2ext.h:133
vec3 sun_dir
Definition: tessellation.h:31
#define PI
Definition: matrix.h:24
void load_backdrop_shader(App *app)
Definition: loader.cpp:120
GLuint heightmap
Definition: tessellation.h:29
float z_near
Definition: tessellation.h:36
float max_lod_coverage
Definition: tessellation.h:33
static vec3 normalize(const vec3 &v)
Definition: matrix.h:154
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:877
#define GL_TESS_EVALUATION_SHADER
Definition: main.cpp:36
ClipmapApplication * app
Definition: main.cpp:47
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint compile_shader(const char *source, GLenum type)
Definition: loader.cpp:76
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp)
GLuint link_program(GLuint *shaders, int count)
Definition: loader.cpp:95
GLuint load_packed_cubemap(const char *filename)
Definition: loader.cpp:30
float fov
Definition: tessellation.h:35
bool use_mip
Definition: tessellation.h:32
GLenum GLuint texture
Definition: gl2ext.h:385
GLenum type
Definition: gl2ext.h:133
STBIDEF void stbi_image_free(void *retval_from_stbi_load)
GLenum GLuint GLenum GLsizei length
Definition: gl2ext.h:134
float z_far
Definition: tessellation.h:37
#define GL_TESS_CONTROL_SHADER
Definition: main.cpp:35
#define HEIGHTMAP_PATH(name)
Definition: main.cpp:49
Definition: geometry.h:33
GLuint program_mapping
Definition: tessellation.h:50
#define LOGE(...)
Definition: AstcTextures.h:30
GLint GLsizei width
Definition: gl2ext.h:179
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
void load_mapping_shader(App *app)
Definition: loader.cpp:168
GLuint program
Definition: gl2ext.h:1475
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
Scene scenes[5]
Definition: tessellation.h:47