Question

This is not a duplicate of OpenGL ES 2 without GLKit

I've been programming OpenGL on iOS for 4 years and ES2 for almost 2. But with the addition of GLKit and Storyboards, and with the latest Xcode, the project templates are different. And there is no longer an OpenGL template that creates an EAGLView Class. I don't want to use GLKit. I prefer to always do things programmatically. I try to avoid nibs and I've never used storyboards before. But in this case below I'm leaving them as is from the template.

My steps:

I start with a new project and pick Single View Application. I run it and it runs fine with a white screen.

Next I go to Build Phases and add QuartzCore, OpenGLES.

Then I do New File and add an Objective-C class, make it a subclass of UIView and call it EAGLView. In the .h I import and the EAGLContext *context

In the .m in the initWithFrame I add this initialization code...

    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

    eaglLayer.opaque = TRUE;


    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                                    kEAGLColorFormatRGB565, kEAGLDrawablePropertyColorFormat,

                                    nil];

    // Creates the EAGLContext and set it as the current one.
    _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    if (!_context || ![EAGLContext setCurrentContext:_context])
    {
        NSLog(@"_context no workie!");
        return nil;
    }

In my ViewController.h I add @class EAGLView; and a property EAGLView *glView;

In the ViewController.m in the viewDidLoad I add:

CGRect rect = [[UIScreen mainScreen] applicationFrame];
int width=rect.size.width;
int height=rect.size.height;


glView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
if([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    glView.contentScaleFactor = [[UIScreen mainScreen] scale];
}
glView.contentMode = UIViewContentModeScaleToFill;
self.view = glView;

and I run it. I get this error message:

-[CALayer setDrawableProperties:]: unrecognized selector sent to instance 0x8e441c0

How does my CAEAGLLayer eaglLayer not have a selector of .drawableProperties? Did I miss a step somewhere?

* UPDATE *

I found this solution:

In the EAGLView.m I added the following:

+ (Class) layerClass
{
    return [CAEAGLLayer class];
}

And now it runs without crashing. Can anyone tell me why I need that?

Was it helpful?

Solution

You always needed to override this method. It seems the default layer class is the CALayer which has no setDrawableProperties: method. You can see the CAEAGLLayer is a subclass of the CALayer.

Somewhere along the pipeline something like this is called

[[[self class] layerClass] performSelector:@selector(setDrawableProperties:) withObject:properties];

which generates the exception without you overriding the layerClass method.

OTHER TIPS

OpenGL can only be use on [CAEAGLayer class], and

 + (Class) layerClass
{
    return [CAEAGLLayer class];
}

mean layer of this view is a CAEAGLayer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top