Lazarus - OpenGL 3.3 Tutorial - Shader - Punkte verschieden darstellen
Inhaltsverzeichnis
Shader - Punkte verschieden darstellen
Einleitung
Bis jetzt wurde alles mit kompletten Dreiecken gerendert und gezeichnet. Es gibt aber noch zwei andere Varianten um Dreiecke zu rendern.
Dies wurde beim Zeichnen mit glDrawArrays(GL_TRIANGLES, ... veranlasst. Diese Version wird in der Paraxis am meisten angewendet.
Man kann die Dreiecke auch als Streifen hintereinander rendern, dies gerschieht mit glDrawArrays(GL_TRIANGLES_STRIP, ....
Oder wie ein Wedel, dabei ist der erste Vektor die Mitte, und der Rest die Eckpunkte. Dies geschieht dann mit glDrawArrays(GL_TRIANGLES_FAN, ....
Das schreiben in die Grafikkarte, ist bei allen Varianten gleich, der Unterschied ist legendlich beim Zeichenen mit glDrawArrays(....
Die Deklaration der Vektor-Koordianten Konstanten, zur Vereinfachung habe ich nur 2D-Vektoren genommen. Natürlich können diese auch 3D sein.
var
// Normale Dreiecke ( Gelb )
Triangles: array of TVertex2f;
TrianglesSize: array of GLfloat;
Hier werden die Daten in die Grafikkarte geschrieben.
Es hat nichts besonderes.
procedure TForm1.InitScene;
begin
glClearColor(0.6, 0.6, 0.4, 1.0); // Hintergrundfarbe
// Daten für GL_TRIANGLE
glBindVertexArray(VBTriangle.VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBTriangle.VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex2f) * Length(Triangles), Pointer(Triangles), GL_STATIC_DRAW);
glEnableVertexAttribArray(10);
glVertexAttribPointer(10, 2, GL_FLOAT, False, 0, nil);
// Daten für GL_TRIANGLE
glBindVertexArray(VBTriangle.VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBTriangle.VBO_Size);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * Length(TrianglesSize), Pointer(TrianglesSize), GL_STATIC_DRAW);
glEnableVertexAttribArray(11);
glVertexAttribPointer(11, 1, GL_FLOAT, False, 0, nil);
end;
Bei glDrawArrays(... ist der erste Parameter das wichtigste, hier wird angegeben, wie die Vektor-Koordinaten gezeichnet werden.
procedure TForm1.ogcDrawScene(Sender: TObject);
const
ofs = 0.4;
begin
glEnable(GL_PROGRAM_POINT_SIZE);
glClear(GL_COLOR_BUFFER_BIT);
Shader.UseProgram;
glBindVertexArray(VBTriangle.VAO);
// Zeichne GL_TRIANGLE
glUniform1i(PointTyp_ID, 0);
glUniform3f(Color_ID, 1.0, 1.0, 0.0); // Gelb
glUniform1f(X_ID, -ofs);
glUniform1f(Y_ID, -ofs);
glDrawArrays(GL_POINTS, 0, Length(Triangles));
// Zeichne GL_TRIANGLE_STRIP
glUniform1i(PointTyp_ID, 1);
glUniform3f(Color_ID, 1.0, 0.0, 0.0); // Rot
glUniform1f(X_ID, ofs);
glUniform1f(Y_ID, -ofs);
glDrawArrays(GL_POINTS, 0, Length(Triangles));
// Zeichne GL_TRIANGLE_FAN
glUniform1i(PointTyp_ID, 2);
glUniform3f(Color_ID, 0.0, 1.0, 0.0); // Grün
glUniform1f(X_ID, ofs);
glUniform1f(Y_ID, ofs);
glDrawArrays(GL_POINTS, 0, Length(Triangles));
// Zeichne GL_TRIANGLE_FAN
glUniform1i(PointTyp_ID, 3);
glUniform3f(Color_ID, 0.0, 0.0, 1.0); // Blau
glUniform1f(X_ID, -ofs);
glUniform1f(Y_ID, ofs);
glDrawArrays(GL_POINTS, 0, Length(Triangles));
Vertex-Shader:
Da die Koordinaten nur als 2D gespeichert sind, wird im Vertex-Shader der Z-Wert auf 0.0 gesetzt.
#version 330
layout (location = 10) in vec2 inPos; // Vertex-Koordinaten in 2D
layout (location = 11) in float inSize; // Vertex-Koordinaten in 2D
uniform float x; // Richtung von Uniform
uniform float y;
void main(void)
{
vec2 pos = inPos;
pos.x = pos.x + x;
pos.y = pos.y + y;
gl_PointSize = inSize;
gl_Position = vec4(pos, 0.0, 1.0); // Der zweiter Parameter (Z) auf 0.0
}
Fragment-Shader:
#version 330
uniform vec3 Color ; // Farbe von Uniform
out vec4 outColor; // ausgegebene Farbe
uniform int PointTyp;
void main(void)
{
vec2 p = gl_PointCoord * 2.0 - vec2(1.0);
float r = sqrt(dot(p, p));
float theta = atan(p.y, p.x);
switch (PointTyp){
case 0: if(dot(gl_PointCoord - 0.5, gl_PointCoord - 0.5) > 0.25)
discard;
else
outColor = vec4(Color, 1.0);
break;
case 1: if(dot(p, p) > cos(theta * 5))
discard;
else
outColor = vec4(Color, 1.0);
break;
case 2: if(dot(p, p) > r || dot(p, p) < r * 0.75)
discard;
else
outColor = vec4(Color, 1.0);
break;
case 3: if(dot(p, p) > 5.0 / cos(theta - 20 * r))
discard;
else
outColor = vec4(Color, 1.0);
break;
default: discard;
}
}
Autor: Mathias
Siehe auch
- Übersichtseite Lazarus - OpenGL 3.3 Tutorial