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

Der Dude

Treue Seele

  • »Der Dude« ist der Autor dieses Themas

Beiträge: 73

Wohnort: Elleringhausen-City

Beruf: ITA

  • Private Nachricht senden

1

09.12.2004, 22:36

Dreiecke sind unsichtbar

Hallo,

wie so oft probiere ich mal wieder was ohne Erfolg nachzuschreiben. Dieses mal geht es um das Beispiel 2-4 dort sollen die Dreiecke im Raum fliegen. Leider sind diese bei mir unsichtbar. Nicht das ich unsichtbar schlecht finde aber nur so der blue Hintergrund - na ja ich weiß nicht. Unten befindet sich dich Render-, Move- und Initfunktion.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
struct SVertex
{
    tbVector3       vPosition;
    D3DCOLOR    D3D_Color;
};

struct STriangle
{
    tbVector3   vVelocity;          //Geschwindigkeit

    tbVector3   vPosition;          //Position

    tbVector3   vRotation;          //Rotationszustand

    tbVector3   vVelocityRotation;  //Rotation in eine bestimmte Richtung


    float       fSize;              //Größe des Dreiecks

    SVertex     SVertex[3];         //Vertexdaten des Dreiecks

};



const int                   g_iNumTriangles = 1000;
STriangle                   g_aTriangle[g_iNumTriangles];

//**************************    Movefunktion    **************************************************

void move(float fTime)
{
    float fDistance;
    g_fTime = g_fTime + fTime;
    for(int iTriangle = 0; iTriangle < g_iNumTriangles ; iTriangle ++)
    {
        g_aTriangle[iTriangle].vPosition += g_aTriangle[iTriangle].vVelocity         * g_fTime;
        g_aTriangle[iTriangle].vRotation += g_aTriangle[iTriangle].vVelocityRotation * g_fTime;

        // Distanz des Dreiecks zum Beobachter (zum Nullpunkt) berechnen

        fDistance = tbVector3Length(g_aTriangle[iTriangle].vPosition);

        // Wenn die Distanz größer als 100 ist, soll das Dreieck umkehren.

        if(fDistance > 100.0f) g_aTriangle[iTriangle].vVelocity *= -1.0f;
    }
}
//************************************************************************************************


//**************************    Renderfunktion  **************************************************

void render(float fTime)
{
    HRESULT     hResult;
    tbMatrix    mTranslation;   // Translationsmatrix

    tbMatrix    mWorld;         // Vereinende Weltmatrix

    tbMatrix    mRotationX;     // Rotation um die X Achse

    tbMatrix    mRotationY;     // Rotation um die Y Achse

    tbMatrix    mRotationZ;     // Rotation um die Z Achse

    tbMatrix    mScaling;

    

    // Den Bildpuffer und den Z-Buffer leeren

    if(FAILED(hResult = pD3D_Interface->Clear(0,
        NULL,
        D3DCLEAR_TARGET| D3DCLEAR_ZBUFFER,
        D3DCOLOR_XRGB(0, 0, 63),
        1.0f,
        0)))
    {
        // Fehler beim Leeren der Strukturen

        MessageBox(NULL, "Fehler beim Leeren der Puffer!",
            "Fehler", MB_OK | MB_ICONEXCLAMATION);
    }

    // Szene beginnen

    pD3D_Interface->BeginScene();

    for(int iTriangle = 0; iTriangle < g_iNumTriangles; iTriangle++);
    {
        mScaling = tbMatrixScaling(g_aTriangle[iTriangle].fSize);

        mRotationX = tbMatrixRotationX(g_aTriangle[iTriangle].vRotation.x);
        mRotationY = tbMatrixRotationY(g_aTriangle[iTriangle].vRotation.y);
        mRotationZ = tbMatrixRotationZ(g_aTriangle[iTriangle].vRotation.z);

        mTranslation = tbMatrixTranslation(g_aTriangle[iTriangle].vPosition);


        // Beide Matrizen kombinieren und als Weltmatrix einsetzen

        mWorld = mScaling * mRotationX * mRotationY * mRotationZ * mTranslation;
        pD3D_Interface->SetTransform(D3DTS_WORLD,(D3DMATRIX*)(&mWorld));

        // Nun das Dreieck zeichnen

        if(FAILED(hResult = pD3D_Interface->DrawPrimitiveUP(D3DPT_TRIANGLELIST, // Dreiecksliste

            1,                                  // 1 Dreieck

            &g_aTriangle[iTriangle].SVertex,    // Vertexdaten

            sizeof(SVertex))))                  // Vertexgröße

        {
            // Fehler beim Zeichnen!

            MessageBox(NULL, "Fehler beim Zeichnen des Dreiecks!",
                "Fehler", MB_OK | MB_ICONEXCLAMATION);
        }
    }

    // Szene beenden

    pD3D_Interface->EndScene();

    // Der große Moment: den Bildpuffer sichtbar machen

    pD3D_Interface->Present(NULL, NULL, NULL, NULL);
}
//************************************************************************************************


//**************************    Funktion zu Scenenerstellung    **********************************

bool initScene()
{
    HRESULT     hResult;
    float       fAspectration;

    //Vertexformat registrieren

    if(FAILED(hResult = pD3D_Interface->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE)))
    {
        MessageBox(NULL,"Das Vertexformat konnte nicht gesetzt werden","Fehler bei initScene",MB_OK);
        return (false);
    }

    //Beleuchtung ausschalten, da sie nicht benötigit wird

    //CULLMODE deaktivieren

    //Dithering aktivieren wegen 16Bit-Farbübergang


    hResult =pD3D_Interface->SetRenderState(D3DRS_LIGHTING,FALSE);
    hResult =pD3D_Interface->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
    hResult =pD3D_Interface->SetRenderState(D3DRS_DITHERENABLE,TRUE);

    //Seitenverhältnis ausrechnen

    fAspectration = (float)(SD3DPresentVarialbes.D3D_Register.BackBufferWidth)/
        (float)(SD3DPresentVarialbes.D3D_Register.BackBufferHeight);

    //Projektionsmatrix erstellen

    tbMatrix    mProjketion = tbMatrixProjection(TB_DEG_TO_RAD(90.0f),
        fAspectration,
        0.1f,
        100.0f);

    //Projektionsmatrix setzen

    hResult = pD3D_Interface->SetTransform(D3DTS_PROJECTION,(D3DMATRIX*)(&mProjketion));

    for(int iTriangle = 0; iTriangle < g_iNumTriangles ; iTriangle++)
    {
        //Zufällige Geschwindigkeit festlegen

        g_aTriangle[iTriangle].vVelocity = tbVector3Random() * RandomNumberFloat(0.1f, 5.0f);

        //Position des Dreiecks festlegen

        g_aTriangle[iTriangle].vPosition = tbVector3(0.0f,0.0f,20.0f);          

        //Rotation zuerste stoppen

        g_aTriangle[iTriangle].vRotation = tbVector3(0.0f,0.0f,0.0f);

        //Rotationsgeschwindigkeit zufällig wählen


        g_aTriangle[iTriangle].vVelocityRotation.x = RandomNumberFloat(-1.0f, 1.0f);
        g_aTriangle[iTriangle].vVelocityRotation.y = RandomNumberFloat(-1.0f, 1.0f);
        g_aTriangle[iTriangle].vVelocityRotation.z = RandomNumberFloat(-1.0f, 1.0f);


        //Größe des Dreiecks festlegen

        g_aTriangle[iTriangle].fSize = RandomNumberFloat(1.0f, 5.0f);



        //Farben festlegen

        for(int iVertex = 0; iVertex < 3; iVertex++)
        {
            g_aTriangle[iTriangle].SVertex[iVertex].vPosition = tbVector3Random();
            g_aTriangle[iTriangle].SVertex[iVertex].D3D_Color = D3DCOLOR_ARGB(255,RandomNumberInt(0,255),RandomNumberInt(0,255),RandomNumberInt(0,255));
        }
    }


    //Alles hat geklappt

    return (true);
}
//************************************************************************************************


Falls jemand etwas entdeckt, bitte eben antworten,.

Mfg
Der dude
"Wenn ich morgens doppelt so schnell über den Flur laufe, kann ich 2 Minuten länger schlaften!" - leider war es ein Irrtum.

2

10.12.2004, 17:12

Als erstes. Die Reihenfolge der Multiplikationen ist nicht egal.

C-/C++-Quelltext

1
mWorld = mScaling * mRotationX * mRotationY * mRotationZ * mTranslation;


Setz mal besser ein paar Klammern:

C-/C++-Quelltext

1
mWorld = (mScaling * (mRotationX * mRotationY * mRotationZ)) * mTranslation;

Erst Skalieren, dann Rotieren, dann Transformieren :)

Dann:

C-/C++-Quelltext

1
2
3
4
5
        for(int iVertex = 0; iVertex < 3; iVertex++)
        {
            g_aTriangle[iTriangle].SVertex[iVertex].vPosition = tbVector3Random();
            g_aTriangle[iTriangle].SVertex[iVertex].D3D_Color = D3DCOLOR_ARGB(255,RandomNumberInt(0,255),RandomNumberInt(0,255),RandomNumberInt(0,255));
        } 

Die Position sollte fest sein. Geschwindigkeit, Richtung und Skalierung ist ja schon zufällig. Denn zu beachten ist, das vor allem die Rotation immer um den NULL-Punkt statt findet. Sollte dein Z-Wert also z.B. den Wert +100 bekommen wird dein Dreieck einen schönen Kreisbogen um den Nullpunkt ziehen.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

3

10.12.2004, 17:21

Zitat

Die Position sollte fest sein. Geschwindigkeit, Richtung und Skalierung ist ja schon zufällig. Denn zu beachten ist, das vor allem die Rotation immer um den NULL-Punkt statt findet. Sollte dein Z-Wert also z.B. den Wert +100 bekommen wird dein Dreieck einen schönen Kreisbogen um den Nullpunkt ziehen.

??? Hängt das nicht von der Multiplikation der Matrixen ab? Also das passiert doch nur wenn du erst trans und dann rotierst....

4

10.12.2004, 17:36

Ja mom....das ist was anderes. Es geht hier um die Initialisierung der Vertice. Wenn ich shon hier einen Z-Wert von 100 habe, wird sich das Dreieck nicht mehr um die eigene Achse drehen.

Schau dir den Codeausschnitt an.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

5

10.12.2004, 18:42

stimmt.... bin immo ein wenig verplant :angel:

NoName

Treue Seele

Beiträge: 118

Beruf: Student

  • Private Nachricht senden

6

10.12.2004, 19:01

Zitat von »"DragonMaster"«

Als erstes. Die Reihenfolge der Multiplikationen ist nicht egal.

C-/C++-Quelltext

1
mWorld = mScaling * mRotationX * mRotationY * mRotationZ * mTranslation;


Setz mal besser ein paar Klammern:

C-/C++-Quelltext

1
mWorld = (mScaling * (mRotationX * mRotationY * mRotationZ)) * mTranslation;

Erst Skalieren, dann Rotieren, dann Transformieren :)

Mathematische Anmerkung:

Matrizenmultiplikation ist assoziativ, das heißt Klammern sind völlig egal.
Sie ist nur nicht kommutativ.

Dave

Alter Hase

Beiträge: 757

Wohnort: Berlin

  • Private Nachricht senden

7

11.12.2004, 13:33

matrizen wären somit mit den verknüpfungen * und + kein körper, oder? sei M die menge aller matrizen, dann wäre (M, +) eine abelsche gruppe. (M\{0}, *) wäre jedoch keine abelsche gruppe, da das kommutativ gesetz ja nicht gilt.
(M, +, *) wäre somit kein körper.

8

11.12.2004, 19:47

Erm...die Klammern implizieren die Reichenfolge in der die Matrizen multipliziert werden.

mat = mat1 * mat2 * mat3;

ist eine andere als z.B.

mat = mat1 * (mat2 * mat3);

weil die Reihenfolge sich ändert ;)

Reihenfolge:
tmp = mat2 * mat3;
mat = mat1 * tmp;

Da kannst du mir noch so mit Mathematischen Schlauheiten kommen. Es gilt hier nämlich keine Mathematische Regel sondern die Regel des * -Operators ;) Und der sagt: "Multiplizieren von Links nach rechts."

Ohne Klammern also diese Reihenfolge:
tmp = mat1 * mat2;
mat = tmp * mat3;

Was ein völlig anderes Ergebnis liefert ;)

[edit]
Für obiges heißt das also
tmp = mRotationX * mRotationY * mRotationZ;
tmp = mScaling * tmp;
mWorld = tmp * mTranslation;

Was der Reihenfolge:
Skalierung
Rotation
Transformation
entspricht.
Wichtig! Ich übernehme keinerlei Verantwortung für eventl. Datenverlust oder Schäden am Rechner ;D

NoName

Treue Seele

Beiträge: 118

Beruf: Student

  • Private Nachricht senden

9

11.12.2004, 20:41

Matrizenmultiplikation ist lediglich ein "Schiefkörper".

Es gilt

mat1 * (mat2 * mat3) = (mat1 * mat2) * mat3

(liefer mir doch mal ein Gegenbeispiel :) ),

aber es gilt nicht (immer)

mat1 * mat2 = mat2 * mat1.

Werbeanzeige