i start new opengles project xcode 4 , delete es2 references , calls (i want use es1 draw code). example project work fine on iphone 4 doesn't work on iphone 3g , ipod 2nd generation. hre modified code :
eaglview.m
#import <quartzcore/quartzcore.h> #import "eaglview.h" @interface eaglview (privatemethods) - (void)createframebuffer; - (void)deleteframebuffer; @end @implementation eaglview @synthesize context; // must implement method + (class)layerclass { return [caeagllayer class]; } //the eagl view stored in nib file. when it's unarchived it's sent -initwithcoder:. - (id)initwithcoder:(nscoder*)coder { self = [super initwithcoder:coder]; if (self) { caeagllayer *eagllayer = (caeagllayer *)self.layer; eagllayer.opaque = true; eagllayer.drawableproperties = [nsdictionary dictionarywithobjectsandkeys: [nsnumber numberwithbool:false], keagldrawablepropertyretainedbacking, keaglcolorformatrgba8, keagldrawablepropertycolorformat, nil]; } return self; } - (void)dealloc { [self deleteframebuffer]; [context release]; [super dealloc]; } - (void)setcontext:(eaglcontext *)newcontext { if (context != newcontext) { [self deleteframebuffer]; [context release]; context = [newcontext retain]; [eaglcontext setcurrentcontext:nil]; } } - (void)createframebuffer { if (context && !defaultframebuffer) { [eaglcontext setcurrentcontext:context]; // create default framebuffer object. glgenframebuffersoes(1, &defaultframebuffer); glbindframebufferoes(gl_framebuffer_oes, defaultframebuffer); // create color render buffer , allocate backing store. glgenrenderbuffersoes(1, &colorrenderbuffer); glbindrenderbufferoes(gl_renderbuffer_oes, colorrenderbuffer); [context renderbufferstorage:gl_renderbuffer_oes fromdrawable:(caeagllayer *)self.layer]; glgetrenderbufferparameterivoes(gl_renderbuffer_oes, gl_renderbuffer_width_oes, &framebufferwidth); glgetrenderbufferparameterivoes(gl_renderbuffer_oes, gl_renderbuffer_height_oes, &framebufferheight); glframebufferrenderbufferoes(gl_framebuffer_oes, gl_color_attachment0_oes, gl_renderbuffer_oes, colorrenderbuffer); if (glcheckframebufferstatusoes(gl_framebuffer_oes) != gl_framebuffer_complete_oes) nslog(@"failed make complete framebuffer object %x", glcheckframebufferstatusoes(gl_framebuffer_oes)); } } - (void)deleteframebuffer { if (context) { [eaglcontext setcurrentcontext:context]; if (defaultframebuffer) { gldeleteframebuffersoes(1, &defaultframebuffer); defaultframebuffer = 0; } if (colorrenderbuffer) { gldeleterenderbuffersoes(1, &colorrenderbuffer); colorrenderbuffer = 0; } } } - (void)setframebuffer { if (context) { [eaglcontext setcurrentcontext:context]; if (!defaultframebuffer) [self createframebuffer]; glbindframebufferoes(gl_framebuffer_oes, defaultframebuffer); glviewport(0, 0, framebufferwidth, framebufferheight); glmatrixmode(gl_projection); glloadidentity(); glorthof(0, framebufferwidth, framebufferheight, 0, 0, 1); glmatrixmode(gl_modelview); glloadidentity(); } } - (bool)presentframebuffer { bool success = false; if (context) { [eaglcontext setcurrentcontext:context]; glbindrenderbufferoes(gl_renderbuffer_oes, colorrenderbuffer); success = [context presentrenderbuffer:gl_renderbuffer_oes]; } return success; } - (void)layoutsubviews { // framebuffer re-created @ beginning of next setframebuffer method call. [self deleteframebuffer]; } @end
testviewcontroller.m
#import "testappdelegate.h" #import "testviewcontroller.h" #import "eaglview.h" // uniform index. enum { uniform_translate, num_uniforms }; glint uniforms[num_uniforms]; // attribute index. enum { attrib_vertex, attrib_color, num_attributes }; @interface testviewcontroller () @property (nonatomic, retain) eaglcontext *context; @property (nonatomic, assign) cadisplaylink *displaylink; @end @implementation pyrotexniviewcontroller @synthesize animating, context, displaylink; - (void)awakefromnib { eaglcontext *acontext = [[eaglcontext alloc] initwithapi:keaglrenderingapiopengles1]; if (!acontext) nslog(@"failed create es context"); else if (![eaglcontext setcurrentcontext:acontext]) nslog(@"failed set es context current"); self.context = acontext; [acontext release]; [(eaglview *)self.view setcontext:context]; [(eaglview *)self.view setframebuffer]; animating = false; animationframeinterval = 1; self.displaylink = nil; - (void)dealloc { // tear down context. if ([eaglcontext currentcontext] == context) [eaglcontext setcurrentcontext:nil]; [context release]; [eaglview dealloc]; [self stopanimation]; [super dealloc]; } - (nsinteger)animationframeinterval { return animationframeinterval; } - (void)setanimationframeinterval:(nsinteger)frameinterval { if (frameinterval >= 1) { animationframeinterval = frameinterval; if (animating) { [self stopanimation]; [self startanimation]; } } } - (void)startanimation { if (!animating) { cadisplaylink *adisplaylink = [[uiscreen mainscreen] displaylinkwithtarget:self selector:@selector(drawframe)]; [adisplaylink setframeinterval:animationframeinterval]; [adisplaylink addtorunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; self.displaylink = adisplaylink; animating = true; } } - (void)stopanimation { if (animating) { [self.displaylink invalidate]; self.displaylink = nil; animating = false; } } - (void)drawframe { [(eaglview *)self.view setframebuffer]; ......draw code here..... [(eaglview *)self.view presentframebuffer]; }
based on project scheme supposed work on opengles 1.1 devices ,but doesn't (this code work on iphone4) ! goes wrong here ? please me. thanks.
one problem cadisplaylink doesn't exist in ios versions earlier 3.1. can detect in awakefromnib this:
nsstring *reqsysver = @"3.1"; nsstring *currsysver = [[uidevice currentdevice] systemversion]; if ([currsysver compare:reqsysver options:nsnumericsearch] != nsorderedascending) mdisplaylinksupported = true;
and in startanimation can this
if (mdisplaylinksupported) { // cadisplaylink api new iphone sdk 3.1. compiling against earlier versions result in warning, can dismissed // if system version runtime check cadisplaylink exists in -initwithcoder:. runtime check ensures code // not called in system versions earlier 3.1. mdisplaylink = [nsclassfromstring(@"cadisplaylink") displaylinkwithtarget:self selector:@selector(drawview:)]; [mdisplaylink setframeinterval:1]; [mdisplaylink addtorunloop:[nsrunloop currentrunloop] formode:nsdefaultrunloopmode]; } else manimationtimer = [nstimer scheduledtimerwithtimeinterval:(nstimeinterval)(1.0 / 60.0) target:self selector:@selector(drawview:) userinfo:nil repeats:true];
and in stopanimation this:
if (manimating) { if (mdisplaylinksupported) { [mdisplaylink invalidate]; mdisplaylink = nil; } else { [manimationtimer invalidate]; manimationtimer = nil; } manimating = false; }
you need make drawframe's signature can handle animationtimer messages.
- (void) drawframe:(id)sender
anyway, code isn't using same variable names had since copied code, gist. incidentally, code derived older xcode template took account older ios versions didn't support display links.
Comments
Post a Comment