OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
tessellation.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 #include "tessellation.h"
22 #define QUAD_RES_X 16
23 #define QUAD_RES_Y 16
24 #define SIDES_IN_A_CUBE 6
25 #define NUM_PATCHES (QUAD_RES_X * QUAD_RES_Y * SIDES_IN_A_CUBE)
26 #define VERTICES_PER_PATCH 4
27 
28 struct Vertex
29 {
30  float x, y, z;
31 };
32 
34 {
35  Top,
41 };
42 
44 {
45  #define CUBE_SIDE_BIAS 0.0f
46  int i = 0;
47  for (int y = 0; y < QUAD_RES_Y; y++)
48  {
49  for (int x = 0; x < QUAD_RES_X; x++)
50  {
51  float x0 = -1.0f - CUBE_SIDE_BIAS + (2.0f + 2.0f * CUBE_SIDE_BIAS) * ((float)x / (float)QUAD_RES_X);
52  float x1 = -1.0f - CUBE_SIDE_BIAS + (2.0f + 2.0f * CUBE_SIDE_BIAS) * ((float)(x + 1) / (float)QUAD_RES_X);
53  float y0 = -1.0f - CUBE_SIDE_BIAS + (2.0f + 2.0f * CUBE_SIDE_BIAS) * ((float)y / (float)QUAD_RES_Y);
54  float y1 = -1.0f - CUBE_SIDE_BIAS + (2.0f + 2.0f * CUBE_SIDE_BIAS) * ((float)(y + 1) / (float)QUAD_RES_Y);
55  Vertex v0 = { };
56  Vertex v1 = { };
57  Vertex v2 = { };
58  Vertex v3 = { };
59  switch (side)
60  {
61  case Top:
62  v0.x = x0; v0.y = 1.0f; v0.z = y0;
63  v1.x = x0; v1.y = 1.0f; v1.z = y1;
64  v2.x = x1; v2.y = 1.0f; v2.z = y1;
65  v3.x = x1; v3.y = 1.0f; v3.z = y0;
66  break;
67  case Bottom:
68  v0.x = x0; v0.y = -1.0f; v0.z = y0;
69  v1.x = x1; v1.y = -1.0f; v1.z = y0;
70  v2.x = x1; v2.y = -1.0f; v2.z = y1;
71  v3.x = x0; v3.y = -1.0f; v3.z = y1;
72  break;
73  case Left:
74  v0.x = -1.0f; v0.y = x0; v0.z = y0;
75  v1.x = -1.0f; v1.y = x0; v1.z = y1;
76  v2.x = -1.0f; v2.y = x1; v2.z = y1;
77  v3.x = -1.0f; v3.y = x1; v3.z = y0;
78  break;
79  case Right:
80  v0.x = +1.0f; v0.y = x0; v0.z = y0;
81  v1.x = +1.0f; v1.y = x1; v1.z = y0;
82  v2.x = +1.0f; v2.y = x1; v2.z = y1;
83  v3.x = +1.0f; v3.y = x0; v3.z = y1;
84  break;
85  case Front:
86  v0.x = x0; v0.y = y0; v0.z = +1.0f;
87  v1.x = x1; v1.y = y0; v1.z = +1.0f;
88  v2.x = x1; v2.y = y1; v2.z = +1.0f;
89  v3.x = x0; v3.y = y1; v3.z = +1.0f;
90  break;
91  case Back:
92  v0.x = x0; v0.y = y0; v0.z = -1.0f;
93  v1.x = x0; v1.y = y1; v1.z = -1.0f;
94  v2.x = x1; v2.y = y1; v2.z = -1.0f;
95  v3.x = x1; v3.y = y0; v3.z = -1.0f;
96  break;
97  }
98  v[i++] = v0;
99  v[i++] = v1;
100  v[i++] = v2;
101  v[i++] = v3;
102  }
103  }
104  return i;
105 }
106 
108 {
110  Vertex *vptr = &v[0];
111  vptr += fill_cube_side(vptr, Top);
112  vptr += fill_cube_side(vptr, Bottom);
113  vptr += fill_cube_side(vptr, Left);
114  vptr += fill_cube_side(vptr, Right);
115  vptr += fill_cube_side(vptr, Front);
116  vptr += fill_cube_side(vptr, Back);
117  GLuint result = 0;
118  glGenBuffers(1, &result);
119  glBindBuffer(GL_ARRAY_BUFFER, result);
120  glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
121  return result;
122 }
123 
125 {
126  float v[] = {
127  -1.0f, -1.0f,
128  +1.0f, -1.0f,
129  +1.0f, +1.0f,
130  +1.0f, +1.0f,
131  -1.0f, +1.0f,
132  -1.0f, -1.0f
133  };
134  GLuint result = 0;
135  glGenBuffers(1, &result);
136  glBindBuffer(GL_ARRAY_BUFFER, result);
137  glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
138  return result;
139 }
140 
142 {
143  glGenVertexArrays(1, &app->vao);
144  glBindVertexArray(app->vao);
145  glViewport(0, 0, app->window_width, app->window_height);
146 
147  app->vbo_cube = make_cube_mesh();
148  app->vbo_quad = make_quad_mesh();
149 
150  get_attrib_location (mapping, position);
151  get_uniform_location(mapping, height_scale);
152  get_uniform_location(mapping, use_mip);
153  get_uniform_location(mapping, max_lod_coverage);
154  get_uniform_location(mapping, screen_size);
155  get_uniform_location(mapping, diffusemap);
156  get_uniform_location(mapping, heightmap);
157  get_uniform_location(mapping, model);
158  get_uniform_location(mapping, view);
160 
161  get_attrib_location (backdrop, position);
162  get_uniform_location(backdrop, sun_dir);
163  get_uniform_location(backdrop, screen_size);
164  get_uniform_location(backdrop, inv_tan_fov);
165  get_uniform_location(backdrop, view);
166 
167  app->current_scene = 0;
168 }
169 
170 float animate_model_scale(float t)
171 {
172  int n = (int)(t / 20.0f);
173  float modt = t - n * 20.0f;
174  if (modt >= 19.5f && modt <= 20.0f)
175  {
176  return cos((modt - 19.5f) * 3.1415926f);
177  }
178  else if (modt <= 0.5f)
179  {
180  return sin(modt * 3.1415926f);
181  }
182  return 1.0f;
183 }
184 
186 {
187  float rx = -0.3f + 0.25f * sin(t * 0.1f);
188  float ry = t * 0.4f;
189  float zoom = 0.5f + 0.5f * sin(t * 0.25f);
190  float z = -5.0f + 3.0f * sin(t * 0.25f);
191  return translate(0.6f, -0.4f, z) * rotateX(rx) * rotateY(0.1f * t);
192 }
193 
195 {
196  app->current_scene = (int)(app->elapsed_time / 20.0f) % NUM_SCENES;
197  Scene scene = app->scenes[app->current_scene];
198 
200 
201  float aspect_ratio = app->window_width / (float)app->window_height;
202  mat4 mat_projection = perspective(scene.fov, aspect_ratio, scene.z_near, scene.z_far);
203  mat4 mat_cube_model = rotateX(PI / 2.0f) * scale(model_scale);
205 
206  glEnable(GL_CULL_FACE);
207  glFrontFace(GL_CCW);
208  glCullFace(GL_BACK);
209 
210  glEnable(GL_DEPTH_TEST);
211  glDepthFunc(GL_LEQUAL);
212 
213  glEnable(GL_DEPTH_TEST);
214  glDepthMask(GL_TRUE);
215  glDepthRangef(0.0, 1.0);
216 
217  glClearDepthf(1.0f);
218  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
219  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
220 
221  glEnable(GL_BLEND);
222  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
223  glBlendEquation(GL_FUNC_ADD);
224 
226  // Draw backdrop
227  glDepthMask(GL_FALSE);
228  glUseProgram(app->program_backdrop);
229  glBindBuffer(GL_ARRAY_BUFFER, app->vbo_quad);
230  attribfv(backdrop, position, 2, 0);
231  uniform3fv(backdrop, sun_dir, scene.sun_dir);
232  uniform2f(backdrop, screen_size, app->window_width, app->window_height);
233  uniform1f(backdrop, inv_tan_fov, 1.0f / (scene.fov / 2.0f));
234  uniformm4(backdrop, view, mat_view);
235  glDrawArrays(GL_TRIANGLES, 0, 6);
236  glDepthMask(GL_TRUE);
237 
239  // Draw tessellated sphere
240  glUseProgram(app->program_mapping);
241  glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube);
242  attribfv(mapping, position, 3, 0);
243 
244  glActiveTexture(GL_TEXTURE0);
245  glBindTexture(GL_TEXTURE_CUBE_MAP, scene.heightmap);
246  uniform1i(mapping, heightmap, 0);
247 
248  glActiveTexture(GL_TEXTURE1);
249  glBindTexture(GL_TEXTURE_CUBE_MAP, scene.diffusemap);
250  uniform1i(mapping, diffusemap, 1);
251 
252  uniform1f(mapping, height_scale, scene.height_scale);
253  uniform1f(mapping, use_mip, scene.use_mip ? 1.0f : 0.0f);
254  uniform1f(mapping, max_lod_coverage, scene.max_lod_coverage);
255  uniform2f(mapping, screen_size, app->window_width, app->window_height);
256  uniformm4(mapping, model, mat_cube_model);
257  uniformm4(mapping, view, mat_view);
260  glDrawArrays(GL_PATCHES, 0, NUM_PATCHES * VERTICES_PER_PATCH);
261 }
GLuint diffusemap
Definition: tessellation.h:30
float y
const GLfloat * v
Definition: gl2ext.h:2231
float height_scale
Definition: tessellation.h:34
#define get_attrib_location(prog, name)
Definition: geometry.h:106
#define GL_PATCH_VERTICES
Definition: main.cpp:34
#define attribfv(prog, name, n, offset)
Definition: geometry.h:118
mat4 animate_camera(float t)
CubeSide
GLuint make_quad_mesh()
#define get_uniform_location(prog, name)
Definition: geometry.h:112
GLuint program_backdrop
Definition: geometry.h:65
GLint GLfloat GLfloat GLfloat v2
Definition: gl2ext.h:1492
mat4 mat_view
Definition: app.cpp:45
static float model_scale
Definition: app.cpp:73
precision highp int
Definition: hiz_cull.cs:38
int window_width
Definition: geometry.h:35
#define QUAD_RES_Y
#define glPatchParameteri
Definition: main.cpp:37
#define QUAD_RES_X
Matrix projection
GLint GLfloat GLfloat GLfloat GLfloat v3
Definition: gl2ext.h:1496
#define CUBE_SIDE_BIAS
static mat4 rotateY(float rad)
Definition: matrix.h:320
vec3 sun_dir
Definition: tessellation.h:31
#define PI
Definition: matrix.h:24
int fill_cube_side(Vertex *v, CubeSide side)
mat4 mat_projection
Definition: app.cpp:45
#define NUM_PATCHES
GLuint heightmap
Definition: tessellation.h:29
float z_near
Definition: tessellation.h:36
int current_scene
Definition: tessellation.h:46
float max_lod_coverage
Definition: tessellation.h:33
static float zoom
Definition: app.cpp:82
Scene * scene
Definition: occlusion.cpp:55
float elapsed_time
Definition: geometry.h:38
float z
Definition: scene.hpp:29
int window_height
Definition: geometry.h:36
GLuint vao
Definition: geometry.h:80
ClipmapApplication * app
Definition: main.cpp:47
#define GL_PATCHES
Definition: main.cpp:33
Matrix perspective
Definition: EGLPreserve.cpp:81
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint make_cube_mesh()
#define uniform3fv(prog, name, value)
Definition: geometry.h:130
float x
static mat4 rotateX(float rad)
Definition: matrix.h:312
Matrix scale
Definition: RotoZoom.cpp:64
float fov
Definition: tessellation.h:35
Definition: mesh.hpp:28
#define VERTICES_PER_PATCH
bool use_mip
Definition: tessellation.h:32
#define NUM_SCENES
Definition: tessellation.h:26
#define uniformm4(prog, name, value)
Definition: geometry.h:132
GLuint vbo_cube
Definition: tessellation.h:72
float animate_model_scale(float t)
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
GLuint vbo_quad
Definition: geometry.h:84
float z_far
Definition: tessellation.h:37
Definition: matrix.h:104
#define uniform1i(prog, name, value)
Definition: geometry.h:131
GLint GLfloat v0
Definition: gl2ext.h:1484
Definition: geometry.h:33
GLuint program_mapping
Definition: tessellation.h:50
precision highp float
Definition: hiz_cull.cs:37
#define uniform1f(prog, name, value)
Definition: geometry.h:128
void app_update_and_render(App *app)
static float aspect_ratio
Definition: app.cpp:92
GLint GLfloat GLfloat v1
Definition: gl2ext.h:1488
void app_initialize(App *app)
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
GLint y
Definition: gl2ext.h:179
static mat4 translate(float x, float y, float z)
Definition: matrix.h:336
Scene scenes[5]
Definition: tessellation.h:47
#define uniform2f(prog, name, x, y)
Definition: geometry.h:129
GLfloat n
Definition: gl2ext.h:2707