Lazarus - OpenGL 3.3 Tutorial - Shader - Punkte verschieden darstellen

Aus DGL Wiki
Version vom 14. Dezember 2017, 18:13 Uhr von Mathias (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „200px<br><br> =Shader - Punkte verschieden darstellen = == Einleitung == B…“)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

Lazarus - OpenGL 3.3 Tutorial - Shader - Punkte verschieden darstellen.png

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