2016-05-31 256 views
0

假设我们有一个对象,并且我们想要创建多个对象并基于某种算法独立地移动它们。 这里是什么,是我使用的过程:从openGL中的顶点缓冲区读取位置数据

  1. 与对象
  2. 创建使用对象
  3. 现在在渲染程序的几何顶点缓存阵列的几何创建一个结构,我需要浏览这些对象中的每一个,并根据特定的算法改变它们的位置。
  4. 为了实现这个目标,我需要获取对象的当前位置来计算新的位置。

如何获得vertice缓冲区的当前位置?显然,我不想在程序外部存储对象的所有位置,因为它们位于顶点缓冲区内。

编辑:这是我使用存储和检索从每个对象的模型矩阵数据的代码

// 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对象“i”是等同于对象'i-1'的newDataOfCurrentObject。换句话说,代码似乎只跟踪所有对象的一个​​模型矩阵,或者它没有正确读取特定对象的模型矩阵。有任何想法吗?

回答

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),并查看如何使用该库设置和重置矩阵。 – Xirema

0

您不必从顶点缓冲区读回任何东西。你只需要在你的应用程序中保存你需要的变形,并将它作为统一的方式传递给每个对象。

例如,如果您需要翻译的对象,保持modelViewMatrix在每帧应用改造中以前的矩阵:

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

所以,你只需要保持引用你的对象模型视图矩阵并应用相应的转换。

如果你想从你的顶点缓冲区(GPU)到你的应用程序读取数据回,你必须使用变换反馈这是一个比较先进的技术,当你修改你的顶点在顶点着色器,它是用来你需要返回结果。 (你的情况不需要)。

+0

如果我有数以百万计的这些对象,我将不得不将这些矩阵保存在程序存储器中。看起来很浪费。从GPU获取数据很难吗?我错过了什么吗? –