OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ClipmapApplication.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 "ClipmapApplication.h"
22 #include "shaders.h"
23 #include "Platform.h"
24 #include <cstdio>
25 
26 using namespace MaliSDK;
27 using namespace std;
28 
29 ClipmapApplication::ClipmapApplication(unsigned int size, unsigned int levels, float clip_scale)
30  : mesh(size, levels, clip_scale), heightmap(size * 4 - 1, levels), frame(0)
31 {
32  // Compile shaders and grab uniform locations for later use.
34  GL_CHECK(glUseProgram(program));
35  GL_CHECK(glUniformBlockBinding(program, glGetUniformBlockIndex(program, "InstanceData"), 0));
36 
37  GL_CHECK(mvp_loc = glGetUniformLocation(program, "uViewProjection"));
38  GL_CHECK(camera_pos_loc = glGetUniformLocation(program, "uCameraPos"));
39 
40  GL_CHECK(GLint heightmap_loc = glGetUniformLocation(program, "sHeightmap"));
41  GL_CHECK(glUniform1i(heightmap_loc, 0));
42 
43  vector<GLfloat> inv_level_size;
44  float inv_size = 1.0f / (clip_scale * (size * 4 - 1));
45  for (unsigned int i = 0; i < levels; i++)
46  {
47  inv_level_size.push_back(inv_size);
48  inv_size *= 0.5f;
49  }
50 
51  GL_CHECK(GLint inv_level_size_loc = glGetUniformLocation(program, "uInvLevelSize"));
52  GL_CHECK(glUniform1fv(inv_level_size_loc, inv_level_size.size(), &inv_level_size[0]));
53  GL_CHECK(glUseProgram(0));
54 }
55 
57 {
58  GL_CHECK(glDeleteProgram(program));
59 }
60 
61 GLuint ClipmapApplication::compile_program(const char *vertex_shader, const char *fragment_shader)
62 {
63  GL_CHECK(GLuint prog = glCreateProgram());
64  GL_CHECK(GLuint vertex = compile_shader(GL_VERTEX_SHADER, vertex_shader));
65  GL_CHECK(GLuint fragment = compile_shader(GL_FRAGMENT_SHADER, fragment_shader));
66 
67  GL_CHECK(glAttachShader(prog, vertex));
68  GL_CHECK(glAttachShader(prog, fragment));
69  GL_CHECK(glLinkProgram(prog));
70 
71  GLint status = 0;
72  GL_CHECK(glGetProgramiv(prog, GL_LINK_STATUS, &status));
73  if (!status)
74  {
75  GLint info_len = 0;
76  GL_CHECK(glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len));
77  if (info_len)
78  {
79  char *buffer = new char[info_len];
80  GLint actual_len;
81  GL_CHECK(glGetProgramInfoLog(prog, info_len, &actual_len, buffer));
82  LOGE("Program failed to link: %s.\n", buffer);
83  delete[] buffer;
84  }
85  }
86 
87  // Don't need these anymore.
88  GL_CHECK(glDeleteShader(vertex));
89  GL_CHECK(glDeleteShader(fragment));
90  return prog;
91 }
92 
94 {
95  GL_CHECK(GLuint shader = glCreateShader(type));
96  GL_CHECK(glShaderSource(shader, 1, &source, NULL));
97  GL_CHECK(glCompileShader(shader));
98 
99  GLint status = 0;
100  GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
101 
102  if (!status)
103  {
104  GLint info_len = 0;
105  GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len));
106  if (info_len)
107  {
108  char *buffer = new char[info_len];
109  GLint actual_len;
110  GL_CHECK(glGetShaderInfoLog(shader, info_len, &actual_len, buffer));
111 
112  LOGE("Shader error: %s.\n", buffer);
113  delete[] buffer;
114  }
115  }
116 
117  return shader;
118 }
119 
120 void ClipmapApplication::render(unsigned int width, unsigned int height)
121 {
122  GL_CHECK(glClearColor(0.5f, 0.5f, 0.5f, 1.0f));
123  GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
124  GL_CHECK(glEnable(GL_DEPTH_TEST));
125  GL_CHECK(glEnable(GL_CULL_FACE));
126  GL_CHECK(glViewport(0, 0, width, height));
127 
128  // Rebind program every frame for clarity.
129  GL_CHECK(glUseProgram(program));
130 
131  // Non-interactive camera that just moves in one direction.
132  frame++;
133  vec2 camera_pos = vec2(frame) * vec2(0.5f, 1.0f);
134  vec3 world_camera_pos = vec3(camera_pos.c.x, 20, camera_pos.c.y);
135 
136  mat4 view = mat_look_at(world_camera_pos, world_camera_pos + vec3(1.0f, -0.2f, 2.0f), vec3(0, 1, 0));
137  mat4 proj = mat_perspective_fov(45.0f, float(width) / float(height), 1.0f, 1000.0f);
138  mat4 vp = proj * view;
139 
140  GL_CHECK(glUniformMatrix4fv(mvp_loc, 1, GL_FALSE, vp.data));
141 
142  // Used for frustum culling.
143  mesh.set_frustum(Frustum(vp));
144 
145  // The clipmap moves along with the camera.
146  mesh.update_level_offsets(camera_pos);
147 
148  GL_CHECK(glUniform3fv(camera_pos_loc, 1, world_camera_pos.data));
149 
150  // As we move around, the heightmap textures are updated incrementally, allowing for an "endless" terrain.
152 
153  GL_CHECK(glActiveTexture(GL_TEXTURE0));
155  mesh.render();
156 
157  GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, 0));
158 }
void set_frustum(const Frustum &frustum)
Definition: GroundMesh.h:36
Definition: matrix.h:51
void update_heightmap(const std::vector< vec2 > &level_offsets)
Definition: Heightmap.cpp:415
mat4 mat_look_at(const vec3 &eye, const vec3 &center, const vec3 &up)
Definition: vector_math.h:358
GLint GLsizei GLsizei height
Definition: gl2ext.h:179
Definition: matrix.h:28
float data[4]
Definition: vector_math.h:102
GLuint get_texture() const
Definition: Heightmap.h:36
static const char vertex_shader_source[]
Definition: shaders.h:30
void update_level_offsets(const vec2 &camera_pos)
[Snapping clipmap level to a grid]
Definition: GroundMesh.cpp:81
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:877
GLfloat GLfloat f
Definition: gl2ext.h:2707
GLuint compile_shader(GLenum type, const char *source)
#define GL_CHECK(x)
Definition: AstcTextures.h:59
void render()
[Rendering the entire terrain]
Definition: GroundMesh.cpp:575
struct vec2::@27::@30 c
GLsizei levels
Definition: gl2ext.h:1816
ClipmapApplication(unsigned int size, unsigned int levels, float clip_scale)
mat4 mat_perspective_fov(float fovy, float aspect, float zn, float zf)
Definition: vector_math.h:419
GLenum type
Definition: gl2ext.h:133
float data[16]
Definition: vector_math.h:151
const std::vector< vec2 > & get_level_offsets() const
Definition: GroundMesh.h:38
#define GL_TEXTURE_2D_ARRAY
Definition: gl2ext.h:1612
GLenum GLuint GLintptr GLsizeiptr size
Definition: gl2ext.h:629
GLuint compile_program(const char *vertex_shader_source, const char *fragment_shader_source)
Definition: matrix.h:104
GLenum GLuint buffer
Definition: gl2ext.h:628
#define LOGE(...)
Definition: AstcTextures.h:30
GLint GLsizei width
Definition: gl2ext.h:179
void render(unsigned int viewport_width, unsigned int viewport_height)
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLuint program
Definition: gl2ext.h:1475
static Mesh * mesh[2]
Definition: ocean.cpp:59
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
static const char fragment_shader_source[]
Definition: shaders.h:92