RSS

(root)/iphone/common : 70 : source/VertexArray.m

To get this branch, use:
bzr branch /browse/iphone/common

« back to all changes in this revision

Viewing changes to source/VertexArray.m

Dömötör Gulyás
2010-08-08 17:59:45
Revision ID: dognotdog@gmail.com-20100808155945-d5p1gehk7jjd3dzo
adds method to free VertexArray resources for shared objects; changes +sharedQuad to have the tex coords rightside up; adds support for VAO on hardware supporting it; changes GLESView animation to be driven by CADisplayLink; ES2Shader can now set arbitrarily named uniforms in shaders, also gets better error checking

Show diffs side-by-side

added added

removed removed

32
32
 */
33
33
 
34
34
#import <OpenGLES/ES2/gl.h>
 
35
#import <OpenGLES/ES2/glext.h>
35
36
 
36
37
#import "VertexArray.h"
37
38
 
39
40
 
40
41
@implementation VertexArray
41
42
 
42
 
 
43
43
+ (VertexArray*) coneWithFraction: (float) fraction
44
44
{
45
45
        VertexArray* va = [[[VertexArray alloc] init] autorelease];
80
80
        return va;
81
81
}
82
82
 
 
83
static VertexArray* cylinderva = nil;
 
84
 
83
85
+ (VertexArray*) sharedCylinder
84
86
{
85
 
        static VertexArray* va = nil;
 
87
        VertexArray* va = cylinderva;
86
88
        if (!va)
87
89
        {
88
90
                va = [[VertexArray alloc] init];
 
91
                cylinderva = va;
89
92
                size_t divisions = 72;
90
93
                
91
94
                va->numVertices = (divisions+1)*2;
122
125
        return va;
123
126
}
124
127
 
 
128
static VertexArray* diskva = nil;
 
129
 
125
130
+ (VertexArray*) sharedDisk
126
131
{
127
 
        static VertexArray* va = nil;
 
132
        VertexArray* va = diskva;
128
133
        if (!va)
129
134
        {
130
135
                va = [[VertexArray alloc] init];
 
136
                diskva = va;
131
137
                
132
138
                unsigned divisions = 72;
133
139
                
166
172
        return va;
167
173
}
168
174
 
 
175
static VertexArray* quadva = nil;
 
176
 
169
177
+ (VertexArray*) sharedQuad
170
178
{
171
 
        static VertexArray* va = nil;
 
179
        VertexArray* va = quadva;
172
180
        if (!va)
173
181
        {
174
182
                va = [[VertexArray alloc] init];
175
 
                
 
183
                quadva = va;
176
184
                
177
185
                va->numVertices = 4;
178
186
                va->vertices = calloc(va->numVertices, sizeof(*va->vertices));
181
189
                va->vertices[0].pos[1] = -1.0;
182
190
                va->vertices[0].normal[2] = 1.0;
183
191
                va->vertices[0].texcoord[0] = 1.0;
184
 
                va->vertices[0].texcoord[1] = 1.0;
 
192
                va->vertices[0].texcoord[1] = 0.0;
185
193
                va->vertices[1].pos[0] = 1.0;
186
194
                va->vertices[1].pos[1] = 1.0;
187
195
                va->vertices[1].normal[2] = 1.0;
188
196
                va->vertices[1].texcoord[0] = 1.0;
189
 
                va->vertices[1].texcoord[1] = 0.0;
 
197
                va->vertices[1].texcoord[1] = 1.0;
190
198
                va->vertices[3].pos[0] = -1.0;
191
199
                va->vertices[3].pos[1] = 1.0;
192
200
                va->vertices[3].normal[2] = 1.0;
193
201
                va->vertices[3].texcoord[0] = 0.0;
194
 
                va->vertices[3].texcoord[1] = 0.0;
 
202
                va->vertices[3].texcoord[1] = 1.0;
195
203
                va->vertices[2].pos[0] = -1.0;
196
204
                va->vertices[2].pos[1] = -1.0;
197
205
                va->vertices[2].normal[2] = 1.0;
198
206
                va->vertices[2].texcoord[0] = 0.0;
199
 
                va->vertices[2].texcoord[1] = 1.0;
 
207
                va->vertices[2].texcoord[1] = 0.0;
200
208
        }
201
209
        
202
210
        va->mode = GL_TRIANGLE_STRIP;
203
211
        return va;
204
212
}
205
213
 
 
214
static VertexArray* sphereva = nil;
206
215
 
207
216
+ (VertexArray*) sharedSphere
208
217
{
209
 
        static VertexArray* va = nil;
 
218
        VertexArray* va = sphereva;
210
219
        if (!va)
211
220
        {
212
221
                va = [[VertexArray alloc] init];
 
222
                sphereva = va;
213
223
                
214
224
                unsigned londivisions = 72;
215
225
                unsigned latdivisions = 36;
270
280
        return va;
271
281
}
272
282
 
 
283
static VertexArray* xsemisphereva = nil;
 
284
 
273
285
+ (VertexArray*) sharedXSemiSphere
274
286
{
275
 
        static VertexArray* va = nil;
 
287
        VertexArray* va = xsemisphereva;
276
288
        if (!va)
277
289
        {
278
290
                va = [[VertexArray alloc] init];
 
291
                xsemisphereva = va;
 
292
                
279
293
                
280
294
                unsigned londivisions = 36;
281
295
                unsigned latdivisions = 36;
336
350
        return va;
337
351
}
338
352
 
 
353
+ (void) releaseSharedObjects
 
354
{
 
355
        [cylinderva release];
 
356
        cylinderva = nil;
 
357
        [diskva release];
 
358
        diskva = nil;
 
359
        [quadva release];
 
360
        quadva = nil;
 
361
        [sphereva release];
 
362
        sphereva = nil;
 
363
        [xsemisphereva release];
 
364
        xsemisphereva = nil;
 
365
}
 
366
 
339
367
 
340
368
- (id) init
341
369
{
344
372
 
345
373
        
346
374
        usageHint = GL_STATIC_DRAW;
 
375
        
 
376
        float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
 
377
        
 
378
        if (osVersion >= 4.0f)
 
379
                useVAO = YES;
347
380
 
348
381
        return self;
349
382
}
350
383
 
 
384
 
351
385
- (void) dealloc
352
386
{
353
387
        if (vertexBufferName)
354
388
                glDeleteBuffers(1, &vertexBufferName);
355
389
        if (indexBufferName)
356
390
                glDeleteBuffers(1, &indexBufferName);
 
391
        if (vertexArrayObject)
 
392
                glDeleteVertexArraysOES(1, &vertexArrayObject);
357
393
        
358
394
        if (vertices)
359
395
                free(vertices);
380
416
        memcpy(vertices, [[coder decodeObjectForKey: @"vertices"] bytes], sizeof(*vertices)*numVertices);
381
417
        memcpy(indices, [[coder decodeObjectForKey: @"indices"] bytes], sizeof(*indices)*numIndices);
382
418
 
 
419
        float osVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
 
420
        
 
421
        if (osVersion >= 4.0f)
 
422
                useVAO = YES;
383
423
 
384
424
        return self;
385
425
}
394
434
        [coder encodeObject: [NSData dataWithBytes: indices length: sizeof(*indices)*numIndices] forKey: @"indices"];
395
435
}
396
436
 
 
437
- (void) setupArrayState
 
438
{
 
439
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
 
440
        
 
441
        if (indexBufferName)
 
442
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
 
443
 
 
444
        EAGLRenderingAPI api = [[EAGLContext currentContext] API];
 
445
 
 
446
        switch(api)
 
447
        {
 
448
                case kEAGLRenderingAPIOpenGLES2:
 
449
                        glVertexAttribPointer(POSITION_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
 
450
                        glVertexAttribPointer(NORMAL_ATTRIB_INDEX, 3, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
 
451
                        glVertexAttribPointer(TEXCOORD_ATTRIB_INDEX, 2, GL_FLOAT, GL_FALSE, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
 
452
 
 
453
                        glEnableVertexAttribArray(POSITION_ATTRIB_INDEX);
 
454
                        glEnableVertexAttribArray(NORMAL_ATTRIB_INDEX);
 
455
                        glEnableVertexAttribArray(TEXCOORD_ATTRIB_INDEX);
 
456
 
 
457
                        break;
 
458
 
 
459
                case kEAGLRenderingAPIOpenGLES1:
 
460
                        glNormalPointer(GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,normal));
 
461
                        glTexCoordPointer(3, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,texcoord));
 
462
                        glVertexPointer(3, GL_FLOAT, sizeof(PositionNormalTex3f3f2f), (void*)offsetof(PositionNormalTex3f3f2f,pos));
 
463
                        
 
464
                        glEnableClientState(GL_VERTEX_ARRAY);
 
465
                        glEnableClientState(GL_NORMAL_ARRAY);
 
466
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
467
                        
 
468
                        break;
 
469
                        
 
470
                default:
 
471
                        [[NSException exceptionWithName: @"com.elmonkey.invalidShader" reason: @" OpenGL ES API selected not supported by VertexArray." userInfo: nil] raise];
 
472
                        break;
 
473
        }
 
474
}
 
475
 
 
476
 
397
477
- (void) generateVBO
398
478
{
399
479
        if (!vertexBufferName)
409
489
                        glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2*numIndices, indices, usageHint);
410
490
                }
411
491
        }
 
492
        if (!vertexArrayObject && useVAO)
 
493
        {
 
494
                glGenVertexArraysOES(1, &vertexArrayObject);
 
495
                glBindVertexArrayOES(vertexArrayObject);
 
496
                
 
497
                [self setupArrayState];
 
498
                glBindVertexArrayOES(0);
 
499
        }
412
500
}
413
501
 
414
502
- (void) convertTriangleIndicesToLines
452
540
        if (!vertexBufferName)
453
541
                [self generateVBO];
454
542
 
455
 
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferName);
 
543
        if (useVAO)
 
544
        {
 
545
                glBindVertexArrayOES(vertexArrayObject);
 
546
        }
 
547
        else
 
548
        {
 
549
                [self setupArrayState];
 
550
        }
456
551
        
457
 
        if (indexBufferName)
458
 
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferName);
459
 
 
460
 
        EAGLRenderingAPI api = [[EAGLContext currentContext] API];
461
 
 
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
 
 
491
552
        if (!indexBufferName)
492
553
                glDrawArrays(mode, 0, numVertices);
493
554
        else
494
555
                glDrawElements(mode, numIndices, GL_UNSIGNED_SHORT, (void*)0);
 
556
                
 
557
                
 
558
        if (useVAO)
 
559
                glBindVertexArrayOES(0);
495
560
        
496
561
        GLenum err = glGetError();
497
562
        if(err)

Loggerhead 1.17 is a web-based interface for Bazaar branches