Lazarus - OpenGL 3.3 Tutorial - Instancing - Instancen nur in einer Array: Unterschied zwischen den Versionen
Aus DGL Wiki
(Die Seite wurde neu angelegt: „200px<br><br> =Instancing - Instancen nur in einer Array = == Einleitun…“) |
|||
Zeile 35: | Zeile 35: | ||
// --- Instancen | // --- Instancen | ||
ofs := 0; | ofs := 0; | ||
+ | glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO.Instance); | ||
+ | glBufferData(GL_ARRAY_BUFFER, SizeOf(Data), @Data, GL_STATIC_DRAW); | ||
+ | |||
// Instance Size | // Instance Size | ||
− | |||
− | |||
glEnableVertexAttribArray(1); | glEnableVertexAttribArray(1); | ||
glVertexAttribPointer(1, 1, GL_FLOAT, False, SizeOf(TData), nil); | glVertexAttribPointer(1, 1, GL_FLOAT, False, SizeOf(TData), nil); | ||
Zeile 44: | Zeile 45: | ||
// Instance Matrix | // Instance Matrix | ||
− | |||
− | |||
for i := 0 to 3 do begin | for i := 0 to 3 do begin | ||
glEnableVertexAttribArray(i + 2); | glEnableVertexAttribArray(i + 2); | ||
Zeile 54: | Zeile 53: | ||
// Instance Color | // Instance Color | ||
− | |||
− | |||
glEnableVertexAttribArray(6); | glEnableVertexAttribArray(6); | ||
glVertexAttribPointer(6, 3, GL_FLOAT, False, SizeOf(TData), Pointer(ofs)); | glVertexAttribPointer(6, 3, GL_FLOAT, False, SizeOf(TData), Pointer(ofs)); | ||
Zeile 66: | Zeile 63: | ||
Shader.UseProgram; | Shader.UseProgram; | ||
− | glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO. | + | glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO.Instance); |
glBufferSubData(GL_ARRAY_BUFFER, 0, SizeOf(Data), @Data); | glBufferSubData(GL_ARRAY_BUFFER, 0, SizeOf(Data), @Data); | ||
Zeile 88: | Zeile 85: | ||
<br><br> | <br><br> | ||
==Vertex-Shader:== | ==Vertex-Shader:== | ||
− | Am Shader hat sich | + | Am Shader hat sich nichts geändert.<br> |
<syntaxhighlight lang="glsl">#version 330 | <syntaxhighlight lang="glsl">#version 330 | ||
Version vom 30. Juli 2018, 22:31 Uhr
Inhaltsverzeichnis
Instancing - Instancen nur in einer Array
Einleitung
Vorher hatte es für jedes Instance-Attribut eine eigene Array gehabt.
Jetzt sind alle Attribute in einer Array, dies macht den Code einiges übersichtlicher.
Dafür ist die Übergabe mit glVertexAttribPointer(... ein weniig komplizierter.
Siehe Vertex-Puffer - Nur eine Array.
Die Deklaration der Array. Es ist nur noch eine Array.
type
TData = record
Scale: GLfloat;
Matrix: TMatrix;
Color: TVector3f;
end;
var
Data: array[0..InstanceCount - 1] of TData;
Das es ein wenig einfacher wird, habe ich ofs verwendet.
procedure TForm1.InitScene;
var
ofs, i: integer;
begin
glClearColor(0.6, 0.6, 0.4, 1.0); // Hintergrundfarbe
glBindVertexArray(VBQuad.VAO);
// --- Normale Vektordaten
// Daten für Vektoren
glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO.Vertex);
glBufferData(GL_ARRAY_BUFFER, sizeof(Quad), @Quad, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, False, 0, nil);
// --- Instancen
ofs := 0;
glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO.Instance);
glBufferData(GL_ARRAY_BUFFER, SizeOf(Data), @Data, GL_STATIC_DRAW);
// Instance Size
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, False, SizeOf(TData), nil);
glVertexAttribDivisor(1, 1);
Inc(ofs, SizeOf(GLfloat));
// Instance Matrix
for i := 0 to 3 do begin
glEnableVertexAttribArray(i + 2);
glVertexAttribPointer(i + 2, 4, GL_FLOAT, False, SizeOf(TData), Pointer(ofs));
glVertexAttribDivisor(i + 2, 1);
Inc(ofs, SizeOf(TVector4f));
end;
// Instance Color
glEnableVertexAttribArray(6);
glVertexAttribPointer(6, 3, GL_FLOAT, False, SizeOf(TData), Pointer(ofs));
glVertexAttribDivisor(6, 1);
end;
An der Zeichenroutine ändert sich nichts.
procedure TForm1.ogcDrawScene(Sender: TObject);
begin
glClear(GL_COLOR_BUFFER_BIT);
Shader.UseProgram;
glBindBuffer(GL_ARRAY_BUFFER, VBQuad.VBO.Instance);
glBufferSubData(GL_ARRAY_BUFFER, 0, SizeOf(Data), @Data);
glBindVertexArray(VBQuad.VAO);
glDrawArraysInstanced(GL_TRIANGLES, 0, Length(Quad) * 3, InstanceCount);
ogc.SwapBuffers;
end;
Matrizen neu berechnen.
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin
for i := 0 to Length(Data) - 1 do begin
Data[i].Matrix.RotateC(0.02);
end;
glBindVertexArray(VBQuad.VAO);
ogcDrawScene(Sender); // Neu zeichnen
end;
Vertex-Shader:
Am Shader hat sich nichts geändert.
#version 330
#define Instance_Count 200
// Vektor-Daten
layout (location = 0) in vec2 inPos;
// Instancen
layout (location = 1) in float Size;
layout (location = 2) in mat4 mat;
layout (location = 6) in vec3 Color;
out vec3 col;
void main(void)
{
gl_Position = mat * vec4((inPos * Size), 0.0, 1.0);
col = Color;
}
Fragment-Shader:
#version 330
out vec4 outColor; // ausgegebene Farbe
in vec3 col;
void main(void)
{
outColor = vec4(col, 1.0);
}
Autor: Mathias
Siehe auch
- Übersichtseite Lazarus - OpenGL 3.3 Tutorial