08 - Texturen

14 - Filter

Selfhtml

Hier wird gezeigt, wie man mehrere Texturen laden kann, im Prinzip geht dies fast gleich wie bei einer Textur.
In diesem Beispiel werden zwei Texturen geladen.

Wichtig dabei ist, das man mit glBindTexture(... immer die richtige Textur bindet.


Da es zwei Texturen hat, bracuht es auch zwei IDs.
var
  textureID: GLuint;
Da die Zextur-IDs in einer Array sind, kann man die Textur-Puffer mit nur einem glGenTextures(... erzeugen.
Dazu gebe ich als ersten Parameter die Länge der Array an.
Natürlich könnte man die Puffer auch einzeln erzeugen.

Das selbe könnte man auch bei den VAOs und VBOs machen.
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.
Mehrer Texturen laden geht genaus so einfache, wie wen man nur eine hat.
procedure TForm1.InitScene;
var
  pic: TPicture;
  border: array[0..3] of GLfloat = (0.0, 1.0, 0.0, 1.0);

begin
  pic := TPicture.Create;
  with pic do begin
    LoadFromFile('mauer.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);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, @border);

    glBindTexture(GL_TEXTURE_2D, 0);
    Free;  // pic
  end;
Hier sieht man, das ich für die beiden Qudrate unterschiedliche Texturen binde.
Koordinaten verwende ich für beide Qudrate die gleichen, einziger Unterschied, ich verschiebe die Matrix in unterschiedliche Richtungen.
Aus diesem Grund wird die VAO auch nur einmal gebunden.
procedure TForm1.ogcDrawScene(Sender: TObject);
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.Assign(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);

  ProdMatrix.Assign(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.Assign(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);

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

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

  ogc.SwapBuffers;
end;
Logischerweise muss man auch wieder beide Textur-Puffer frei geben.
procedure TForm1.FormDestroy(Sender: TObject);
begin
  glDeleteTextures(1, @textureID); // Textur-Puffer frei geben.


Die Shader sind genau gleich, wie bei einer Textur.

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 );
}



zurück