2009-07-14 3 views
1

Ich entwickle ein 3D-Spiel mit SDL und OpenGL auf Ubuntu 9.04 mit Eclipse CDT. Ich habe eine Klasse, um die Mesh-Daten in Vektoren für jeden Typ zu halten. Wie Vertex, Normal, UVcoord (Texturkoordinaten), sowie ein Vektor von Gesichtern. Jede Seite hat 3 int-Vektoren, die Indizes zu den anderen Daten enthalten. Bis jetzt hat mein Spiel ziemlich gut funktioniert, wenn man es zu guten Raten rendert. Aber ich hatte nur noch weniger als hundert Scheitelpunkte zwischen zwei Objekten zu Testzwecken.C++ - Vektorelement unterscheidet sich, wenn auf verschiedene Zeiten zugegriffen wird

Die Schleife, diese Daten wie folgt aussieht Zugriff:

void RenderFace(oFace face) 
{ 
    /* 
    * More Stuff 
    */ 

    oVertice gvert; 
    oUVcoord tvert; 
    oNormal nvert; 

    for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++) 
    { 
     gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1); 
     tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1); 
     nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1); 

     glNormal3f(nvert.X, nvert.Y, nvert.Z); 
     glTexCoord2f(tvert.U, tvert.V); 
     glVertex3f(scale * gvert.X, scale * gvert.Y, scale * gvert.Z); 
    } 

    /* 
    * More Stuff 
    */ 
} 

es eine Schleife ist, die die renderFace() Funktion, die die oben for Schleife aufruft. Das Minuszeichen liegt darin, dass Wavefront-OBJ-Dateien 1-indiziert sind (anstelle von C++ 0-Index). Wie auch immer, ich entdeckte, dass, sobald Sie etwa 30 Tausend Gesichter haben, alle diese Anrufe zu glVertex3f() und dergleichen das Spiel auf etwa 10 FPS verlangsamen. Das kann ich nicht zulassen. Also habe ich über Vertex-Arrays erfahren, die Zeiger auf Arrays benötigen. Dem Beispiel eines NeHe-Tutorials folgend, benutzte ich weiterhin meine oVertice-Klasse und die anderen. Die haben nur floats x, y, z, oder u, v. Also habe ich die gleiche Funktion oben zu meiner OnLoad() Funktion hinzugefügt, um die Arrays zu erstellen, die nur "oVertice*" und ähnlich sind. Hier

ist der Code:

bool oEntity::OnLoad(std::string FileName) 
{ 
    if (!obj.OnLoad(FileName)) 
    { 
     return false; 
    } 

    unsigned int flsize = obj.TheMesh.GetFaceListSize(); 

    obj.TheMesh.VertListPointer = new oVertice[flsize]; 
    obj.TheMesh.UVlistPointer = new oUVcoord[flsize]; 
    obj.TheMesh.NormListPointer = new oNormal[flsize]; 

    oFace face = obj.TheMesh.GetFace(0); 
    oVertice gvert; 
    oUVcoord tvert; 
    oNormal nvert; 
    unsigned int counter = 0; 
    unsigned int temp = 0; 

    for (unsigned int flIndex = 0; flIndex < obj.TheMesh.GetFaceListSize(); flIndex++) 
    { 
     face = obj.TheMesh.GetFace(flIndex); 

     for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++) 
     { 
      temp = face.GeoVerts[fvIndex]; 
      gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1); 

      temp = face.UV_Verts[fvIndex]; 
      tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1); 

      temp = face.NrmVerts[fvIndex]; 
      nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1); 

      obj.TheMesh.VertListPointer[counter].X = gvert.X; 
      obj.TheMesh.VertListPointer[counter].Y = gvert.Y; 
      obj.TheMesh.VertListPointer[counter].Z = gvert.Z; 

      obj.TheMesh.UVlistPointer[counter].U = tvert.U; 
      obj.TheMesh.UVlistPointer[counter].V = tvert.V; 

      obj.TheMesh.NormListPointer[counter].X = nvert.X; 
      obj.TheMesh.NormListPointer[counter].Y = nvert.Y; 
      obj.TheMesh.NormListPointer[counter].Z = nvert.Z; 

      counter++; 
     } 
    } 

    return true; 
} 

Die unsigned int temp Variable ist für Debug-Zwecke. Anscheinend habe ich keinen Standardkonstruktor für oFace, der nicht mit etwas zu initialisieren ist. Jedenfalls, wie Sie sehen können, ist es genau die gleiche genaue Routine. Nur anstatt eine gl-Funktion aufzurufen, füge ich die Daten zu drei Arrays hinzu.

Hier ist der Kicker:

Ich bin ein typischen Würfel aus Dreiecken laden.

Wenn ich Zugriff Element 16 (0 indiziert) des UV_Verts Vektor aus der RenderFace() Funktion ich 12.

Aber wenn ich Element zugreifen 16 (0 indexiert) des gleichen UV_Verts Vektor aus der OnLoad() Funktion, die ich bekommen etwas wie 3045472189

Ich bin so verwirrt.

Weiß jemand, was das verursacht? Und wenn ja, wie löst man es?

+1

Ich habe Probleme, Ihre Frage zu verstehen. Können Sie den Code auf den minimalen Ausdruck reduzieren, der den Fehler auslöst? Ich glaube nicht, dass dies das Problem sein wird, aber Sie verwenden die Variable temp, um nicht initialisierte Elemente aus dem Array zu extrahieren. –

Antwort

3

Ein möglicher Grund könnte sein, dass Sie Arrays mit Größe sind die Schaffung flsize:

obj.TheMesh.VertListPointer = new oVertice[flsize]; 
obj.TheMesh.UVlistPointer = new oUVcoord[flsize]; 
obj.TheMesh.NormListPointer = new oNormal[flsize]; 

aber verwenden die Arrays mit Indizes bis flsize * face.GeoVerts.size

for (...; flIndex < obj.TheMesh.GetFaceListSize(); ...) { // flsize = GetFaceListSize 
    for (...; fvIndex < face.GeoVerts.size(); ...) { 
    ... 
    obj.TheMesh.UVlistPointer[counter].U = ...; 
    ... 
    counter++; 
    } 
} 

so Ihre Array Code Schöpfung eigentlich sein sollte mehr wie

obj.TheMesh.VertListPointer = new oVertice[flsize * face.GeoVerts.size()]; 
obj.TheMesh.UVlistPointer = new oUVcoord[flsize * face.GeoVerts.size()]; 
obj.TheMesh.NormListPointer = new oNormal[flsize * face.GeoVerts.size()];