Wie variable anzahl an Instanzen eines structs zur Laufzeit erstellen?

  • Ersteller Ersteller Crymes
  • Erstellt am Erstellt am
Nochmal ne Frage, bin grad auf Fehlersuche bei meinem Programm, an Quelltext hätte ich jetzt alles zusammen und vernetzt:
Funktioniert folgender Code bzw. wofür brauche ich die Klammern hinter ball? (Ball ist ein structure)

Code:
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]
ballliste.push_back(ball());
[/SIZE][/FONT][/SIZE][/FONT]
 
Kleines Beispiel
Code:
struct Ball
{
    int posX;
    int posY;
};

// erzeugt dynamisch 10 Bälle
Ball *pBaelle = new Ball[10];

// Zugriff auf den 2. Ball (Index beginnt bei 0)
pBaelle[1].posX = 1;
pBaelle[1].posY = 1;

// Löschen (mit [], da es sich um ein Array handelt)
delete[] pBaelle;
hi, ich hatte schon ne andere (ähnliche) lösung probiert und jetzt nochmal die hier, aber er will bei mir die so erzeugten arrays einfach nich gescheit füllen :/

zur "vorgeschichte":
ich hab ne klasse die objekt daten vorhält. also koordinaten, farben, tex koords usw. das wird entweder aus ner *.obj datei gelesen (nach deren struktur ich mich auch orientiert hatte) oder aber aus create... funkrionen. hab testweise ne createCube() gebaut und die punktdaten usw stimmen auch, so wie ich mir das erstmal gedacht hatte. joa, die klasse besitzt nun mehrere listen. einmal die vektorenliste (pointlist), wo alle punktdaten halt gespeichert sind und dann noch listen für texcoords, normalen und farben (auch wenn die später wohl wieder rausfliegt um nahe bei der obj-datei struktur zu bleiben). das sin dann die vnlist (normalen), vtlist (texcoords) und vclist (colors). so, jede dieser listen beinhaltet alles nur einmalig. also wenn 3 flächen den selben punkt nutzen, is er dennoch nur einmal aufgeführt. desweiteren gibts eine flist für die flächen, und hier wird nur der index jeweils gespeichert. also bei den punkten hat man dann eben flist.points[0]=0. soll bedeuten, der punkt 1 (0) der fläche (points is nen int[3]) ist der punkt mit dem index 0 aus pointlist (vector liste) -> pointlist[0]. mit all den anderen dingern das selbe.

najut, jedenfalls fülle ich nun mittels for schleifen (eine äussere, die die flächenliste durchgeht und innere, die dann die werte raussuchen) diese pointer-arrays, die mittels calloc oder deiner methode da gebastelt wurden. allerdings wird jedesmal nur der allererste wert gespeichert, und das wars :/

PHP:
struct Face
{
public:
    Texture tex;                        // textur der fläche
    int Points[3];                        // indizes der 3 punkte
    int TexCoords[3];                    // indizes der 3 texcoords
    int Normals[3];                        // indizes der 3 normalen
    int Colors[3];                        // indizes der 3 farben
    M3DVector3f vNormal;                // berechnete flächennormale
    Edge vEdges[3];                        // kanten, aus denen die fläche besteht
    ...
};

void Objectloader::generateBatch(void) {
    // wir haben flist.size flächen
    // pro fläche haben wir 3 vertizes
    // jedes vertex besteht aus 3d punkt, 3d normale, 2d texcoord und 4d farbe - jeweils float
    int vCount = this->flist.size() * 3 * 3;
    int nCount = this->flist.size() * 3 * 3;
    int tCount = this->flist.size() * 3 * 2;
    int cCount = this->flist.size() * 3 * 4;

    float *vPtr = (float*)calloc(vCount, sizeof(float));
    float *nPtr = (float*)calloc(nCount, sizeof(float));
    float *tPtr = (float*)calloc(tCount, sizeof(float));
    float *cPtr = (float*)calloc(cCount, sizeof(float));

    /*float *vPtr = new float[vCount];
    float *nPtr = new float[nCount];
    float *tPtr = new float[tCount];
    float *cPtr = new float[cCount];*/

    // arrays mit daten der flächen füllen
    for(int i = 0; i < this->flist.size(); i++) {
        for(int j = 0; j < 3; j++) {
            vPtr[(i*9)+(j*3)]   = this->pointlist[this->flist[i].Points[j]].x;
            vPtr[(i*9)+(j*3)+1] = this->pointlist[this->flist[i].Points[j]].y;
            vPtr[(i*9)+(j*3)+2] = this->pointlist[this->flist[i].Points[j]].z;

            nPtr[(i*9)+(j*3)]   = this->vnlist[this->flist[i].Normals[j]].x;
            nPtr[(i*9)+(j*3)+1] = this->vnlist[this->flist[i].Normals[j]].y;
            nPtr[(i*9)+(j*3)+2] = this->vnlist[this->flist[i].Normals[j]].z;
        }
        for(int j = 0; j < 3; j++) {
            tPtr[(i*6)+(j*2)]   = this->vtlist[this->flist[i].TexCoords[j]].x;
            tPtr[(i*6)+(j*2)+1] = this->vtlist[this->flist[i].TexCoords[j]].y;
        }
        for(int j = 0; j < 3; j++) {
            cPtr[(i*12)+(j*4)]   = this->vclist[this->flist[i].Colors[j]].x;
            cPtr[(i*12)+(j*4)+1] = this->vclist[this->flist[i].Colors[j]].y;
            cPtr[(i*12)+(j*4)+2] = this->vclist[this->flist[i].Colors[j]].z;
            cPtr[(i*12)+(j*4)+3] = this->vclist[this->flist[i].Colors[j]].w;
        }
    }

    glGenVertexArrays(1, &this->vertexArrayObjID);            // objekt
    glGenBuffers(1, &this->vertexBufferObjID);                // geometriedaten (vertizes), texcoords, normalen, farbe - all in one
    glBindVertexArray(this->vertexArrayObjID);

    GLuint offset = 0;
    // VBO für alle daten vorbereiten
    glBindBuffer(GL_ARRAY_BUFFER, this->vertexBufferObjID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vPtr)+sizeof(nPtr)+sizeof(tPtr)+sizeof(cPtr), NULL, GL_STATIC_DRAW);
    // vertex daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vPtr), vPtr);
    offset += sizeof(vPtr);
    // normal daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(nPtr), nPtr);
    offset += sizeof(nPtr);
    // texcoord daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(tPtr), tPtr);
    offset += sizeof(tPtr);
    // color daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(cPtr), cPtr);
    offset += sizeof(cPtr);

    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)sizeof(vPtr));
    glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(sizeof(vPtr) + sizeof(nPtr)));
    glVertexAttribPointer((GLuint)3, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)(sizeof(vPtr) + sizeof(nPtr) + sizeof(tPtr)));

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);

    glBindVertexArray(0);

    free(vPtr); vPtr = NULL;
    free(nPtr); nPtr = NULL;
    free(tPtr); tPtr = NULL;
    free(cPtr); cPtr = NULL;
    /*delete[] vPtr;
    delete[] nPtr;
    delete[] tPtr;
    delete[] cPtr;*/
}
hmm, ich habs mal als php code gebastelt - farben lassens vllt leichter erkennen. deine version der umsetzung is - wie man unschwer erkennt - gerade auskommentiert gewesen. aber keine version hat wirklich erfolge erzielt :/ weis einer, was ich falsch mache so als neuling in dieser disziplin? ^^



mal zu deiner letzten frage (eh ich als thread-napper gelte :P ):
Nochmal ne Frage, bin grad auf Fehlersuche bei meinem Programm, an Quelltext hätte ich jetzt alles zusammen und vernetzt:
Funktioniert folgender Code bzw. wofür brauche ich die Klammern hinter ball? (Ball ist ein structure)

Code:
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]
ballliste.push_back(ball());
[/SIZE][/FONT][/SIZE][/FONT]
is ball ein objekt des structs oder is ball der struct an sich (also ball = typname und nicht variablen name)? wenn zweiteres der fall is: vllt müssen deswegen die klammern da hin dann, weil er dann szs den konstruktor (eine parameterlose funktion) aufruft. besser wäre es wohl, wenn du ein objekt von ball anlegst, es mit sinnvollen werten füllst und dann an die liste anhängst.
 
Zuletzt bearbeitet:
hab übrigens rausgefunden, woran es lag. man darf nich sizeof(myPointerVar) nehmen - dann nimmt er quasi nur das erste von vielen elementen, sondern man muss explizit sagen arrayMemberCount * arrayMemberType -> bei mir zum bsp dann vCount * sizeof(float). das ganze überall so angepasst, und es funzt ><

PHP:
void Objectloader::generateBatch(void) {
    // wir haben flist.size flächen
    // pro fläche haben wir 3 vertizes
    // jedes vertex besteht aus 3d punkt, 3d normale, 2d texcoord und 4d farbe - jeweils float
    int vCount = this->flist.size() * 3 * 3;
    int nCount = this->flist.size() * 3 * 3;
    int tCount = this->flist.size() * 3 * 2;
    int cCount = this->flist.size() * 3 * 4;

    float *vPtr = 0; vPtr = new float[vCount];
    float *nPtr = 0; nPtr = new float[nCount];
    float *tPtr = 0; tPtr = new float[tCount];
    float *cPtr = 0; cPtr = new float[cCount];

    // arrays mit daten der flächen füllen
    for(int i = 0; i < this->flist.size(); i++) {
        for(int j = 0; j < 3; j++) {
            vPtr[(i*9)+(j*3)]   = this->pointlist[this->flist[i].Points[j]].x;
            vPtr[(i*9)+(j*3)+1] = this->pointlist[this->flist[i].Points[j]].y;
            vPtr[(i*9)+(j*3)+2] = this->pointlist[this->flist[i].Points[j]].z;

            nPtr[(i*9)+(j*3)]   = this->vnlist[this->flist[i].Normals[j]].x;
            nPtr[(i*9)+(j*3)+1] = this->vnlist[this->flist[i].Normals[j]].y;
            nPtr[(i*9)+(j*3)+2] = this->vnlist[this->flist[i].Normals[j]].z;
        }
        for(int j = 0; j < 3; j++) {
            tPtr[(i*6)+(j*2)]   = this->vtlist[this->flist[i].TexCoords[j]].x;
            tPtr[(i*6)+(j*2)+1] = this->vtlist[this->flist[i].TexCoords[j]].y;
        }
        for(int j = 0; j < 3; j++) {
            cPtr[(i*12)+(j*4)]   = this->vclist[this->flist[i].Colors[j]].x;
            cPtr[(i*12)+(j*4)+1] = this->vclist[this->flist[i].Colors[j]].y;
            cPtr[(i*12)+(j*4)+2] = this->vclist[this->flist[i].Colors[j]].z;
            cPtr[(i*12)+(j*4)+3] = this->vclist[this->flist[i].Colors[j]].w;
        }
    }

    glGenVertexArrays(1, &this->vertexArrayObjID);            // objekt
    glGenBuffers(1, &this->vertexBufferObjID);                // geometriedaten (vertizes), texcoords, normalen, farbe - all in one
    glBindVertexArray(this->vertexArrayObjID);

    GLuint offset = 0;
    // VBO für alle daten vorbereiten
    glBindBuffer(GL_ARRAY_BUFFER, this->vertexBufferObjID);
    glBufferData(GL_ARRAY_BUFFER, ((vCount + nCount + tCount + cCount) * sizeof(float)), NULL, GL_STATIC_DRAW);
    // vertex daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, (vCount * sizeof(float)), vPtr);
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    offset += (vCount * sizeof(float));
    // normal daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, (nCount * sizeof(float)), nPtr);
    glVertexAttribPointer((GLuint)1, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid *)offset);
    offset += (nCount * sizeof(float));
    // texcoord daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, (tCount * sizeof(float)), tPtr);
    glVertexAttribPointer((GLuint)2, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)offset);
    offset += (tCount * sizeof(float));
    // color daten ins VBO kopieren
    glBufferSubData(GL_ARRAY_BUFFER, offset, (cCount * sizeof(float)), cPtr);
    glVertexAttribPointer((GLuint)3, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid *)offset);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glEnableVertexAttribArray(3);

    glBindVertexArray(0);

    delete[] vPtr; vPtr = NULL;
    delete[] nPtr; nPtr = NULL;
    delete[] tPtr; tPtr = NULL;
    delete[] cPtr; cPtr = NULL;
}
 
Zurück