Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Anonymous

unregistriert

1

11.03.2004, 03:32

Casting Operator für eigene Matrix Klasse

Hallo,

ich habe eine Frage bezüglich des Überladens eines Cast Operators. Es geht dabei darum, meine eigene Matrix Klasse in eine D3DMATRIX Klasse zu konvertieren.

Das Überladen des Operators sieht z.Z. so aus:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
operator D3DMATRIX ()
{
    D3DMATRIX m;

    m._11 = (float)m11; m._12 = (float)m12; m._13 = (float)m13; m._14 = (float)m14;
    m._21 = (float)m21; m._22 = (float)m22; m._23 = (float)m23; m._24 = (float)m24;
    m._31 = (float)m31; m._32 = (float)m32; m._33 = (float)m33; m._34 = (float)m34;
    m._41 = (float)m41; m._42 = (float)m42; m._43 = (float)m43; m._44 = (float)m44;

    return m;
}


(die ganzen (float)s sind deshalb da, weil meine Matrix Klasse intern mit double arbeitet, was hier aber nicht weiter stören soll)

Es wird also einfach eine D3DMATRIX Variable erzeugt und alle Komponenten auf die meiner eigenen Matrix Klasse gesetzt. Diese D3DMATRIX wird dann zurückgeliefert.

Brauche ich nun einen D3DMATRIX Pointer, habe jedoch eine Matrix meiner eigenen Matrixklasse, so würde ich im Programm folgendes machen:

Quellcode

1
(D3DMATRIX*)(&(D3DMATRIX)mMeineMatrix)


Dort nimmt er meine Matrix (mMeineMatrix), konvertiert sie in eine D3DMATRIX (mit dem oben genannten überladenen Operator), nimmt dann die Adresse der Matrix (&) und konvertiert diese widerum in einen D3DMATRIX Zeiger.
Diese Zeile funktioniert, kommt mir aber irgendwie ganz böse vor ;-) Sieht sehr schlecht programmiert aus...

Nun dachte ich mir, ich überlade den Operator so, dass man gleich einen D3DMATRIX Pointer erhält, was dann so aussah:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
operator D3DMATRIX* ()
{
    D3DMATRIX m;

    m._11 = (float)m11; m._12 = (float)m12; m._13 = (float)m13; m._14 = (float)m14;
    m._21 = (float)m21; m._22 = (float)m22; m._23 = (float)m23; m._24 = (float)m24;
    m._31 = (float)m31; m._32 = (float)m32; m._33 = (float)m33; m._34 = (float)m34;
    m._41 = (float)m41; m._42 = (float)m42; m._43 = (float)m43; m._44 = (float)m44;

    return &m;
}


Also fast wie oben, jedoch wird die Adresse der Matrix zurückgegeben. Leider ist dies auch nicht sehr fein, denn es wird die Adresse einer lokalen Variable zurückgegeben.


Deshalb von mir die Frage, wie würdet ihr das lösen? Ist diese Cast-Zeile oben gut so, oder würdet Ihr vielleicht einen anderen Code für das Casten in ein D3DMATRIX Zeiger verwenden bzw. wie sieht so ein überladener Operator aus? Ziel wäre es ja, einfach das hier machen zu können:

Quellcode

1
(D3DMATRIX*)mProjection


oder auch

Quellcode

1
(D3DMATRIX*)&mProjection



Würde mich sehr freuen, wenn Ihr mir dazu ein paar Tipps gebt oder Vorschläge macht.

(P.S. Ich möchte meine eigene Matrix Klasse nicht auf float umstellen)


Vielen Dank!


Grüsse,
Timo

2

11.03.2004, 21:24

Für

Quellcode

1
(D3DMATRIX*)&mProjection
ist kein Casting Operator notwendig. Weil man vordert die Adresse der Matrix an und Castest diese dann zu dem Typ D3DMATRIX*.

Wenn du deinen Casting-Operator so Definiert hast wie du es gepostet hast, sollte es eigentlich auch ohne zusätzliches Casten, bei der Parameter übergabe, funktionieren.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
operator D3DMATRIX ()
{
   D3DMATRIX m;

   m._11 = (float)m11; m._12 = (float)m12; m._13 = (float)m13; m._14 = (float)m14;
   m._21 = (float)m21; m._22 = (float)m22; m._23 = (float)m23; m._24 = (float)m24;
   m._31 = (float)m31; m._32 = (float)m32; m._33 = (float)m33; m._34 = (float)m34;
   m._41 = (float)m41; m._42 = (float)m42; m._43 = (float)m43; m._44 = (float)m44;

   return m;
}

pD3DDevice->SetTransform(D3DTS_WORLD, &mProjektion);
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

3

13.03.2004, 17:08

Hallo,

Zitat


Für Code:

(D3DMATRIX*)&mProjection

ist kein Casting Operator notwendig. Weil man vordert die Adresse der Matrix an und Castest diese dann zu dem Typ D3DMATRIX*.


aber meine Matrix Kasse benutzt double als Werte, wobei D3DMATRIX jedoch float nutzt - deshalb ist ein ganz normales casten doch nicht möglich, oder irre ich mich da jetzt?

Zitat


Wenn du deinen Casting-Operator so Definiert hast wie du es gepostet hast, sollte es eigentlich auch ohne zusätzliches Casten, bei der Parameter übergabe, funktionieren


Dann "erkennt" der Compiler, dass ich einen Casting Operator definiert habe und macht automatisch das implizite casten, ist das richtig?


Dank Dir!


Gruß, Timo

4

13.03.2004, 18:57

:ohoh: Du hast eine "Matrix Kasse"? :ohoh:

Zitat

Für Code:

(D3DMATRIX*)&mProjection

ist kein Casting Operator notwendig. Weil man vordert die Adresse der Matrix an und Castest diese dann zu dem Typ D3DMATRIX*.
Das war allgemein gemeint. War wohl etwas blöde ausgedrückt.

Wenn du für deine Klasse einen Cast Operator Definiert hast, sollte er diesen auch benutzen. In deinem Fall sollte er die Klasse mittels deinem Cast Operators in eine D3DMATRIX Klasse Casten und und die Adresse des Rückgabewertes, deines Cast Operator, ermitteln. Wenn er das nicht macht, macht der Cast Operator wenig Sinn, wenn man zum Schluß doch noch mal Casten muss.

Ausgehen von deiner Matrix Klasse (mit Casting Operator)

Quellcode

1
2
3
4
MyMatrix mat;
D3DMATRIX d3dmat = mat; // Ausführen des Cast-Operators

D3DMATRIX* pd3dmat = &mat; // Auch hier sollte der Cast-Operator greifen


Aufpassen muss man aber mit const. Denn es gibt einen Unterschied zwischen dem Cast-Operator

Quellcode

1
operator D3DMATRIX () {...}
und

Quellcode

1
operator const D3DMATRIX () const {...}
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

5

14.03.2004, 00:25

Hallo,

sorry falls ich nerve - ich glaub ich bin zu blöd dafür :-)

Wie muss denn nun der überladene Cast Operator aussehen, wenn ich das hier machen will:

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, MeineProjektionsMatrix);


(MeineProjektionsMatrix ist meine Matrixklasse)

SetTransform erwartet hier als Parameter nen const D3DMATRIX*, also muss ja meine Matrix irgendwie nach D3DMATRIX kovertiert werden und dann auch noch nen Pointer daraus..

Brauche ich dann nicht einfahc einen Cast von meiner Matrix Klasse zu D3DMATRIX und mache dann

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&MeineProjektionsMatrix);


?

Aber Du meintest ja, vorsicht bei const ... also müsste mein cast Operator ja anders aussehen, oder nicht?

Große Rede, kleiner Sinn - wie muss denn nur mein Cast Operator aussehen? :-)

Vielen Dank für Deine Hilfe


Beste Grüsse,
Timo

6

14.03.2004, 01:22

Normalerweise macht mein einen Cast-Operator immer in beiden Varianten. Dann hat man keine Probleme

Quellcode

1
2
operator D3DMATRIX() { .... }
operator const D3DMATRIX() const { .... }

Das D3DMATRIX* erreicht man durch jetzt einfach durch den Adress-Operator.

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &MeineProjektionsMatrix);
Was passiert. Erst wird der Casting Operator für den Typ D3DMATRIX aufgerufen und dann dessen Adresse ermittelt. Der Casting-Operator liefert ja immer ein Ergebnis. Dessen Adress wird dann genommen.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Anonymous

unregistriert

7

18.03.2004, 13:09

Hallo DragonMaster,

recht späte antwort, aber ich kam in den letzten Tagen nicht dazu

ich bekomme es einfach nicht hin, ich werde dir mal kurz meine beiden Casting Operatoren zeigen, welche so aussehen:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
operator D3DMATRIX()
    {
        D3DMATRIX m;
        m._11 = (float)m11; m._12 = (float)m12; m._13 = (float)m13; m._14 = (float)m14;
        m._21 = (float)m21; m._22 = (float)m22; m._23 = (float)m23; m._24 = (float)m24;
        m._31 = (float)m31; m._32 = (float)m32; m._33 = (float)m33; m._34 = (float)m34;
        m._41 = (float)m41; m._42 = (float)m42; m._43 = (float)m43; m._44 = (float)m44;

        return m;
    }

    operator const D3DMATRIX() const
    {
        D3DMATRIX m;
        m._11 = (float)m11; m._12 = (float)m12; m._13 = (float)m13; m._14 = (float)m14;
        m._21 = (float)m21; m._22 = (float)m22; m._23 = (float)m23; m._24 = (float)m24;
        m._31 = (float)m31; m._32 = (float)m32; m._33 = (float)m33; m._34 = (float)m34;
        m._41 = (float)m41; m._42 = (float)m42; m._43 = (float)m43; m._44 = (float)m44;

        return m;
    }



Um nun z.B. eine Projektionsmatrix zu setzen, funktioniert das hier:

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)(&(D3DMATRIX)mProjection));


Diese beiden Versionen jedoch nicht:

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)&mProjection);


-> ist kompilierfähig, jedoch sieht man nun nichts mehr auf dem Bildschirm, ich gehe davon aus, dass die Projektionsmatrix dann einfach falsch ist, also die Konvertiertung auch fehlerhaft.

Quellcode

1
hResult= g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &mProjection);


-> ist nicht kompilierbar, Fehler:

---
c:\....\src\CQuestBase.cpp(208): error C2664: 'IDirect3DDevice9::SetTransform' : Konvertierung des Parameters 2 von 'qCMatrix *__w64 ' in 'const D3DMATRIX *' nicht möglich
---

(wobei qCMatrix der Name meiner Matrix Klasse ist)

Wie muss denn nur der Cast Operator aussehen, damit die letzte der 3 oben genannten Versionen funktioniert?


Vielen Dank


Beste Grüsse,
Timo

Anonymous

unregistriert

8

24.03.2004, 18:34

so weit ich weis geht ver 3 garnicht.
Ergo kannst du hacken. aber die 2 ist möglich. hmmmmm........ na toll ich wollte jetzt eigendlich einen Code einfügen woran man das nachvollziehen kann wie es geht, aber ich stelle gerade fest dass ich keine Casting funktion drinne habe....... aber es funzt trotzdem.... wenn mir das einer erklären könnte wäre ich froh.

class myMatrix
{
public:
float m11, m12, m13, m14, // Elemente der Matrix
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44;


inline myMatrix(float _m11, float _m12, float _m13, float _m14,
float _m21, float _m22, float _m23, float _m24,
float _m31, float _m32, float _m33, float _m34,
float _m41, float _m42, float _m43, float _m44)
{
m11=_m11; m12=_m12; m13=_m13; m14=_m14;
m21=_m21; m22=_m22; m23=_m23; m24=_m24;
m31=_m31; m32=_m32; m33=_m33; m34=_m34;
m41=_m41; m42=_m42; m43=_m43; m44=_m44;
}
};

spiel.pDirektX->g_pD3DDevice->SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)(&promax));

naja sowas passiert im rausch ;D ABER wie gesagt es funzt!

In Deinem Beitrag befinden sich noch Fehler.
Bitte bearbeite die rot markierten Stellen und lösche diesen Text.

Anonymous

unregistriert

9

24.03.2004, 18:47

zu der Rotmarkierung:
Auch schweig doch Stille!!

Anonymous

unregistriert

10

24.03.2004, 18:49

Ach...

Werbeanzeige