Le vertex shader sous Linux

 

 

Le vertex shader permet de modifier la position, la couleur et l'éclairage d'un vertex. Un processus sera donc lancé sur un vertex et autant de processus qu'il y a de vertice.

Ce shader recevra des variables de type "Attribute variables".

 

Quelques attributs standards

Le minimum que doit faire ce vertex est de définir gl_position (disponible en lecture et écriture) qui va contenir les positions du vertex:

Et un minimum de code qui serait nécessaire pour exécuter ce shader:

/* Effacer le fond de l'écran et mettre une couleur blanche */
const GLfloat color[] = { 1.0f, 1.0f, 1.0f, 1.0f};
glClearBufferfv(GL_COLOR, 0, color);

/* Autoriser la définition de la taille d'un point */
glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
/* Utiliser un programme shader préalablement compilé, linké avec un fragment shader et validé */
glUseProgram(prg1->getNumProgram()); // Identifiant OpenGL du programme

/* Mémoriser le type de primitive : ici un point pour dessiner le vertex. */
glDrawArrays (GL_POINTS, 0, 1);

[...] // suite du code dépendant entre autre du framework utilisé

Image non trouvée !Pour permettre de visualiser le point à l'écran, glPointSize est utilisé afin de définir une taille à ce point.

Les coordonnées d'un vertex peuvent varier en x, y et en z entre [-1, 1] et [0,0, 0] et le crentre d'un repère orthonormé.

 

Le but n'étant pas de dessiner un point, mais une figure complète, il sera possible de traiter les n points d'un tableau dans le shader:

Pour cela, préciser à OpenGL le nombre de vertice:

glDrawArrays(GL_POINTS, 0, 4);

Ici 4, puis définir un tableau contenant les quatres coordonnées des vertices:

Une nouvelle variable fait son apparition: gl_VertexID qui représente l'indice d'un élément (contenant les coordonnées d'un vertex) du tableau des vertice.

Il suffit ainsi de positionner glPosition aux coordonnées du vertex en cours de traitement par le shader.

Cette solution n'est pas forcement intéressante, car le shader comprend le dessin des objets 3D. Ce n'est pas ce que l'on veut...

 

Attributs personnalisés

Dans les shaders vertex, les attributs personnalisés sont numérotés à partir de 0. Il possible de définir vos propres attributs en les nommant, ce qui rendra le code plus simple à lire.

Pour cela, utilisez la fonction OpenGL glBindAttribLocation()

glBindAttribLocation(prg1->getNumProgram(), 0, "aPosition"); // L'attribut 0 se nommera aPosition dans le shader avec a pour attribut (vec4 ici).

glVertexAttrib4fv(0, &vVertices[2]); // Affectation pour l'attribut 0 de l'adresse d'un vertex (ici le 3 ième élément provenant d'un tableau).

Image non trouvée !A partir d'OpenGL 3.3, il est possible d'indiquer la localisation d'un attribut via la directive de compilation layout. Mais cette solution n'existe pas pour OpenGL ES.

Dans le vertex shader:

layout (location = 0) in vec4 aPosition; // aPosition est donc l'attribut de type vec4 en input localisé à la position 0 dans la zone mémoire réservée aux attributs.

gl_Position = aPosition;

Le passage de l'information pourrait se faire de la façon suivante:

GLfloat attrib[]= { 0.25f, -0.25f, 0.5f, 0.0f }
// Maj de la valeur de l'attribut 0 en input
glVertexAttrib4fv(0, attrib);

Image non trouvée !Les fonctions glVertexPointer sont dépréciées en versions 3.x, donc ne pas les utiliser !

Il existe d'autres solutions pour renseigner les valeurs dans vos attributs...

 

Définir la taille d'un point

En mathématique, les professeurs n'ont eu de cesse de vous apprendre qu'un point n'a pas de taille...

Si vous désirez dessiner un point à l'écran, il sera judicieux de lui définir une taille (sic !). Sinon, vous ne verrez pas grand chose à l'écran.

La variable gl_PointSize permet d'indiquer cette taille (disponible en lecture et écriture):

gl_PointSize = 40.0;

Mais pour que le shader puisse modifier cette taille, il faut rendre cette opération possible via la fonction glEnable() en précisant GL_VERTEX_PROGRAM_POINT_SIZE en paramètre avant l'appel au shader:

glEnable (GL_VERTEX_PROGRAM_POINT_SIZE)