RSS

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

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 70
#import <OpenGLES/ES2/glext.h>
36 20
37 83
#import <malloc/malloc.h>
38
39 5
#import "VertexArray.h"
40
41 20
#import "ESShader.h"
42
43 5
@implementation VertexArray
44
45 73
static inline size_t _sizeofFormat(int format)
46
{
47
	switch(format)
48
	{
49
		case VA_FORMAT_POS3F:
50
			return sizeof(Position3f);
51
		case VA_FORMAT_POS3F_TEX2F:
52
			return sizeof(PositionTex3f2f);
53 86
		case VA_FORMAT_POS3F_COL4B_TEX2F:
54
			return sizeof(PositionColorTex3f4b2f);
55 73
		case VA_FORMAT_POS3F_NORMAL3F_TEX2F:
56
			return sizeof(PositionNormalTex3f3f2f);
57
		default:
58
			return -1;
59
	}
60
}
61
62
- (size_t) sizeofFormat
63
{
64
	return _sizeofFormat(vertexFormat);
65
}
66
67 5
+ (VertexArray*) coneWithFraction: (float) fraction
68
{
69 94
	VertexArray* va = [[VertexArray alloc] init];
70 5
71 42
	size_t divisions = 72;
72 5
	
73 73
	
74
	
75 5
	va->numVertices = (divisions+1)*2;
76 73
	PositionNormalTex3f3f2f* vertices = calloc(va->numVertices,sizeof(*vertices));
77
	va->_vertices = vertices;
78
	va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
79
80 5
	for (size_t i = 0; i <= divisions; ++i)
81
	{
82
		float t = (float)i/(float)divisions;
83
		float alpha = t*2.0*M_PI;
84
		float sina = sinf(alpha);
85
		float cosa = cosf(alpha);
86
		
87 73
		vertices[2*i].pos[0] = cosa;
88
		vertices[2*i].pos[1] = sina;
89
		vertices[2*i].pos[2] = 0.0;
90
		vertices[2*i+1].pos[0] = (1.0-fraction)*cosa;
91
		vertices[2*i+1].pos[1] = (1.0-fraction)*sina;
92
		vertices[2*i+1].pos[2] = fraction;
93
94
		vertices[2*i].normal[0] = cosa*M_SQRT1_2;
95
		vertices[2*i].normal[1] = sina*M_SQRT1_2;
96
		vertices[2*i].normal[2] = M_SQRT1_2;
97
		vertices[2*i+1].normal[0] = cosa*M_SQRT1_2;
98
		vertices[2*i+1].normal[1] = sina*M_SQRT1_2;
99
		vertices[2*i+1].normal[2] = M_SQRT1_2;
100
101
		vertices[2*i].texcoord[0] = 1.0-t;
102
		vertices[2*i].texcoord[1] = 0.0;
103
		vertices[2*i+1].texcoord[0] = 1.0-t;
104
		vertices[2*i+1].texcoord[1] = 1.0;
105 5
	}
106
	
107
	va->mode = GL_TRIANGLE_STRIP;
108
109
	return va;
110
}
111
112 70
static VertexArray* cylinderva = nil;
113
114 5
+ (VertexArray*) sharedCylinder
115
{
116 70
	VertexArray* va = cylinderva;
117 5
	if (!va)
118
	{
119
		va = [[VertexArray alloc] init];
120 70
		cylinderva = va;
121 42
		size_t divisions = 72;
122 5
		
123
		va->numVertices = (divisions+1)*2;
124 73
		PositionNormalTex3f3f2f* vertices = calloc(va->numVertices,sizeof(*vertices));
125
		va->_vertices = vertices;
126
		va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
127
		
128 5
		for (size_t i = 0; i <= divisions; ++i)
129
		{
130
			float t = (float)i/(float)divisions;
131
			float alpha = t*2.0*M_PI;
132
			float sina = sinf(alpha);
133
			float cosa = cosf(alpha);
134
			
135 73
			vertices[2*i].pos[0] = cosa;
136
			vertices[2*i].pos[1] = sina;
137
			vertices[2*i].pos[2] = 1.0;
138
			vertices[2*i+1].pos[0] = cosa;
139
			vertices[2*i+1].pos[1] = sina;
140
			vertices[2*i+1].pos[2] = -1.0;
141
142
			vertices[2*i].normal[0] = cosa;
143
			vertices[2*i].normal[1] = sina;
144
			vertices[2*i].normal[2] = 0.0;
145
			vertices[2*i+1].normal[0] = cosa;
146
			vertices[2*i+1].normal[1] = sina;
147
			vertices[2*i+1].normal[2] = 0.0;
148
149
			vertices[2*i].texcoord[0] = t;
150
			vertices[2*i].texcoord[1] = 0.0;
151
			vertices[2*i+1].texcoord[0] = t;
152
			vertices[2*i+1].texcoord[1] = 1.0;
153 5
		}
154
	}
155
	
156
	va->mode = GL_TRIANGLE_STRIP;
157
	return va;
158
}
159
160 70
static VertexArray* diskva = nil;
161
162 5
+ (VertexArray*) sharedDisk
163
{
164 70
	VertexArray* va = diskva;
165 5
	if (!va)
166
	{
167
		va = [[VertexArray alloc] init];
168 70
		diskva = va;
169 5
		
170 42
		unsigned divisions = 72;
171 5
		
172
		va->numVertices = (divisions+1) + 1;
173 73
		PositionNormalTex3f3f2f* vertices = calloc(va->numVertices,sizeof(*vertices));
174
		va->_vertices = vertices;
175
		va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
176 5
177 73
		vertices->pos[0] = 0.0;
178
		vertices->pos[1] = 0.0;
179
		vertices->pos[2] = 0.0;
180
		vertices->normal[0] = 0.0;
181
		vertices->normal[1] = 0.0;
182
		vertices->normal[2] = 1.0;
183
		vertices->texcoord[0] = 0.5;
184
		vertices->texcoord[1] = 0.5;
185 5
		for (size_t i = 0; i <= divisions; ++i)
186
		{
187
			float t = (float)i/(float)divisions;
188
			float alpha = t*2.0*M_PI;
189
			float sina = sinf(alpha);
190
			float cosa = cosf(alpha);
191
			
192 73
			vertices[i+1].pos[0] = cosa;
193
			vertices[i+1].pos[1] = sina;
194
			vertices[i+1].pos[2] = 0.0;
195
196
			vertices[i+1].normal[0] = 0.0;
197
			vertices[i+1].normal[1] = 0.0;
198
			vertices[i+1].normal[2] = 1.0;
199
200
			vertices[i+1].texcoord[0] = 0.5 + 0.5*cosa;
201
			vertices[i+1].texcoord[1] = 0.5 - 0.5*sina;
202 5
		}
203
	}
204
	
205
	va->mode = GL_TRIANGLE_FAN;
206
	return va;
207
}
208
209 70
static VertexArray* quadva = nil;
210
211 23
+ (VertexArray*) sharedQuad
212
{
213 70
	VertexArray* va = quadva;
214 23
	if (!va)
215
	{
216
		va = [[VertexArray alloc] init];
217 70
		quadva = va;
218 23
		
219
		va->numVertices = 4;
220 73
		PositionNormalTex3f3f2f* vertices = calloc(va->numVertices, sizeof(*vertices));
221
		va->_vertices = vertices;
222
		va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
223
		/*
224
		va->numIndices = 4;
225
		va->indices = calloc(sizeof(*va->indices), va->numIndices);
226
		for (size_t i = 0; i < 4; ++i)
227
			va->indices[i] = i;
228
		*/
229 23
230 73
		vertices[0].pos[0] = 1.0;
231
		vertices[0].pos[1] = -1.0;
232
		vertices[0].normal[2] = 1.0;
233
		vertices[0].texcoord[0] = 1.0;
234
		vertices[0].texcoord[1] = 0.0;
235
		vertices[1].pos[0] = 1.0;
236
		vertices[1].pos[1] = 1.0;
237
		vertices[1].normal[2] = 1.0;
238
		vertices[1].texcoord[0] = 1.0;
239
		vertices[1].texcoord[1] = 1.0;
240
		vertices[3].pos[0] = -1.0;
241
		vertices[3].pos[1] = 1.0;
242
		vertices[3].normal[2] = 1.0;
243
		vertices[3].texcoord[0] = 0.0;
244
		vertices[3].texcoord[1] = 1.0;
245
		vertices[2].pos[0] = -1.0;
246
		vertices[2].pos[1] = -1.0;
247
		vertices[2].normal[2] = 1.0;
248
		vertices[2].texcoord[0] = 0.0;
249
		vertices[2].texcoord[1] = 0.0;
250 23
	}
251
	
252
	va->mode = GL_TRIANGLE_STRIP;
253
	return va;
254
}
255
256 70
static VertexArray* sphereva = nil;
257 23
258 7
+ (VertexArray*) sharedSphere
259
{
260 70
	VertexArray* va = sphereva;
261 7
	if (!va)
262
	{
263
		va = [[VertexArray alloc] init];
264 70
		sphereva = va;
265 7
		
266 42
		unsigned londivisions = 72;
267
		unsigned latdivisions = 36;
268 7
		
269
		va->numVertices = (londivisions+1)*(latdivisions+1);
270 73
		PositionNormalTex3f3f2f* vertices = calloc(va->numVertices,sizeof(*vertices));
271
		va->_vertices = vertices;
272
		va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
273 7
		
274
		int soff = (latdivisions+1);
275
276
		for (size_t i = 0; i <= londivisions; ++i)
277
		{
278
			float ti = (float)i/(float)londivisions;
279
			float alpha = ti*2.0*M_PI;
280
			float sini = sinf(alpha);
281
			float cosi = cosf(alpha);
282
			for (size_t j = 0; j <= latdivisions; ++j)
283
			{
284
				float tj = (float)j/(float)latdivisions;
285
				float aj = tj*M_PI;
286
				float sinj = sinf(aj);
287
				float cosj = cosf(aj);
288
				
289 73
				vertices[i*soff + j].pos[0] = sinj*cosi;
290
				vertices[i*soff + j].pos[1] = sinj*sini;
291
				vertices[i*soff + j].pos[2] = cosj;
292
293
				vertices[i*soff + j].normal[0] = sinj*cosi;
294
				vertices[i*soff + j].normal[1] = sinj*sini;
295
				vertices[i*soff + j].normal[2] = cosj;
296
297
				vertices[i*soff + j].texcoord[0] = ti;
298
				vertices[i*soff + j].texcoord[1] = tj;
299 7
			}
300
		}
301
302
		va->numIndices = (londivisions)*(latdivisions+1)*2;
303 73
		va->indices = calloc(2*va->numIndices,sizeof(*va->indices));
304 7
		
305
		uint16_t* indices = va->indices;
306
		
307
		for (size_t i = 0; i < londivisions; ++i)
308
		{
309
			for (size_t j = 0; j <= latdivisions; ++j)
310
			{
311
				int x0 = i*soff + j;
312
				int x1 = (i+1)*soff + j;
313
				
314
				indices[2*(i*soff + j) + 0] = x1;
315
				indices[2*(i*soff + j) + 1] = x0;
316
			}
317
		}
318
		
319
	}
320
321
	
322
	
323
	va->mode = GL_TRIANGLE_STRIP;
324
	return va;
325
}
326
327 70
static VertexArray* xsemisphereva = nil;
328
329 7
+ (VertexArray*) sharedXSemiSphere
330
{
331 70
	VertexArray* va = xsemisphereva;
332 7
	if (!va)
333
	{
334
		va = [[VertexArray alloc] init];
335 70
		xsemisphereva = va;
336
		
337 7
		
338 42
		unsigned londivisions = 36;
339
		unsigned latdivisions = 36;
340 7
		
341
		va->numVertices = (londivisions+1)*(latdivisions+1);
342 73
		PositionNormalTex3f3f2f* vertices = calloc(va->numVertices,sizeof(*vertices));
343
		va->_vertices = vertices;
344
		va->vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
345 7
		
346
		int soff = (latdivisions+1);
347
348
		for (size_t i = 0; i <= londivisions; ++i)
349
		{
350
			float ti = 0.5*(float)i/(float)londivisions - 0.25;
351
			float alpha = ti*2.0*M_PI;
352
			float sini = sinf(alpha);
353
			float cosi = cosf(alpha);
354
			for (size_t j = 0; j <= latdivisions; ++j)
355
			{
356
				float tj = (float)j/(float)latdivisions;
357
				float aj = tj*M_PI;
358
				float sinj = sinf(aj);
359
				float cosj = cosf(aj);
360
				
361 73
				vertices[i*soff + j].pos[0] = sinj*cosi;
362
				vertices[i*soff + j].pos[1] = sinj*sini;
363
				vertices[i*soff + j].pos[2] = cosj;
364
365
				vertices[i*soff + j].normal[0] = sinj*cosi;
366
				vertices[i*soff + j].normal[1] = sinj*sini;
367
				vertices[i*soff + j].normal[2] = cosj;
368
369
				vertices[i*soff + j].texcoord[0] = ti;
370
				vertices[i*soff + j].texcoord[1] = tj;
371 7
			}
372
		}
373
374
		va->numIndices = (londivisions)*(latdivisions+1)*2;
375 73
		va->indices = calloc(2*va->numIndices,sizeof(*va->indices));
376 7
		
377
		uint16_t* indices = va->indices;
378
		
379
		for (size_t i = 0; i < londivisions; ++i)
380
		{
381
			for (size_t j = 0; j <= latdivisions; ++j)
382
			{
383
				int x0 = i*soff + j;
384
				int x1 = (i+1)*soff + j;
385
				
386
				indices[2*(i*soff + j) + 0] = x1;
387
				indices[2*(i*soff + j) + 1] = x0;
388
			}
389
		}
390
		
391
	}
392
393
	
394
	
395
	va->mode = GL_TRIANGLE_STRIP;
396
	return va;
397
}
398
399 70
+ (void) releaseSharedObjects
400
{
401
	cylinderva = nil;
402
	diskva = nil;
403
	quadva = nil;
404
	sphereva = nil;
405
	xsemisphereva = nil;
406
}
407
408 7
409 5
- (id) init
410
{
411
	if (!(self = [super init]))
412
		return nil;
413
414 38
	
415
	usageHint = GL_STATIC_DRAW;
416 73
	vertexFormat = VA_FORMAT_POS3F_NORMAL3F_TEX2F;
417 70
	
418
	float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
419
	
420
	if (osVersion >= 4.0f)
421
		useVAO = YES;
422 5
423 74
	needsVertexBufferUpdate = YES;
424
	needsIndexBufferUpdate = YES;
425
426 5
	return self;
427
}
428
429 70
430 5
- (void) dealloc
431
{
432
	if (vertexBufferName)
433
		glDeleteBuffers(1, &vertexBufferName);
434 32
	if (indexBufferName)
435
		glDeleteBuffers(1, &indexBufferName);
436 70
	if (vertexArrayObject)
437
		glDeleteVertexArraysOES(1, &vertexArrayObject);
438 5
	
439 73
	if (_vertices)
440
		free(_vertices);
441 5
442 32
	if (indices)
443
		free(indices);
444
445 5
}
446
447 32
- (id) initWithCoder: (NSCoder*) coder
448
{
449
	if (!(self = [super init]))
450
		return nil;
451
452 38
	usageHint = [coder decodeIntegerForKey: @"usageHint"];
453 32
	mode = [coder decodeIntegerForKey: @"mode"];
454 73
	vertexFormat = [coder decodeIntegerForKey: @"vertexFormat"];
455 32
	numVertices = [coder decodeIntegerForKey: @"numVertices"];
456
	numIndices = [coder decodeIntegerForKey: @"numIndices"];
457
	
458 73
	_vertices = calloc(_sizeofFormat(vertexFormat),numVertices);
459
	indices = calloc(sizeof(*indices),numIndices);
460 32
	
461 73
	memcpy(_vertices, [[coder decodeObjectForKey: @"vertices"] bytes], _sizeofFormat(vertexFormat)*numVertices);
462 32
	memcpy(indices, [[coder decodeObjectForKey: @"indices"] bytes], sizeof(*indices)*numIndices);
463
464 70
	float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
465
	
466
	if (osVersion >= 4.0f)
467
		useVAO = YES;
468 32
469 74
	needsVertexBufferUpdate = YES;
470
	needsIndexBufferUpdate = YES;
471
472 32
	return self;
473
}
474
475
- (void) encodeWithCoder: (NSCoder*) coder
476
{
477 38
	[coder encodeInteger: usageHint forKey: @"usageHint"];
478 32
	[coder encodeInteger: mode forKey: @"mode"];
479 73
	[coder encodeInteger: vertexFormat forKey: @"vertexFormat"];
480 32
	[coder encodeInteger: numVertices forKey: @"numVertices"];
481
	[coder encodeInteger: numIndices forKey: @"numIndices"];
482 73
	[coder encodeObject: [NSData dataWithBytes: _vertices length: _sizeofFormat(vertexFormat)*numVertices] forKey: @"vertices"];
483 32
	[coder encodeObject: [NSData dataWithBytes: indices length: sizeof(*indices)*numIndices] forKey: @"indices"];
484
}
485
486 70
- (void) setupArrayState
487
{
488
	glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
489
	
490
	if (indexBufferName)
491
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
492 73
	else
493
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
494 70
495
	EAGLRenderingAPI api = [[EAGLContext currentContext] API];
496
497
	switch(api)
498
	{
499
		case kEAGLRenderingAPIOpenGLES2:
500 73
			switch (vertexFormat)
501
			{
502
				case VA_FORMAT_POS3F_NORMAL3F_TEX2F:
503
					glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
504
					glVertexAttribPointer(NORMAL_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
505
					glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
506
507
					glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
508
					glEnableVertexAttribArray(NORMAL_ATTRIB_INDEX);
509 86
					glDisableVertexAttribArray(COLOR_ATTRIB_INDEX);
510
					glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
511
512
					break;
513
				case VA_FORMAT_POS3F_COL4B_TEX2F:
514
					glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,pos));
515
					glVertexAttribPointer(COLOR_ATTRIB_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,color));
516
					glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,texcoord));
517
518
					glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
519
					glDisableVertexAttribArray(NORMAL_ATTRIB_INDEX);
520
					glEnableVertexAttribArray(COLOR_ATTRIB_INDEX);
521 73
					glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
522
523
					break;
524
				case VA_FORMAT_POS3F_TEX2F:
525
					glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionTex3f2f), (void*)offsetof(PositionTex3f2f,pos));
526
					glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(PositionTex3f2f), (void*)offsetof(PositionTex3f2f,texcoord));
527
528
					glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
529
					glDisableVertexAttribArray(NORMAL_ATTRIB_INDEX);
530 86
					glDisableVertexAttribArray(COLOR_ATTRIB_INDEX);
531 73
					glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
532
533
					break;
534
				case VA_FORMAT_POS3F:
535
					glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(Position3f), (void*)offsetof(Position3f,pos));
536
537
					glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
538
					glDisableVertexAttribArray(NORMAL_ATTRIB_INDEX);
539 86
					glDisableVertexAttribArray(COLOR_ATTRIB_INDEX);
540 73
					glDisableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
541
542
					break;
543
				default:
544
					assert(0);
545
			}
546 70
			break;
547
548
		case kEAGLRenderingAPIOpenGLES1:
549 73
			switch (vertexFormat)
550
			{
551
				case VA_FORMAT_POS3F_NORMAL3F_TEX2F:
552
					glNormalPointer(GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
553
					glTexCoordPointer(2, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
554
					glVertexPointer(3, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
555
					
556
					glEnableClientState(GL_VERTEX_ARRAY);
557
					glEnableClientState(GL_NORMAL_ARRAY);
558 86
					glDisableClientState(GL_COLOR_ARRAY);
559
					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
560
					break;
561
					
562
				case VA_FORMAT_POS3F_COL4B_TEX2F:
563
					glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,color));
564
					glTexCoordPointer(2, GL_FLOAT, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,texcoord));
565
					glVertexPointer(3, GL_FLOAT, sizeof(PositionColorTex3f4b2f), (void*)offsetof(PositionColorTex3f4b2f,pos));
566
					
567
					glEnableClientState(GL_VERTEX_ARRAY);
568
					glDisableClientState(GL_NORMAL_ARRAY);
569
					glEnableClientState(GL_COLOR_ARRAY);
570 73
					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
571
					break;
572
					
573
				case VA_FORMAT_POS3F_TEX2F:
574
					glTexCoordPointer(2, GL_FLOAT, sizeof(PositionTex3f2f), (void*)offsetof(PositionTex3f2f,texcoord));
575
					glVertexPointer(3, GL_FLOAT, sizeof(PositionTex3f2f), (void*)offsetof(PositionTex3f2f,pos));
576
					
577
					glEnableClientState(GL_VERTEX_ARRAY);
578
					glDisableClientState(GL_NORMAL_ARRAY);
579 86
					glDisableClientState(GL_COLOR_ARRAY);
580 73
					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
581
					break;
582
					
583
				case VA_FORMAT_POS3F:
584
					glVertexPointer(3, GL_FLOAT, sizeof(Position3f), (void*)offsetof(Position3f,pos));
585
					
586
					glEnableClientState(GL_VERTEX_ARRAY);
587
					glDisableClientState(GL_NORMAL_ARRAY);
588 86
					glDisableClientState(GL_COLOR_ARRAY);
589 73
					glDisableClientState(GL_TEXTURE_COORD_ARRAY);
590
					break;
591
				default:
592
					assert(0);
593
			}
594 70
			break;
595
			
596
		default:
597
			[[NSException exceptionWithName: @"com.elmonkey.invalidShader" reason: @" OpenGL ES API selected not supported by VertexArray." userInfo: nil] raise];
598
			break;
599
	}
600
}
601
602
603 5
- (void) generateVBO
604
{
605 71
	BOOL regenVAO = !vertexBufferName && useVAO;
606
607 5
	if (!vertexBufferName)
608
	{
609
		glGenBuffers(1, &vertexBufferName);
610 86
		glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
611
		glBufferData(GL_ARRAY_BUFFER, _sizeofFormat(vertexFormat)*numVertices, _vertices, usageHint);
612
		glBindBuffer(GL_ARRAY_BUFFER, 0);
613 74
	}
614
	if (needsVertexBufferUpdate)
615
	{
616 5
		glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
617 86
		glBufferSubData(GL_ARRAY_BUFFER, 0, _sizeofFormat(vertexFormat)*numVertices, _vertices);
618 73
		glBindBuffer(GL_ARRAY_BUFFER, 0);
619 74
		needsVertexBufferUpdate = NO;
620
	}
621
	if (!indexBufferName && numIndices)
622
	{
623
		glGenBuffers(1, &indexBufferName);
624 86
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
625
		glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2*numIndices, indices, usageHint);
626
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
627 74
	}
628
	if (indexBufferName && needsIndexBufferUpdate)
629
	{
630
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
631 86
		glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 2*numIndices, indices);
632 74
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
633
		needsIndexBufferUpdate = NO;
634
	}
635
636 70
	if (!vertexArrayObject && useVAO)
637
	{
638
		glGenVertexArraysOES(1, &vertexArrayObject);
639 71
		regenVAO = YES;
640
	}
641
	if (regenVAO)
642
	{
643 70
		glBindVertexArrayOES(vertexArrayObject);
644
		
645
		[self setupArrayState];
646
		glBindVertexArrayOES(0);
647
	}
648 5
}
649
650 39
- (void) convertTriangleIndicesToLines
651
{
652 74
	uint16_t* tris = NULL;
653
	@synchronized(self)
654 39
	{
655 74
		tris = indices;
656
		indices = calloc(sizeof(*indices), numIndices*2);
657
		
658
		for (size_t i = 0; i < numIndices/3; ++i)
659
		{
660
			indices[6*i+0] = tris[3*i+0];
661
			indices[6*i+1] = tris[3*i+1];
662
			indices[6*i+2] = tris[3*i+1];
663
			indices[6*i+3] = tris[3*i+2];
664
			indices[6*i+4] = tris[3*i+2];
665
			indices[6*i+5] = tris[3*i+0];
666
		}
667
		numIndices *= 2;
668
		mode = GL_LINES;
669
		needsIndexBufferUpdate = YES;
670 39
	}
671
	free(tris);
672
}
673 40
- (void) convertPseudoQuadIndicesToLines
674
{
675 74
	uint16_t* tris = NULL;
676
	@synchronized(self)
677 40
	{
678 74
		tris = indices;
679
		indices = calloc(sizeof(*indices), numIndices*2);
680
		size_t ii = 0;
681
		for (size_t i = 0; i < numIndices/3; ++i)
682
		{
683
			indices[ii++] = tris[3*i+0];
684
			indices[ii++] = tris[3*i+1];
685
			indices[ii++] = tris[3*i+2];
686
			indices[ii++] = tris[3*i+0];
687
		}
688
		numIndices = ii;
689
		mode = GL_LINES;
690
		needsIndexBufferUpdate = YES;
691 40
	}
692
	free(tris);
693
}
694
695 39
696 5
- (void) draw
697
{
698 88
	if (!numVertices)
699
		return;
700
	
701 74
	@synchronized(self)
702
	{
703
704 5
		[self generateVBO];
705
706 74
		if (useVAO)
707
		{
708
			glBindVertexArrayOES(vertexArrayObject);
709
		}
710
		else
711
		{
712
			[self setupArrayState];
713
		}
714
		
715
		if (!indexBufferName)
716
			glDrawArrays(mode, 0, numVertices);
717
		else
718
			glDrawElements(mode, numIndices, GL_UNSIGNED_SHORT, (void*)0);
719
		
720
	}
721
722 70
	if (useVAO)
723
		glBindVertexArrayOES(0);
724 5
	
725 21
	GLenum err = glGetError();
726
	if(err)
727
	{
728
		assert(err);
729
	};
730 5
}
731
732 89
- (void) drawRangeFrom: (int) fromi to: (int) toi
733
{
734
	int numi = toi-fromi;
735
	assert(numi >= 0);
736
	assert(fromi >= 0);
737
	
738
	@synchronized(self)
739
	{
740
741
		[self generateVBO];
742
743
		if (useVAO)
744
		{
745
			glBindVertexArrayOES(vertexArrayObject);
746
		}
747
		else
748
		{
749
			[self setupArrayState];
750
		}
751
		
752
		if (!indexBufferName)
753
		{
754 96
			assert(toi <= (int)numVertices);
755 89
			glDrawArrays(mode, fromi, numi);
756
		}
757
		else
758
		{
759 96
			assert(toi <= (int)numIndices);
760 89
			glDrawElements(mode, numi, GL_UNSIGNED_SHORT, (void*)(2*fromi));
761
		}
762
	}
763
764
	if (useVAO)
765
		glBindVertexArrayOES(0);
766
	
767
	GLenum err = glGetError();
768
	if(err)
769
	{
770
		assert(err);
771
	};
772
}
773
774 15
- (void) applyVertexTransform: (m16) m
775
{
776 74
	@synchronized(self)
777 73
	{
778 74
		switch (vertexFormat)
779
		{
780
			case VA_FORMAT_POS3F_NORMAL3F_TEX2F:
781
			{
782
				PositionNormalTex3f3f2f* vertices = _vertices;
783
				for (size_t i = 0; i < numVertices; ++i)
784
				{
785
					v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
786
					v = mtransformpos3(m, v);
787
					vertices[i].pos[0] = v.a[0];
788
					vertices[i].pos[1] = v.a[1];
789
					vertices[i].pos[2] = v.a[2];
790
				}
791
				
792
				break;
793
			}
794 86
			case VA_FORMAT_POS3F_COL4B_TEX2F:
795
			{
796
				PositionColorTex3f4b2f* vertices = _vertices;
797
				for (size_t i = 0; i < numVertices; ++i)
798
				{
799
					v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
800
					v = mtransformpos3(m, v);
801
					vertices[i].pos[0] = v.a[0];
802
					vertices[i].pos[1] = v.a[1];
803
					vertices[i].pos[2] = v.a[2];
804
				}
805
				
806
				break;
807
			}
808 74
			case VA_FORMAT_POS3F_TEX2F:
809
			{
810
				PositionTex3f2f* vertices = _vertices;
811
				for (size_t i = 0; i < numVertices; ++i)
812
				{
813
					v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
814
					v = mtransformpos3(m, v);
815
					vertices[i].pos[0] = v.a[0];
816
					vertices[i].pos[1] = v.a[1];
817
					vertices[i].pos[2] = v.a[2];
818
				}
819
				
820
				break;
821
			}
822
			case VA_FORMAT_POS3F:
823
			{
824
				Position3f* vertices = _vertices;
825
				for (size_t i = 0; i < numVertices; ++i)
826
				{
827
					v3 v = {{vertices[i].pos[0], vertices[i].pos[1], vertices[i].pos[2]}};
828
					v = mtransformpos3(m, v);
829
					vertices[i].pos[0] = v.a[0];
830
					vertices[i].pos[1] = v.a[1];
831
					vertices[i].pos[2] = v.a[2];
832
				}
833
				
834
				break;
835
			}
836
			default:
837
				assert(0);
838
		}
839
		needsVertexBufferUpdate = YES;
840 73
	}
841
}
842
843
- (void) disposeOfNormals
844
{
845 74
	@synchronized(self)
846 73
	{
847 74
		switch (vertexFormat)
848
		{
849
			case VA_FORMAT_POS3F_NORMAL3F_TEX2F:
850
			{
851
				PositionNormalTex3f3f2f* vertices = _vertices;
852
				PositionTex3f2f* nvertices = calloc(sizeof(*nvertices),numVertices);
853
				for (size_t i = 0; i < numVertices; ++i)
854
				{
855
					nvertices[i].pos[0] = vertices[i].pos[0];
856
					nvertices[i].pos[1] = vertices[i].pos[1];
857
					nvertices[i].pos[2] = vertices[i].pos[2];
858
					nvertices[i].texcoord[0] = vertices[i].texcoord[0];
859
					nvertices[i].texcoord[1] = vertices[i].texcoord[1];
860
				}
861
				free(vertices);
862
				_vertices = nvertices;
863
				vertexFormat = VA_FORMAT_POS3F_TEX2F;
864
				
865
				needsVertexBufferUpdate = YES;
866
				break;
867
			}
868 86
			case VA_FORMAT_POS3F_COL4B_TEX2F:
869
			{
870
				break;
871
			}
872 74
			case VA_FORMAT_POS3F_TEX2F:
873
			{
874
				break;
875
			}
876
			case VA_FORMAT_POS3F:
877
			{			
878
				break;
879
			}
880
			default:
881
				assert(0);
882
		}
883 73
	}
884 15
}
885
886 75
- (size_t) memoryUsage
887
{
888 94
	return malloc_size((__bridge void*)self) + _sizeofFormat(vertexFormat)*numVertices*2 + sizeof(*indices)*numIndices;
889 75
}
890 15
891 77
@synthesize numVertices;
892
893 5
@end
894
895

Loggerhead 1.17 is a web-based interface for Bazaar branches