OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
geometry.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 "geometry.h"
22 #include <vector>
23 
24 // The size of one grid side length
25 #define N 64
26 
28 {
29  // This should be one more than the dimensions of
30  // the centroid texture, since each centroid should
31  // have two neighbor noise values.
32  int width = N + 1;
33  int height = N + 1;
34  int depth = N + 1;
35 
36  GLuint handle;
37  glGenTextures(1, &handle);
38  glBindTexture(GL_TEXTURE_3D, handle);
39  glTexStorage3D(GL_TEXTURE_3D, 1, GL_R32F, width, height, depth);
40  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
41  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
42  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
43  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
44  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
45  Volume result;
46  result.tex = handle;
47  result.x = width;
48  result.y = height;
49  result.z = depth;
50  return result;
51 }
52 
54 {
55  int width = N;
56  int height = N;
57  int depth = N;
58 
59  GLuint handle;
60  glGenTextures(1, &handle);
61  glBindTexture(GL_TEXTURE_3D, handle);
62  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
63  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
64  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
65  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
66  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
67  glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, width, height, depth);
68  Volume result;
69  result.tex = handle;
70  result.x = width;
71  result.y = height;
72  result.z = depth;
73  return result;
74 }
75 
77 {
78  float v[] = {
79  -1.0f, -1.0f,
80  +1.0f, -1.0f,
81  +1.0f, +1.0f,
82  +1.0f, +1.0f,
83  -1.0f, +1.0f,
84  -1.0f, -1.0f
85  };
86  GLuint result = 0;
87  glGenBuffers(1, &result);
88  glBindBuffer(GL_ARRAY_BUFFER, result);
89  glBufferData(GL_ARRAY_BUFFER, sizeof(v), v, GL_STATIC_DRAW);
90  return result;
91 }
92 
93 void make_points(GLuint *vbo, GLuint *ibo)
94 {
95  std::vector<int> v(N*N*N*3);
96  int *vptr = &v[0];
97  unsigned int i = 0;
98  std::vector<unsigned int> I(N*N*N);
99  for (int z = 0; z < N; z++)
100  for (int y = 0; y < N; y++)
101  for (int x = 0; x < N; x++)
102  {
103  vptr[0] = x;
104  vptr[1] = y;
105  vptr[2] = z;
106  vptr += 3;
107  I[i] = i;
108  i++;
109  }
110  glGenBuffers(1, vbo);
111  glBindBuffer(GL_ARRAY_BUFFER, *vbo);
112  glBufferData(GL_ARRAY_BUFFER, sizeof(v[0]) * v.size(), v.data(), GL_STATIC_DRAW);
113  glGenBuffers(1, ibo);
114  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *ibo);
115  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(I[0]) * I.size(), I.data(), GL_STATIC_DRAW);
116 }
117 
119 {
120  typedef struct {
121  GLuint count;
122  GLuint instanceCount;
123  GLuint firstIndex;
124  GLint baseVertex;
125  GLuint reservedMustBeZero;
126  } DrawElementsIndirectCommand;
127 
128  DrawElementsIndirectCommand cmd = {};
129  cmd.instanceCount = 1;
130  glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, app->indirect_buffer);
131  glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(cmd), &cmd, GL_STREAM_DRAW);
132 }
133 
135 {
136  int local_size_x = 4;
137  int local_size_y = 4;
138  int local_size_z = 4;
139 
140  // Since the surface volume texture has a resolution
141  // one higher than the centroid texture, we cannot divide
142  // it evenly to work groups of size larger than one. To
143  // accommodate this, we add one work group for the edge.
144  int work_groups_x = 1 + (app->tex_surface.x - 1) / local_size_x;
145  int work_groups_y = 1 + (app->tex_surface.y - 1) / local_size_y;
146  int work_groups_z = 1 + (app->tex_surface.z - 1) / local_size_z;
147 
148  glUseProgram(app->program_generate);
149  uniform1f(generate, time, app->elapsed_time);
150  uniform1i(generate, dimension, N);
151  uniform3fv(generate, sphere_pos, app->sphere_pos);
152  uniform1f(generate, sphere_radius, app->sphere_radius);
153  glBindImageTexture(0, app->tex_surface.tex, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R32F);
154  glDispatchCompute(work_groups_x, work_groups_y, work_groups_z);
155 
156  // Ensure that the surface texture is properly updated
157  // before it is sampled in the centroid shader (using imageLoad)
158  glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
159 }
160 
162 {
163  int local_size_x = 4;
164  int local_size_y = 4;
165  int local_size_z = 4;
166 
167  int work_groups_x = app->tex_centroid.x / local_size_x;
168  int work_groups_y = app->tex_centroid.y / local_size_y;
169  int work_groups_z = app->tex_centroid.z / local_size_z;
170 
172 
173  glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 2, app->indirect_buffer);
174  glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, app->index_buffer);
175 
176  glUseProgram(app->program_centroid);
177  uniform1f(centroid, voxel_mode, app->voxel_mode);
178  glBindImageTexture(0, app->tex_surface.tex, 0, GL_TRUE, 0, GL_READ_ONLY, GL_R32F);
179  glBindImageTexture(1, app->tex_centroid.tex, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8);
180  glDispatchCompute(work_groups_x, work_groups_y, work_groups_z);
181 
182  // Ensure that the centroid offsets are properly written
183  // before we attempt to read them in the geometry shader.
184  glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
185 
186  // Ensure that the indirect draw buffer and the index buffer
187  // is properly written before we attempt to use it for drawing.
188  glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
189  glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);
190 }
191 
193 {
194  // Raycast mouse point onto the floor
195  float u = -1.0f + 2.0f * app->pointer_x / app->window_width;
196  float v = +1.0f - 2.0f * app->pointer_y / app->window_height;
197  u *= (float)app->window_width / (float)app->window_height;
198 
199  // Compute the camera basis from the view-transformation matrix
200  mat4 R = transpose(mat_view);
201  vec3 up = normalize(R.y.xyz());
202  vec3 right = normalize(R.x.xyz());
203  vec3 forward = normalize(R.z.xyz());
204 
205  // Compute the ray origin and direction
206  vec4 camera_pos = -vec4(mat_view.w.xyz(), 0.0f);
207  vec3 ro = (R * camera_pos).xyz();
208  vec3 rd = normalize(-forward * (1.0f / tan(app->fov / 2.0f)) + right * u + up * v);
209 
210  // Raytrace floor
211  float t = -ro.y / rd.y;
212  vec3 target = ro + rd * t;
213 
214  // Animate sphere position and size
215  app->sphere_pos = target;
216  if (app->pointer_down && app->sphere_radius < 0.15f)
217  app->sphere_radius += 10.0f * app->frame_time * (0.15f - app->sphere_radius);
218  else if (!app->pointer_down && app->sphere_radius > 0.0f)
219  app->sphere_radius += 10.0f * app->frame_time * (0.0f - app->sphere_radius);
220 }
221 
222 // Make the camera bob from side to side as the user drags the cursor
224 {
225  float center_tz = -4.0f;
226  if (app->window_height > app->window_width)
227  center_tz = -6.0f;
228 
229  float center_rx = -0.50f;
230  float center_ry = -0.25f;
231 
232  float pan = -1.0f + 2.0f * app->pointer_x / app->window_width;
233  float target_ry = 0.1f * pan;
234  float target_rx = -0.1f * pan * pan;
235  float target_tz = 1.2f * pan * pan;
236  float translate_x = -0.5f * app->rotate_y;
237 
238  app->rotate_y += 2.5f * app->frame_time * (target_ry - app->rotate_y);
239  app->rotate_x += 1.2f * app->frame_time * (target_rx - app->rotate_x);
240  app->translate_z += 0.8f * app->frame_time * (target_tz - app->translate_z);
241  mat4 result = translate(translate_x, 0.0f, center_tz + app->translate_z) *
242  rotateX(center_rx + app->rotate_x) *
243  rotateY(center_ry + app->rotate_y);
244 
245  return result;
246 }
247 
249 {
250  glGenVertexArrays(1, &app->vao);
251  glBindVertexArray(app->vao);
252  glViewport(0, 0, app->window_width, app->window_height);
253 
256  app->vbo_quad = make_quad();
257  make_points(&app->vbo_points, &app->ibo_points);
258 
259  app->fov = PI / 7.0f;
260  app->z_near = 1.0f;
261  app->z_far = 15.0f;
262  app->pointer_x = 0.0f;
263  app->pointer_y = 0.0f;
264  app->voxel_mode = 0.0f;
265 
266  app->rotate_x = 0.0f;
267  app->rotate_y = 0.0f;
268  app->translate_z = 0.0f;
269  app->sphere_pos = vec3(0.0f, 0.0f, 0.0f);
270  app->sphere_radius = 0.0f;
271 
272  get_attrib_location (backdrop, position);
273 
274  get_attrib_location (geometry, texel);
275  get_uniform_location(geometry, inCentroid);
276  get_uniform_location(geometry, inSurface);
277  get_uniform_location(geometry, inMaterial);
278  get_uniform_location(geometry, view);
279  get_uniform_location(geometry, projection);
280 
282  get_uniform_location(generate, sphere_pos);
283  get_uniform_location(generate, dimension);
284  get_uniform_location(generate, time);
285 
286  get_uniform_location(centroid, voxel_mode);
287 
288  glGenBuffers(1, &app->indirect_buffer);
289  glGenBuffers(1, &app->index_buffer);
290  glBindBuffer(GL_SHADER_STORAGE_BUFFER, app->index_buffer);
291  glBufferData(GL_SHADER_STORAGE_BUFFER, N*N*N*sizeof(GLuint), 0, GL_STREAM_DRAW);
292 
293  update_surface(app);
294  update_centroid(app);
295 }
296 
298 {
299  update_surface(app);
300  update_centroid(app);
301 
302  float aspect_ratio = app->window_width / (float)app->window_height;
303  mat4 mat_projection = perspective(app->fov, aspect_ratio, app->z_near, app->z_far);
304  mat4 mat_view = animate_view(app);
305  update_sphere(app, mat_view);
306 
307  glEnable(GL_DEPTH_TEST);
308  glDepthFunc(GL_LEQUAL);
309  glDepthMask(GL_TRUE);
310  glDepthRangef(0.0, 1.0);
311 
312  glClearDepthf(1.0f);
313  glClearColor(0.16f, 0.16f, 0.16f, 1.0f);
314  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
315 
317  // Backdrop shader
318 
319  glDepthMask(GL_FALSE);
320  glUseProgram(app->program_backdrop);
321  glBindBuffer(GL_ARRAY_BUFFER, app->vbo_quad);
322  attribfv(backdrop, position, 2, 0);
323  glDrawArrays(GL_TRIANGLES, 0, 6);
324 
326  // Geometry shader
327 
328  glDepthMask(GL_TRUE);
329  glActiveTexture(GL_TEXTURE0);
330  glBindTexture(GL_TEXTURE_3D, app->tex_surface.tex);
331  glActiveTexture(GL_TEXTURE1);
332  glBindTexture(GL_TEXTURE_3D, app->tex_centroid.tex);
333  glActiveTexture(GL_TEXTURE2);
334  glBindTexture(GL_TEXTURE_2D, app->tex_material);
335 
336  glUseProgram(app->program_geometry);
337  uniform1i(geometry, inSurface, 0);
338  uniform1i(geometry, inCentroid, 1);
339  uniform1i(geometry, inMaterial, 2);
340  uniformm4(geometry, projection, mat_projection);
341  uniformm4(geometry, view, mat_view);
342 
343  glBindBuffer(GL_ARRAY_BUFFER, app->vbo_points);
344  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, app->index_buffer);
345  glBindBuffer(GL_DRAW_INDIRECT_BUFFER, app->indirect_buffer);
346  attribiv(geometry, texel, 3, 0);
347  glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0);
348 }
vec3 sphere_pos
Definition: geometry.h:51
const GLfloat * v
Definition: gl2ext.h:2231
int z
Definition: geometry.h:30
float sphere_radius
Definition: geometry.h:52
int y
Definition: geometry.h:30
bool pointer_down
Definition: geometry.h:46
float rotate_x
Definition: geometry.h:48
void app_update_and_render(App *app)
Definition: geometry.cpp:297
#define get_attrib_location(prog, name)
Definition: geometry.h:106
uniform float sphere_radius
Definition: generate.cs:28
GLuint program_geometry
Definition: geometry.h:56
void app_initialize(App *app)
Definition: geometry.cpp:248
GLuint index_buffer
Definition: geometry.h:89
#define attribfv(prog, name, n, offset)
Definition: geometry.h:118
vec3 xyz() const
Definition: matrix.h:101
Volume tex_surface
Definition: geometry.h:96
GLuint make_quad()
Definition: geometry.cpp:76
vec3 sphere_pos
Definition: app.cpp:56
Definition: matrix.h:51
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
#define get_uniform_location(prog, name)
Definition: geometry.h:112
GLuint program_backdrop
Definition: geometry.h:65
uniform int dimension
Definition: generate.cs:29
GLuint program_centroid
Definition: geometry.h:69
float rotate_y
Definition: geometry.h:49
vec4 y
Definition: matrix.h:106
Volume make_surface_volume()
Definition: geometry.cpp:27
float frame_time
Definition: geometry.h:37
mat4 mat_view
Definition: app.cpp:45
int window_width
Definition: geometry.h:35
Matrix projection
static mat4 rotateY(float rad)
Definition: matrix.h:320
Definition: matrix.h:75
GLenum GLenum GLsizei count
Definition: gl2ext.h:133
#define PI
Definition: matrix.h:24
GLuint ibo_points
Definition: geometry.h:83
int x
Definition: geometry.h:30
mat4 mat_projection
Definition: app.cpp:45
mat4 animate_view(App *app)
Definition: geometry.cpp:223
float translate_z
Definition: geometry.h:50
uniform float voxel_mode
Definition: centroid.cs:32
GLuint indirect_buffer
Definition: geometry.h:88
Volume make_centroid_volume()
Definition: geometry.cpp:53
float z_near
Definition: geometry.h:40
GLenum target
Definition: gl2ext.h:720
GLuint vbo_points
Definition: geometry.h:82
float elapsed_time
Definition: geometry.h:38
static vec3 normalize(const vec3 &v)
Definition: matrix.h:154
float z_far
Definition: geometry.h:41
int window_height
Definition: geometry.h:36
float fov
Definition: geometry.h:39
GLuint vao
Definition: geometry.h:80
ClipmapApplication * app
Definition: main.cpp:47
Matrix perspective
Definition: EGLPreserve.cpp:81
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:572
GLuint tex
Definition: geometry.h:29
#define uniform3fv(prog, name, value)
Definition: geometry.h:130
static mat4 rotateX(float rad)
Definition: matrix.h:312
float voxel_mode
Definition: geometry.h:53
float pointer_x
Definition: geometry.h:44
float y
Definition: matrix.h:54
void update_centroid(App *app)
Definition: geometry.cpp:161
#define uniformm4(prog, name, value)
Definition: geometry.h:132
#define GL_TEXTURE_3D
Definition: gl2ext.h:1613
float pointer_y
Definition: geometry.h:45
vec4 w
Definition: matrix.h:106
void update_sphere(App *app, mat4 mat_view)
Definition: geometry.cpp:192
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
GLuint vbo_quad
Definition: geometry.h:84
Definition: matrix.h:104
void clear_indirect_buffer(App *app)
Definition: geometry.cpp:118
#define uniform1i(prog, name, value)
Definition: geometry.h:131
void make_points(GLuint *vbo, GLuint *ibo)
Definition: geometry.cpp:93
GLuint tex_material
Definition: geometry.h:92
Volume tex_centroid
Definition: geometry.h:95
Definition: geometry.h:33
precision highp float
Definition: hiz_cull.cs:37
#define attribiv(prog, name, n, offset)
Definition: geometry.h:123
vec4 z
Definition: matrix.h:106
#define uniform1f(prog, name, value)
Definition: geometry.h:128
GLint GLsizei width
Definition: gl2ext.h:179
static float aspect_ratio
Definition: app.cpp:92
GLuint program_generate
Definition: geometry.h:73
vec4 x
Definition: matrix.h:106
#define N
Definition: geometry.cpp:25
GLint GLsizei GLboolean transpose
Definition: gl2ext.h:1500
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
void update_surface(App *app)
Definition: geometry.cpp:134
uniform float time
Definition: spawn.cs:50