假设我们有一个对象,我们想要创建多个对象并根据某些算法独立移动它们。 以下是我正在使用的流程:
如何获取顶点缓冲区的当前位置?显然,我不希望在程序外存储对象的所有位置,因为它们位于顶点缓冲区内。
编辑:这是我用来存储和检索每个对象的模型矩阵中的数据的代码
// 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);
}
}
我现在遇到的问题是对象'i'的dataOfCurrentObject与对象'i-1'的newDataOfCurrentObject相同。换句话说,似乎代码仅跟踪所有对象的一个模型矩阵,或者它不能正确读取特定对象的模型矩阵。有什么想法吗?
答案 0 :(得分:0)
使用的最简单方法是在模型矩阵中设置对象的位置,并在每次绘制新对象时将该对象的相应模型矩阵上传为Uniform。 [伪]代码看起来像这样:
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模型矩阵。但基本逻辑应该与你最终使用的相同。
答案 1 :(得分:0)
您不必从顶点缓冲区读取任何内容。您只需要在应用程序中保留所需的转换,并将其作为每个对象的统一传递。
例如,如果您需要翻译对象,请保持modelViewMatrix并且每个帧都将trasformation应用于前一个矩阵:
GLKMatrix4 modelViewMatrix;
...
modelViewMatrix = GLKMatrix4Identity;
...
-(void) render {
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, deltaX, deltaY, deltaZ);
glUniformMatrix4fv(_modelViewUniform, 1,0, modelViewMatrix.m);
}
所以你只需要继续引用你的对象modelView矩阵并相应地应用你的转换。
如果要将数据从顶点缓冲区(gpu)读回到应用程序,则必须使用变换反馈,这是一种更高级的技术,在您修改顶点时使用它顶点着色器,您需要返回结果。 (你的情况不需要)。