用GLKit绘图

bot*_*ptr 8 opengl-es ios ios5 glkit

我正在尝试使用opengl编写游戏,但是我在使用新的glkit类和iOS的默认模板时遇到了很多麻烦.

- (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, 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, width, height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 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, 0.4f, 0.4f, 1.0f);


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);


    float iva[] = {
        0.0,0.0,0.0,
        0.0,1.0,0.0,
        1.0,1.0,0.0,
        1.0,0.0,0.0,
    };

    glVertexPointer(3, GL_FLOAT, sizeof(float) * 3, iva);

    glDrawArrays(GL_POINTS, 0, 4);

}
@end
Run Code Online (Sandbox Code Playgroud)

有了这个,缓冲区清除(灰色),但顶点数组没有渲染.我不知道该怎么做,由于技术的时代,关于如何正确使用glkit的信息不多.

Stu*_*art 12

我没有在您的设置代码中看到任何加载着色器的内容 - 我认为您在代码中的某个位置执行此操作?

此外,在您的设置代码中,您正在创建帧缓冲区.这样GLKView做对你来说 - 实际上你是在告诉视图在你的viewDidLoad方法中使用24位深度缓冲:

GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
Run Code Online (Sandbox Code Playgroud)

所以你glkView:drawInRect:上面的代码正在做的是:"绑定我的手工制作的帧缓冲区,然后将一些东西放入其中".在GLKView随后自动显示本身,但什么也没有拉入它,你只吸进你的手工制作的缓冲区.除非您需要额外的帧缓冲对象来执行渲染到纹理等任务,否则您根本不需要关注帧缓冲区创建 - 让它GLKView自动执行.

您应该在您的setupGL方法中(或在设置中的任何位置)执行的操作是创建记住执行绘制所需的openGL状态的顶点数组对象.然后,在glkView:drawInRect:方法中你应该:

  1. 清楚使用glClear().
  2. 启用您的程序.
  3. 绑定顶点数组对象(或者,如果您不使用VAO,则启用适当的顶点属性指针).
  4. 使用glDrawArrays()或绘制数据glDrawElements().

GLKView自动设置它的上下文作为电流,并且每个绘图周期之前结合其帧缓冲区对象.

或许试着想象GLKView更像一个普通人UIView.它为您处理幕后的大部分openGL代码,让您只需告诉它需要绘制的内容.它有它的drawRect:代码就像一个普通的UIView-一个普通UIViewdrawRect:你只需告诉它应该使用核心图形绘制功能,例如-你不必再告诉它提出自己.

GLKViewController随后的处理作为幕后渲染循环的机制最好的思想.您不需要实现计时器,甚至担心暂停进入后台的应用程序上的动画.您只需要覆盖update or glkViewControllerUpdate:方法(取决于您是子类还是委托)来更新openGL对象或视图矩阵的状态.


Jim*_*imN 0

我还没有使用过 GLKit,但似乎你在绘制后没有显示你的帧缓冲区。在 iO 下使用 OpenGL ES 2 但没有 GLKit 的应用程序中,我通常在渲染循环结束时调用以下代码。

if(context) {
  [EAGLContext setCurrentContext:context];
  glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
  [context presentRenderbuffer:GL_RENDERBUFFER];
Run Code Online (Sandbox Code Playgroud)

}

正如我所说,我还没有使用过 GLKit,所以我希望这可能有用。

  • 在 GLKit 中,GLKView 将自动呈现自身并在每个渲染周期结束时丢弃不需要的渲染缓冲区。这不是代码的问题。详情请参阅我的回答。 (3认同)