2016-05-31 2 views
0

Скажем, у нас есть объект, и мы хотим создать несколько объектов и переместить их самостоятельно на основе некоторого алгоритма. Вот что это процесс, я использую:Чтение данных позиции из Vertex Buffer в openGL

  1. Создать структуру с геометрией объекта
  2. Создание массива Vertice буферов, используя геометрию объекта
  3. Теперь в процедуре рендеринга, Мне нужно пройти каждый из этих объектов и изменить их положение на основе определенного алгоритма.
  4. Для этого мне нужно получить текущее местоположение объекта для вычисления новой позиции.

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

EDIT: Это код, я использую для хранения и извлечения данных из модели матрицы каждого объекта

// Set up Code 
- (void)setupGL 
{ 
    [EAGLContext setCurrentContext:self.context]; 
    [self loadShaders]; 
    glEnable(GL_DEPTH_TEST); 
    for(int i; i<num_objects; i++) { 
     glGenVertexArraysOES(1, &_objectArray[i]); 
     glBindVertexArrayOES(_objectArray[i]); 

     glGenBuffers(1, &_objectBuffer[i]); 
     glBindBuffer(GL_ARRAY_BUFFER, _objectBuffer[i]); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(objectData), objectData, GL_STATIC_DRAW); 

     glEnableVertexAttribArray(....); 
     glVertexAttribPointer(......, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0)); 
    } 
    glBindVertexArrayOES(0); 
} 
//******************************************************** 
// Rendering Code 
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    glUseProgram(_program); 
    for(int i=0; i<num_objects; i++) { 

     glBindVertexArrayOES(_objectArray[i]); 

     // Get Previous data 
     GLint uMatrix = glGetUniformLocation(_program, "modelMatrix"); 
     glGetUniformfv(_program, uMatrix, dataOfCurrentObject); 

     // Get Previous data 
     ... transform dataOfCurrentObject based on an algorithm and create newDataOfCurrentObject 

     // Update object with new data and draw 
     glUniformMatrix4fv(uMatrix, 1, 0, newDataOfCurrentObject); 
     glDrawArrays(GL_TRIANGLES, 0, 36); 
    } 
} 

Проблема у меня сейчас является то, что dataOfCurrentObject для объекта «я» идентичен newDataOfCurrentObject для объекта 'i-1'. Другими словами, кажется, что код отслеживает только одну модельную матрицу для всех объектов или не корректно считывает матрицу модели конкретного объекта. Есть идеи?

ответ

0

Простейший метод, который используется, заключается в том, чтобы установить положение объекта в Матрице моделей и загрузить соответствующую Матрицу Модели объекта в виде Униформы каждый раз, когда вы рисуете новый объект. [Псевдо-] код будет выглядеть следующим образом:

for(game_object object : game_object_list) { 
    glUniformMatrix4f(modelMatrixUniformLocation, 1, false, object->model_matrix); 
    object->draw(); 
} 

И когда вам нужно обновить положение объекта:

for(game_object object : game_object_list) { 
    object->model_matrix = Matrix.identity(); 
    /*Any transformations that need to take place here*/ 
    object->model_matrix = object->model_matrix.transpose(/*x*/, /*y*/); 
    /*Any other transformations that need to take place*/ 
} 

именно то, что вы положили туда будет меняться в зависимости от ваших потребностей. Если вы программируете 2D-игру, вам, вероятно, не нужна матрица модели 4x4. Но основная логика должна быть идентична той, которую вы в конечном итоге используете.

+0

Я пробовал этот метод, но я делаю это в приложении iOS, поэтому Matrix.identity() не существует. Знаете ли вы, какой вызов получит матрица модели в iOS –

+0

@ Z.Zepos Я сказал, что это псевдокод.Вам нужно взглянуть на используемые вами API (одна из которых должна быть Math/Matrices Library) и посмотрите, как вы устанавливаете и восстанавливаете Matrices с помощью этой библиотеки. – Xirema

0

Вам не нужно ничего читать с буферов вершин. Вам просто нужно сохранить в своем приложении необходимый вам транскрипт и передать его как единое для каждого объекта.

Например, если вам нужно перевести объект, сохранить modelViewMatrix в и каждом кадре применять trasformation к предыдущей матрице:

GLKMatrix4 modelViewMatrix; 
... 
modelViewMatrix = GLKMatrix4Identity; 
... 
-(void) render { 
    modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, deltaX, deltaY, deltaZ); 
    glUniformMatrix4fv(_modelViewUniform, 1,0, modelViewMatrix.m); 
} 

Так что вам просто нужно держать ссылку на ваши объекты видовых матриц и применить соответственно.

Если вы хотите прочитать данные обратно из ваших вершинных буферов (ГП) для вашего приложения, вы должны использовать Transform Обратной связи который немного более продвинутый метод и используются, когда вы изменяете свои вершины в вершинном шейдере и вам нужны результаты. (Это не нужно для вашего дела).

+0

Если у меня есть миллионы этих объектов, мне придется хранить миллионы этих матриц в памяти программ. Кажется, это довольно расточительно. Сложно ли получить данные с GPU? Я что-то упускаю? –

Смежные вопросы