Ich schreibe eine App, die ein dynamisches 640 * 480 Terrain erstellt (ändert jeden Frame). Jedes Gelände wird in einer Rohdatendatei gespeichert, die eine Folge von (Fließ-) Höhenwerten darstellt. Bis jetzt kann ich die Dateien nacheinander in den Speicher lesen und dynamisch ein Mesh basierend auf den Höhenwerten für jeden Frame erstellen (und die Framerate ist eigentlich vernünftig), aber ich maximiere 20 Frames, bevor meine App ohne Fehler oder Stack beendet wird Spur.OpenGLES2 iOS: Wie kann man die Vertex-Animation für dynamisches Terrain am besten streamen?
Ich vermute, dass ich das falsch annähere. Wie würde ich diese Daten streamen, so dass ich nicht jeden Frame im Speicher halten muss? Hier
ist ein Ausschnitt aus meiner Datenklasse, die eine Sammlung von Terrains hält:
- (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];
}
Und meinen Draw-Code (jeden Frame ich ein anderes Terrain nennen, hoffentlich bis zu 500 oder so, aber ich max out bei ~ 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);
...
}
Dank einer Million für Ihre Hilfe,
Josh
Sie sollten definitiv einen Vertex-Shader schreiben, um das Terrain für Sie zu verändern. Abgesehen davon, wie lässt man die Erinnerung an jeden Geländeabschnitt frei? – arul
Soweit ich es verstehe, kann ich die Erinnerung an jeden Geländebrocken nicht freigeben, da ich sie mit ~ 30 Bildern pro Sekunde durchlaufen muss. Wenn ich es also loslasse, müsste ich die Terraindatei wieder in jeden Frame laden, was sehr langsam wäre, oder? Ist es möglich, einen Vertex-Shader für die Tiefe des Geländes zu schreiben? Es scheint albern, die X- und Y-Werte jedes Mal zu erstellen, da sie sich nicht ändern, aber ich weiß nicht wirklich, wie ich anfangen soll, die Z-Position an den Shader zu senden. Irgendwelche Tipps? – Josh
Eine Nebenbemerkung: Verwenden Sie 'NSData's' NSDataReadingMappedAlways' Option (mit 'dataWithContentsOfFile: Optionen: Fehler:' als Drop-In-Substitution für Ihre aktuelle 'dataWithContentsOfFile:'); Dies führt dazu, dass die Datei im Speicher abgelegt wird und nicht geladen wird. Sie erhalten also einen Zeiger, den Sie genau so verwenden können, als ob die gesamte Datei geladen wäre, aber das Betriebssystem behandelt, welcher Teil der Datei tatsächlich im Speicher ist und was bleibt Festplatte als Caching-Aufgabe, die automatisch den Gesamtspeicherbedarf verarbeitet. – Tommy