failed to bind EAGLDrawable in CADisplayLink render loop

纵然是瞬间 提交于 2019-12-24 02:22:20

问题


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;
}

回答1:


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

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




回答2:


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.



来源:https://stackoverflow.com/questions/26039275/failed-to-bind-eagldrawable-in-cadisplaylink-render-loop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!