RSS

(root)/iphone/common : /source/VertexArray.m (revision 61)

To get this branch, use:
bzr branch /browse/iphone/common
Line Revision Contents
1 5
//
2
//  VertexArray.m
3
//
4
//  Created by döme on 28.07.2009.
5
//
6
7 54
/*
8
 * Copyright (c) 2009 Doemoetoer Gulyas.
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
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.
21
 *
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.
32
 */
33
34 20
#import <OpenGLES/ES2/gl.h>
35
36 5
#import "VertexArray.h"
37
38 20
#import "ESShader.h"
39
40 5
@implementation VertexArray
41
42
43
+ (VertexArray*) coneWithFraction: (float) fraction
44
{
45
	VertexArray* va = [[[VertexArray alloc] init] autorelease];
46
47 42
	size_t divisions = 72;
48 5
	
49
	va->numVertices = (divisions+1)*2;
50
	va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
51
	for (size_t i = 0; i <= divisions; ++i)
52
	{
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);
57
		
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;
64
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;
71
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;
76
	}
77
	
78
	va->mode = GL_TRIANGLE_STRIP;
79
80
	return va;
81
}
82
83
+ (VertexArray*) sharedCylinder
84
{
85
	static VertexArray* va = nil;
86
	if (!va)
87
	{
88
		va = [[VertexArray alloc] init];
89 42
		size_t divisions = 72;
90 5
		
91
		va->numVertices = (divisions+1)*2;
92
		va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
93
		for (size_t i = 0; i <= divisions; ++i)
94
		{
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);
99
			
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;
106
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 7
			va->vertices[2*i+1].normal[2] = 0.0;
113 5
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;
118
		}
119
	}
120
	
121
	va->mode = GL_TRIANGLE_STRIP;
122
	return va;
123
}
124
125
+ (VertexArray*) sharedDisk
126
{
127
	static VertexArray* va = nil;
128
	if (!va)
129
	{
130
		va = [[VertexArray alloc] init];
131
		
132 42
		unsigned divisions = 72;
133 5
		
134
		va->numVertices = (divisions+1) + 1;
135
		va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
136
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)
146
		{
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);
151
			
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;
155
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;
159
160
			va->vertices[i+1].texcoord[0] = 0.5 + 0.5*cosa;
161
			va->vertices[i+1].texcoord[1] = 0.5 - 0.5*sina;
162
		}
163
	}
164
	
165
	va->mode = GL_TRIANGLE_FAN;
166
	return va;
167
}
168
169 23
+ (VertexArray*) sharedQuad
170
{
171
	static VertexArray* va = nil;
172
	if (!va)
173
	{
174
		va = [[VertexArray alloc] init];
175
		
176
		
177
		va->numVertices = 4;
178
		va->vertices = calloc(va->numVertices, sizeof(*va->vertices));
179
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 24
		va->vertices[0].texcoord[1] = 1.0;
185 23
		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 24
		va->vertices[1].texcoord[1] = 0.0;
190 23
		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 24
		va->vertices[3].texcoord[1] = 0.0;
195 23
		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 24
		va->vertices[2].texcoord[1] = 1.0;
200 23
	}
201
	
202
	va->mode = GL_TRIANGLE_STRIP;
203
	return va;
204
}
205
206
207 7
+ (VertexArray*) sharedSphere
208
{
209
	static VertexArray* va = nil;
210
	if (!va)
211
	{
212
		va = [[VertexArray alloc] init];
213
		
214 42
		unsigned londivisions = 72;
215
		unsigned latdivisions = 36;
216 7
		
217
		va->numVertices = (londivisions+1)*(latdivisions+1);
218
		va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
219
		
220
		int soff = (latdivisions+1);
221
222
		for (size_t i = 0; i <= londivisions; ++i)
223
		{
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)
229
			{
230
				float tj = (float)j/(float)latdivisions;
231
				float aj = tj*M_PI;
232
				float sinj = sinf(aj);
233
				float cosj = cosf(aj);
234
				
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;
238
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;
242
243
				va->vertices[i*soff + j].texcoord[0] = ti;
244
				va->vertices[i*soff + j].texcoord[1] = tj;
245
			}
246
		}
247
248
		va->numIndices = (londivisions)*(latdivisions+1)*2;
249
		va->indices = malloc(2*va->numIndices);
250
		
251
		uint16_t* indices = va->indices;
252
		
253
		for (size_t i = 0; i < londivisions; ++i)
254
		{
255
			for (size_t j = 0; j <= latdivisions; ++j)
256
			{
257
				int x0 = i*soff + j;
258
				int x1 = (i+1)*soff + j;
259
				
260
				indices[2*(i*soff + j) + 0] = x1;
261
				indices[2*(i*soff + j) + 1] = x0;
262
			}
263
		}
264
		
265
	}
266
267
	
268
	
269
	va->mode = GL_TRIANGLE_STRIP;
270
	return va;
271
}
272
273
+ (VertexArray*) sharedXSemiSphere
274
{
275
	static VertexArray* va = nil;
276
	if (!va)
277
	{
278
		va = [[VertexArray alloc] init];
279
		
280 42
		unsigned londivisions = 36;
281
		unsigned latdivisions = 36;
282 7
		
283
		va->numVertices = (londivisions+1)*(latdivisions+1);
284
		va->vertices = malloc(va->numVertices*sizeof(*va->vertices));
285
		
286
		int soff = (latdivisions+1);
287
288
		for (size_t i = 0; i <= londivisions; ++i)
289
		{
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)
295
			{
296
				float tj = (float)j/(float)latdivisions;
297
				float aj = tj*M_PI;
298
				float sinj = sinf(aj);
299
				float cosj = cosf(aj);
300
				
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;
304
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;
308
309
				va->vertices[i*soff + j].texcoord[0] = ti;
310
				va->vertices[i*soff + j].texcoord[1] = tj;
311
			}
312
		}
313
314
		va->numIndices = (londivisions)*(latdivisions+1)*2;
315
		va->indices = malloc(2*va->numIndices);
316
		
317
		uint16_t* indices = va->indices;
318
		
319
		for (size_t i = 0; i < londivisions; ++i)
320
		{
321
			for (size_t j = 0; j <= latdivisions; ++j)
322
			{
323
				int x0 = i*soff + j;
324
				int x1 = (i+1)*soff + j;
325
				
326
				indices[2*(i*soff + j) + 0] = x1;
327
				indices[2*(i*soff + j) + 1] = x0;
328
			}
329
		}
330
		
331
	}
332
333
	
334
	
335
	va->mode = GL_TRIANGLE_STRIP;
336
	return va;
337
}
338
339
340 5
- (id) init
341
{
342
	if (!(self = [super init]))
343
		return nil;
344
345 38
	
346
	usageHint = GL_STATIC_DRAW;
347 5
348
	return self;
349
}
350
351
- (void) dealloc
352
{
353
	if (vertexBufferName)
354
		glDeleteBuffers(1, &vertexBufferName);
355 32
	if (indexBufferName)
356
		glDeleteBuffers(1, &indexBufferName);
357 5
	
358
	if (vertices)
359
		free(vertices);
360
361 32
	if (indices)
362
		free(indices);
363
364 5
	[super dealloc];
365
}
366
367 32
- (id) initWithCoder: (NSCoder*) coder
368
{
369
	if (!(self = [super init]))
370
		return nil;
371
372 38
	usageHint = [coder decodeIntegerForKey: @"usageHint"];
373 32
	mode = [coder decodeIntegerForKey: @"mode"];
374
	numVertices = [coder decodeIntegerForKey: @"numVertices"];
375
	numIndices = [coder decodeIntegerForKey: @"numIndices"];
376
	
377
	vertices = malloc(sizeof(*vertices)*numVertices);
378
	indices = malloc(sizeof(*indices)*numIndices);
379
	
380
	memcpy(vertices, [[coder decodeObjectForKey: @"vertices"] bytes], sizeof(*vertices)*numVertices);
381
	memcpy(indices, [[coder decodeObjectForKey: @"indices"] bytes], sizeof(*indices)*numIndices);
382
383
384
	return self;
385
}
386
387
- (void) encodeWithCoder: (NSCoder*) coder
388
{
389 38
	[coder encodeInteger: usageHint forKey: @"usageHint"];
390 32
	[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"];
395
}
396
397 5
- (void) generateVBO
398
{
399
	if (!vertexBufferName)
400
	{
401
		glGenBuffers(1, &vertexBufferName);
402
		glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
403 38
		glBufferData(GL_ARRAY_BUFFER, sizeof(*vertices)*numVertices, vertices, usageHint);
404 7
		
405
		if (numIndices)
406
		{
407
			glGenBuffers(1, &indexBufferName);
408
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
409 38
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2*numIndices, indices, usageHint);
410 7
		}
411 5
	}
412
}
413
414 39
- (void) convertTriangleIndicesToLines
415
{
416
	uint16_t* tris = indices;
417
	indices = calloc(sizeof(*indices), numIndices*2);
418
	
419
	for (size_t i = 0; i < numIndices/3; ++i)
420
	{
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];
427
	}
428
	numIndices *= 2;
429
	mode = GL_LINES;
430
	free(tris);
431
}
432 40
- (void) convertPseudoQuadIndicesToLines
433
{
434
	uint16_t* tris = indices;
435
	indices = calloc(sizeof(*indices), numIndices*2);
436
	size_t ii = 0;
437
	for (size_t i = 0; i < numIndices/3; ++i)
438
	{
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];
443
	}
444
	numIndices = ii;
445
	mode = GL_LINES;
446
	free(tris);
447
}
448
449 39
450 5
- (void) draw
451
{
452
	if (!vertexBufferName)
453
		[self generateVBO];
454
455
	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
456
	
457 7
	if (indexBufferName)
458
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
459 5
460 21
	EAGLRenderingAPI api = [[EAGLContext currentContext] API];
461 20
462
	switch(api)
463
	{
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));
468
469
			glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
470
			glEnableVertexAttribArray(NORMAL_ATTRIB_INDEX);
471
			glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
472
473
			break;
474
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));
479
			
480
			glEnableClientState(GL_VERTEX_ARRAY);
481
			glEnableClientState(GL_NORMAL_ARRAY);
482
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
483
			
484
			break;
485
			
486
		default:
487
			[[NSException exceptionWithName: @"com.elmonkey.invalidShader" reason: @" OpenGL ES API selected not supported by VertexArray." userInfo: nil] raise];
488
			break;
489
	}
490 5
491 7
	if (!indexBufferName)
492
		glDrawArrays(mode, 0, numVertices);
493
	else
494
		glDrawElements(mode, numIndices, GL_UNSIGNED_SHORT, (void*)0);
495 5
	
496 21
	GLenum err = glGetError();
497
	if(err)
498
	{
499
		assert(err);
500
	};
501 5
}
502
503 15
- (void) applyVertexTransform: (m16) m
504
{
505
	for (size_t i = 0; i < numVertices; ++i)
506
	{
507 42
		v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
508 15
		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];
512
	}
513 19
	
514
	if (vertexBufferName)
515
		glDeleteBuffers(1, &vertexBufferName);
516
	vertexBufferName = 0;
517
	if (indexBufferName)
518
		glDeleteBuffers(1, &indexBufferName);
519
	indexBufferName = 0;
520 15
}
521
522
523 5
@end
524
525

Loggerhead 1.17 is a web-based interface for Bazaar branches