Struct mit dynamic array

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Struct mit dynamic array

Beitrag von snoob741 »

Aktuell implementiere ich für mich einen ASSIMP Importer. Um beim Auslesen der Texturdaten nicht für jede Channel Kombinationsmöglichkeit ein eigenes Texture-Struct zu definieren (Nutze VBO-Multistreaming) wollte ich ein TextureStruct verwenden, dass ein dynamisch allokiertes Array nutzt:

Code: Alles auswählen

struct TXSTREAM
{
  float* uv;
};
Beim Import der Texturdaten mache ich folgendes:

Code: Alles auswählen

    unsigned int channels = 1; // mesh->GetNumUVChannels();
    std::shared_ptr<brGraphics::brVertexDeclaration> vxDecl = system.createVertexDeclaration();
    for(int c=0; c<channels; c++){ 
        vxDecl->addElement(brGraphics::brVertexElement(brGraphics::brVertexElement::TYPE_FLOAT_2, 
                                                       brGraphics::brVertexElement::USE_TEXCOORD, 
                                                       sizeof(float)*(c*2)));                                            
    }
    
    std::vector<TXSTREAM> texCoords;     
    for(unsigned int v = 0 ; v < mesh->mNumVertices; v++) 
    {    
        struct TXSTREAM coord;
        coord.uv = (float*)malloc((channels*2)*sizeof(float));
             
        for(int c=0; c<channels; c++){ 
           const aiVector3D texCoord  = (mesh->mTextureCoords[c][v]);
           coord.uv[0+(c*2)] = texCoord.x;
           coord.uv[1+(c*2)] = texCoord.y;                                                                                       
        }         
        texCoords.push_back(coord);                                             
    }   
    
    unsigned int size = texCoords.size();    
    unsigned int bytes = sizeof(TXSTREAM)+((channels*2)*sizeof(float));
     
    std::shared_ptr<brGraphics::brVertexBuffer> tbo =
    system.createVertexBuffer(brGraphics::brVertexBuffer::USE_STATIC, 
                              bytes, 
                              size); 
    tbo->writeData(0, size, &texCoords[0]);
    tbo->setVertexDeclaration(vxDecl);
Irgendwie wird nur Müll gemapped. Habe ich bei der Berechnung der Bytegröße evtl. einen gedanklichen Fehler?
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Struct mit dynamic array

Beitrag von Artificial Mind »

Ehm ja, ich glaube ich sehe dein Problem.

Du hast texCoords als vector von TXSTREAMs gemacht, also einen Vektor von Pointern. Die Daten liegen also mit einer Indirektion zu viel im Speicher und "tbo->writeData(0, size, &texCoords[0]);" schreibt die Pointer und nicht die Daten in den Buffer.

Meine Lösung: nutz einen vector<char> und push dort alle Daten rein. Alternativ ein vector<float>.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: Struct mit dynamic array

Beitrag von snoob741 »

Danke für Deinen Hinweis. Hab einmal versucht das ganze mit einem std::vector<float> abzuhandlen. Aber irgendwie
bekomme ich das nicht gebacken (k.A. ob die Hitze mir mal wieder zu Kopf steigt :? )

Code: Alles auswählen

    std::vector<float> texCoords;   
    for(unsigned int v = 0 ; v < mesh->mNumVertices; v++) 
    {           
        for(int c=0; c<channels; c++){ 
           const aiVector3D texCoord  = (mesh->mTextureCoords[c][v]);
           texCoords.push_back(texCoord.x);
           texCoords.push_back(texCoord.y);
        }                                            
    }   
    
    unsigned int size = texCoords.size();         
    std::shared_ptr<brGraphics::brVertexBuffer> tbo =
    system.createVertexBuffer(brGraphics::brVertexBuffer::USE_STATIC, 
                              (sizeof(float)*(channels*2), 
                              size); 
    tbo->writeData(0, size, texCoords.data());
    tbo->setVertexDeclaration(vxDecl);
Klappt soweit ich nur einen texture channel habe. Sobald die Mesh 2 Channels hat, steigt mir das ganze beim schreiben der Daten aus. Hab ich etwas übersehen oder meintest Du generell etwas anderes?
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Struct mit dynamic array

Beitrag von Artificial Mind »

Dein size scheint viel zu groß zu sein. Wenn ich die binrevengine richtig verstehe, muss size bei createVB die Anzahl der vertices sein, also texCoord.size() / (channels * 2).
Gleiches gilt dann natürlich auch bei writeData, dort muss auch die Anzahl der vertices stehen.
Weiterhin fehlt mir bei (sizeof ..., (in createVB) die schließende Klammer, ich gehe davon aus, dass das ein copy'n'paste Fehler ist.
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: Struct mit dynamic array

Beitrag von snoob741 »

Eigentlich nicht. CreateVB erwartet die Size eines einzelnen Vertex bzw. Datensatzes als 2. Parameter und die Anzahl der Vertices als 3. Daraus wird dann dynamisch die Anzahl der Bytes berechnet:

Code: Alles auswählen

/**
@brief Default constructor.
@param usage The buffer usage enum type.
@param sizeVertex The size of a single vertex.
@param numVertices The number of vertices append to this buffer.
*/
brVertexBuffer::brVertexBuffer(brDataBuffer::eBufferUsage usage, unsigned int sizeVertex, unsigned int numVertices)
: brDataBuffer(usage), m_numVertices(numVertices), m_sizeVertex(sizeVertex), m_useIndices(false)
{
    // calculate the number of bytes of data
    m_size = m_sizeVertex*m_numVertices;
}
Somit müsste doch die Größe eines Datensatzes im std::vector doch sizeof(float)*2*channels (2 floats pro channel) sein, oder bin ich da grad auf dem Holzweg? P.S. Jupp das mit der fehlenden Klammer war ein C&P Fehler ...
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: Struct mit dynamic array

Beitrag von Artificial Mind »

die Size pro Vertex ist sizeof(float)*2*channels, aber die Anzahl der Vertices ist NICHT texCoord.size() sondern texCoord.size() / (2 * channels)
snoob741
Beiträge: 76
Registriert: 03.04.2012, 22:36

Re: Struct mit dynamic array

Beitrag von snoob741 »

Oh man danke! Das quiescht ja schon vor Dummheit :? Ich glaub ich geh erstmal ne runde Schwimmen um den Kopf frei zu bekommen 8-)
Antworten