rev |
line source |
nuclear@0
|
1 #import "glview.h"
|
nuclear@0
|
2 #include "game.h"
|
nuclear@0
|
3 #include "screen.h"
|
nuclear@0
|
4 #include "logger.h"
|
nuclear@0
|
5
|
nuclear@0
|
6 static GLView *view;
|
nuclear@0
|
7
|
nuclear@0
|
8 void request_redisplay()
|
nuclear@0
|
9 {
|
nuclear@0
|
10 // TODO
|
nuclear@0
|
11 }
|
nuclear@0
|
12
|
nuclear@0
|
13 void swap_buffers()
|
nuclear@0
|
14 {
|
nuclear@0
|
15 if(view) {
|
nuclear@0
|
16 [view swap_buffers];
|
nuclear@0
|
17 }
|
nuclear@0
|
18 }
|
nuclear@0
|
19
|
nuclear@0
|
20
|
nuclear@0
|
21 @implementation GLView
|
nuclear@0
|
22
|
nuclear@0
|
23 @synthesize animating;
|
nuclear@0
|
24 @dynamic anim_frame_interval;
|
nuclear@0
|
25
|
nuclear@0
|
26 // You must implement this method
|
nuclear@0
|
27 + (Class)layerClass
|
nuclear@0
|
28 {
|
nuclear@0
|
29 return [CAEAGLLayer class];
|
nuclear@0
|
30 }
|
nuclear@0
|
31
|
nuclear@0
|
32
|
nuclear@0
|
33 - (id)initWithFrame: (CGRect) frame
|
nuclear@0
|
34 {
|
nuclear@0
|
35 if((self = [super initWithFrame: frame]))
|
nuclear@0
|
36 {
|
nuclear@0
|
37 // Get the layer
|
nuclear@0
|
38 CAEAGLLayer *eaglLayer = (CAEAGLLayer*)self.layer;
|
nuclear@0
|
39
|
nuclear@0
|
40 //self.contentScaleFactor = 2.0;
|
nuclear@0
|
41
|
nuclear@0
|
42 eaglLayer.opaque = TRUE;
|
nuclear@0
|
43 eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:FALSE],
|
nuclear@0
|
44 kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8,
|
nuclear@0
|
45 kEAGLDrawablePropertyColorFormat, nil];
|
nuclear@0
|
46
|
nuclear@0
|
47 // initialize OpenGL ES context
|
nuclear@0
|
48 context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
|
nuclear@0
|
49 if(!context || ![EAGLContext setCurrentContext: context]) {
|
nuclear@0
|
50 [self release];
|
nuclear@0
|
51 return self;
|
nuclear@0
|
52 }
|
nuclear@0
|
53
|
nuclear@0
|
54 // create the framebuffer
|
nuclear@0
|
55 glGenFramebuffers(1, &fbo);
|
nuclear@0
|
56 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
nuclear@0
|
57
|
nuclear@0
|
58 glGenRenderbuffers(1, &rbuf_color);
|
nuclear@0
|
59 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
|
nuclear@0
|
60 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbuf_color);
|
nuclear@0
|
61
|
nuclear@0
|
62 glGenRenderbuffers(1, &rbuf_depth);
|
nuclear@0
|
63 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
|
nuclear@0
|
64 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
|
nuclear@0
|
65
|
nuclear@0
|
66 animating = FALSE;
|
nuclear@0
|
67 display_link_supported = FALSE;
|
nuclear@0
|
68 anim_frame_interval = 1;
|
nuclear@0
|
69 display_link = nil;
|
nuclear@0
|
70 anim_timer = nil;
|
nuclear@0
|
71
|
nuclear@0
|
72 // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
|
nuclear@0
|
73 // class is used as fallback when it isn't available.
|
nuclear@0
|
74 NSString *reqSysVer = @"3.1";
|
nuclear@0
|
75 NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
|
nuclear@0
|
76 if([currSysVer compare: reqSysVer options: NSNumericSearch] != NSOrderedAscending) {
|
nuclear@0
|
77 display_link_supported = TRUE;
|
nuclear@0
|
78 }
|
nuclear@0
|
79
|
nuclear@0
|
80 self.multipleTouchEnabled = 1;
|
nuclear@0
|
81
|
nuclear@0
|
82 if(!game_init()) {
|
nuclear@0
|
83 exit(1);
|
nuclear@0
|
84 }
|
nuclear@0
|
85 }
|
nuclear@0
|
86
|
nuclear@0
|
87 view = self;
|
nuclear@0
|
88 return self;
|
nuclear@0
|
89 }
|
nuclear@0
|
90
|
nuclear@0
|
91 - (void)drawView: (id)sender
|
nuclear@0
|
92 {
|
nuclear@0
|
93 game_display();
|
nuclear@0
|
94 }
|
nuclear@0
|
95
|
nuclear@0
|
96 - (void)swap_buffers
|
nuclear@0
|
97 {
|
nuclear@0
|
98 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
|
nuclear@0
|
99 [context presentRenderbuffer: GL_RENDERBUFFER];
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102 - (BOOL)resize: (CAEAGLLayer*)layer
|
nuclear@0
|
103 {
|
nuclear@0
|
104 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_color);
|
nuclear@0
|
105 [context renderbufferStorage: GL_RENDERBUFFER fromDrawable: layer];
|
nuclear@0
|
106 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &xsz);
|
nuclear@0
|
107 glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &ysz);
|
nuclear@0
|
108
|
nuclear@0
|
109 glBindRenderbuffer(GL_RENDERBUFFER, rbuf_depth);
|
nuclear@0
|
110 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, xsz, ysz);
|
nuclear@0
|
111
|
nuclear@0
|
112 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
nuclear@0
|
113 NSLog(@"resize failed, framebuffer incomplete\n");
|
nuclear@0
|
114 return FALSE;
|
nuclear@0
|
115 }
|
nuclear@0
|
116 assert(glGetError() == GL_NO_ERROR);
|
nuclear@0
|
117
|
nuclear@0
|
118 //current_screen()->reshape(xsz, ysz);
|
nuclear@0
|
119 return TRUE;
|
nuclear@0
|
120 }
|
nuclear@0
|
121
|
nuclear@0
|
122 - (void)layoutSubviews
|
nuclear@0
|
123 {
|
nuclear@0
|
124 [self resize: (CAEAGLLayer*)self.layer];
|
nuclear@0
|
125 [self drawView:nil];
|
nuclear@0
|
126 }
|
nuclear@0
|
127
|
nuclear@0
|
128 - (NSInteger)anim_frame_interval
|
nuclear@0
|
129 {
|
nuclear@0
|
130 return anim_frame_interval;
|
nuclear@0
|
131 }
|
nuclear@0
|
132
|
nuclear@0
|
133 - (void)setAnimationFrameInterval: (NSInteger)frameInterval
|
nuclear@0
|
134 {
|
nuclear@0
|
135 // Frame interval defines how many display frames must pass between each time the
|
nuclear@0
|
136 // display link fires. The display link will only fire 30 times a second when the
|
nuclear@0
|
137 // frame internal is two on a display that refreshes 60 times a second. The default
|
nuclear@0
|
138 // frame interval setting of one will fire 60 times a second when the display refreshes
|
nuclear@0
|
139 // at 60 times a second. A frame interval setting of less than one results in undefined
|
nuclear@0
|
140 // behavior.
|
nuclear@0
|
141 if(frameInterval >= 1) {
|
nuclear@0
|
142 anim_frame_interval = frameInterval;
|
nuclear@0
|
143
|
nuclear@0
|
144 if(animating) {
|
nuclear@0
|
145 [self stopAnimation];
|
nuclear@0
|
146 [self startAnimation];
|
nuclear@0
|
147 }
|
nuclear@0
|
148 }
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 - (void)startAnimation
|
nuclear@0
|
152 {
|
nuclear@0
|
153 if(!animating) {
|
nuclear@0
|
154 if(display_link_supported) {
|
nuclear@0
|
155 // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
|
nuclear@0
|
156 // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
|
nuclear@0
|
157 // not be called in system versions earlier than 3.1.
|
nuclear@0
|
158
|
nuclear@0
|
159 display_link = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
|
nuclear@0
|
160 [display_link setFrameInterval: anim_frame_interval];
|
nuclear@0
|
161 [display_link addToRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
|
nuclear@0
|
162 } else {
|
nuclear@0
|
163 anim_timer = [NSTimer scheduledTimerWithTimeInterval: (NSTimeInterval)((1.0 / 60.0) * anim_frame_interval)
|
nuclear@0
|
164 target: self selector: @selector(drawView:) userInfo: nil repeats: TRUE];
|
nuclear@0
|
165 }
|
nuclear@0
|
166
|
nuclear@0
|
167 animating = TRUE;
|
nuclear@0
|
168 }
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@0
|
171 - (void)stopAnimation
|
nuclear@0
|
172 {
|
nuclear@0
|
173 if(animating) {
|
nuclear@0
|
174 if(display_link_supported) {
|
nuclear@0
|
175 [display_link invalidate];
|
nuclear@0
|
176 display_link = nil;
|
nuclear@0
|
177 } else {
|
nuclear@0
|
178 [anim_timer invalidate];
|
nuclear@0
|
179 anim_timer = nil;
|
nuclear@0
|
180 }
|
nuclear@0
|
181
|
nuclear@0
|
182 animating = FALSE;
|
nuclear@0
|
183 }
|
nuclear@0
|
184 }
|
nuclear@0
|
185
|
nuclear@0
|
186 - (void)dealloc
|
nuclear@0
|
187 {
|
nuclear@0
|
188 game_cleanup();
|
nuclear@0
|
189
|
nuclear@0
|
190 if(fbo) {
|
nuclear@0
|
191 glDeleteFramebuffers(1, &fbo);
|
nuclear@0
|
192 fbo = 0;
|
nuclear@0
|
193 }
|
nuclear@0
|
194 if(rbuf_color) {
|
nuclear@0
|
195 glDeleteRenderbuffers(1, &rbuf_color);
|
nuclear@0
|
196 rbuf_color = 0;
|
nuclear@0
|
197 }
|
nuclear@0
|
198 if(rbuf_depth) {
|
nuclear@0
|
199 glDeleteRenderbuffers(1, &rbuf_depth);
|
nuclear@0
|
200 rbuf_depth = 0;
|
nuclear@0
|
201 }
|
nuclear@0
|
202
|
nuclear@0
|
203 if([EAGLContext currentContext] == context) {
|
nuclear@0
|
204 [EAGLContext setCurrentContext: nil];
|
nuclear@0
|
205 }
|
nuclear@0
|
206 [context release];
|
nuclear@0
|
207 context = nil;
|
nuclear@0
|
208
|
nuclear@0
|
209 [super dealloc];
|
nuclear@0
|
210 }
|
nuclear@0
|
211
|
nuclear@0
|
212 @end
|