Lazarus - OpenGL 3.3 Tutorial - Texturen - Filter: Unterschied zwischen den Versionen
(→Fragment-Shader:) |
K (Mathias verschob die Seite Lazarus - OpenGL 3.3 Tutorial - Texturen - glTexParameterf nach Lazarus - OpenGL 3.3 Tutorial - Texturen - Filter) |
(kein Unterschied)
|
Version vom 2. Januar 2018, 18:50 Uhr
Inhaltsverzeichnis
Texturen - glTexParameterf
Einleitung
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 );
}
Autor: Mathias
Siehe auch
- Übersichtseite Lazarus - OpenGL 3.3 Tutorial