Lazarus - OpenGL 3.3 Tutorial - Shader - Variablen Namen auslesen
Aus DGL Wiki
Inhaltsverzeichnis
Shader - Variablen Namen auslesen
Einleitung
Es ist auch möglich aus dem Shader auszulesen, welche Variablen dort verwendet werden.
In diesem Beispiel werden Attribut, Uniform und Uniform-Blöcke ausgelesen.
Für was man Uniform-Blöcke verwendet, wird in einem späteren Kapitel behandelt.
Auch die Beleuchtung, etc. wird später behandelt.
Mit glGetProgramiv(... wird ermittelt, wie viele Variablen dieses Typen hat.
Mit glGetActiveAttrib(... wird der Bezeichner der Variable ausgelesen. Typ gibt die Art der Variable an, zB. vec3, mat4, etc.
Der komplexe Beleuchtungs-Shader wird später beschrieben.
procedure TForm1.MenuItem1Click(Sender: TObject);
var
s: ansistring;
i, Count, len, size, Typ: integer;
sl: TStringList;
begin
sl := TStringList.Create;
sl.Add('Attribute:');
SetLength(s, 255);
glGetProgramiv(Shader.ID, GL_ACTIVE_ATTRIBUTES, @Count);
for i := 0 to Count - 1 do begin
glGetActiveAttrib(Shader.ID, i, 255, len, size, Typ, @s[1]);
sl.Add(copy(s, 0, len) + ' ' + IntToStr(Typ));
end;
sl.Add('');
sl.Add('Uniform:');
glGetProgramiv(Shader.ID, GL_ACTIVE_UNIFORMS, @Count);
for i := 0 to Count - 1 do begin
glGetActiveUniform(Shader.ID, i, 255, len, size, Typ, @s[1]);
sl.Add(copy(s, 0, len) + ' ' + IntToStr(Typ));
end;
sl.Add('');
sl.Add('Uniform-Blöcke:');
glGetProgramiv(Shader.ID, GL_ACTIVE_UNIFORM_BLOCKS, @Count);
for i := 0 to Count - 1 do begin
glGetActiveUniformBlockName(Shader.ID, i, 255, @len, @s[1]);
sl.Add(copy(s, 0, len) + ' ' + IntToStr(Typ));
end;
ShowMessage(sl.Text);
sl.Free;
end;
Hier wurde noch eine Variable KeineVerwendung deklariert, da diese von Compiler wegoptimiert wurde, wird so auch nicht aufgelistet.
Vertex-Shader:
#version 330
// Attribute
layout (location = 0) in vec3 inPos; // Vertex-Koordinaten
layout (location = 1) in vec3 inNormal; // Normale
// Uniform-Variablen
uniform mat4 ModelMatrix;
uniform mat4 Matrix;
uniform vec4 KeineVerwendung; // Wird nicht angezeigt, da nicht verwendet.
// Daten für Fragment-shader
out Data {
vec3 Pos;
vec3 Normal;
} DataOut;
void main(void)
{
gl_Position = Matrix * vec4(inPos, 1.0);
DataOut.Normal = mat3(ModelMatrix) * inNormal;
DataOut.Pos = (ModelMatrix * vec4(inPos, 1.0)).xyz;
}
Fragment-Shader
#version 330
// Licht
#define Lposition vec3(35.0, 17.5, 35.0)
#define Lambient vec3(1.8, 1.8, 1.8)
#define Ldiffuse vec3(1.5, 1.5, 1.5)
in Data {
vec3 Pos;
vec3 Normal;
} DataIn;
// Der Uniform-Block
layout(std140) uniform Material {
vec3 Mambient; // Umgebungslicht
vec3 Mdiffuse; // Farbe
vec3 Mspecular; // Spiegelnd
float Mshininess; // Glanz
};
out vec4 outColor;
vec3 Light(in vec3 p, in vec3 n) {
vec3 nn = normalize(n);
vec3 np = normalize(p);
vec3 diffuse; // Licht
vec3 specular; // Reflektion
float angele = max(dot(nn, np), 0.0);
if (angele > 0.0) {
vec3 eye = normalize(np + vec3(0.0, 0.0, 1.0));
specular = pow(max(dot(eye, nn), 0.0), Mshininess) * Mspecular;
diffuse = angele * Mdiffuse * Ldiffuse;
} else {
specular = vec3(0.0);
diffuse = vec3(0.0);
}
return (Mambient * Lambient) + diffuse + specular;
}
void main(void)
{
outColor = vec4(Light(Lposition - DataIn.Pos, DataIn.Normal), 1.0);
}
Autor: Mathias
Siehe auch
- Übersichtseite Lazarus - OpenGL 3.3 Tutorial