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

Aus DGL Wiki
Wechseln zu: Navigation, Suche
(Die Seite wurde neu angelegt: „200px<br><br> =3D - Erster-Wuerfel = == Einleitung == Jetzt wird das erste mal 3D gerendert.<…“)
 
(Einleitung)
 
Zeile 35: Zeile 35:
 
Der Kleine übermahlt einfach den grossen.<br>
 
Der Kleine übermahlt einfach den grossen.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
 +
var
 +
  TempMatrix: TMatrix;
 
begin
 
begin
 
   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 
   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Zeile 47: Zeile 49:
 
   glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);  // Zeichne grossen Würfel
 
   glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);  // Zeichne grossen Würfel
  
   WorldMatrix.Push;                                       // Matrix sichern
+
   TempMatrix := WorldMatrix;                               // Matrix sichern
  
 
   WorldMatrix.Scale(0.5);                                  // Matrix kleiner scalieren
 
   WorldMatrix.Scale(0.5);                                  // Matrix kleiner scalieren
Zeile 53: Zeile 55:
 
   glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);  // Zeichne kleinen Würfel
 
   glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);  // Zeichne kleinen Würfel
  
   WorldMatrix.Pop;                                         // Matrix laden
+
   WorldMatrix := TempMatrix;                               // Matrix laden
  
 
   ogc.SwapBuffers;
 
   ogc.SwapBuffers;
end;</syntaxhighlight>
+
end;
 +
</syntaxhighlight>
 
Mit einem Timer wird der Würfel gedreht und neu gezeichnet.<br>
 
Mit einem Timer wird der Würfel gedreht und neu gezeichnet.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.Timer1Timer(Sender: TObject);
 
<syntaxhighlight lang="pascal">procedure TForm1.Timer1Timer(Sender: TObject);
Zeile 66: Zeile 69:
 
end;</syntaxhighlight>
 
end;</syntaxhighlight>
 
<br><br>
 
<br><br>
 +
 
==Vertex-Shader:==
 
==Vertex-Shader:==
 
<syntaxhighlight lang="glsl">#version 330
 
<syntaxhighlight lang="glsl">#version 330

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

Lazarus - OpenGL 3.3 Tutorial - 3D - Erster-Wuerfel.png

3D - Erster-Wuerfel

Einleitung

Jetzt wird das erste mal 3D gerendert.
Dafür wird ein einfacher Würfel genommen, welcher sechs unterschiedlich farbige Flächen hat.

In diesem Beispiel wird bewusst noch auf den Tiefenbuffer verzichtet.
Somit sieht man gut, was passiert wen man diesen nicht berücksichtigt.


Hier sind die Koordinaten und die Farben des Würfels deklariert.

type
  TCube = array[0..11] of Tmat3x3;

const
  CubeVertex: TCube =
    (((-0.5, 0.5, 0.5), (-0.5, -0.5, 0.5), (0.5, -0.5, 0.5)), ((-0.5, 0.5, 0.5), (0.5, -0.5, 0.5), (0.5, 0.5, 0.5)),
    ((0.5, 0.5, 0.5), (0.5, -0.5, 0.5), (0.5, -0.5, -0.5)), ((0.5, 0.5, 0.5), (0.5, -0.5, -0.5), (0.5, 0.5, -0.5)),
    ((0.5, 0.5, -0.5), (0.5, -0.5, -0.5), (-0.5, -0.5, -0.5)), ((0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (-0.5, 0.5, -0.5)),
    ((-0.5, 0.5, -0.5), (-0.5, -0.5, -0.5), (-0.5, -0.5, 0.5)), ((-0.5, 0.5, -0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, 0.5)),
    // oben
    ((0.5, 0.5, 0.5), (0.5, 0.5, -0.5), (-0.5, 0.5, -0.5)), ((0.5, 0.5, 0.5), (-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5)),
    // unten
    ((-0.5, -0.5, 0.5), (-0.5, -0.5, -0.5), (0.5, -0.5, -0.5)), ((-0.5, -0.5, 0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5)));
  CubeColor: TCube =
    (((1.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 0.0, 0.0)), ((1.0, 0.0, 0.0), (1.0, 0.0, 0.0), (1.0, 0.0, 0.0)),
    ((0.0, 1.0, 0.0), (0.0, 1.0, 0.0), (0.0, 1.0, 0.0)), ((0.0, 1.0, 0.0), (0.0, 1.0, 0.0), (0.0, 1.0, 0.0)),
    ((0.0, 0.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0, 1.0)), ((0.0, 0.0, 1.0), (0.0, 0.0, 1.0), (0.0, 0.0, 1.0)),
    ((0.0, 1.0, 1.0), (0.0, 1.0, 1.0), (0.0, 1.0, 1.0)), ((0.0, 1.0, 1.0), (0.0, 1.0, 1.0), (0.0, 1.0, 1.0)),
    // oben
    ((1.0, 1.0, 0.0), (1.0, 1.0, 0.0), (1.0, 1.0, 0.0)), ((1.0, 1.0, 0.0), (1.0, 1.0, 0.0), (1.0, 1.0, 0.0)),
    // unten
    ((1.0, 0.0, 1.0), (1.0, 0.0, 1.0), (1.0, 0.0, 1.0)), ((1.0, 0.0, 1.0), (1.0, 0.0, 1.0), (1.0, 0.0, 1.0)));

Ohne Tiefenbuffer wird einfach alles gezeichnet, auch wen es verdeckt hinter einem anderen Object ist.
Das man dies gut sieht, zeichne ich einen kleinen Würfel in den Grossen.
Der Kleine übermahlt einfach den grossen.

procedure TForm1.ogcDrawScene(Sender: TObject);
var
  TempMatrix: TMatrix;
begin
  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

  Shader.UseProgram;

  // --- Zeichne Würfel

  glBindVertexArray(VBCube.VAO);

  WorldMatrix.Uniform(WorldMatrix_ID);                     // Matrix dem Shader übergeben
  glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);   // Zeichne grossen Würfel

  TempMatrix := WorldMatrix;                               // Matrix sichern

  WorldMatrix.Scale(0.5);                                  // Matrix kleiner scalieren
  WorldMatrix.Uniform(WorldMatrix_ID);                     // Matrix dem Shader übergeben
  glDrawArrays(GL_TRIANGLES, 0, Length(CubeVertex) * 3);   // Zeichne kleinen Würfel

  WorldMatrix := TempMatrix;                               // Matrix laden

  ogc.SwapBuffers;
end;

Mit einem Timer wird der Würfel gedreht und neu gezeichnet.

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

  ogc.Invalidate;
end;



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

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