Lazarus - OpenGL 3.3 Tutorial - Matrix - Matrix Verschieben und Multiplizieren: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „200px<br><br> =Matrix - Matrix Verschieben und Multiplizieren = ==…“)
 
Zeile 8: Zeile 8:
 
Im Timer wird Matrix-Rotation ausgeführt.<br>
 
Im Timer wird Matrix-Rotation ausgeführt.<br>
 
<br>
 
<br>
Für Matrixen, wird ab jetzt Klassen aus der Unit '''OpenGLMatrix''' verwendent, dies macht das Ganze übersichtlicher.<br>
+
Für Matrixen, wird ab jetzt ein Type Helper aus der Unit '''OpenGLMatrix''' verwendent, dies macht das Ganze übersichtlicher.<br>
 
Dafür muss einfach die Unit '''oglMatrix''' bei uses eingebunden werden.<br>
 
Dafür muss einfach die Unit '''oglMatrix''' bei uses eingebunden werden.<br>
Im Constructor wird die Matrix von Anfang an auf die Einheits-Matrix gesetzt.<br>
+
In der Regel muss dann die Matrix mit '''TMatrix.Indenty''' auf die Einheits-Matrix gesetzt werden.<br>
 
<br><br>
 
<br><br>
 
Die Deklaration der drei Matrixen.<br>
 
Die Deklaration der drei Matrixen.<br>
Und die ID für den Shader. ID wird nur eine gebraucht, da nur da Produkt dem Shader übergeben wird.<br>
+
Und die ID für den Shader. Die ID wird nur eine gebraucht, da nur das Produkt dem Shader übergeben wird.<br>
 
<syntaxhighlight lang="pascal">var
 
<syntaxhighlight lang="pascal">var
 
   RotMatrix, TransMatrix, prodMatrix: TMatrix;  // Matrixen von der Klasse aus oglMatrix.
 
   RotMatrix, TransMatrix, prodMatrix: TMatrix;  // Matrixen von der Klasse aus oglMatrix.
 
   Matrix_ID: GLint;                              // ID für Matrix.</syntaxhighlight>
 
   Matrix_ID: GLint;                              // ID für Matrix.</syntaxhighlight>
Hier werden die drei Matrixen-Klassen erzeugt.<br>
+
Hier werden die drei Matrixen auf die gesetzt.<br>
Mit diesem Kontruktor wird die Matrix automatisch auf die Einheits-Matrix gesetzt.<br>
 
 
<syntaxhighlight lang="pascal">procedure TForm1.CreateScene;
 
<syntaxhighlight lang="pascal">procedure TForm1.CreateScene;
 
begin
 
begin
Zeile 25: Zeile 24:
 
   Color_ID := Shader.UniformLocation('Color');
 
   Color_ID := Shader.UniformLocation('Color');
 
   Matrix_ID := Shader.UniformLocation('mat');
 
   Matrix_ID := Shader.UniformLocation('mat');
   RotMatrix := TMatrix.Create;           // Die drei Konstruktoren
+
   RotMatrix.Identity;                   // Zuerst ist eine Einheitsmatrix erwünscht.
   TransMatrix := TMatrix.Create;
+
   TransMatrix.Identity;
   prodMatrix := TMatrix.Create;
+
   prodMatrix.Identity;
   TransMatrix.Translate(0.5, 0.0, 0.0);   // TransMatrix um 0.5 nach links verschieben.</syntaxhighlight>
+
   TransMatrix.Translate(0.5, 0.0, 0.0); // TransMatrix um 0.5 nach links verschieben.</syntaxhighlight>
 
Hier wird das Produkt von TransMatrx und RotMatrix den Shader übergeben.<br>
 
Hier wird das Produkt von TransMatrx und RotMatrix den Shader übergeben.<br>
 
Mit der Klasse geht dies einfacht mit '''xxxx.Uniform(ID)'''<br>
 
Mit der Klasse geht dies einfacht mit '''xxxx.Uniform(ID)'''<br>
Zeile 36: Zeile 35:
 
==Die Reihenfolge der Multiplikatoren ist sehr wichtig !==
 
==Die Reihenfolge der Multiplikatoren ist sehr wichtig !==
 
<br>
 
<br>
Einfach mal TransMatrix und RotMatrix vertauschen, dann sieht man ganz ein anderes Egebniss.<br>
+
Einfach mal TransMatrix und RotMatrix vertauschen, dann sieht man ganz ein anderes Ergebniss.<br>
 
Dann wird zuerst die Mesh verschoben und dann das Ganze um den Mittelpunkt gedreht.<br>
 
Dann wird zuerst die Mesh verschoben und dann das Ganze um den Mittelpunkt gedreht.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
Zeile 44: Zeile 43:
 
   prodMatrix.Multiply(TransMatrix, RotMatrix);
 
   prodMatrix.Multiply(TransMatrix, RotMatrix);
 
   prodMatrix.Uniform(Matrix_ID);    // prodMatrix in den Shader.</syntaxhighlight>
 
   prodMatrix.Uniform(Matrix_ID);    // prodMatrix in den Shader.</syntaxhighlight>
Die Matrixen-Klassen müssen am Ende wieder frei gegeben werden.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.FormDestroy(Sender: TObject);
 
begin
 
  Timer1.Enabled := False;
 
 
  prodMatrix.Free;
 
  RotMatrix.Free;
 
  TransMatrix.Free;</syntaxhighlight>
 
 
Die Drehung der Matrix wird fortlaufend um den Wert '''step''' gedreht.<br>
 
Die Drehung der Matrix wird fortlaufend um den Wert '''step''' gedreht.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.Timer1Timer(Sender: TObject);
 
<syntaxhighlight lang="pascal">procedure TForm1.Timer1Timer(Sender: TObject);

Version vom 23. März 2018, 21:29 Uhr

Lazarus - OpenGL 3.3 Tutorial - Matrix - Matrix Verschieben und Multiplizieren.png

Matrix - Matrix Verschieben und Multiplizieren

Einleitung

Hier wird die Mesh verschoben, und anschliessend gedreht.

Dazu werden zwei 4x4 Matrixen verwendet, eine für das Verschieben und die andere für die Drehung.
Eine dritte Matrix ist noch für das Produkt von den zweit Matrixen, welche dann am Shader übergeben wird.
Im Timer wird Matrix-Rotation ausgeführt.

Für Matrixen, wird ab jetzt ein Type Helper aus der Unit OpenGLMatrix verwendent, dies macht das Ganze übersichtlicher.
Dafür muss einfach die Unit oglMatrix bei uses eingebunden werden.
In der Regel muss dann die Matrix mit TMatrix.Indenty auf die Einheits-Matrix gesetzt werden.


Die Deklaration der drei Matrixen.
Und die ID für den Shader. Die ID wird nur eine gebraucht, da nur das Produkt dem Shader übergeben wird.

var
  RotMatrix, TransMatrix, prodMatrix: TMatrix;   // Matrixen von der Klasse aus oglMatrix.
  Matrix_ID: GLint;                              // ID für Matrix.

Hier werden die drei Matrixen auf die gesetzt.

procedure TForm1.CreateScene;
begin
  Shader := TShader.Create([FileToStr('Vertexshader.glsl'), FileToStr('Fragmentshader.glsl')]);
  Shader.UseProgram;
  Color_ID := Shader.UniformLocation('Color');
  Matrix_ID := Shader.UniformLocation('mat');
  RotMatrix.Identity;                   // Zuerst ist eine Einheitsmatrix erwünscht.
  TransMatrix.Identity;
  prodMatrix.Identity;
  TransMatrix.Translate(0.5, 0.0, 0.0); // TransMatrix um 0.5 nach links verschieben.

Hier wird das Produkt von TransMatrx und RotMatrix den Shader übergeben.
Mit der Klasse geht dies einfacht mit xxxx.Uniform(ID)

xxxx.Multiply(... macht prodMatrix = TransMatrix * RotMatrix .
Debei wird die Mesh zuerst gedreht und dann verschoben.

Die Reihenfolge der Multiplikatoren ist sehr wichtig !


Einfach mal TransMatrix und RotMatrix vertauschen, dann sieht man ganz ein anderes Ergebniss.
Dann wird zuerst die Mesh verschoben und dann das Ganze um den Mittelpunkt gedreht.

procedure TForm1.ogcDrawScene(Sender: TObject);
begin
  glClear(GL_COLOR_BUFFER_BIT);
  Shader.UseProgram;
  prodMatrix.Multiply(TransMatrix, RotMatrix);
  prodMatrix.Uniform(Matrix_ID);     // prodMatrix in den Shader.

Die Drehung der Matrix wird fortlaufend um den Wert step gedreht.

procedure TForm1.Timer1Timer(Sender: TObject);
const
  step: GLfloat = 0.01;
begin
  RotMatrix.RotateC(step); // RotMatrix rotieren
  ogcDrawScene(Sender);    // Neu zeichnen
end;



Vertex-Shader:


Hier ist die Uniform-Variable mat hinzugekommen.
Diese wird im Vertex-Shader deklariert, Bewegungen kommen immer in diesen Shader.

#version 330

layout (location = 10) in vec3 inPos; // Vertex-Koordinaten
uniform mat4 mat;                     // Matrix von Uniform

void main(void)
{
  gl_Position = mat * vec4(inPos, 1.0);
}



Fragment-Shader:

#version 330

uniform vec3 Color;  // Farbe von Uniform
out vec4 outColor;   // ausgegebene Farbe

void main(void)
{
  outColor = vec4(Color, 1.0);
}


Autor: Mathias

Siehe auch