Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

failed to bind EAGLDrawable in CADisplayLink render loop

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;
}
like image 853
user3682618 Avatar asked Aug 14 '26 04:08

user3682618


1 Answers

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

like image 86
Charlie Martin Avatar answered Aug 16 '26 17:08

Charlie Martin