我正在编写一个创建动态640 * 480地形的应用程序(每帧都会更改)。每个地形都存储在原始数据文件中,该文件表示一串(浮点)高度值。到目前为止,我可以按顺序将文件读入内存,并根据每帧的高度值动态创建一个网格(并且帧速率实际上是合理的),但是在我的应用程序退出之前我没有出现任何错误或堆栈时最大约20帧跟踪。
我怀疑我接近这个错误。我如何传输这些数据,以便我不必将每个帧保存在内存中?
以下是我的数据类的一个部分,其中包含一系列地形:
- (void)addModelWithID:(int)modelID;
{
NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
NSString* fileName = [NSString stringWithFormat:@"depth_%i.raw", modelID];
NSString* fullPath = [resourcePath stringByAppendingPathComponent:fileName];
NSData *myData = [NSData dataWithContentsOfFile:fullPath];
if (!myData)
return;
const float *data = [myData bytes];
int meshWidth = 640;
int meshHeight = 480;
Model *kModel = [[Model alloc] init];
int indicesPtr = 0;
int depthPtr = 2;
for (int y=0;y<meshHeight;y++) // Loop through y pixels
{
for (int x=0;x<meshWidth;x++) // Loop through x pixels
{
// Set up vertex positions
int index = y*meshWidth+x;
float xpos = ((float)x/(float)(meshWidth-1)) - 0.5f;
float ypos = ((float)y/(float)(meshHeight-1)) - 0.5f;
float zpos = (float)data[index];
kModel.vertices1[index*3+0] = xpos;
kModel.vertices1[index*3+1] = ypos;
kModel.vertices1[index*3+2] = zpos;
// Create a new index based on whether the current line is even or odd (flipped horizontally if odd)
int _index = (y%2==0) ? index : (y*meshWidth) + ((meshWidth-1)-x);
//Create the first index
kModel.indices[indicesPtr++] = _index;
// Create the second index
if ((x<meshWidth-1) || (x==meshWidth-1 && y==meshHeight-2))
kModel.indices[indicesPtr++] = _index+meshWidth;
}
}
}
// Add the model to the data object
[Models addObject:kModel];
[kModel release];
}
我的绘图代码(每个框架我称之为不同的地形,希望高达500左右,但我最多可以在20左右:
{
...
Model *kModel = [kData.kinectModels objectAtIndex:sequenceCurrentFrame];
glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)kModel.vertices1);
glEnableVertexAttribArray(vertexHandle);
glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
glDrawElements(GL_TRIANGLE_STRIP, kModel.numIndices, GL_UNSIGNED_SHORT, (const GLvoid*)kModel.indices);
...
}
万分感谢你的帮助,
约什
答案 0 :(得分:3)
您可以将高度数据存储在纹理中,然后在顶点着色器中使用texture2D
函数来修改顶点的当前高度。
使用此设置,您可以使用单个网格,只需使用纹理中存储的值调整每个顶点的高度。
如果您确定自己受GPU限制,则可以进一步优化用于查找高度数据的纹理格式。假设您的高度图范围为0-255
,给定GL_RGBA
格式,您可以使用相同的纹理渲染最多4帧(第一帧从红色组件读取高度,从蓝色组件读取下一帧,等等)。
使背景纹理大两倍(1280x960)将进一步允许您在单个纹理中存储多达16个帧。
关于纹理值得一提的另一件事是,使用GPU的原生格式也可以提高GPU / IO绑定方案的性能。对于iDevices,此格式为PVRTC。
我真的认为问题只是每帧单独分配300k +顶点...每帧分配最多640 * 480 * 3 * 4 = 3 686 400字节没有提到你停止分配内存多少帧(等等...... 你呢?)。对于这种资源有限的环境来说,这太过分了。