für VBO offset berechnen



  • Ich habe bisher immer eine Klasse gehabt in der die Koordinaten über 3 floats gespeichert wurden. In etwa so wie hier:

    struct coord {
      float x;
      float y;
      float z;
    }
    

    Diese Coords habe ich dann in eine Klasse gespeichert, die einen Vertex beschreiben sollte. Nun ist das Problem, dass ich ne Klasse für Vektoren geschrieben habe, die die Coords in eine std::vector<float> speichert.

    Bisher habe ich den Pointer so gesetzt:

    std::cout<<"diff "<<sizeof(Vertex)<<" "<<vertices[0].m_vTanSpaceLight.GetArray()<<" "<<vertices[1].m_vTanSpaceLight.GetArray()<<std::endl;  // 84, adresse, adresse+84 ist die ausgabe
    
    	glVertexPointer(3, GL_FLOAT, sizeof(Vertex), vertices[0].m_vPosition.GetArray() );
    

    GetArray liefert entweder die adresse des ersten std::vector elementes oder die adresse der obigen struct.

    Wenn ich jedoch meine neue vectorklasse benutze, klappt das nicht. Die ausgabe von sizeof ist dann 144, die beiden speicheradressen liegen jedoch nur 120 bytes auseinander. beide offsets werden auch falsch gerendert. Wie kann das sein?!

    Was ich ausschließen kann, ist, dass in der Vectorklasse falsche Daten stehen, bisher benutze ich noch eine Wrapperklasse, die in so eine structform konvertiert, aber leider ist das 3x langsamer.

    was mich vor allem wundert, ist, dass die errechnete offset nicht funktioniert. wenn die speicherbereiche 120 bytes auseinanderstehen muss das funktionieren, auch wenn sizeof spinnt.



  • padding und allignment sind dein problem.

    VS: #pragma pack
    GCC: __attribute__((packed))

    google 😉



  • hmm, ich versuch das mal zu verstehen, und poste mal meine wichtigen deklarationen:

    class Vector {
    public:
    	Vector();
    
    // member, operatoren etc
    
    	std::vector<float> m_vData;
    };
    
    class Vec3 : public Vector {
    // usw, keine membervariablen
    
    class Vertex {
    public:
    	Vec3 m_vPosition;					// cartesian coordinates
    	ColorRGBA m_cColor;					// color (RGBA)
    	TexCoord m_fTexCoord;				// glTexCoord2f Textur coordinate (s, t)
    
    	Vec3 m_sTangent, m_tTangent;		// tangents
    	Vec3 m_vNormal;					// normals for lightening
    
    	Vec3 m_vTanSpaceLight;				// tangent for light source
    

    Ich habe mir überlegt gehabt, dass ein in der größe variabler vector ganz nett ist und dann allgemeingültige funktionalität in die klasse gepackt. der vector Vec3 leitet sich davon ab und initialisiert das std::vector array mit platz für 3 floats.

    jetzt habe ich nochmal die größe gemessen. Vec3 ist 12 bytes groß.
    Die klasse Vertex ist 84 bytes groß und dass kommt auch irgendwie hin, denke ich.
    aber nun liegt der laut meiner ausgabe

    &vertices[0].m_vPosition.m_vData[0]<<" "<<&vertices[[b]2[/b]].m_vPosition.m_vData[[b]0[/b]]
    

    240 bytes auseinander (0x81f4e88 0x81f4f78); bzw 120 wenn ich direkt benachbarte vertices nehme.

    wie ist das möglich, dass der abstand der floats im array weiter als 84 ist? ich habe etwas über padding gelesen, und dass man füllbytes damit aufheben kann, oder vermutlich bytes einfügen kann. aber bin mir nicht sicher wie ich das hier verwenden könnte, weil ich die böse ahnung habe, dass die daten irgendwo im speicher verstreut liegen könnten.



  • Deine Vec3 halt ich irgendwie für etwas gewagt...



  • warum?



  • Ich weiß nicht wie du die Daten in den Puffer bekommst... Aber zumindest sizeof( Vec3 ) liefert die wahrscheinlich nicht das was du gern hättest...



  • ja, das gefühl habe ich auch, aber ich weis nicht genau warum.
    und die daten gehen entweder über konstruktor oder über set-funktion in das array.
    nur, weis ich nicht wie sich das mit einer abgeleiteten klasse verhält. ich vermute, dass die klasse vec3 intern einfach ein objekt vom std::vector erzeugt, genau wies in der vector klasse definiert ist.
    nur erklärt, dass nicht das merkwürdige verhalten. vielleicht sollte ich einfach auf so eine coole vectorklasse verzichten, aber dass kann doch nicht die lösung sein.



  • Wenn du sizeof auf ein std::vector anwendest bekommst du natürlich die Größe des Objekts zurück, und nicht die größe des verwalteten Speichers...



  • ich weis, aber die 120 die ich aus den speicheradressen habe müsste uneingeschränkt richtig sein, weil ich an dieser speicheradresse auf die array-daten zugreifen kann.

    da ein rendern über forschleife und opengl primitien funktioniert, aber über v-arrays nicht, kann es also nur sein, dass irgendwann die elemente nicht mehr 120 bytes entfernt sind. irgendwas läuft da mit meinem compiler mächtig schief habe ich zumindest im gefühl.



  • um es nochmal deutlicher zu sagen:
    in Vec3 und in std::vector sind deine daten nicht!
    das ist lediglisch eine klasse deren implementierung du scheinbar absolut nicht kennst und auf gut glueck davon ableitest.
    das ableiten an sich ist nicht schlimm, aber da es eine blackbox ist, darfst du keine schlussfolgerungen ueber deren aufbau machen.

    aber ich glaube damit oeffnet sich erst die buechse der grundlagen-pandora fuer dich, deswegen -> verschoben 😉



  • Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Anmelden zum Antworten