boost::tuple<float * 4> als float* interpretieren?
-
Eisflamme schrieb:
Ich habe ein Array (ich weiß, vector geht, wird noch verbessert) von boost::tuple<float, float, float, float>. Ich bastel da alle möglichen Einträge rein. OpenGL erwartet jetzt allerdings ein eindimensionales Array von float, also float*.
Dann verwende boost::array<float,4> statt boost::tuple<float,float,float,float>, oder definiere Dir Deinen eigenen Typen, mit dem man auch ein bissel mehr anstellen kann (operator+, operator*, ...) und der intern ein Array speichert.
Eisflamme schrieb:
std::tuple hat wegen head, tail einen Overhead, der natürlich stört.
Von was für einem Overhead sprichst Du?
Eisflamme schrieb:
Gibt es irgendein Konstrukt, mit dem ich das tuple so interpretieren kann, dass ich es als float* interpretieren kann?
Nein, nicht portabel. Ein reinterpret_cast verletzt strenggenommen §3.10/15 und außerdem ist nicht festgelegt, in welcher Reihenfolge die Elemente im Tuple gespeichert werden, oder ob "Lücken" zwischen den Elementen sind. Kurz gesagt: Du solltest Dich nicht auf ein bestimmtes Speicherlayout verlassen.
Eisflamme schrieb:
Ich gehe Mal stark davon aus, dass nicht, frage mich aber schon länger, ob ich nicht irgendwas übersehe... Irgendwer ne Idee?
Siehe oben.
kk
-
Eisflamme schrieb:
Ach und falls das nicht geht, findet ihr so einen operator[] unschön?
Ja.
kk
-
314159265358979 schrieb:
reinterpret_cast sollte nicht verwendet werden, um cv-qualifier zu ändern.
Tut er auch nirgends.
Bzw. kann er gar nicht, nicht mit einem einzelnen reinterpret_cast.Was ist dein Problem?
-
Alles klar, damit weiß ich Bescheid, danke.

-
CoordinateType operator[](std::size_t n) const { return reinterpret_cast<const CoordinateType*>(this)[n]; }Der Typ von this ist Class* const. Hier wird zu const Other* gecastet.
-
Eisflamme schrieb:
Okay, aber die Reihenfolge muss schon stimmen. Wenn ich eine eigene Struktur basteln möchte, diese einem void* übergeben muss (das erwartet die OGL-Funktion),
Ich verstehe nicht, was Du mit "diese einem void* übergeben" meinst.
Eisflamme schrieb:
kann ich mein Problem dann durch ein float[4] in der Struktur lösen statt float x,y,z,w? Würde boost::array mein Problem auch lösen?
Wenn es darum geht, einen Zeiger p vom Typ float* zu erzeugen, wobei p[0],p[1],p[2],p[3] die vier Komponenten anspricht, ja, dann kannst Du das mit einem Array machen. boost::array benutzt intern auch ein "C-Array" -- ist also dasselbe.
struct vec4f { float data[4]; float const& operator[](int i) const {return data[i];} float & operator[](int i) {return data[i];} }; int main() { vec4f v; for (int k=0; k<4; ++k) v[k] = 11*(k+1); float* p = v.data; for (int k=0; k<4; ++k) cout << p[k] << '\n'; }
-
314159265358979 schrieb:
CoordinateType operator[](std::size_t n) const { return reinterpret_cast<const CoordinateType*>(this)[n]; }Der Typ von this ist Class* const.
Nein.
Der Typ istClass const*, da es eine "const Funktion" ist. Und Top-Level const gibt es für "this" keines.Hier wird zu const Other* gecastet.
Ja.
Und selbst wenn der Source-TypeClass* constwäre (was er wie gesagt nicht ist) ...
Da das Top-Level const egal ist (es wird ja eine Kopie des Primären Objekts, also hier des Zeigers, erstellt), wäre auch diese Konvertierung erlaubt, da sie implizit erlaubt ist.
-
Du hast zur Hälfte Recht, habe übersehen, dass die Funktion ja const ist.
Der Typ von this ist in der Funktion const Class* const. this ist immer const!
Wo hier eine Kopie erstellt wird, sehe ich gerade nicht.Edit: Entschuldige, du hast Recht, ist scheinbar nur beim GCC ein T* const

-
Hi,
Okay, das beantwortet meine Frage, danke.

Dieses eine void* übergeben bedeutet, ich habe 40 4x4-Matrizen. Diese möchte OpenGL aber als void*[40*4*4] haben. Für das, was ich reinstecke, bietet es sich an, die Matrizen quasi in Zeilen anzugeben, also jeweils als 4er-float-Tupel. Davon nehme ich dann 160 zusammen und habe meine 4 Matrizen abgebildet, gebe die an OpenGL, sage dem, dass er das die einzelnen Komponenten float sind und dann geht der Spaß los. :)=
-
314159265358979 schrieb:
Du hast zur Hälfte Recht, habe übersehen, dass die Funktion ja const ist.
Der Typ von this ist in der Funktion const Class* const. this ist immer const!
Wo hier eine Kopie erstellt wird, sehe ich gerade nicht.Edit: Entschuldige, du hast Recht, ist scheinbar nur beim GCC ein T* const

Ja, this ist nicht const, nur halt keine Lvalue, daher "verhält es sich const".
Und die Kopie wird beim Casten erstellt. Man kann über einen Cast ja nicht ein bestehendes Objekt "mutieren", man kann nur eine Kopie erstellen. Man kann höchstens eine Kopie einer Referenz oder eines Zeigers erstellen, und über die so erhaltene Referenz bzw. den Zeiger dann auf ein bestehendes Objekt zugreifen. Dabei wird dann das "eigentliche" Objekt nicht kopiert. Die Referenz bzw. der Zeiger wird aber kopiert. Und genau das passiert hier.
-
Stimmt du hast Recht, bin schon etwas müde.

-
Eisflamme schrieb:
Dieses eine void* übergeben bedeutet, ich habe 40 4x4-Matrizen. Diese möchte OpenGL aber als void*[40*4*4] haben.
Du meinst so etwas wie
void ogl_func(float const*);?
Eisflamme schrieb:
Für das, was ich reinstecke, bietet es sich an, die Matrizen quasi in Zeilen anzugeben, also jeweils als 4er-float-Tupel.
Ich sehe nicht, "wie sich das anbietet".
-
Die Funktion möchte schon einen void* (bzw. GLvoid*), man gibt über einen anderen Parameter an, ob dahinter floats oder doubles stecken.
Und ich habe Blödsinn erzählt. Ich bin noch etwas von dem Thema verwirrt, die Matrizen übergebe ich an anderer Stelle. Hier übergebe ich so genannte BoneWeights und BoneIndices. Ich arbeite mit Shadern und die GPU arbeitet immer mit float4, also mit vier floats, je Parameter. Wenn man weniger floats nimmt, wird dennoch genau so viel Speicher akquiriert, man gewinnt also nichts. Außerdem ist man in dem, was man an die GPU gibt, beschränkt, man kann nicht beliebig viel übergeben, daher macht es Sinn speicherschonend zu arbeiten. Daher das Vierertupel an floats.
-
Prinzipiell sollte man sich vorher ueberlegen, wofuer man die entsprechenden Typen einsetzen moechte. In deinem Fall ist boost::tuple einfach ungeeignet. Ein Array mit fester Laenge nimmt normalerweise nicht mehr Speicherplatz weg als das Tupel.