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

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

1

05.12.2011, 00:50

ModelView Matrix manuell erstellen

Hallo

Ich möchte eine ModelView Matrix unter openGL manuell erstellen.
Ich habe zu dem Thema hunderte von Berechnungsvorschriften im Internet
gefunden und die Berechnung entsprechend kodiert. Um meinen code zu prüfen
habe ich dessen Ergebnis mit dem resultat von gluLookAt verglichen.
Mein Problem ist das ich das Ergebnis von gluLookAt mit keiner Berechnungvorschrift
in Einklang kriege. Die Matrizen die gluLookAt liefert sind mir ein absolutes Rätzel.

Beispiel:
eye = (0.0, 0.0, -2.0); center = (0.0, 0.0, 0.0); up = (0.0, 1.0, 0.0)
Laut meinem Verständnis ergibt sich hier keine Rotation sondern nur eine Translation
um -eye also um (0.0, 0.0, 2.0). Damit ergibt sich eine Matrix ...
M = 1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 2.0 1.0

gluLookAt liefert folgendes float array:
- f1 0x0013fe1c float [16]
[0] -1.0000000 float
[1] 0.00000000 float
[2] 0.00000000 float
[3] 0.00000000 float
[4] 0.00000000 float
[5] 1.0000000 float
[6] 0.00000000 float
[7] 0.00000000 float
[8] 0.00000000 float
[9] 0.00000000 float
[10] -1.0000000 float
[11] 0.00000000 float
[12] 0.00000000 float
[13] 0.00000000 float
[14] -2.0000000 float
[15] 1.0000000 float


dies entspricht einer Matrix ...
M= -1.0 0.0 0.0 0.0
0.0 1.0 0.0 0.0
0.0 0.0 -1.0 -2.0
0.0 0.0 0.0 1.0

Wie kommt diese Matrix zustande ?????
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

05.12.2011, 01:13

Auf den Seiten 22 (unten) und 23 findest du hier eine kurze Erklärung. Die Viewmatrix transformiert vom Worldspace in den Viewspace. Um sie zu berechnen, bestimmt man die Basisvektoren des Viewspace in Weltkoordinaten, packt das ganze in eine Matrix und berechnet die Inverse davon. Die Formeln, die man dabei erhält, findest du dort in den Gleichungen (20) und (21). Beachte aber, dass dort ein linkshändiges Koordinatensystem verwendet wird. Wenn du ein rechtshändiges willst, musst du die Richtung von cz umdrehen.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

3

05.12.2011, 01:36

Hallo dot

Was bedeutet -<cx,eye> und wo ist die Invertierung in den Formeln zu erkennen ?
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

05.12.2011, 01:40

Die Formel stellt bereits die invertierte Matrix dar. <a,b> ist die gängige Notation für das Skalarprodukt der Vektoren a und b.

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

05.12.2011, 09:01

Hab ich geschrieben und liefert genau die OpenGL Ergebnisse:

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
    void setIdentity(){
        for(int i = 0; i < 16; i++){
            values[i] = 0;
        }

        values[0] = 1;
        values[5] = 1;
        values[10] = 1;
        values[15] = 1;
    }

    void translate(float x, float y, float z){
        mat4 m;

        m.setIdentity();

        m.values[12] = x;
        m.values[13] = y;
        m.values[14] = z;

        *this *= m;
    }

    void scale(float x, float y, float z){
        mat4 m;

        m.setIdentity();
        
        m.values[0] = x;
        m.values[5] = y;
        m.values[10] = z;

        *this *= m;
    }

    void rotate(float angle, float x, float y, float z){
        mat4 m;
        float co, si;
        vec3 axis;
        
        axis = vec3(x, y, z);
        axis.normalize();

        angle = angle*(PI/180);
        co = cos(angle);
        si = sin(angle);
 
        m.values[0] = axis.x*axis.x*(1-co)+co;
        m.values[1] = axis.y*axis.x*(1-co)+axis.z*si;
        m.values[2] = axis.x*axis.z*(1-co)-axis.y*si;
        m.values[3]= 0;
 
        m.values[4] = axis.x*axis.y*(1-co)-axis.z*si;
        m.values[5] = axis.y*axis.y*(1-co)+co;
        m.values[6] = axis.y*axis.z*(1-co)+axis.x*si;
        m.values[7]= 0;
 
        m.values[8] = axis.x*axis.z*(1-co)+axis.y*si;
        m.values[9] = axis.y*axis.z*(1-co)-axis.x*si;
        m.values[10]= axis.z*axis.z*(1-co)+co;
        m.values[11]= 0;
 
        m.values[12] = 0;
        m.values[13] = 0;
        m.values[14]= 0;
        m.values[15]= 1;
        
        *this *= m;
    }

    void lookAt(float x, float y, float z, float xlook, float ylook, float zlook, float xup, float yup, float zup){
        mat4 m;
        vec3 dir, right, up, eye;
 
        eye.x = x;
        eye.y = y;
        eye.z = z;

        up.x = xup;    
        up.y = yup;    
        up.z = zup;
         
        dir.x = (xlook-x);
        dir.y = (ylook-y);
        dir.z = (zlook-z);
        dir.normalize();

        right.cross(dir, up);
        right.normalize();

        up.cross(right, dir);
        up.normalize();
 
        m.values[0] = right.x;
        m.values[4] = right.y;
        m.values[8] = right.z;
        m.values[12] = -right.dot(eye);
 
        m.values[1] = up.x;
        m.values[5] = up.y;
        m.values[9] = up.z;
        m.values[13] = -up.dot(eye);
 
        m.values[2] = -dir.x;
        m.values[6] = -dir.y;
        m.values[10] = -dir.z;
        m.values[14] = dir.dot(eye);
 
        m.values[3] = 0;
        m.values[7] = 0;
        m.values[11] = 0;
        m.values[15] = 1;

        *this *= m;
    }

    void perspective(float fov, float ratio, float nearp, float farp){ 
        mat4 m;     
        float f = 1/tan(fov*(PI/360));
 
        m.setIdentity();
 
        m.values[0] = f/ratio;
        m.values[5] = f;
        m.values[10] = (farp+nearp)/(nearp-farp);
        m.values[11] = -1;
        m.values[14] = (2*farp*nearp)/(nearp-farp);
        m.values[15] = 0;
 
        *this *= m;
    }

    void ortho(float left, float right, float bottom, float top, float nearp, float farp){
        mat4 m;
        
        m.setIdentity();
        
        if(left != right && bottom != top && nearp != farp){
            m.values[0] = 2/(right-left);
            m.values[5] = 2/(top-bottom);
            m.values[10] = -2/(farp-nearp);
            m.values[12] = -(right+left)/(right-left);
            m.values[13] = -(top+bottom)/(top-bottom);
            m.values[14] = -(farp+nearp)/(farp-nearp);
        }
        
        *this *= m;
    }


Wenn du das ganze struct haben willst sag mir bescheid...
Wie sich das jetzt im einzellnen genau berechnet hab ich schon wieder vergessen ^^ Aber danach googlen hilft ja, und zum Glück muss ich das jetzt nicht mehr so genau wissen.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

6

05.12.2011, 11:50

Translationsmatrix ??? wie denn nu ????

Hallo

Vielen Dank für die Hilfe.
Ich habe noch eine Frage zu der ganzen Sache:

Warum wird in DirectX Literatur die Translationsmatrix mit

1 0 0 0
0 1 0 0
m = 0 0 1 0
x y z 1

und in OpenGL Literatur mit

1 0 0 x
0 1 0 y
m = 0 0 1 z
0 0 0 1


bschrieben ?

Gruß

stef
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

05.12.2011, 11:55

OpenGL verwendet ein anderes Matrix Layout als DirectX: http://www.mindcontrol.org/~hplus/graphi…rix-layout.html
@D13_Dreinig

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

05.12.2011, 12:14

In DirectX war es üblich, Vektoren als Zeilen zu interpretieren. Damit ergibt sich eine andere Multiplikationsreihenfolge, nämlich §\mathrm\mathbf v \cdot \mathrm\mathbf M§ anstatt §\mathrm\mathbf M \cdot \mathrm\mathbf v§. Und daher sind "DirectX Matritzen" genau die transponierten Versionen ihrer OpenGL-Gegenstücke. Da "DirectX Matritzen" aber auch im transponierten Layout gespeichert wurden (Row-Major statt Column-Major), sahen "DirectX" und "OpenGL Matritzen" am Ende im Speicher völlig identisch aus.

Die "" sind kein Unfall und ich rede bewusst in der Vergangenheitsform, da heutzutage keine der beiden APIs mehr ein Format für die Matrizen vorgibt. In modernem OpenGL und Direct3D läuft alles über Shader und dort kannst du machen was du willst, so ist es natürlich auch deine Sache wie du deine Matritzen interpretierst.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

9

05.12.2011, 13:06

@David_pb: Das mit dem unterschiedlichem Speicherlayout ist bekannt. Trotzdem Danke.

@Dot: Ich habe bezüglich Translation folgendes Problem. Ich habe unter DirectX (wo ich eigentlich herkomme) einen Alg. geschrieben der einen Torus aufbaut (Vertexbuffer).
Diesen Alg. habe ich unter openGL angewand und es funktioniert mit der DirectX-Variante der Translationsmatrix. Für das Lösen der ModelView Problematik habe ich nun
meine Translationsmatrix umgebaut (openGL-Variante). Jetzt sieht mein Torus völlig deformiert aus.
Wenn ich dich richtig verstehe kann ich den Torus wieder hinbiegen indem ich in meinem Alg. die Multiplikationsreihenfolge (von Vector * Matrix nach Matrix * Vector) tausche.
Ist das richtig ?

Gruß und danke

stef
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

stef

Treue Seele

  • »stef« ist der Autor dieses Themas

Beiträge: 246

Wohnort: Kassel

Beruf: Softwareentwickler

  • Private Nachricht senden

10

05.12.2011, 13:08

@DeKugelschieber: Vielen Dank für den Code. Ich möcht es aber auch gern verstehn.

Gruß

stef
"In C++ it's harder to shoot yourself in the foot, but when you do, you blow off your whole leg." — Bjarne Stroustrup.

Werbeanzeige