Creare di uno Shader

Per creare uno shader in OpenGL servono tre passaggi:

  1. Creazione;
  2. Caricamento del codice sorgente;
  3. Compilazione.

Creazione

Per creare uno shader si usa la funzione:

GLuint glCreateShader(GLenum shaderType);

Questa funzione ritorna l'id dello shader vuoto creato, oppure 0 se la creazione è fallita. shaderType può essere:

GL_VERTEX_SHADER
GL_FRAGMENT_SHADER
GL_GEOMETRY_SHADER
GL_TESS_EVALUATION_SHADER
GL_TESS_CONTROL_SHADER

Caricamento del codice sorgente

Il caricamento del codice sorgente avviene attraverso questa funzione:

void glShaderSource(GLuint shader, int numRows, const char **rows, int *length);

Dove shader è l'id dello shader. I restanti parametri possono essere utilizzati nei seguenti modi:

Quando questa funzione ritorna, il codice è già stato copiato all'interno del driver, perciò è possibile sovrascrivere o deallocare i buffer senza rischi.

Per qualche misterioso motivo di compatibilità, è spesso necessario terminare le stringhe con CR-LF-0, invece che solo con 0.

Compilazione

Per la compilazione, la funzione è:

void glCompileShader(GLuint shader);

Dove shader è l'id dello shader che deve essere compilato.

Per controllare il risultato della compilazione, ci sono due metodi. Il primo permette di sapere se la compilazione ha avuto successo oppure no.

void glGetShaderiv(GLuint shader, GLenum pname, GLint * params);

Dove shader è come sempre l'id dello shader, pname deve essere uguale a GL_COMPILE_STATUS, params deve contenere il puntatore a un intero.
Quando la funzione ritorna, nell'intero puntato da params è stato scritto GL_TRUE se lo shader è stato compilato senza errori, GL_FALSE altrimenti.

Il secondo metodo consiste nell'accedere al log della compilazione (InfoLog):

void glGetShaderInfoLog(GLuint id, int maxLength, int *length, char *log);

Questa funzione ritira i primi maxLength caratteri dall'InfoLog dello shader id, scrive il numero dei caratteri effettivamente letti nell'intero puntato da length e i caratteri come stringa di caratteri 0-terminata nel buffer log.

Spesso è necessario conoscere le dimensioni totali dell'InfoLog senza leggerlo, ad esempio per poter allocare il buffer per la funzione precedente. Per questo si può usare di nuovo la funzione:

void glGetShaderiv(GLuint shader, GLenum pname, int *param);

Dove shader è l'id dello shader, pname è GL_INFO_LOG_LENGTH. Il numero richiesto viene scritto nell'intero puntato da param.

L'InfoLog è l'unico modo per ottenere il motivo per cui la compilazione di uno shader è fallita. Tuttavia, esso è utile solo al programmatore, perché non esiste nessuno standard che specifica come devono essere organizzate le informazioni che contiene. Modelli diversi di scheda video possono produrre InfoLog con struttura molto diversa, perciò non è possibile interpretarlo con una procedura automatica.
Il programma OpenGL deve accontentarsi di usare il primo metodo e sapere soltanto se la compilazione ha avuto successo oppure no. Il secondo serve solo per il debug dell'applicazione.


Copyright © 2011 Riccardo Monica
Eccetto ove espressamente indicato altrimenti, il contenuto di questa pagina è disponibile secondo la licenza Creative Commons Attribuzione - Condividi allo stesso modo 3.0.