Lazarus - OpenGL 3.3 Tutorial - Texturen - Filter: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
 
(3 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 2: Zeile 2:
 
=Texturen - Filter =
 
=Texturen - Filter =
 
== Einleitung ==
 
== Einleitung ==
Hier wird gezeigt, wie man mehrere Texturen laden kann, im Prinzip geht dies fast gleich wie bei einer Textur.<br>
+
Hier wird gezeigt, wie man Filter für Texturen verwenden kann.<br>
In diesem Beispiel werden zwei Texturen geladen.<br>
+
In diesem Beispiel wird nur eine Texturen geladen, aber es werden mehrere Filter verwendet.<br>
 
<br>
 
<br>
Wichtig dabei ist, das man mit '''glBindTexture(...''' immer die richtige Textur bindet.<br>
+
Die Filter verstellt man mit '''glTexParameter(...'''.<br>
 
<br><br>
 
<br><br>
Da es zwei Texturen hat, bracuht es auch zwei IDs.<br>
+
Hier wird die Textur geladen und der Filter '''MIN_FILTER''' festgelegt, welcher für alle Ausgaben gültig ist.<br>
<syntaxhighlight lang="pascal">var
 
  textureID: GLuint;</syntaxhighlight>
 
Da die Zextur-IDs in einer Array sind, kann man die Textur-Puffer mit nur einem '''glGenTextures(...''' erzeugen.<br>
 
Dazu gebe ich als ersten Parameter die Länge der Array an.<br>
 
Natürlich könnte man die Puffer auch einzeln erzeugen.<br>
 
<br>
 
Das selbe könnte man auch bei den VAOs und VBOs machen.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.CreateScene;
 
begin
 
  glGenVertexArrays(1, @VBQuad.VAO);
 
  glGenBuffers(1, @VBQuad.VBOVertex);
 
  glGenBuffers(1, @VBQuad.VBOTex);
 
 
 
  glGenTextures(1, @textureID);  // Erster Parameter die Länge der Arrray.</syntaxhighlight>
 
Mehrer Texturen laden geht genaus so einfache, wie wen man nur eine hat.<br>
 
 
<syntaxhighlight lang="pascal">procedure TForm1.InitScene;
 
<syntaxhighlight lang="pascal">procedure TForm1.InitScene;
 
var
 
var
 
   pic: TPicture;
 
   pic: TPicture;
  border: array[0..3] of GLfloat = (0.0, 1.0, 0.0, 1.0);
 
  
 
begin
 
begin
Zeile 33: Zeile 17:
 
     LoadFromFile('bild.xpm');
 
     LoadFromFile('bild.xpm');
  
     // Textur laden.
+
     // Textur laden
 
     glBindTexture(GL_TEXTURE_2D, textureID);
 
     glBindTexture(GL_TEXTURE_2D, textureID);
 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Width, Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Bitmap.RawImage.Data);
 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Width, Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Bitmap.RawImage.Data);
  
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
     // Globaler Filter
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, @border);
 
  
 
     glBindTexture(GL_TEXTURE_2D, 0);
 
     glBindTexture(GL_TEXTURE_2D, 0);
     Free; // pic
+
     Free;
 
   end;</syntaxhighlight>
 
   end;</syntaxhighlight>
Hier sieht man, das ich für die beiden Qudrate unterschiedliche Texturen binde.<br>
+
Bei dem Filter '''GL_CLAMP_TO_BORDER''' kann man noch eine Hintergrundfarbe festlegen.<br>
Koordinaten verwende ich für beide Qudrate die gleichen, einziger Unterschied, ich verschiebe die Matrix in unterschiedliche Richtungen.<br>
 
Aus diesem Grund wird die VAO auch nur einmal gebunden.<br>
 
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
 
<syntaxhighlight lang="pascal">procedure TForm1.ogcDrawScene(Sender: TObject);
 +
// Hintergrundfarbe für Clamp_to_Border, ein Dunkelgrün.
 +
const
 +
  border: array[0..3] of GLfloat = (0.0, 0.3, 0.0, 1.0);
 +
var
 +
  ProdMatrix: TMatrix;
 
begin
 
begin
 
   glClear(GL_COLOR_BUFFER_BIT);
 
   glClear(GL_COLOR_BUFFER_BIT);
Zeile 61: Zeile 46:
 
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  
   ProdMatrix.Assign(ScaleMatrix);
+
   ProdMatrix := ScaleMatrix;
 
   ProdMatrix.Translate(-0.5, 0.5, 0.0);
 
   ProdMatrix.Translate(-0.5, 0.5, 0.0);
 
   ProdMatrix.Uniform(Matrix_ID);
 
   ProdMatrix.Uniform(Matrix_ID);
Zeile 70: Zeile 55:
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 +
  glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, @border);
  
   ProdMatrix.Assign(ScaleMatrix);
+
   ProdMatrix := ScaleMatrix;
 
   ProdMatrix.Translate(0.5, 0.5, 0.0);
 
   ProdMatrix.Translate(0.5, 0.5, 0.0);
 
   ProdMatrix.Uniform(Matrix_ID);
 
   ProdMatrix.Uniform(Matrix_ID);
Zeile 82: Zeile 69:
 
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
   ProdMatrix.Assign(ScaleMatrix);
+
   ProdMatrix := ScaleMatrix;
 
   ProdMatrix.Translate(-0.5, -0.5, 0.0);
 
   ProdMatrix.Translate(-0.5, -0.5, 0.0);
 
   ProdMatrix.Uniform(Matrix_ID);
 
   ProdMatrix.Uniform(Matrix_ID);
Zeile 91: Zeile 78:
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 +
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
   ProdMatrix.Assign(ScaleMatrix);
+
   ProdMatrix := ScaleMatrix;
 
   ProdMatrix.Translate(0.5, -0.5, 0.0);
 
   ProdMatrix.Translate(0.5, -0.5, 0.0);
 
   ProdMatrix.Uniform(Matrix_ID);
 
   ProdMatrix.Uniform(Matrix_ID);
Zeile 100: Zeile 88:
 
   ogc.SwapBuffers;
 
   ogc.SwapBuffers;
 
end;</syntaxhighlight>
 
end;</syntaxhighlight>
Logischerweise muss man auch wieder beide Textur-Puffer frei geben.<br>
 
<syntaxhighlight lang="pascal">procedure TForm1.FormDestroy(Sender: TObject);
 
begin
 
  glDeleteTextures(1, @textureID); // Textur-Puffer frei geben.</syntaxhighlight>
 
 
<br><br>
 
<br><br>
Die Shader sind genau gleich, wie bei einer Textur.<br>
 
<br>
 
 
==Vertex-Shader:==
 
==Vertex-Shader:==
 
<br>
 
<br>
 
<syntaxhighlight lang="glsl">#version 330
 
<syntaxhighlight lang="glsl">#version 330
  
layout (location = 0) in vec3 inPos;   // Vertex-Koordinaten
+
layout (location = 0) in vec3 inPos;   // Vertex-Koordinaten
 
layout (location = 10) in vec2 inUV;    // Textur-Koordinaten
 
layout (location = 10) in vec2 inUV;    // Textur-Koordinaten
  

Aktuelle Version vom 21. August 2018, 17:28 Uhr

Lazarus - OpenGL 3.3 Tutorial - Texturen - Filter.png

Texturen - Filter

Einleitung

Hier wird gezeigt, wie man Filter für Texturen verwenden kann.
In diesem Beispiel wird nur eine Texturen geladen, aber es werden mehrere Filter verwendet.

Die Filter verstellt man mit glTexParameter(....


Hier wird die Textur geladen und der Filter MIN_FILTER festgelegt, welcher für alle Ausgaben gültig ist.

procedure TForm1.InitScene;
var
  pic: TPicture;

begin
  pic := TPicture.Create;
  with pic do begin
    LoadFromFile('bild.xpm');

    // Textur laden
    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, Width, Height, 0, GL_BGR, GL_UNSIGNED_BYTE, Bitmap.RawImage.Data);

    // Globaler Filter
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D, 0);
    Free;
  end;

Bei dem Filter GL_CLAMP_TO_BORDER kann man noch eine Hintergrundfarbe festlegen.

procedure TForm1.ogcDrawScene(Sender: TObject);
// Hintergrundfarbe für Clamp_to_Border, ein Dunkelgrün.
const
  border: array[0..3] of GLfloat = (0.0, 0.3, 0.0, 1.0);
var
  ProdMatrix: TMatrix;
begin
  glClear(GL_COLOR_BUFFER_BIT);
  Shader.UseProgram;

  glBindVertexArray(VBQuad.VAO);
  glBindTexture(GL_TEXTURE_2D, textureID);  // Textur binden.

  // Links-Oben
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  ProdMatrix := ScaleMatrix;
  ProdMatrix.Translate(-0.5, 0.5, 0.0);
  ProdMatrix.Uniform(Matrix_ID);

  glDrawArrays(GL_TRIANGLES, 0, Length(QuadVertex));

  // Rechts-Oben
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, @border);

  ProdMatrix := ScaleMatrix;
  ProdMatrix.Translate(0.5, 0.5, 0.0);
  ProdMatrix.Uniform(Matrix_ID);

  glDrawArrays(GL_TRIANGLES, 0, Length(QuadVertex));

  // Links-Unten
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  ProdMatrix := ScaleMatrix;
  ProdMatrix.Translate(-0.5, -0.5, 0.0);
  ProdMatrix.Uniform(Matrix_ID);

  glDrawArrays(GL_TRIANGLES, 0, Length(QuadVertex));

  // Rechts-Unten
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  ProdMatrix := ScaleMatrix;
  ProdMatrix.Translate(0.5, -0.5, 0.0);
  ProdMatrix.Uniform(Matrix_ID);

  glDrawArrays(GL_TRIANGLES, 0, Length(QuadVertex));

  ogc.SwapBuffers;
end;



Vertex-Shader:


#version 330

layout (location =  0) in vec3 inPos;   // Vertex-Koordinaten
layout (location = 10) in vec2 inUV;    // Textur-Koordinaten

uniform mat4 mat;

out vec2 UV0;

void main(void)
{
  gl_Position = mat * vec4(inPos, 1.0);
  UV0 = inUV;                           // Texur-Koordinaten weiterleiten.
}



Fragment-Shader:


#version 330

in vec2 UV0;

uniform sampler2D Sampler;

out vec4 FragColor;

void main()
{
    FragColor = texture( Sampler, UV0 );
}



bild.xpm


/* XPM */
static char *XPM_mauer[] = {
  "8 8 6 1",
  "  c #882222",
  "* c #FFFFFF",
  "r c #FF0000",
  "g c #00FF00",
  "b c #0000FF",
  "y c #00FFFF",
  "r******g",
  "*rr**gg*",
  "*rr**gg*",
  "********",
  "********",
  "*bb**yy*",
  "*bb**yy*",
  "b******y"
};


Autor: Mathias

Siehe auch