+#ifdef BACKBUFFER_OPENGL
+ CGSize new_backbuffer_size;
+
+ {
+# ifndef USE_IPHONE
+ if (!ogl_ctx) {
+
+ NSOpenGLPixelFormat *pixfmt = [self getGLPixelFormat];
+
+ NSAssert (pixfmt, @"unable to create NSOpenGLPixelFormat");
+
+ [pixfmt retain]; // #### ???
+
+ // Fun: On OS X 10.7, the second time an OpenGL context is created, after
+ // the preferences dialog is launched in SaverTester, the context only
+ // lasts until the first full GC. Then it turns black. Solution is to
+ // reuse the OpenGL context after this point.
+ ogl_ctx = [[NSOpenGLContext alloc] initWithFormat:pixfmt
+ shareContext:nil];
+
+ // Sync refreshes to the vertical blanking interval
+ GLint r = 1;
+ [ogl_ctx setValues:&r forParameter:NSOpenGLCPSwapInterval];
+// check_gl_error ("NSOpenGLCPSwapInterval"); // SEGV sometimes. Too early?
+ }
+
+ [ogl_ctx makeCurrentContext];
+ check_gl_error ("makeCurrentContext");
+
+ // NSOpenGLContext logs an 'invalid drawable' when this is called
+ // from initWithFrame.
+ [ogl_ctx setView:self];
+
+ // Clear frame buffer ASAP, else there are bits left over from other apps.
+ glClearColor (0, 0, 0, 1);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+// glFinish ();
+// glXSwapBuffers (mi->dpy, mi->window);
+
+
+ // Enable multi-threading, if possible. This runs most OpenGL commands
+ // and GPU management on a second CPU.
+ {
+# ifndef kCGLCEMPEngine
+# define kCGLCEMPEngine 313 // Added in MacOS 10.4.8 + XCode 2.4.
+# endif
+ CGLContextObj cctx = CGLGetCurrentContext();
+ CGLError err = CGLEnable (cctx, kCGLCEMPEngine);
+ if (err != kCGLNoError) {
+ NSLog (@"enabling multi-threaded OpenGL failed: %d", err);
+ }
+ }
+
+ new_backbuffer_size = NSSizeToCGSize ([self bounds].size);
+
+# else // USE_IPHONE
+ if (!ogl_ctx) {
+ CAEAGLLayer *eagl_layer = (CAEAGLLayer *) self.layer;
+ eagl_layer.opaque = TRUE;
+ eagl_layer.drawableProperties = [self getGLProperties];
+
+ // Without this, the GL frame buffer is half the screen resolution!
+ eagl_layer.contentsScale = [UIScreen mainScreen].scale;
+
+ ogl_ctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
+ }
+
+ [EAGLContext setCurrentContext: ogl_ctx];
+
+ CGSize screen_size = [[[UIScreen mainScreen] currentMode] size];
+ // iPad, simulator: 768x1024
+ // iPad, physical: 1024x768
+ if (screen_size.width > screen_size.height) {
+ CGFloat w = screen_size.width;
+ screen_size.width = screen_size.height;
+ screen_size.height = w;
+ }
+
+ if (gl_framebuffer) glDeleteFramebuffersOES (1, &gl_framebuffer);
+ if (gl_renderbuffer) glDeleteRenderbuffersOES (1, &gl_renderbuffer);
+
+ glGenFramebuffersOES (1, &gl_framebuffer);
+ glBindFramebufferOES (GL_FRAMEBUFFER_OES, gl_framebuffer);
+
+ glGenRenderbuffersOES (1, &gl_renderbuffer);
+ glBindRenderbufferOES (GL_RENDERBUFFER_OES, gl_renderbuffer);
+
+// redundant?
+// glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_RGBA8_OES,
+// (int)size.width, (int)size.height);
+ [ogl_ctx renderbufferStorage:GL_RENDERBUFFER_OES
+ fromDrawable:(CAEAGLLayer*)self.layer];
+
+ glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,
+ GL_RENDERBUFFER_OES, gl_renderbuffer);
+
+ [self addExtraRenderbuffers:screen_size];
+
+ int err = glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES);
+ switch (err) {
+ case GL_FRAMEBUFFER_COMPLETE_OES:
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES:
+ NSAssert (0, @"framebuffer incomplete attachment");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES:
+ NSAssert (0, @"framebuffer incomplete missing attachment");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES:
+ NSAssert (0, @"framebuffer incomplete dimensions");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES:
+ NSAssert (0, @"framebuffer incomplete formats");
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED_OES:
+ NSAssert (0, @"framebuffer unsupported");
+ break;
+/*
+ case GL_FRAMEBUFFER_UNDEFINED:
+ NSAssert (0, @"framebuffer undefined");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
+ NSAssert (0, @"framebuffer incomplete draw buffer");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
+ NSAssert (0, @"framebuffer incomplete read buffer");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
+ NSAssert (0, @"framebuffer incomplete multisample");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ NSAssert (0, @"framebuffer incomplete layer targets");
+ break;
+ */
+ default:
+ NSAssert (0, @"framebuffer incomplete, unknown error 0x%04X", err);
+ break;
+ }
+
+ glViewport (0, 0, screen_size.width, screen_size.height);
+
+ new_backbuffer_size = initial_bounds;
+
+# endif // USE_IPHONE
+
+ check_gl_error ("startAnimation");
+
+// NSLog (@"%s / %s / %s\n", glGetString (GL_VENDOR),
+// glGetString (GL_RENDERER), glGetString (GL_VERSION));
+
+ [self enableBackbuffer:new_backbuffer_size];
+ }
+#endif // BACKBUFFER_OPENGL
+
+#ifdef USE_BACKBUFFER
+ [self createBackbuffer:new_backbuffer_size];
+#endif
+}