Обрабатывать несколько сеток в Open GL ES 2.0 (iOS GLKit)? - PullRequest
4 голосов
/ 04 февраля 2012

Мне удалось создать одну сетку в Open GL ES 2.0 с помощью iOS GLKit. Чего я не могу понять, так это как создать вторую сетку, которая выглядит идентично первой, за исключением другой позиции.

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

  • Я создал два C-массива информации о вершинах. Первый - это мой шаблон (жестко запрограммированные координаты с центром в 0,0,0), а второй - то, что я хотел бы отобразить (изначально пустой).
  • Я создал два C-массива информации индексов. То же самое, что и с информацией о вершине.
  • У меня есть две глобальные переменные int, vertexCount и indiceCount, оба изначально равны 0.
  • У меня есть функция c, createAt (float x, float y, float z). Эта функция копирует мой шаблон вершины в мой массив отображения вершин и затем применяет переданные смещения к каждой вершине. Он также копирует индексы и применяет смещение, чтобы они указывали на новые вершины отображения.

Это не работает, хотя. На экране отображается только один объект.

Просматривая вопросы и ответы других людей, кажется, что у меня должно быть несколько буферов вершин? Я не знаю; Я ужасно смущен.

Ответы [ 3 ]

5 голосов
/ 06 февраля 2012

С помощью класса GLKBaseEffect рендеринг нескольких мешей с одинаковой геометрией, но разными позициями или ориентациями довольно прост.Взгляните на шаблон «OpenGL Game», предоставляемый XCode, который отображает куб с GLKit и другой куб с OpenGL ES 2.0.

Вот модификация образца OpenGL Game, которая добавляет новый куб над двумяВращающиеся:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object with GLKit
    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Render another version of the object with GLKit

    // First put it in a different place (you would normally
    // do this in the update loop):
    GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
    baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);    
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 1.5, -0.0f);
    modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
    self.effect.transform.modelviewMatrix = modelViewMatrix;

    // Now render it:
    [self.effect prepareToDraw];
    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Render the object again with ES2
    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLES, 0, 36);
}

Код между комментариями «Отобразить другую версию» и «Отобразить объект снова» является новым.Первое, что нужно сделать, - это создать новую матрицу просмотра модели для дополнительного куба;это основано на коде в update: (не показан).Обычно я размещал код там, но хотел, чтобы образец был коротким.

Затем он рендерит куб, что довольно просто с GLKit.Yay GLKit!

Screenshot of three cubes in Apple's GLKit / OpenGL Game sample

Надеюсь, это поможет.Похоже, вы лаете не на то дерево с дополнительными массивами вершин и индексов;это необходимо, если вы хотите визуализировать разные геометрии, но вы сказали, что одна и та же модель в разных местах.Это то, для чего GLKit идеально подходит.

0 голосов
/ 15 октября 2014

Джон Ризелвато комментирует выше, что он действительно хотел бы видеть обновление: метод содержимого.Я действительно хотел увидеть это сам, так как мне было трудно обернуть голову вокруг размещения нескольких объектов на экране, используя один и тот же объект GLKBaseEffect.Вот как я наконец это сделал:

// update method where I create 3 different modelViewMatrices to use with my GLKBaseEffect object later in the draw method
- (void)updateWithDeltaTime:(NSTimeInterval)deltaTime
{
    _rotation1 += 120.0 * deltaTime;
    _rotation2 += 150.0 * deltaTime;
    _rotation3 += 180.0 * deltaTime;

    GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
    modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, -1.0f, 0.0f, -4.0f);
    modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
    modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation1));
    _modelViewMatrix1 = modelViewMatrix;

    modelViewMatrix = GLKMatrix4Identity;
    modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0.0f, 0.0f, -4.0f);
    modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
    modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation2));
    _modelViewMatrix2 = modelViewMatrix;

    modelViewMatrix = GLKMatrix4Identity;
    modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 1.0f, 0.0f, -4.0f);
    modelViewMatrix = GLKMatrix4RotateY(modelViewMatrix, GLKMathDegreesToRadians(90.0f));
    modelViewMatrix = GLKMatrix4RotateZ(modelViewMatrix, GLKMathDegreesToRadians(_rotation3));
    _modelViewMatrix3 = modelViewMatrix;
}

// draw method where I re-use my GLKBaseEffect object, applying the 3 modelViewMatrices I set in the update: method above
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    _effect.transform.modelviewMatrix = _modelViewMatrix1;
    [_effect prepareToDraw];
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
    glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);

    _effect.transform.modelviewMatrix = _modelViewMatrix2;
    [_effect prepareToDraw];
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
    glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);

    _effect.transform.modelviewMatrix = _modelViewMatrix3;
    [_effect prepareToDraw];
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
    glDrawArrays(GL_TRIANGLES, 0, cylinderVertices);
}

// how i initially setup my GLKBaseEffect object and my opengl buffers
- (void)_setupGL
{
    [EAGLContext setCurrentContext:_context];
    //glEnable(GL_CULL_FACE);
    glEnable(GL_DEPTH_TEST);
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

    _effect = [[GLKBaseEffect alloc] init];
    [self _createEffect];
    [_effect prepareToDraw];

    glGenBuffers(1, &_vertexBuffer1);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_vertexBuffer2);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_vertexBuffer3);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer3);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Position));
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Texel));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, Normal));
}

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 13 июня 2012

Поскольку существует только 1 базовый эффект, я полагаю, что вы будете выполнять вычисления матрицы в обновлении и просто назначать его матрице вида модели базового эффекта перед рисованием снова?

...