RSS

(root)/iphone/tappity : 60 : common/source/GLESView.m

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

« back to all changes in this revision

Viewing changes to common/source/GLESView.m

Dömötör Gulyás
2010-01-18 09:01:40
Revision ID: dognotdog@gmail.com-20100118080140-g8bc7z6dp9ilr8rt
made tappity a standalone tree

Show diffs side-by-side

added added

removed removed

1
 
//
2
 
//  GLESView.m
3
 
//  MarineCompass
4
 
//
5
 
//  Created by döme on 03.08.2009.
6
 
//
7
 
 
8
 
/*
9
 
 * Copyright (c) 2009 Doemoetoer Gulyas.
10
 
 * All rights reserved.
11
 
 *
12
 
 * Redistribution and use in source and binary forms, with or without
13
 
 * modification, are permitted provided that the following conditions
14
 
 * are met:
15
 
 * 1. Redistributions of source code must retain the above copyright
16
 
 *    notice, this list of conditions and the following disclaimer.
17
 
 * 2. Redistributions in binary form must reproduce the above copyright
18
 
 *    notice, this list of conditions and the following disclaimer in the
19
 
 *    documentation and/or other materials provided with the distribution.
20
 
 * 3. The name of the author may not be used to endorse or promote products
21
 
 *    derived from this software without specific prior written permission.
22
 
 *
23
 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24
 
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25
 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26
 
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27
 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28
 
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29
 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30
 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32
 
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
 
 */
34
 
 
35
 
 
36
 
#import "GLESView.h"
37
 
 
38
 
#import <QuartzCore/QuartzCore.h>
39
 
#import <OpenGLES/EAGLDrawable.h>
40
 
#import <CoreGraphics/CoreGraphics.h>
41
 
 
42
 
#import "geometry.h"
43
 
#import "VertexArray.h"
44
 
#import "ESShader.h"
45
 
 
46
 
 
47
 
@interface ESShader (GLESView)
48
 
+ (void) setShaderAPI: (EAGLRenderingAPI) api;
49
 
@end
50
 
 
51
 
 
52
 
@implementation GLESView
53
 
 
54
 
+ (Class)layerClass
55
 
{
56
 
    return [CAEAGLLayer class];
57
 
}
58
 
 
59
 
- (void) lineGradientTexture: (GLuint*) texname red: (float) r green: (float) g blue: (float) b
60
 
{
61
 
        uint8_t* spriteData = calloc(1, 256 * 4);
62
 
        for (int i = 0; i < 256; ++i)
63
 
        {
64
 
                spriteData[4*i+0] = r*(float)i;
65
 
                spriteData[4*i+1] = g*(float)i;
66
 
                spriteData[4*i+2] = b*(float)i;
67
 
                spriteData[4*i+3] = i;
68
 
        }
69
 
 
70
 
        glGenTextures(1, texname);
71
 
        glBindTexture(GL_TEXTURE_2D, *texname);
72
 
 
73
 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
74
 
 
75
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
76
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
77
 
 
78
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
79
 
 
80
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
81
 
 
82
 
        free(spriteData);
83
 
}
84
 
 
85
 
- (void) doubleGradientTexture: (GLuint*) texname red: (float) r green: (float) g blue: (float) b
86
 
{
87
 
        uint8_t* spriteData = calloc(1, 512 * 4);
88
 
        for (int i = 0; i < 256; ++i)
89
 
        {
90
 
                spriteData[4*i+0] = r*(float)i;
91
 
                spriteData[4*i+1] = g*(float)i;
92
 
                spriteData[4*i+2] = b*(float)i;
93
 
                spriteData[4*i+3] = i;
94
 
        }
95
 
        
96
 
        for (int i = 256; i < 512; ++i)
97
 
        {
98
 
                spriteData[4*i+0] = r*(float)(511-i);
99
 
                spriteData[4*i+1] = g*(float)(511-i);
100
 
                spriteData[4*i+2] = b*(float)(511-i);
101
 
                spriteData[4*i+3] = (511-i);
102
 
        }
103
 
 
104
 
 
105
 
        glGenTextures(1, texname);
106
 
        glBindTexture(GL_TEXTURE_2D, *texname);
107
 
 
108
 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
109
 
 
110
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
111
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
112
 
 
113
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
114
 
 
115
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
116
 
 
117
 
        free(spriteData);
118
 
}
119
 
 
120
 
 
121
 
- (void) textureFromCgImage: (CGImageRef) img texName: (GLuint*) texname width: (size_t) width height: (size_t) height repeat: (BOOL) doRepeat mipmap: (BOOL) doMipmap filter: (BOOL) doFilter
122
 
{
123
 
        void* spriteData = malloc(width * height * 4);
124
 
        
125
 
        assert(img);
126
 
 
127
 
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
128
 
        CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
129
 
        CGColorSpaceRelease(colorSpace);
130
 
 
131
 
        CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), img);
132
 
        CGContextRelease(spriteContext);
133
 
        
134
 
        glGenTextures(1, texname);
135
 
        glBindTexture(GL_TEXTURE_2D, *texname);
136
 
 
137
 
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
138
 
 
139
 
        free(spriteData);
140
 
 
141
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, doRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
142
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, doRepeat ? GL_REPEAT : GL_CLAMP_TO_EDGE);
143
 
 
144
 
        if (doMipmap)
145
 
                glGenerateMipmap(GL_TEXTURE_2D);
146
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, doFilter ? (doMipmap ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : GL_NEAREST);
147
 
 
148
 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, doFilter ? GL_LINEAR : GL_NEAREST);
149
 
}
150
 
 
151
 
- (void) loadTextureFromBitmapNamed: (NSString*) name texName: (GLuint*) texname repeat: (BOOL) doRepeat mipmap: (BOOL) doMipmap filter: (BOOL) doFilter
152
 
{
153
 
 
154
 
        // Creates a Core Graphics image from an image file
155
 
        CGImageRef spriteImage = [UIImage imageNamed: name].CGImage;
156
 
        // Get the width and height of the image
157
 
        size_t width = CGImageGetWidth(spriteImage);
158
 
        size_t height = CGImageGetHeight(spriteImage);
159
 
 
160
 
 
161
 
        [self textureFromCgImage: spriteImage texName: texname width: width height: height repeat: doRepeat mipmap: doMipmap filter: doFilter];
162
 
        
163
 
}
164
 
 
165
 
static CGImageRef       CreateCGImageFromPDFPage(CGPDFDocumentRef document, size_t pageNumber, int width, int height)
166
 
{
167
 
 
168
 
        CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);
169
 
        if(!page)
170
 
                return NULL;
171
 
 
172
 
//      CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
173
 
 
174
 
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
175
 
//      void* data = malloc(4*width*height);
176
 
        CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
177
 
        CGColorSpaceRelease(colorSpace);
178
 
 
179
 
        if(!bitmapContext)
180
 
        {
181
 
                //free(data);
182
 
                return NULL;
183
 
        }
184
 
 
185
 
        CGAffineTransform M = CGPDFPageGetDrawingTransform(page, kCGPDFMediaBox, CGRectMake(0.0f, 0.0f, width, height), 0, NO);
186
 
        
187
 
        CGContextConcatCTM(bitmapContext, M);
188
 
        CGContextDrawPDFPage(bitmapContext, page);                                                                      
189
 
        CGImageRef pdfImage = CGBitmapContextCreateImage(bitmapContext);
190
 
        CFRelease(bitmapContext);
191
 
        //free(data);
192
 
        return pdfImage;  
193
 
 
194
 
195
 
 
196
 
static CGImageRef CreateImageFromPDFNamed(NSString* name, int width, int height)
197
 
{
198
 
        CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef) [[NSBundle mainBundle] pathForResource: name ofType: nil], 0, NO);
199
 
        CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL(url);
200
 
        CFRelease(url);
201
 
        assert(pdfDoc);
202
 
        
203
 
        CGImageRef img = CreateCGImageFromPDFPage(pdfDoc, 1, width, height);
204
 
        
205
 
        CGPDFDocumentRelease(pdfDoc);
206
 
        
207
 
        return img;
208
 
}
209
 
 
210
 
 
211
 
- (void) loadTextureFromPDFNamed: (NSString*) name texName: (GLuint*) texname width: (size_t) width height: (size_t) height repeat: (BOOL) doRepeat mipmap: (BOOL) doMipmap filter: (BOOL) doFilter
212
 
{
213
 
 
214
 
        CGImageRef img = CreateImageFromPDFNamed(name, width, height);
215
 
        [self textureFromCgImage: img texName: texname width: width height: height repeat: doRepeat mipmap: doMipmap filter: doFilter];
216
 
        CGImageRelease(img);
217
 
}
218
 
 
219
 
 
220
 
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
221
 
- (id)initWithCoder:(NSCoder*)coder {
222
 
    
223
 
    if (!(self = [super initWithCoder:coder]))
224
 
                return nil;
225
 
 
226
 
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
227
 
        
228
 
        eaglLayer.opaque = YES;
229
 
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
230
 
        
231
 
        context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
232
 
        if (!context)
233
 
                context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
234
 
        
235
 
        if (!context || ![EAGLContext setCurrentContext: context])
236
 
        {
237
 
                [self release];
238
 
                return nil;
239
 
        }
240
 
        
241
 
        animationInterval = 1.0 / 100.0;
242
 
                
243
 
        [self setupGraphicsForApi: [context API]];
244
 
 
245
 
    return self;
246
 
}
247
 
 
248
 
- (id)initWithFrame:(CGRect)frame {
249
 
    
250
 
    if (!(self = [super initWithFrame:frame]))
251
 
                return nil;
252
 
 
253
 
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
254
 
        
255
 
        eaglLayer.opaque = YES;
256
 
        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
257
 
        
258
 
        context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
259
 
        if (!context)
260
 
                context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
261
 
        
262
 
        if (!context || ![EAGLContext setCurrentContext: context])
263
 
        {
264
 
                [self release];
265
 
                return nil;
266
 
        }
267
 
        
268
 
        animationInterval = 1.0 / 100.0;
269
 
                
270
 
        [self setupGraphicsForApi: [context API]];
271
 
 
272
 
    return self;
273
 
}
274
 
 
275
 
 
276
 
 
277
 
- (void) setupGraphicsForApi: (EAGLRenderingAPI) glApi
278
 
{
279
 
        glClearColor(0.0,0.0,1.0,1.0);
280
 
}
281
 
 
282
 
 
283
 
- (void)dealloc 
284
 
{
285
 
    [self stopAnimation];
286
 
    
287
 
    if ([EAGLContext currentContext] == context)
288
 
        [EAGLContext setCurrentContext:nil];
289
 
    
290
 
    [context release];  
291
 
    [super dealloc];
292
 
}
293
 
 
294
 
 
295
 
- (void) setupViewDrawing
296
 
{
297
 
    [EAGLContext setCurrentContext:context];
298
 
    
299
 
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
300
 
    glViewport(0, 0, backingWidth, backingHeight);
301
 
 
302
 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
303
 
}
304
 
 
305
 
- (void) finishViewDrawing
306
 
{
307
 
        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
308
 
    [context presentRenderbuffer: GL_RENDERBUFFER];
309
 
        
310
 
        GLenum err = glGetError();
311
 
        if (err)
312
 
                NSLog(@"OpenGL error %d occured", err);
313
 
}
314
 
 
315
 
- (void) drawView
316
 
{
317
 
        [self setupViewDrawing];
318
 
        
319
 
        [self finishViewDrawing];
320
 
}
321
 
 
322
 
 
323
 
- (void)drawRect:(CGRect)rect
324
 
{
325
 
        [super drawRect: rect];
326
 
        
327
 
        [self drawView];
328
 
 
329
 
//      [[UIColor clearColor] set];
330
 
//      UIRectFill(rect);
331
 
}
332
 
 
333
 
- (void)animationCallback
334
 
{
335
 
 
336
 
}
337
 
 
338
 
 
339
 
- (void)startAnimation
340
 
{
341
 
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(animationCallback) userInfo:nil repeats:YES];
342
 
}
343
 
 
344
 
 
345
 
- (void)stopAnimation
346
 
{
347
 
    animationTimer = nil;
348
 
}
349
 
 
350
 
 
351
 
- (void)setAnimationTimer:(NSTimer *)newTimer
352
 
{
353
 
    [animationTimer invalidate];
354
 
    animationTimer = newTimer;
355
 
}
356
 
 
357
 
 
358
 
- (void)setAnimationInterval:(NSTimeInterval)interval
359
 
{
360
 
    
361
 
    animationInterval = interval;
362
 
    if (animationTimer) {
363
 
        [self stopAnimation];
364
 
        [self startAnimation];
365
 
    }
366
 
}
367
 
 
368
 
 
369
 
 
370
 
- (BOOL)createFramebuffer {
371
 
    
372
 
    glGenFramebuffers(1, &viewFramebuffer);
373
 
    glGenRenderbuffers(1, &viewRenderbuffer);
374
 
    
375
 
    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
376
 
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
377
 
    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.layer];
378
 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
379
 
    
380
 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
381
 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
382
 
    
383
 
    if (USE_DEPTH_BUFFER) {
384
 
        glGenRenderbuffers(1, &depthRenderbuffer);
385
 
        glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
386
 
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
387
 
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
388
 
    }
389
 
    
390
 
    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
391
 
        {
392
 
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
393
 
                NSLog(@"%f %f %f %f", self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
394
 
        return NO;
395
 
    }
396
 
    
397
 
    return YES;
398
 
}
399
 
 
400
 
 
401
 
- (void)destroyFramebuffer {
402
 
    
403
 
    glDeleteFramebuffers(1, &viewFramebuffer);
404
 
    viewFramebuffer = 0;
405
 
    glDeleteRenderbuffers(1, &viewRenderbuffer);
406
 
    viewRenderbuffer = 0;
407
 
    
408
 
    if(depthRenderbuffer)
409
 
        {
410
 
        glDeleteRenderbuffers(1, &depthRenderbuffer);
411
 
        depthRenderbuffer = 0;
412
 
    }
413
 
}
414
 
 
415
 
- (void)layoutSubviews {
416
 
    [EAGLContext setCurrentContext:context];
417
 
    [self destroyFramebuffer];
418
 
    [self createFramebuffer];
419
 
    [self drawView];
420
 
}
421
 
 
422
 
@synthesize animationInterval;
423
 
 
424
 
@end

Loggerhead 1.17 is a web-based interface for Bazaar branches