OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mesh.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 "mesh.hpp"
22 #include <utility>
23 using namespace std;
24 
26 {
27  aabb.minpos = vec4(0.0f);
28  aabb.maxpos = vec4(0.0f);
29 
30  GL_CHECK(glGenVertexArrays(1, &vertex_array));
31  GL_CHECK(glGenBuffers(1, &vertex_buffer));
32  GL_CHECK(glGenBuffers(1, &index_buffer));
33 
34  GL_CHECK(glBindVertexArray(vertex_array));
35 
36  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer));
37 
38  static const float vertices[] = {
39  -1, -1,
40  1, -1,
41  -1, 1,
42  1, 1,
43  };
44  static const uint16_t indices[] = { 0, 1, 2, 3, 2, 1, };
45 
46  GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW));
47 
48  GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer));
49  GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW));
50 
51  GL_CHECK(glEnableVertexAttribArray(0));
52  GL_CHECK(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0));
53 
54  GL_CHECK(glBindVertexArray(0));
55  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
56  GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
57 
58  num_elements = 6;
59 }
60 
62 {
63  aabb = mesh.aabb;
64  num_elements = mesh.ibo.size();
65 
66  GL_CHECK(glGenVertexArrays(1, &vertex_array));
67  GL_CHECK(glGenBuffers(1, &vertex_buffer));
68  GL_CHECK(glGenBuffers(1, &index_buffer));
69 
70  GL_CHECK(glBindVertexArray(vertex_array));
71 
72  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer));
73  GL_CHECK(glBufferData(GL_ARRAY_BUFFER, mesh.vbo.size() * sizeof(Vertex), &mesh.vbo[0],
74  GL_STATIC_DRAW));
75 
76  GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer));
77  GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.ibo.size() * sizeof(uint16_t),
78  &mesh.ibo[0], GL_STATIC_DRAW));
79 
80  // Vertex position
81  GL_CHECK(glEnableVertexAttribArray(0));
82  GL_CHECK(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
83  reinterpret_cast<const GLvoid*>(offsetof(Vertex, position))));
84 
85  // Normal
86  GL_CHECK(glEnableVertexAttribArray(1));
87  GL_CHECK(glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
88  reinterpret_cast<const GLvoid*>(offsetof(Vertex, normal))));
89 
90  // Tex coord
91  GL_CHECK(glEnableVertexAttribArray(2));
92  GL_CHECK(glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
93  reinterpret_cast<const GLvoid*>(offsetof(Vertex, tex))));
94 
95  GL_CHECK(glBindVertexArray(0));
96  GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
97  GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
98 }
99 
101 {
102  glDeleteVertexArrays(1, &vertex_array);
103  glDeleteBuffers(1, &vertex_buffer);
104  glDeleteBuffers(1, &index_buffer);
105 }
106 
108 {
109  return aabb;
110 }
111 
113 {
114  return num_elements;
115 }
116 
118 {
119  return vertex_array;
120 }
121 
122 Mesh create_sphere_mesh(float radius, vec3 center, unsigned vertices_per_circumference)
123 {
124  Mesh mesh;
125 
126  mesh.vbo.resize(2 + vertices_per_circumference * vertices_per_circumference);
127 
128  // No idea if the tangents here are correct.
129 
130  // Bottom
131  mesh.vbo[0] = Vertex(vec3(0, -1, 0) * vec3(radius) + center, vec3(0, -1, 0), vec2(0.5f, 0.0f));
132  // Top
133  mesh.vbo[vertices_per_circumference * vertices_per_circumference + 1] = Vertex(vec3(0, +1, 0) * vec3(radius) + center, vec3(0, +1, 0), vec2(0.5f, 1.0f));
134 
135  for (unsigned y = 0; y < vertices_per_circumference; y++)
136  {
137  for (unsigned x = 0; x < vertices_per_circumference; x++)
138  {
139  float pos_y = sin(PI * (float(y + 1) / (vertices_per_circumference + 1) - 0.5f));
140  float xz_mod = sqrt(1.0f - pos_y * pos_y);
141  float radians_rot_y = 2.0f * PI * x / vertices_per_circumference;
142  float pos_x = xz_mod * cos(radians_rot_y);
143  float pos_z = xz_mod * -sin(radians_rot_y);
144 
145  vec3 normal(pos_x, pos_y, pos_z);
146 
147  mesh.vbo[y * vertices_per_circumference + x + 1] = Vertex(
148  vec3(radius) * normal + center,
149  normal,
150  vec2(float(x) / vertices_per_circumference, (y + 1.0f) / (vertices_per_circumference + 1))
151  );
152  }
153  }
154 
155  // Bottom
156  for (unsigned x = 0; x < vertices_per_circumference - 1; x++)
157  {
158  mesh.ibo.push_back(x + 1);
159  mesh.ibo.push_back(0);
160  mesh.ibo.push_back(x + 2);
161  }
162  mesh.ibo.push_back(vertices_per_circumference);
163  mesh.ibo.push_back(0);
164  mesh.ibo.push_back(1);
165 
166  // Quads
167  for (unsigned y = 0; y < vertices_per_circumference - 1; y++)
168  {
169  for (unsigned x = 0; x < vertices_per_circumference - 1; x++)
170  {
171  unsigned base = 1 + y * vertices_per_circumference + x;
172  mesh.ibo.push_back(base);
173  mesh.ibo.push_back(base + 1);
174  mesh.ibo.push_back(base + vertices_per_circumference);
175  mesh.ibo.push_back(base + vertices_per_circumference + 1);
176  mesh.ibo.push_back(base + vertices_per_circumference);
177  mesh.ibo.push_back(base + 1);
178  }
179  unsigned base = 1 + y * vertices_per_circumference + (vertices_per_circumference - 1);
180  mesh.ibo.push_back(base);
181  mesh.ibo.push_back(base - (vertices_per_circumference - 1));
182  mesh.ibo.push_back(base + vertices_per_circumference);
183  mesh.ibo.push_back(base + 1);
184  mesh.ibo.push_back(base + vertices_per_circumference);
185  mesh.ibo.push_back(base - (vertices_per_circumference - 1));
186  }
187 
188  // Top
189  for (unsigned x = 0; x < vertices_per_circumference - 1; x++)
190  {
191  unsigned base = 1 + (vertices_per_circumference - 1) * vertices_per_circumference + x;
192  mesh.ibo.push_back(base);
193  mesh.ibo.push_back(base + 1);
194  mesh.ibo.push_back(vertices_per_circumference * vertices_per_circumference + 1);
195  }
196  mesh.ibo.push_back(1 + (vertices_per_circumference - 1) * vertices_per_circumference + vertices_per_circumference - 1);
197  mesh.ibo.push_back(1 + (vertices_per_circumference - 1) * vertices_per_circumference);
198  mesh.ibo.push_back(vertices_per_circumference * vertices_per_circumference + 1);
199 
200  mesh.aabb.minpos = vec4(center - vec3(radius), 0.0f);
201  mesh.aabb.maxpos = vec4(center + vec3(radius), 0.0f);
202 
203  return mesh;
204 }
205 
207 {
208  static const Vertex vertex_data[] = {
209  Vertex( vec3(-1, -1, 1), vec3( 0, 0, 1 ), vec2(0, 0) ), // Front
210  Vertex( vec3( 1, -1, 1), vec3( 0, 0, 1 ), vec2(1, 0) ),
211  Vertex( vec3(-1, 1, 1), vec3( 0, 0, 1 ), vec2(0, 1) ),
212  Vertex( vec3( 1, 1, 1), vec3( 0, 0, 1 ), vec2(1, 1) ),
213 
214  Vertex( vec3( 1, -1, -1), vec3( 0, 0, -1 ), vec2(0, 0) ), // Back
215  Vertex( vec3(-1, -1, -1), vec3( 0, 0, -1 ), vec2(1, 0) ),
216  Vertex( vec3( 1, 1, -1), vec3( 0, 0, -1 ), vec2(0, 1) ),
217  Vertex( vec3(-1, 1, -1), vec3( 0, 0, -1 ), vec2(1, 1) ),
218 
219  Vertex( vec3(-1, -1, -1), vec3(-1, 0, 0 ), vec2(0, 0) ), // Left
220  Vertex( vec3(-1, -1, 1), vec3(-1, 0, 0 ), vec2(1, 0) ),
221  Vertex( vec3(-1, 1, -1), vec3(-1, 0, 0 ), vec2(0, 1) ),
222  Vertex( vec3(-1, 1, 1), vec3(-1, 0, 0 ), vec2(1, 1) ),
223 
224  Vertex( vec3( 1, -1, 1), vec3( 1, 0, 0 ), vec2(0, 0) ), // Right
225  Vertex( vec3( 1, -1, -1), vec3( 1, 0, 0 ), vec2(1, 0) ),
226  Vertex( vec3( 1, 1, 1), vec3( 1, 0, 0 ), vec2(0, 1) ),
227  Vertex( vec3( 1, 1, -1), vec3( 1, 0, 0 ), vec2(1, 1) ),
228 
229  Vertex( vec3(-1, 1, 1), vec3( 0, 1, 0 ), vec2(0, 0) ), // Top
230  Vertex( vec3( 1, 1, 1), vec3( 0, 1, 0 ), vec2(1, 0) ),
231  Vertex( vec3(-1, 1, -1), vec3( 0, 1, 0 ), vec2(0, 1) ),
232  Vertex( vec3( 1, 1, -1), vec3( 0, 1, 0 ), vec2(1, 1) ),
233 
234  Vertex( vec3(-1, -1, -1), vec3( 0, -1, 0), vec2(0, 0) ), // Bottom
235  Vertex( vec3( 1, -1, -1), vec3( 0, -1, 0), vec2(1, 0) ),
236  Vertex( vec3(-1, -1, 1), vec3( 0, -1, 0), vec2(0, 1) ),
237  Vertex( vec3( 1, -1, 1), vec3( 0, -1, 0), vec2(1, 1) ),
238  };
239 
240  static const GLushort indices[] = {
241  0, 1, 2, // Front
242  3, 2, 1,
243 
244  4, 5, 6, // Back
245  7, 6, 5,
246 
247  8, 9, 10, // Left
248  11, 10, 9,
249 
250  12, 13, 14, // Right
251  15, 14, 13,
252 
253  16, 17, 18, // Top
254  19, 18, 17,
255 
256  20, 21, 22, // Bottom
257  23, 22, 21,
258  };
259 
260  Mesh mesh;
261  mesh.aabb = aabb;
262 
263  vec3 half_position = vec3(0.5f) * (vec3(aabb.minpos) + vec3(aabb.maxpos));
264  vec3 half_distance = vec3(0.5f) * (vec3(aabb.maxpos) - vec3(aabb.minpos));
265 
266  for (unsigned i = 0; i < sizeof(vertex_data) / sizeof(Vertex); i++)
267  {
268  const Vertex &vert = vertex_data[i];
269  vec3 pos = half_position + half_distance * vert.position;
270  mesh.vbo.push_back(Vertex(pos, vert.normal, vert.tex));
271  }
272 
273  mesh.ibo.insert(mesh.ibo.begin(), indices, indices + sizeof(indices) / sizeof(indices[0]));
274  return mesh;
275 }
276 
vec2 tex
Definition: mesh.hpp:36
unsigned get_num_elements() const
Definition: mesh.cpp:112
Definition: matrix.h:51
Mesh create_box_mesh(const AABB &aabb)
Definition: mesh.cpp:206
Definition: matrix.h:28
const float vertices[]
Definition: Cube.h:30
AABB aabb
Definition: mesh.hpp:49
GLuint ibo
Definition: mesh.hpp:82
Definition: matrix.h:75
#define PI
Definition: matrix.h:24
vec4 minpos
Definition: mesh.hpp:41
GLuint get_vertex_array() const
Definition: mesh.cpp:117
GLsizei GLenum const void * indices
Definition: gl2ext.h:322
vec3 position
Definition: mesh.hpp:34
GLfloat GLfloat f
Definition: gl2ext.h:2707
#define GL_CHECK(x)
Definition: AstcTextures.h:59
Definition: mesh.hpp:28
~GLDrawable()
Definition: mesh.cpp:100
vec3 normal
Definition: mesh.hpp:35
GLint GLint GLint GLint GLint x
Definition: gl2ext.h:574
vec4 maxpos
Definition: mesh.hpp:42
GLuint vbo
Definition: mesh.hpp:81
Definition: mesh.hpp:39
GLDrawable()
Definition: mesh.cpp:25
const AABB & get_aabb() const
Definition: mesh.cpp:107
static Mesh * mesh[2]
Definition: ocean.cpp:59
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
GLint y
Definition: gl2ext.h:179
Mesh create_sphere_mesh(float radius, vec3 center, unsigned vertices_per_circumference)
Definition: mesh.cpp:122