- (void)viewDidLoad { [super viewDidLoad]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!self.context) { NSLog(@"Failed to create ES context"); } if(!renderer) renderer = [RenderManager sharedManager]; tiles = [[TileSet alloc]init]; GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24; [self setupGL]; } - (void)setupGL { int width = [[self view] bounds].size.width; int height = [[self view] bounds].size.height; [EAGLContext setCurrentContext:self.context]; self.effect = [[GLKBaseEffect alloc] init]; self.effect.light0.enabled = GL_TRUE; self.effect.light0.diffuseColor = GLKVector4Make(0.4f,0.4f,1.0f); //Configure Buffers glGenFramebuffers(1,&framebuffer); glBindFramebuffer(GL_FRAMEBUFFER,framebuffer); glGenRenderbuffers(2,&colourRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER,colourRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER,GL_RGBA8_OES,width,height); glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_RENDERBUFFER,colourRenderBuffer); glGenRenderbuffers(3,&depthRenderBuffer); glBindRenderbuffer(GL_RENDERBUFFER,depthRenderBuffer); glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT16,GL_DEPTH_ATTACHMENT,depthRenderBuffer); //Confirm everything happened awesomely GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER) ; if(status != GL_FRAMEBUFFER_COMPLETE) { NSLog(@"Failed to make complete framebuffer object %x",status); } glEnable(GL_DEPTH_TEST); // Enable the OpenGL states we are going to be using when rendering glEnableClientState(GL_VERTEX_ARRAY); } - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.4f,1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBindFramebuffer(GL_FRAMEBUFFER,framebuffer); float iva[] = { 0.0,0.0,1.0,}; glVertexPointer(3,GL_FLOAT,sizeof(float) * 3,iva); glDrawArrays(GL_POINTS,4); } @end
使用此缓冲区清除(为灰色),但顶点数组没有任何渲染.我不知道该怎么做,由于技术的时代,没有太多关于如何正确使用glkit的信息.
解决方法
此外,在您的设置代码中,您正在创建帧缓冲区. GLKView为您完成此操作 – 实际上您正在告诉视图在viewDidLoad方法中使用24位深度缓冲区:
GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
那么你的glkView:drawInRect:上面的代码正在做的是:“绑定我手工制作的帧缓冲区,并将一些东西放入其中”.然后GLKView会自动呈现,但没有任何内容被吸引到你的手中,你只会被吸引到手工制作的缓冲区中.除非您需要额外的帧缓冲对象来执行渲染到纹理等任务,否则您根本不需要关注帧缓冲区创建 – 让GLKView自动执行此操作.
你应该在setupGL方法中(或者在设置中你喜欢的任何地方)做的是创建你应该记住执行绘制所需的openGL状态的顶点数组对象.然后,在glkView:drawInRect:方法中,您应该:
>使用glClear()清除.
>启用您的程序.
>绑定顶点数组对象(或者,如果您未使用VAO,则启用
适当的顶点属性指针).
>使用glDrawArrays()或glDrawElements()绘制数据.
GLKView自动将其上下文设置为当前,并在每个绘制周期之前绑定其framebuffer对象.
或许试着将GLKView更像是一个普通的UIView.它为您处理幕后的大部分openGL代码,让您只需告诉它需要绘制的内容.它有drawRect:代码就像一个普通的UIView – 在drawRect中有一个常规的UIView:你只需告诉它应该绘制什么,例如使用Core Graphics函数 – 你不要告诉它呈现自己.
然后最好将GLKViewController视为在幕后处理渲染循环的机制.您不需要实现计时器,甚至担心暂停进入后台的应用程序上的动画.您只需要覆盖update或glkViewControllerUpdate:方法(取决于您是子类还是委托)来更新openGL对象或视图矩阵的状态.