Lazarus - OpenGL 3.3 Tutorial - 3D - Orthogonalprojektion: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „200px<br><br> =3D - Orthogonalprojektion = == Einleitung == Eine OpenGL-Scene wird imme…“)
 
(3D - Orthogonalprojektion)
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 3: Zeile 3:
 
== Einleitung ==
 
== Einleitung ==
 
Eine OpenGL-Scene wird immer in einem Bereich von '''-1''' bis '''+1''' in allen drei Achsen gezeichnet. Ist etwas ausserhalb dieses Bereiches, wird dies ignoriert.<br>
 
Eine OpenGL-Scene wird immer in einem Bereich von '''-1''' bis '''+1''' in allen drei Achsen gezeichnet. Ist etwas ausserhalb dieses Bereiches, wird dies ignoriert.<br>
Um dies zu umgehen mutipliziert man die Scene mit einer Ortho-Matrix.<br>
+
Um dies zu umgehen multipliziert man die Scene mit einer Ortho-Matrix.<br>
 
Für diesen Zweck habe ich eine Funtkion '''TMatrix.Ortho(...'''. Mit den sechs Parametern in der Funktion, kann man den gewünschten Bereich einstellen.<br>
 
Für diesen Zweck habe ich eine Funtkion '''TMatrix.Ortho(...'''. Mit den sechs Parametern in der Funktion, kann man den gewünschten Bereich einstellen.<br>
 
<br>
 
<br>
Zeile 23: Zeile 23:
 
   w = 12.0;  // Seiten-Länge
 
   w = 12.0;  // Seiten-Länge
 
begin
 
begin
   Matrix := TMatrix.Create;
+
   Matrix.Identity;
  OrthoMatrix := TMatrix.Create;
+
   WorldMatrix.Identity;
   WorldMatrix := TMatrix.Create;
 
 
   WorldMatrix.Scale(0.75);                    // Welt-Matrix zoomen
 
   WorldMatrix.Scale(0.75);                    // Welt-Matrix zoomen
 
   OrthoMatrix.Ortho(-w, w, -w, +w, -w, +w);  // Den Ortho-Bereich einstellen.</syntaxhighlight>
 
   OrthoMatrix.Ortho(-w, w, -w, +w, -w, +w);  // Den Ortho-Bereich einstellen.</syntaxhighlight>
Hier werden die einzelnen kleinen Würfel gezeichnet, dabei sieht man gut, wie alle drei Matrixen mutipliziert werden.<br>
+
Hier werden die einzelnen kleinen Würfel gezeichnet, dabei sieht man gut, wie alle drei Matrizen mutipliziert werden.<br>
Diese entspricht '''Matrix = OrthoMatrix * WorldMatrix * Matrix'''.<br>
+
Die Matrizen könnte man auch im Shader multiplizieren, dafür müsste man einfach für jede Matrix eine Uniform deklarieren.<br>
Die Matrixen könnte man auch im Shader multiplizieren, dafür müsste man einfach wür jeder Matrix eine Unifom deklarieren.<br>
+
Dies hat aber den Nachteil, das die Multiplikation bei jedem Vektor ausgeführt wird, bei Meshes mit hoher Vektor-Zahl merkt man dies bemerklich.<br>
Dies hat aber den Nachteil, das die Multiplikation bei jedem Vektor ausgefüht wird, bei Meshes mit hoher Vektor-Zahl merkt man dies bemerklich.<br>
 
 
<br>
 
<br>
 
Hier sieht man auch gut, das man eine Mesh nach dem Binden mehrmals gezeichnet werden kann.<br>
 
Hier sieht man auch gut, das man eine Mesh nach dem Binden mehrmals gezeichnet werden kann.<br>
Zeile 58: Zeile 56:
 
         Matrix.Translate(x * d, y * d, z * d);                // Matrix verschieben.
 
         Matrix.Translate(x * d, y * d, z * d);                // Matrix verschieben.
  
         Matrix.Multiply(WorldMatrix, Matrix);                 // Matrixen multiplizieren.
+
         Matrix := OrthoMatrix * WorldMatrix * Matrix;         // Matrizen multiplizieren.
        Matrix.Multiply(OrthoMatrix, Matrix);
 
  
 
         Matrix.Uniform(Matrix_ID);                            // Matrix dem Shader übergeben.
 
         Matrix.Uniform(Matrix_ID);                            // Matrix dem Shader übergeben.
Zeile 75: Zeile 72:
 
   WorldMatrix.RotateB(0.0234);  // Drehe um Y-Achse</syntaxhighlight>
 
   WorldMatrix.RotateB(0.0234);  // Drehe um Y-Achse</syntaxhighlight>
 
<br><br>
 
<br><br>
 +
 
==Vertex-Shader:==
 
==Vertex-Shader:==
 
<syntaxhighlight lang="glsl">#version 330
 
<syntaxhighlight lang="glsl">#version 330
Zeile 95: Zeile 93:
 
<syntaxhighlight lang="glsl">#version 330
 
<syntaxhighlight lang="glsl">#version 330
  
in vec4 Color;     // interpolierte Farbe vom Vertexshader
+
in vec4 Color;     // interpolierte Farbe vom Vertexshader
 
out vec4 outColor;  // ausgegebene Farbe
 
out vec4 outColor;  // ausgegebene Farbe
  
Zeile 105: Zeile 103:
  
 
<br>Autor: [[Mathias]]
 
<br>Autor: [[Mathias]]
 +
 
== Siehe auch ==
 
== Siehe auch ==
 
* Übersichtseite [[Lazarus - OpenGL 3.3 Tutorial]]
 
* Übersichtseite [[Lazarus - OpenGL 3.3 Tutorial]]

Aktuelle Version vom 20. Juni 2018, 17:38 Uhr

Lazarus - OpenGL 3.3 Tutorial - 3D - Orthogonalprojektion.png

3D - Orthogonalprojektion

Einleitung

Eine OpenGL-Scene wird immer in einem Bereich von -1 bis +1 in allen drei Achsen gezeichnet. Ist etwas ausserhalb dieses Bereiches, wird dies ignoriert.
Um dies zu umgehen multipliziert man die Scene mit einer Ortho-Matrix.
Für diesen Zweck habe ich eine Funtkion TMatrix.Ortho(.... Mit den sechs Parametern in der Funktion, kann man den gewünschten Bereich einstellen.

Zusätzlich ist noch eine Welt-Matrix hinzugekommen. Damit wird die ganze Scene in den sichtbaren Bereich bewegt,


Deklaration der drei Matrixen.

var
  OrthoMatrix,         // Matrix für Ortho.
  WorldMatrix,         // Matrix für Welt.
  Matrix: TMatrix;     // Matrix, welche dem Shader übergeben wird.
  Matrix_ID: GLint;    // ID der Matrix für den Shader.

So sieht die Funktion aus: Ortho(left, right, bottom, top, znear, zfar);.
Hier wird die OrthoMatrix erzeugt, und mit neuen Werten eingestellt.
Im Beispiel ist dies eine Seitenlänge in allen Achsen um 24.0 (2 * 12.0).

Die Skalierung der Welt-Matrix hat den Effekt, das die ganze Scene gezoomt wird.

procedure TForm1.CreateScene;
const
  w = 12.0;  // Seiten-Länge
begin
  Matrix.Identity;
  WorldMatrix.Identity;
  WorldMatrix.Scale(0.75);                    // Welt-Matrix zoomen
  OrthoMatrix.Ortho(-w, w, -w, +w, -w, +w);   // Den Ortho-Bereich einstellen.

Hier werden die einzelnen kleinen Würfel gezeichnet, dabei sieht man gut, wie alle drei Matrizen mutipliziert werden.
Die Matrizen könnte man auch im Shader multiplizieren, dafür müsste man einfach für jede Matrix eine Uniform deklarieren.
Dies hat aber den Nachteil, das die Multiplikation bei jedem Vektor ausgeführt wird, bei Meshes mit hoher Vektor-Zahl merkt man dies bemerklich.

Hier sieht man auch gut, das man eine Mesh nach dem Binden mehrmals gezeichnet werden kann.

procedure TForm1.ogcDrawScene(Sender: TObject);
var
  x, y, z: integer;
const
  d = 1.8;  // Abstand der Würfel.
  s = 4;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  glEnable(GL_CULL_FACE);
  glCullface(GL_BACK);

  Shader.UseProgram;

  glBindVertexArray(VBCube.VAO);

  // --- Zeichne Würfel

  for x := -s to s do begin
    for y := -s to s do begin
      for z := -s to s do begin
        Matrix.Identity;
        Matrix.Translate(x * d, y * d, z * d);                 // Matrix verschieben.

        Matrix := OrthoMatrix * WorldMatrix * Matrix;          // Matrizen multiplizieren.

        Matrix.Uniform(Matrix_ID);                             // Matrix dem Shader übergeben.
        glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3); // Zeichnet einen kleinen Würfel.
      end;
    end;
  end;

  ogc.SwapBuffers;
end;

Kamera um die Mesh bewegen.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  WorldMatrix.RotateA(0.0123);  // Drehe um X-Achse
  WorldMatrix.RotateB(0.0234);  // Drehe um Y-Achse



Vertex-Shader:

#version 330

layout (location = 10) in vec3 inPos; // Vertex-Koordinaten
layout (location = 11) in vec3 inCol; // Farbe

out vec4 Color;                       // Farbe, an Fragment-Shader übergeben

uniform mat4 Matrix;                  // Matrix für die Drehbewegung und Ortho

void main(void)
{
  gl_Position = Matrix * vec4(inPos, 1.0);
  Color = vec4(inCol, 1.0);
}



Fragment-Shader

#version 330

in  vec4 Color;     // interpolierte Farbe vom Vertexshader
out vec4 outColor;  // ausgegebene Farbe

void main(void)
{
  outColor = Color; // Die Ausgabe der Farbe
}


Autor: Mathias

Siehe auch