Computergrafik

Einfache Standard-Codesequenz

Interpolierte Parameter | | 2D Texturen im Shader

Annahme: die Framework-Funktionen werden verwendet, es gibt eine Initialisierungs-Funktion, und eine Display-Funktion, die für jeden Frame aufgerufen wird.

Das ganze sind nur Code-Vorschläge, diese müssen für eigene Funktionalität verändert werden, und die Variablennamen den eigenen Konventionen angepasst werden.

Shader

  • Simpler Vertex-Shader
#version 120
uniform   mat4 mvp;                 // Standard: ModelViewProjection-Matrix
uniform   vec4 scale;               // um *irgendwas* mit dem Attribut zu machen
attribute vec4 vertex_position;     // Der übergebene Vertex
attribute vec4 vertex_color;        // Ein Per-Vertex Attribut
varying   vec4 c;                   // Um Farbe an Fragment-Shader zu übergeben
void main ()
{
  gl_Position = mvp   * vertex_position;
  c           = scale * vertex_color;
}
  • Simpler Fragment-Shader
#version 120
varying   vec4 c;                   // *Exakt* gleich wie im Vertex-Shader
void main ()
{
  gl_FragColor = c;                 // Interpolation der pro Vertex angegebenen Farbe
  //gl_FragColor = vec4 (1, 1, 0, 1); // ALTERNATIV: alles gelb
}

Global

Variablen anlegen für:

  • Shader-Programm ( GLuint program; )
  • Ggf. Locations für Attribute und Uniforms
    GLint uniform_scale, uniform_mvp

Init-Funktion

1) Erzeugen des Shader-Programms
  • Aus String-Variablen shader:
program = lglCompileGLSLProgram (shader);
  • Aus einem externen Shader-File:
program = lglLoadGLSLProgram ("shader.txt");
  • Zusätzlich: Editor Fenster erstellen:
create_lgl_Qt_ShaderEditor ("shader", &program);
2) Ggf. Nachschlagen sämtlicher Attribute und Uniforms

Um uniforme und per-Vertex Attribute des Shaders im Hauptprogramm befüllen zu können, müssen die Positionen (Locations) als Handles bekannt sein; im Framework wird das abgenommen.

Aus Geschwindigkeitsgründen kann man das hier trotzdem machen, und anstelle der Namen (Strings) die Locations benutzen. Hier immer unbedingt überprüfen, ob das geklappt hat (Ergebnis ≥ 0), sonst entstehen … schwer zu debuggende Fehler.

uniform_scale = glUniformLocation (program, "scale");
if (uniform_scale < 0)
    lglError ("uniform: 'scale' nicht gefunden");
3) Weitere Initialisierungen

Können auch jederzeit während der Zeichenroutine verändert werden, aber meist reicht die Initialisierung einmal am Anfang.

  • Löschfarbe für glClear()
glClearColor (0.0, 0.0, 0.0, 0.0);
  • Tiefen-Test (z-Buffer) einschalten
glEnable (GL_DEPTH_TEST);
  • Blending (für Semitransparente Flächen) einschalten
glEnable    (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  • Antialiased Lines einschalten (beinhaltet Blending)
glLineWidth (1.5);
glEnable    (GL_LINE_SMOOTH);
glEnable    (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Display-Funktion

1) Bildschirm löschen

Ohne z-Buffers GL_DEPTH_BUFFER_BIT weglassen:

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2) Shader-Programm auswählen
lglUseProgramm (program, false);
3) Uniforme Attribute setzen

Anzahl an Komponenten (bzw. Typ) muss mit Definition im Shader übereinstimmen. Bei VBO-Objekten auch her an dem Objekt aufrufen.

lglUniformfv ("variable_name", vec4(1,2,3,4));
lglUniformfv ("matrix", mat4(1));
lglUniformi  ("integer", 3);  // Ein einzelner Integer-Wert

Auch die ModelView und Projection (MVP) nicht vergessen:

lglProjection (proj);
lglModelView (mv);
4) Endlich: Dreiecke zeichnen
lglBegin  (LGL_TRIANGLES);
lglColor  (1, 0, 0, 1);
lglVertex (0, 0, 0, 1);
lglColor  (0, 1, 0, 1);
lglVertex (1, 0, 0, 1);
lglColor  (0, 0, 1, 1);
lglVertex (1, 1, 0, 1);
lglEnd    ();

Alternativ: VBO bzw. Standard-Geometrie zeichnen (eine davon); dann aber natürlich ohne eigene Attribute:

lglRender (cube);

Weitere Informationen

Weitere Standard-Codesequenzen:


Interpolierte Parameter | | 2D Texturen im Shader

Options: