Lazarus - OpenGL 3.3 Tutorial - Shader - Punkte verschieden darstellen

Aus DGL Wiki
Wechseln zu: Navigation, Suche

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

Shader - Punkte verschieden darstellen

Einleitung

Man kann auch Punkte mit dem Shader darstellen, dies kann man auf verschiedene Weise.
Im Fragment-Shader kann man das Zeichen der Punkte manipulieren.


Die Deklaration der Koordianten und Punktgrösse.

var
  Point: array of TVertex2f;
  PointSize: array of GLfloat;

Daten für die Punkte in die Grafikkarte übertragen

procedure TForm1.InitScene;
begin
  glClearColor(0.6, 0.6, 0.4, 1.0); // Hintergrundfarbe

  // Daten für Punkt Position
  glBindVertexArray(VBPoint.VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBPoint.VBO);
  glBufferData(GL_ARRAY_BUFFER, sizeof(TVertex2f) * Length(Point), Pointer(Point), GL_STATIC_DRAW);
  glEnableVertexAttribArray(10);
  glVertexAttribPointer(10, 2, GL_FLOAT, False, 0, nil);

  // Daten für Punkt Grösse
  glBindVertexArray(VBPoint.VAO);
  glBindBuffer(GL_ARRAY_BUFFER, VBPoint.VBO_Size);
  glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * Length(PointSize), Pointer(PointSize), GL_STATIC_DRAW);
  glEnableVertexAttribArray(11);
  glVertexAttribPointer(11, 1, GL_FLOAT, False, 0, nil);
end;

Zeichnen der Punkte

procedure TForm1.ogcDrawScene(Sender: TObject);
const
  ofs = 0.4;
begin
  glEnable(GL_PROGRAM_POINT_SIZE);

  glClear(GL_COLOR_BUFFER_BIT);
  Shader.UseProgram;

  glBindVertexArray(VBPoint.VAO);
  // gelb
  glUniform1i(PointTyp_ID, 0);
  glUniform3f(Color_ID, 1.0, 1.0, 0.0);
  glUniform1f(X_ID, -ofs);
  glUniform1f(Y_ID, -ofs);
  glDrawArrays(GL_POINTS, 0, Length(Point));

  // rot
  glUniform1i(PointTyp_ID, 1);
  glUniform3f(Color_ID, 1.0, 0.0, 0.0);
  glUniform1f(X_ID, ofs);
  glUniform1f(Y_ID, -ofs);
  glDrawArrays(GL_POINTS, 0, Length(Point));

  // grün
  glUniform1i(PointTyp_ID, 2);
  glUniform3f(Color_ID, 0.0, 1.0, 0.0);
  glUniform1f(X_ID, ofs);
  glUniform1f(Y_ID, ofs);
  glDrawArrays(GL_POINTS, 0, Length(Point));

  // blau
  glUniform1i(PointTyp_ID, 3);
  glUniform3f(Color_ID, 0.0, 0.0, 1.0);
  glUniform1f(X_ID, -ofs);
  glUniform1f(Y_ID, ofs);
  glDrawArrays(GL_POINTS, 0, Length(Point));

  ogc.SwapBuffers;
end;



Vertex-Shader:

#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