4
// Created by döme on 28.07.2009.
8
* Copyright (c) 2009 Doemoetoer Gulyas.
11
* Redistribution and use in source and binary forms, with or without
12
* modification, are permitted provided that the following conditions
14
* 1. Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
16
* 2. Redistributions in binary form must reproduce the above copyright
17
* notice, this list of conditions and the following disclaimer in the
18
* documentation and/or other materials provided with the distribution.
19
* 3. The name of the author may not be used to endorse or promote products
20
* derived from this software without specific prior written permission.
22
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
#import <OpenGLES/ES2/gl.h>
36
#import "VertexArray.h"
40
@implementation VertexArray
43
+ (VertexArray*) coneWithFraction: (float) fraction
45
VertexArray* va = [[[VertexArray alloc] init] autorelease];
47
size_t divisions = 72;
49
va->numVertices = (divisions+1)*2;
50
va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
51
for (size_t i = 0; i <= divisions; ++i)
53
float t = (float)i/(float)divisions;
54
float alpha = t*2.0*M_PI;
55
float sina = sinf(alpha);
56
float cosa = cosf(alpha);
58
va->vertices[2*i].pos[0] = cosa;
59
va->vertices[2*i].pos[1] = sina;
60
va->vertices[2*i].pos[2] = 0.0;
61
va->vertices[2*i+1].pos[0] = (1.0-fraction)*cosa;
62
va->vertices[2*i+1].pos[1] = (1.0-fraction)*sina;
63
va->vertices[2*i+1].pos[2] = fraction;
65
va->vertices[2*i].normal[0] = cosa*M_SQRT1_2;
66
va->vertices[2*i].normal[1] = sina*M_SQRT1_2;
67
va->vertices[2*i].normal[2] = M_SQRT1_2;
68
va->vertices[2*i+1].normal[0] = cosa*M_SQRT1_2;
69
va->vertices[2*i+1].normal[1] = sina*M_SQRT1_2;
70
va->vertices[2*i+1].normal[2] = M_SQRT1_2;
72
va->vertices[2*i].texcoord[0] = 1.0-t;
73
va->vertices[2*i].texcoord[1] = 0.0;
74
va->vertices[2*i+1].texcoord[0] = 1.0-t;
75
va->vertices[2*i+1].texcoord[1] = 1.0;
78
va->mode = GL_TRIANGLE_STRIP;
83
+ (VertexArray*) sharedCylinder
85
static VertexArray* va = nil;
88
va = [[VertexArray alloc] init];
89
size_t divisions = 72;
91
va->numVertices = (divisions+1)*2;
92
va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
93
for (size_t i = 0; i <= divisions; ++i)
95
float t = (float)i/(float)divisions;
96
float alpha = t*2.0*M_PI;
97
float sina = sinf(alpha);
98
float cosa = cosf(alpha);
100
va->vertices[2*i].pos[0] = cosa;
101
va->vertices[2*i].pos[1] = sina;
102
va->vertices[2*i].pos[2] = 1.0;
103
va->vertices[2*i+1].pos[0] = cosa;
104
va->vertices[2*i+1].pos[1] = sina;
105
va->vertices[2*i+1].pos[2] = -1.0;
107
va->vertices[2*i].normal[0] = cosa;
108
va->vertices[2*i].normal[1] = sina;
109
va->vertices[2*i].normal[2] = 0.0;
110
va->vertices[2*i+1].normal[0] = cosa;
111
va->vertices[2*i+1].normal[1] = sina;
112
va->vertices[2*i+1].normal[2] = 0.0;
114
va->vertices[2*i].texcoord[0] = t;
115
va->vertices[2*i].texcoord[1] = 0.0;
116
va->vertices[2*i+1].texcoord[0] = t;
117
va->vertices[2*i+1].texcoord[1] = 1.0;
121
va->mode = GL_TRIANGLE_STRIP;
125
+ (VertexArray*) sharedDisk
127
static VertexArray* va = nil;
130
va = [[VertexArray alloc] init];
132
unsigned divisions = 72;
134
va->numVertices = (divisions+1) + 1;
135
va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
137
va->vertices->pos[0] = 0.0;
138
va->vertices->pos[1] = 0.0;
139
va->vertices->pos[2] = 0.0;
140
va->vertices->normal[0] = 0.0;
141
va->vertices->normal[1] = 0.0;
142
va->vertices->normal[2] = 1.0;
143
va->vertices->texcoord[0] = 0.5;
144
va->vertices->texcoord[1] = 0.5;
145
for (size_t i = 0; i <= divisions; ++i)
147
float t = (float)i/(float)divisions;
148
float alpha = t*2.0*M_PI;
149
float sina = sinf(alpha);
150
float cosa = cosf(alpha);
152
va->vertices[i+1].pos[0] = cosa;
153
va->vertices[i+1].pos[1] = sina;
154
va->vertices[i+1].pos[2] = 0.0;
156
va->vertices[i+1].normal[0] = 0.0;
157
va->vertices[i+1].normal[1] = 0.0;
158
va->vertices[i+1].normal[2] = 1.0;
160
va->vertices[i+1].texcoord[0] = 0.5 + 0.5*cosa;
161
va->vertices[i+1].texcoord[1] = 0.5 - 0.5*sina;
165
va->mode = GL_TRIANGLE_FAN;
169
+ (VertexArray*) sharedQuad
171
static VertexArray* va = nil;
174
va = [[VertexArray alloc] init];
178
va->vertices = calloc(va->numVertices, sizeof(*va->vertices));
180
va->vertices[0].pos[0] = 1.0;
181
va->vertices[0].pos[1] = -1.0;
182
va->vertices[0].normal[2] = 1.0;
183
va->vertices[0].texcoord[0] = 1.0;
184
va->vertices[0].texcoord[1] = 1.0;
185
va->vertices[1].pos[0] = 1.0;
186
va->vertices[1].pos[1] = 1.0;
187
va->vertices[1].normal[2] = 1.0;
188
va->vertices[1].texcoord[0] = 1.0;
189
va->vertices[1].texcoord[1] = 0.0;
190
va->vertices[3].pos[0] = -1.0;
191
va->vertices[3].pos[1] = 1.0;
192
va->vertices[3].normal[2] = 1.0;
193
va->vertices[3].texcoord[0] = 0.0;
194
va->vertices[3].texcoord[1] = 0.0;
195
va->vertices[2].pos[0] = -1.0;
196
va->vertices[2].pos[1] = -1.0;
197
va->vertices[2].normal[2] = 1.0;
198
va->vertices[2].texcoord[0] = 0.0;
199
va->vertices[2].texcoord[1] = 1.0;
202
va->mode = GL_TRIANGLE_STRIP;
207
+ (VertexArray*) sharedSphere
209
static VertexArray* va = nil;
212
va = [[VertexArray alloc] init];
214
unsigned londivisions = 72;
215
unsigned latdivisions = 36;
217
va->numVertices = (londivisions+1)*(latdivisions+1);
218
va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
220
int soff = (latdivisions+1);
222
for (size_t i = 0; i <= londivisions; ++i)
224
float ti = (float)i/(float)londivisions;
225
float alpha = ti*2.0*M_PI;
226
float sini = sinf(alpha);
227
float cosi = cosf(alpha);
228
for (size_t j = 0; j <= latdivisions; ++j)
230
float tj = (float)j/(float)latdivisions;
232
float sinj = sinf(aj);
233
float cosj = cosf(aj);
235
va->vertices[i*soff + j].pos[0] = sinj*cosi;
236
va->vertices[i*soff + j].pos[1] = sinj*sini;
237
va->vertices[i*soff + j].pos[2] = cosj;
239
va->vertices[i*soff + j].normal[0] = sinj*cosi;
240
va->vertices[i*soff + j].normal[1] = sinj*sini;
241
va->vertices[i*soff + j].normal[2] = cosj;
243
va->vertices[i*soff + j].texcoord[0] = ti;
244
va->vertices[i*soff + j].texcoord[1] = tj;
248
va->numIndices = (londivisions)*(latdivisions+1)*2;
249
va->indices = malloc(2*va->numIndices);
251
uint16_t* indices = va->indices;
253
for (size_t i = 0; i < londivisions; ++i)
255
for (size_t j = 0; j <= latdivisions; ++j)
258
int x1 = (i+1)*soff + j;
260
indices[2*(i*soff + j) + 0] = x1;
261
indices[2*(i*soff + j) + 1] = x0;
269
va->mode = GL_TRIANGLE_STRIP;
273
+ (VertexArray*) sharedXSemiSphere
275
static VertexArray* va = nil;
278
va = [[VertexArray alloc] init];
280
unsigned londivisions = 36;
281
unsigned latdivisions = 36;
283
va->numVertices = (londivisions+1)*(latdivisions+1);
284
va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
286
int soff = (latdivisions+1);
288
for (size_t i = 0; i <= londivisions; ++i)
290
float ti = 0.5*(float)i/(float)londivisions - 0.25;
291
float alpha = ti*2.0*M_PI;
292
float sini = sinf(alpha);
293
float cosi = cosf(alpha);
294
for (size_t j = 0; j <= latdivisions; ++j)
296
float tj = (float)j/(float)latdivisions;
298
float sinj = sinf(aj);
299
float cosj = cosf(aj);
301
va->vertices[i*soff + j].pos[0] = sinj*cosi;
302
va->vertices[i*soff + j].pos[1] = sinj*sini;
303
va->vertices[i*soff + j].pos[2] = cosj;
305
va->vertices[i*soff + j].normal[0] = sinj*cosi;
306
va->vertices[i*soff + j].normal[1] = sinj*sini;
307
va->vertices[i*soff + j].normal[2] = cosj;
309
va->vertices[i*soff + j].texcoord[0] = ti;
310
va->vertices[i*soff + j].texcoord[1] = tj;
314
va->numIndices = (londivisions)*(latdivisions+1)*2;
315
va->indices = malloc(2*va->numIndices);
317
uint16_t* indices = va->indices;
319
for (size_t i = 0; i < londivisions; ++i)
321
for (size_t j = 0; j <= latdivisions; ++j)
324
int x1 = (i+1)*soff + j;
326
indices[2*(i*soff + j) + 0] = x1;
327
indices[2*(i*soff + j) + 1] = x0;
335
va->mode = GL_TRIANGLE_STRIP;
342
if (!(self = [super init]))
346
usageHint = GL_STATIC_DRAW;
353
if (vertexBufferName)
354
glDeleteBuffers(1, &vertexBufferName);
356
glDeleteBuffers(1, &indexBufferName);
367
- (id) initWithCoder: (NSCoder*) coder
369
if (!(self = [super init]))
372
usageHint = [coder decodeIntegerForKey: @"usageHint"];
373
mode = [coder decodeIntegerForKey: @"mode"];
374
numVertices = [coder decodeIntegerForKey: @"numVertices"];
375
numIndices = [coder decodeIntegerForKey: @"numIndices"];
377
vertices = malloc(sizeof(*vertices)*numVertices);
378
indices = malloc(sizeof(*indices)*numIndices);
380
memcpy(vertices, [[coder decodeObjectForKey: @"vertices"] bytes], sizeof(*vertices)*numVertices);
381
memcpy(indices, [[coder decodeObjectForKey: @"indices"] bytes], sizeof(*indices)*numIndices);
387
- (void) encodeWithCoder: (NSCoder*) coder
389
[coder encodeInteger: usageHint forKey: @"usageHint"];
390
[coder encodeInteger: mode forKey: @"mode"];
391
[coder encodeInteger: numVertices forKey: @"numVertices"];
392
[coder encodeInteger: numIndices forKey: @"numIndices"];
393
[coder encodeObject: [NSData dataWithBytes: vertices length: sizeof(*vertices)*numVertices] forKey: @"vertices"];
394
[coder encodeObject: [NSData dataWithBytes: indices length: sizeof(*indices)*numIndices] forKey: @"indices"];
399
if (!vertexBufferName)
401
glGenBuffers(1, &vertexBufferName);
402
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
403
glBufferData(GL_ARRAY_BUFFER, sizeof(*vertices)*numVertices, vertices, usageHint);
407
glGenBuffers(1, &indexBufferName);
408
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
409
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2*numIndices, indices, usageHint);
414
- (void) convertTriangleIndicesToLines
416
uint16_t* tris = indices;
417
indices = calloc(sizeof(*indices), numIndices*2);
419
for (size_t i = 0; i < numIndices/3; ++i)
421
indices[6*i+0] = tris[3*i+0];
422
indices[6*i+1] = tris[3*i+1];
423
indices[6*i+2] = tris[3*i+1];
424
indices[6*i+3] = tris[3*i+2];
425
indices[6*i+4] = tris[3*i+2];
426
indices[6*i+5] = tris[3*i+0];
432
- (void) convertPseudoQuadIndicesToLines
434
uint16_t* tris = indices;
435
indices = calloc(sizeof(*indices), numIndices*2);
437
for (size_t i = 0; i < numIndices/3; ++i)
439
indices[ii++] = tris[3*i+0];
440
indices[ii++] = tris[3*i+1];
441
indices[ii++] = tris[3*i+2];
442
indices[ii++] = tris[3*i+0];
452
if (!vertexBufferName)
455
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
458
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
460
EAGLRenderingAPI api = [[EAGLContext currentContext] API];
464
case kEAGLRenderingAPIOpenGLES2:
465
glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
466
glVertexAttribPointer(NORMAL_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
467
glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
469
glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
470
glEnableVertexAttribArray(NORMAL_ATTRIB_INDEX);
471
glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
475
case kEAGLRenderingAPIOpenGLES1:
476
glNormalPointer(GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
477
glTexCoordPointer(3, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
478
glVertexPointer(3, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
480
glEnableClientState(GL_VERTEX_ARRAY);
481
glEnableClientState(GL_NORMAL_ARRAY);
482
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
487
[[NSException exceptionWithName: @"com.elmonkey.invalidShader" reason: @" OpenGL ES API selected not supported by VertexArray." userInfo: nil] raise];
491
if (!indexBufferName)
492
glDrawArrays(mode, 0, numVertices);
494
glDrawElements(mode, numIndices, GL_UNSIGNED_SHORT, (void*)0);
496
GLenum err = glGetError();
503
- (void) applyVertexTransform: (m16) m
505
for (size_t i = 0; i < numVertices; ++i)
507
v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
508
v = mtransformpos3(m, v);
509
vertices[i].pos[0] = v.a[0];
510
vertices[i].pos[1] = v.a[1];
511
vertices[i].pos[2] = v.a[2];
514
if (vertexBufferName)
515
glDeleteBuffers(1, &vertexBufferName);
516
vertexBufferName = 0;
518
glDeleteBuffers(1, &indexBufferName);