In OpenGL kann man Vertex Shader und Fragment Shader definieren. Diese werden im Setup zu einem Shader Programm zusammengefasst, welches beim Draw-Call in der Render-Pipeline automatisch ausgeführt wird. Dafür müssen einige Sachen vorbereitet werden:
- Shader Program erstellen mit glCreateProgram
- Für jeden Shader:
- Shader erstellen mit glCreateShader
- Shader-Quellcode in den Shader laden mit glShaderSource
- Shader kompilieren mit glCompileShader
- Kompilierstatus kann eingesehen werden mit glGetShaderiv
- Ggf. Ausführliche Fehlermeldungen können eingesehen werden mit glGetShaderInfoLog
- Shader in das Shader Program einbinden mit glAttachShader
- Shader Program linken mit glLinkProgram
- Link-Status kann eingesehen werden mit glGetProgramiv
Erst dann ist das Shader Program bereit genutzt zu werden:
- Beim Rendern das Shader Program nutzen mit glUseProgram
Zum Löschen:
- Shader löschen mit glDeleteShader
- Shader Program löschen mit glDeleteShader
Löschen
- Schlägt das Kompilieren fehl sollten die Shader und Programme gelöscht werden.
- Shader können auch direkt nach dem erfolgreichem Linken gelöscht werden. Davor sollten sie noch mit glDetachShader vom Programm gelöst werden.
- Das Shader Programm sollte dann natürlich erst gelöscht werden, wenn es nicht mehr zum Rendern benötigt wird.
Beispiel
// 1. Shader Program erstellen
GLuint shader_prog = glCreateProgram();
// 2.1. Shader erstellen
GLuint vert_shader = glCreateShader(GL_VERTEX_SHADER);
// 2.2. Shader-Quellcode in den Shader laden
const char *vert_source_cstr; // Sei hier mal Definiert und Nullterminiert
glShaderSource(vert_shader, 1, &vert_source_cstr, 0);
// 2.3. Shader kompilieren
glCompileShader(vert_shader);
// Check ob es Kompilierfehler gab
GLint result = GL_FALSE;
glGetShaderiv(vert_shader, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
cerr << "Failed to compile shader" << endl;
// Aufräumen
glDeleteShader(vert_shader);
glDeleteProgram(shader_prog);
shader_prog = -1;
exit(-1);
}
// 2.4. Shader an das Program anheften
glAttachShader(shader_prog, vert_shader);
// (2.1. bis 2.4. analog nochmal für den Fragment Shader)
// 3. Shader Program linken
glLinkProgram(shader_prog);
// Check auf Linkerfehler
result = GL_FALSE;
glGetProgramiv(shader_prog, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
cerr << "Failed to link shaders" << endl;
// Aufräumen
glDeleteShader(vert_shader);
glDeleteShader(frag_shader);
glDeleteProgram(shader_prog);
shader_prog = -1;
exit(-1);
}
// Alles lief durch! Wir können den Shader jetzt verwenden:
glUseProgram(shader_prog);