1 //
2 // Book: OpenGL(R) ES 2.0 Programming Guide
3 // Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
4 // ISBN-10: 0321502795
5 // ISBN-13: 9780321502797
6 // Publisher: Addison-Wesley Professional
7 // URLs: http://safari.informit.com/9780321563835
8 // http://www.opengles-book.com
9 //
10
11 // ESShapes.c
12 //
13 // Utility functions for generating shapes
14 //
15
16 ///
17 // Includes
18 //
19 #include "esUtil.h"
20 #include <stdlib.h>
21 #include <math.h>
22
23 ///
24 // Defines
25 //
26 #define ES_PI (3.14159265f)
27
28 //////////////////////////////////////////////////////////////////
29 //
30 // Private Functions
31 //
32 //
33
34
35
36 //////////////////////////////////////////////////////////////////
37 //
38 // Public Functions
39 //
40 //
41
42 //
43 /// \brief Generates geometry for a sphere. Allocates memory for the vertex data and stores
44 /// the results in the arrays. Generate index list for a TRIANGLE_STRIP
45 /// \param numSlices The number of slices in the sphere
46 /// \param vertices If not NULL, will contain array of float3 positions
47 /// \param normals If not NULL, will contain array of float3 normals
48 /// \param texCoords If not NULL, will contain array of float2 texCoords
49 /// \param indices If not NULL, will contain the array of indices for the triangle strip
50 /// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
51 /// if it is not NULL ) as a GL_TRIANGLE_STRIP
52 //
esGenSphere(int numSlices,float radius,GLfloat ** vertices,GLfloat ** normals,GLfloat ** texCoords,GLushort ** indices)53 int ESUTIL_API esGenSphere ( int numSlices, float radius, GLfloat **vertices, GLfloat **normals,
54 GLfloat **texCoords, GLushort **indices )
55 {
56 int i;
57 int j;
58 int numParallels = numSlices / 2;
59 int numVertices = ( numParallels + 1 ) * ( numSlices + 1 );
60 int numIndices = numParallels * numSlices * 6;
61 float angleStep = (2.0f * ES_PI) / ((float) numSlices);
62
63 // Allocate memory for buffers
64 if ( vertices != NULL )
65 *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
66
67 if ( normals != NULL )
68 *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
69
70 if ( texCoords != NULL )
71 *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
72
73 if ( indices != NULL )
74 *indices = malloc ( sizeof(GLushort) * numIndices );
75
76 for ( i = 0; i < numParallels + 1; i++ )
77 {
78 for ( j = 0; j < numSlices + 1; j++ )
79 {
80 int vertex = ( i * (numSlices + 1) + j ) * 3;
81
82 if ( vertices )
83 {
84 (*vertices)[vertex + 0] = radius * sinf ( angleStep * (float)i ) *
85 sinf ( angleStep * (float)j );
86 (*vertices)[vertex + 1] = radius * cosf ( angleStep * (float)i );
87 (*vertices)[vertex + 2] = radius * sinf ( angleStep * (float)i ) *
88 cosf ( angleStep * (float)j );
89 }
90
91 if ( normals )
92 {
93 (*normals)[vertex + 0] = (*vertices)[vertex + 0] / radius;
94 (*normals)[vertex + 1] = (*vertices)[vertex + 1] / radius;
95 (*normals)[vertex + 2] = (*vertices)[vertex + 2] / radius;
96 }
97
98 if ( texCoords )
99 {
100 int texIndex = ( i * (numSlices + 1) + j ) * 2;
101 (*texCoords)[texIndex + 0] = (float) j / (float) numSlices;
102 (*texCoords)[texIndex + 1] = ( 1.0f - (float) i ) / (float) (numParallels - 1 );
103 }
104 }
105 }
106
107 // Generate the indices
108 if ( indices != NULL )
109 {
110 GLushort *indexBuf = (*indices);
111 for ( i = 0; i < numParallels ; i++ )
112 {
113 for ( j = 0; j < numSlices; j++ )
114 {
115 *indexBuf++ = i * ( numSlices + 1 ) + j;
116 *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + j;
117 *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
118
119 *indexBuf++ = i * ( numSlices + 1 ) + j;
120 *indexBuf++ = ( i + 1 ) * ( numSlices + 1 ) + ( j + 1 );
121 *indexBuf++ = i * ( numSlices + 1 ) + ( j + 1 );
122 }
123 }
124 }
125
126 return numIndices;
127 }
128
129 //
130 /// \brief Generates geometry for a cube. Allocates memory for the vertex data and stores
131 /// the results in the arrays. Generate index list for a TRIANGLES
132 /// \param scale The size of the cube, use 1.0 for a unit cube.
133 /// \param vertices If not NULL, will contain array of float3 positions
134 /// \param normals If not NULL, will contain array of float3 normals
135 /// \param texCoords If not NULL, will contain array of float2 texCoords
136 /// \param indices If not NULL, will contain the array of indices for the triangle strip
137 /// \return The number of indices required for rendering the buffers (the number of indices stored in the indices array
138 /// if it is not NULL ) as a GL_TRIANGLE_STRIP
139 //
esGenCube(float scale,GLfloat ** vertices,GLfloat ** normals,GLfloat ** texCoords,GLushort ** indices)140 int ESUTIL_API esGenCube ( float scale, GLfloat **vertices, GLfloat **normals,
141 GLfloat **texCoords, GLushort **indices )
142 {
143 int i;
144 int numVertices = 24;
145 int numIndices = 36;
146
147 GLfloat cubeVerts[] =
148 {
149 -0.5f, -0.5f, -0.5f,
150 -0.5f, -0.5f, 0.5f,
151 0.5f, -0.5f, 0.5f,
152 0.5f, -0.5f, -0.5f,
153 -0.5f, 0.5f, -0.5f,
154 -0.5f, 0.5f, 0.5f,
155 0.5f, 0.5f, 0.5f,
156 0.5f, 0.5f, -0.5f,
157 -0.5f, -0.5f, -0.5f,
158 -0.5f, 0.5f, -0.5f,
159 0.5f, 0.5f, -0.5f,
160 0.5f, -0.5f, -0.5f,
161 -0.5f, -0.5f, 0.5f,
162 -0.5f, 0.5f, 0.5f,
163 0.5f, 0.5f, 0.5f,
164 0.5f, -0.5f, 0.5f,
165 -0.5f, -0.5f, -0.5f,
166 -0.5f, -0.5f, 0.5f,
167 -0.5f, 0.5f, 0.5f,
168 -0.5f, 0.5f, -0.5f,
169 0.5f, -0.5f, -0.5f,
170 0.5f, -0.5f, 0.5f,
171 0.5f, 0.5f, 0.5f,
172 0.5f, 0.5f, -0.5f,
173 };
174
175 GLfloat cubeNormals[] =
176 {
177 0.0f, -1.0f, 0.0f,
178 0.0f, -1.0f, 0.0f,
179 0.0f, -1.0f, 0.0f,
180 0.0f, -1.0f, 0.0f,
181 0.0f, 1.0f, 0.0f,
182 0.0f, 1.0f, 0.0f,
183 0.0f, 1.0f, 0.0f,
184 0.0f, 1.0f, 0.0f,
185 0.0f, 0.0f, -1.0f,
186 0.0f, 0.0f, -1.0f,
187 0.0f, 0.0f, -1.0f,
188 0.0f, 0.0f, -1.0f,
189 0.0f, 0.0f, 1.0f,
190 0.0f, 0.0f, 1.0f,
191 0.0f, 0.0f, 1.0f,
192 0.0f, 0.0f, 1.0f,
193 -1.0f, 0.0f, 0.0f,
194 -1.0f, 0.0f, 0.0f,
195 -1.0f, 0.0f, 0.0f,
196 -1.0f, 0.0f, 0.0f,
197 1.0f, 0.0f, 0.0f,
198 1.0f, 0.0f, 0.0f,
199 1.0f, 0.0f, 0.0f,
200 1.0f, 0.0f, 0.0f,
201 };
202
203 GLfloat cubeTex[] =
204 {
205 0.0f, 0.0f,
206 0.0f, 1.0f,
207 1.0f, 1.0f,
208 1.0f, 0.0f,
209 1.0f, 0.0f,
210 1.0f, 1.0f,
211 0.0f, 1.0f,
212 0.0f, 0.0f,
213 0.0f, 0.0f,
214 0.0f, 1.0f,
215 1.0f, 1.0f,
216 1.0f, 0.0f,
217 0.0f, 0.0f,
218 0.0f, 1.0f,
219 1.0f, 1.0f,
220 1.0f, 0.0f,
221 0.0f, 0.0f,
222 0.0f, 1.0f,
223 1.0f, 1.0f,
224 1.0f, 0.0f,
225 0.0f, 0.0f,
226 0.0f, 1.0f,
227 1.0f, 1.0f,
228 1.0f, 0.0f,
229 };
230
231 // Allocate memory for buffers
232 if ( vertices != NULL )
233 {
234 *vertices = malloc ( sizeof(GLfloat) * 3 * numVertices );
235 memcpy( *vertices, cubeVerts, sizeof( cubeVerts ) );
236 for ( i = 0; i < numVertices; i++ )
237 {
238 (*vertices)[i] *= scale;
239 }
240 }
241
242 if ( normals != NULL )
243 {
244 *normals = malloc ( sizeof(GLfloat) * 3 * numVertices );
245 memcpy( *normals, cubeNormals, sizeof( cubeNormals ) );
246 }
247
248 if ( texCoords != NULL )
249 {
250 *texCoords = malloc ( sizeof(GLfloat) * 2 * numVertices );
251 memcpy( *texCoords, cubeTex, sizeof( cubeTex ) ) ;
252 }
253
254
255 // Generate the indices
256 if ( indices != NULL )
257 {
258 GLushort cubeIndices[] =
259 {
260 0, 2, 1,
261 0, 3, 2,
262 4, 5, 6,
263 4, 6, 7,
264 8, 9, 10,
265 8, 10, 11,
266 12, 15, 14,
267 12, 14, 13,
268 16, 17, 18,
269 16, 18, 19,
270 20, 23, 22,
271 20, 22, 21
272 };
273
274 *indices = malloc ( sizeof(GLushort) * numIndices );
275 memcpy( *indices, cubeIndices, sizeof( cubeIndices ) );
276 }
277
278 return numIndices;
279 }
280