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®et;
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;
}
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
I'm experiencing the same thing. I'm creating and adding the
SCNView
on a callback fromCADisplayLink
. It is very laggy, it is not visible and the error shows up in console. When I just saydispatch_async(dispatch_get_main_queue(), ^{ /* code */ });
Then everything is fine.