Let's say I have some C++ code that renders stuff in OpenGL ES. This code has it's own render loop which is the same on all platforms. One of the things that are OS dependent and have to be written for each platform separately is creating a window that is linked to an OpenGL context that is then used for drawing. I used the GLKView placed as a subview to the UIWindow but from what I've noticed the first attempt to render results in nothing and all that is visible for a while is a black screen.
The next iterations of the loop however render just fine. To see the problem more clearly here is a minimal code that behaves similarly:
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
assert(context);
GLKView *glView = [[GLKView alloc] initWithFrame:[[self window] frame] context:context];
[[self window] addSubview:glView];
[EAGLContext setCurrentContext:context];
prepareOpengl();
drawTriangle(); //GL_INVALID_FRAMEBUFFER_OPERATION
[self performSelector:@selector(drawTriangleWithContext:) withObject:context afterDelay:1.0]; //nice triangle
The prepareOpengl() function creates the buffers for vertices and whatnot and the drawTraingle() clears the buffers and draws a traingle. The first call results in GL_INVALID_FRAMEBUFFER_OPERATION and the one called by performSelector:afterDelay: draws just fine. This probably means that the GLKView defers the creation of it's renderbuffer.
I would really like to not have to wait for the first rendering and instead be able to draw immediately to the created context. Here is the whole demo project that shows the issue.
I think I got it. The trick is to explicitly call
bindDrawableon theGLKViewafter creating it. This in turn forces the creation of the renderbuffer.This is how it should be: