8

我正在尝试使用 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

这样,缓冲区就会清除(变为灰色),但顶点数组中的任何内容都不会呈现。我不知道从这里开始做什么,并且由于技术年代久远,没有太多关于如何正确使用 glkit 的信息。

4

5 回答 5

12

我在您的设置代码中看不到任何加载着色器的内容 - 我想您是在代码中的某个地方执行此操作?

此外,在您的设置代码中,您正在创建帧缓冲区。为您执行此GLKView操作 - 实际上您是在告诉视图在您的方法中使用 24 位深度缓冲区viewDidLoad

GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

所以你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 对象或视图矩阵的状态。

于 2011-10-19T01:16:03.487 回答
1

我发表了一篇关于使用 GLKit 设置基本项目模板的方法的帖子。你可以在这里找到它:

Steve Zissou 的编程博客

于 2012-03-27T15:11:06.787 回答
0

我想你忘了打电话

[self.effect prepareToDraw];

就在之前

glDrawArrays(GL_POINTS, 0, 4);
于 2011-10-28T10:45:34.513 回答
0

我还没有使用过 GLKit,但看起来你在绘制到它之后并没有展示你的帧缓冲区。在 iOs 下使用 OpenGL ES 2 但没有 GLKit 的应用程序中,我使用在渲染循环结束时调用以下代码。

if(context) {
  [EAGLContext setCurrentContext:context];
  glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
  [context presentRenderbuffer:GL_RENDERBUFFER];

}

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

于 2011-10-18T12:31:47.190 回答
0

由于 GLKit 模仿 OpenGL ES 1.1 渲染管道,因此您不需要包含定义着色器的例程。如果您希望使用像 OpenGL ES1.1 这样的基本管道,GLKit 实际上会为您执行此操作

于 2011-12-05T18:24:46.500 回答