Computergrafik

Native Standard-Codesequenz

Einfache Standard-Codesequenz | | 2D Texturen im Shader

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

Der folgende Code dient nur zur Erläuterung, was hinter den Kulissen passiert. Speziell im Praktikum benutzen wir aus offensichtlichen Gründen lieber die Framework-Funktionen!!!

Shader

Gespeichert in getrennten String-Variablen.

  • Vertex-Shader
#version 120
uniform   mat4 mvp;                 // ModelViewProjection-Matrix
attribute vec4 vert;                // Der zu transformierende Vertex
attribute vec4 col;                 // Ein Per-Vertex Attribut
varying   vec4 c;                   // Um Farbe an Fragment-Shader zu übergeben
void main ()
{
  gl_Position = mvp * vert;
  c           = col;
}
  • Fragment-Shader
#version 120
varying   vec4 c;                   // *Exakt* gleich wie im Vertex-Shader
void main ()
{
  gl_FragColor = c;                 // Interpolation der pro Vertex angegebenen Farbe
}

VBO

Daten für den VBO bereithalten - hier im Beispiel interleaved.

  • Der Stride ist für beide Attribute sizeof(float)*(3+4) - es sind 3 vertex und 4 color Werte im Array, jeweils im float Format.
  • Der Offset für die Vertices ist natürlich 0
  • Der Offset für die Farbinformation ist sizeof(float)*3 - da die 3 Werte des ersten Vertex übersprungen werden müssen!
const float vecData[] = {
    +0.75, +0.75, 0.0,     // vertex
    1,     0,     0,    1, // color
    +0.75, -0.75, 0.0,     // vertex
    0,     1,     0,    1, // color
    -0.75, -0.75, 0.0,     // vertex
    0,     0,     1,    1  // color
};

Global

Variablen anlegen für:

  • Shader-Programm und VBO
    GLuint program, vbo;
  • Locations für Uniforms
    GLint uniform_mvp;
  • Konstanten für Attribute
    enum { ATTRIB_VERT, ATTRIB_COL };

Init-Funktion

1) Erzeugen des Shader-Programms, inkl. Attribute
// Erzeuge und compiliere Vertex Shader
GLuint vs =     glCreateShader (GL_VERTEX_SHADER);
glShaderSource  (vs, 1, &vertex_shader, NULL);
glCompileShader (vs);

// Erzeuge und compiliere Fragment Shader
GLuint fs =     glCreateShader (GL_FRAGMENT_SHADER);
glShaderSource  (fs, 1, &fragment_shader, NULL);
glCompileShader (fs);

// Erzeuge Programm
program =       glCreateProgram();
glAttachShader  (program, vs);
glAttachShader  (program, fs);

// Location der Attribute setzen - VOR dem Linken!
glBindAttribLocation (program, ATTRIB_VERT, "vert");
glBindAttribLocation (program, ATTRIB_COL,  "col");
lglGetError();

// Linke Programm
glLinkProgram   (program);

// Aktiviere Programm
glUseProgram    (program);
2) Nachschlagen sämtlicher Uniforms
uniform_mvp = glGetUniformLocation (program, "mvp");
if (uniform_mvp < 0)
    lglError ("uniform 'mvp' nicht gefunden");
3) VAO und VBO erstellen und mit Daten füllen
GLuint vao;
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);

glGenBuffers    (1, &vbo);
glBindBuffer    (GL_ARRAY_BUFFER, vbo);
glBufferData    (GL_ARRAY_BUFFER, sizeof(vecData), vecData, GL_STATIC_DRAW);
4) Weitere Initialisierungen
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable     (GL_DEPTH_TEST);

Render-Funktion

1) Bildschirm löschen
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2) Uniforme Attribute setzen

Die Syntax ist hier relativ eklig, gerade bei Matrizen… Die MVP-Matrix muss hier selbstständig berechnet werden, da wir ja das Framework nicht nutzen!

mat4f mvp = proj * mv;
glUniformMatrix4fv (uniform_mvp, 1, GL_FALSE, (const float *)(mvp));
4) Endlich: VBO selektieren, konfigurieren und zeichnen

Die Syntax ist noch ekliger, da eine Funktion (glVertexAttribPointer) nicht für den ursprünglichen Zweck der Funktion benutzt (missbraucht) wurde. Deshalb muss der Offset (eigentlich ein Ganzzahlwert) als Pointer übergeben werden…

glBindBuffer              (GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray (ATTRIB_VERT);
glVertexAttribPointer     (ATTRIB_VERT, 3, GL_FLOAT, GL_FALSE,
                           sizeof(float) * (3+4),
                           NULL);
glEnableVertexAttribArray (ATTRIB_COL);
glVertexAttribPointer     (ATTRIB_COL, 4, GL_FLOAT, GL_FALSE,
                           sizeof(float) * (3+4),
                           (void*) (sizeof(float) * 3));
glDrawArrays              (GL_TRIANGLES, 0, 3);


Einfache Standard-Codesequenz | | 2D Texturen im Shader

Options: