Рисование с помощью GLKit - PullRequest
       46

Рисование с помощью GLKit

8 голосов
/ 18 октября 2011

Я пытаюсь написать игру с использованием 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.

Ответы [ 5 ]

12 голосов
/ 19 октября 2011

Я не вижу в вашем установочном коде ничего, что загружало бы ваши шейдеры - я предполагаю, что вы делаете это где-то в вашем коде?

Кроме того, в вашем установочном коде вы создаете свой кадровый буфер.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 - с обычным UIView в drawRect: вы просто указываете ему, что он должен рисовать, например, используя функции Core Graphics - вы не говорите ему представитьсам по себе.

В таком случае GLKViewController лучше всего рассматривать как обработку механики цикла рендеринга за сценой.Вам не нужно реализовывать таймеры или даже беспокоиться о приостановке анимации в вашем приложении, входящем в фоновый режим.Вам просто нужно переопределить метод update или glkViewControllerUpdate: (в зависимости от того, используете ли вы подклассы или делегировать), чтобы обновить состояние объектов openGL или матрицы представления.

1 голос
/ 27 марта 2012

Я сделал сообщение о том, как настроить базовый шаблон проекта с помощью GLKit. Вы можете найти его здесь:

Блог программиста Стива Зиссу

0 голосов
/ 05 декабря 2011

Поскольку GLKit имитирует конвейер рендеринга OpenGL ES 1.1, вам не нужно включать подпрограммы для определения шейдера.GLKit действительно делает это для вас, если вы хотите использовать базовый конвейер, такой как OpenGL ES1.1

0 голосов
/ 28 октября 2011

Я думаю, что вы забыли позвонить

[self.effect prepareToDraw];

как раз перед

glDrawArrays(GL_POINTS, 0, 4);
0 голосов
/ 18 октября 2011

Я еще не использовал GLKit, но кажется, что вы не представляете свой кадровый буфер после рисования в нем. В приложении, использующем OpenGL ES 2 под iOs, но без GLKit, я использую для вызова следующего кода в конце цикла рендеринга.

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

}

Как я уже сказал, я еще не использовал GLKit, поэтому я надеюсь, что это может быть полезно.

...