failed to bind EAGLDrawable in CADisplayLink rende

2019-07-16 11:56发布

i use CADisplayLink render-loop callback to render a serial of image textures with openGLes. after CADisplayLink's first callback called, i just get these error output

Failed to bind EAGLDrawable: <CAEAGLLayer: 0x946bb40> to GL_RENDERBUFFER 2
Failed to make complete framebuffer object 8cd6

i setup the renderBuffer&frameBuffer and call glFramebufferRenderbuffer in controller's viewDidLoad stage, the return of glCheckFramebufferStatus is fine in that stage.

this is the code I'm using.

//GLKViewController.m
typedef struct {
    GLKVector3  positionCoords;
    GLKVector2  textureCoords;
}SceneVertex;

static const SceneVertex vertices[] =
{
    {{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f}}, // lower left corner
    {{ 1.0f, -1.0f, 0.0f}, {1.0f, 0.0f}}, // lower right corner
    {{-1.0f,  1.0f, 0.0f}, {0.0f, 1.0f}}, // upper left corner
    {{ 1.0f,  1.0f, 0.0f}, {1.0f, 1.0f}},
};

@interface myViewController ()  //glkViewController
@property (nonatomic) GLuint renderBuffer;
@property (nonatomic) GLuint frameBuffer;
@property (nonatomic) GLuint glBuffer;

@property (nonatomic) int renderWidth;
@property (nonatomic) int renderHeight;

@property(strong, nonatomic) CADisplayLink* displayLink;
@property(strong, nonatomic) EAGLContext* context;
@end

@implementation myViewController

-(void)setupBuffers
{

    glGenFramebuffers(1, &_frameBuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);

    glGenRenderbuffers(1, &_renderBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer);
    [self.context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer*)self.view.layer];
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, _renderBuffer);

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_renderWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_renderHeight);

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
        NSLog(@"AAfailed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }
    glGenBuffers(1,&_glBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _glBuffer);
    glBufferData(
                 GL_ARRAY_BUFFER,   // Initialize buffer contents
                 sizeof(vertices),  // Number of bytes to copy
                 vertices,          // Address of bytes to copy
                 GL_STATIC_DRAW);   // Hint: cache in GPU memory
}


-(void)loadView
{
    _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    self.view  = [[myView alloc] initWithFrame:[[UIScreen mainScreen] bounds] context:_context];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [EAGLContext setCurrentContext:self.context];
    [self setupBuffers];

    _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render)];
    [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    _displayLink.frameInterval = 1;
}

- (void)render
{
    myView *view = (myView*)self.view;
    NSData *image = [view getOneImage]; //if nil, return or sleep&reget;

    glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffer);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glViewport(0, 0, _renderWidth, _renderHeight);

    GLuint texture = -1;
    glGenTextures(1, &texture);

    glActiveTexture(GL_TEXTURE0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

    glTexImage2D(
                 GL_TEXTURE_2D, 0,           /* target, level */
                 GL_RGB,                    /* internal format */
                 _renderWidth, _renderHeight, 0,           /* width, height, border */
                 GL_RGB, GL_UNSIGNED_BYTE,   /* external format, type */
                 image.bytes                      /* pixels */
                 );

    glBindBuffer(GL_ARRAY_BUFFER,_glBuffer);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition,   // Identifies the attribute to use
                          3,                         // number of coordinates for attribute
                          GL_FLOAT,                  // data is floating point
                          GL_FALSE,                  // no fixed point scaling
                          sizeof(SceneVertex),      // total num bytes stored
                          NULL+offsetof(SceneVertex, positionCoords));

    glBindBuffer(GL_ARRAY_BUFFER, _glBuffer);
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0,   // Identifies the attribute to use
                          2,                         // number of coordinates for attribute
                          GL_FLOAT,                  // data is floating point
                          GL_FALSE,                  // no fixed point scaling
                          sizeof(SceneVertex),       // total num bytes stored per vertex
                          NULL+offsetof(SceneVertex, textureCoords));

    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDrawArrays(GL_TRIANGLES, 1, 4);


    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    [_context presentRenderbuffer:GL_RENDERBUFFER];
    glFlush();
    glDeleteTextures(1, &texture);
}
@end

//GLKView
@implementation myView
+ (Class)layerClass {
    return [CAEAGLLayer class];
}
- (id)initWithFrame:(CGRect)frame context:(EAGLContext *)context
{
    self = [super initWithFrame:frame];
    if (self) {
        self.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;

        self.context = context;
        CAEAGLLayer *layer= (CAEAGLLayer *)self.layer;
        self.images = [[NSMutableArray alloc] init];
        layer.opaque = YES;
        layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                        [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

        }
    return self;
}

@end


//APPDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];

    self.window.rootViewController = [[QCPViewController alloc]init];
    [self.window makeKeyAndVisible];
    return YES;
}

2条回答
家丑人穷心不美
2楼-- · 2019-07-16 12:29

This occurs when you try to draw an openGL view that isn't currently on screen. In my case, the view wasn't installed in the current size class in my storyboard.

If you are using storyboards, double check that the view is installed in the current size class

  1. Select the open GL view in the storyboard
  2. Go to the Attributes inspector

enter image description here

  1. Verify the view is installed in all size classes like below

enter image description here

查看更多
闹够了就滚
3楼-- · 2019-07-16 12:38

I'm experiencing the same thing. I'm creating and adding the SCNView on a callback from CADisplayLink. It is very laggy, it is not visible and the error shows up in console. When I just say dispatch_async(dispatch_get_main_queue(), ^{ /* code */ }); Then everything is fine.

查看更多
登录 后发表回答