Shader et les variables

 

Les variables peuvent être en décimal, octal ou hexadecimal 0x...

Typage des variables standards

Les standards sont disponibles:

  • Décimaux: float
  • Booleen: bool (true ou false)
  • entier: int (16 bits)
  • structure: struct, typedef n'est pas utile.
  • struct stLight

    {

    vec3 position;

    vec3 color;

    }

    light monLight;

    ou

    struct light

    {

    vec3 position;

    struct stLightColor

    {

    float intensite;

    vec3 color;

    } lightColor;

    }

    light monLight;

     

  • tableau:array

    vec4 points[] pour définir un tableau vecteurs nommé points (vec4 étant type particulier de variable, vue plus loin), dont la taille n'est pas définie. Les indexes qui seront utilisées ultérieurement permettront au compilateur de positionner un index maximum. Par exemple points[5]=vec4 (0,0,0,0); positionnera le tableau à 5 élément lors de la compilation.

    vec4 points[10] idem pour un tableau de taille connue (10 éléments de type vec4).

    Image non trouvée !Si vous déclarez un tableau sans taille puis de nouveau avec une taille, le compilateur fixera la taille avec cette seconde déclaration. Mais il est interdit d'augmenter la taille d'un tableau si celui-ci a déjà une taille fixée.

 

Et des types orientés 3D

Des vecteurs peuvent représenter plusieurs choses, et rien à la base ne permettra de savoir exactement à quoi...

  • vec2 vecteur composé de 2 floats
  • vec3 vecteur composé de 3 floats
  • vec4 vecteur composé de 4 floats
  • ivec2 vecteur composé de 2 entiers
  • ivec3 vecteur composé de 3 entiers
  • ivec4 vecteur composé de 4 entiers
  • bvec2 vecteur composé de 2 booléens
  • bvec3 vecteur composé de 3 booléens
  • bvec4 vecteur composé de 4 booléens

Ces vecteurs peuvent représenter:

  • couleurs (composé de r, g, b ou a)
  • positions (composé de x, y, z ou w)
  • coordonnées de textures (composé de s, t, p ou q)

C'est entre autre ce qui permettra d'avoir une idée de ce à quoi pourra servir un vecteur. Mais il s'agit juste d'une aide dans le code.

Exemple

vec4 v;

v.a=1.0;

Suivant le type de la variable devant recevoir/affecter les valeurs rgba, xyzw, stpq, vous pourrez aussi écrire:

vec2 v2;

vec4 v;

v.rg = v2; ce qui revient à écrire v.r=v2.r et v.g = v2.g car v.rg est équivalent au type vec2.

Et de même avec les types suivants jusqu'à écrire v.rgba = v4;

Il sera donc possible d'accéder aux différents composants d'un vecteur par l'un de leurs noms, mais aussi via un index (qui commencera à 0).

Image non trouvée ! Evidemment la composante b ou a par exemple ne sera pas disponible pour une variable de type vec2 !

Exemple

vec2 position

position[2]=5.0;

qui alimentera la composante z avec la valeur 5.

 

Les matrices

  • mat2: matrice 2x2 de nombre de types float
  • mat3: matrice 3x3 de nombre de types float
  • mat4: matrice 4x4 de nombre de types float

Là aussi, un index permettra d'accéder aux composantes de la matrice

Soit mat4 matrice;

matrice [2] sera la 3ième colonne de la matrice, le type de matrice[2] sera un vecteur (ici vec4 car mat4 initialement).

matrice [4][1] sera 1 est la seconde composante du vecteur formé dans la 5ième colonne (le 4, n'oubliez pas que les indexes commencent à 0).

 

Les samplers

Les samplers sont comme des handles qui permettent d'accéder à des textures.

  • sampler1D pour accéder à une texture 1D
  • sampler2D pour accéder à une texture 2D
  • sampler3D pour accéder à une texture 3D
  • samplerCube pour accéder à une texture de type cube-map
  • sampler1DShadow
  • sampler2DShadow

 

Portée des variables

La portée d'une variable est identique à celle du C/C++.

La portée peut être globale, sur tout le code, dans une fonction, voire durant la boucle d'un for...

 

Initialiseurs et constructeurs

Il est possible d'initialiser les variables lors de la déclaration de celles-ci.

float a=3.0;

Mais il existe aussi la possibilité d'initialiser ces variables via des constructeurs:

Vec4 v=vec4 (0.0, 1.0, 2.0, 3.0);

 

Il existe des constructeurs pour presque tous les types OpenGL (presque car il n'y en a pas pour les samplers)

Déjà vu:vec4 v=vec4 (0.0, 1.0, 2.0, 3.0);

ivec2 v2=ivec2 (1.0, 2.0);

vec3 v3= vec3 (1.0, 2.0, 3.0);

vec4 v4= vec4 (vec3, 4.0);

Et plus surprenant: vec3 v = vec3 (0.2) duplique la même valeur à toutes les composantes du vecteur v. Ce qui revient à écrire v = vec3 (0.2, 0.2, 0.2);

mat2 m = mat2 (0.0,1.0,2.0,3.0) avec pour rappel, les colonnes pour définir les vecteurs de la matrice, nous aurions donc deux matrices, l'une à 0.0, 1.0 et l'autre à 2.0, 3.0.

et le même truc surprenant, mat2 m = mat2 (2.0); et identique à mat2 m = mat2 (1.0, 0.0, 0.0, 1.0); (remplissage en diagonale de la matrice)

De même, les structures auront automatiquement leur constructeur.

En reprenant les exemples du début, nous aurions pu écrire:

monLight=light (v, stLightColor (color, 0.7);

avec v de type vec3, color de type vec3 et 0.7 un float...

 

 

 

Attribute variables

Attributs réservés

Les variables de type attribut sont réservées au shader vertex (cf. Linux ou Android):

gl_Color

gl_Normal

gl_Vertex

gl_MultiTexCoord0

...

Ces variables sont produites entre les appels glBegin et glEnd ou lors des appels aux fonctions utilisant des tableaux. Ces données proviennent directement de l'application et permettent de définir les vertice.

 

Attributs personnalisés

Mais il est possible de définir vos propres variables attributs.

Il existe en effet une zone mémoire pour chaque programme shader dans laquelle sera stockée les différents attributs. Pour accéder à ces différents attributs de cette mémoire, vous utiliserez un index (A voir comme l'index d'un tableau).

 

 

 

Il est possible d'ajouter à votre shader vertex vos propres attributs. Il faudra les nommer via la fonction glBindAttribLocation(). En effet, OpenGL passe les valeurs de vos attributs personnalisés via des indexes. Ce qui n'est pas facile ensuite pour les traiter...

  • Sous OpenGL 2.0 en C/C++ sous Linux

    void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name);

  • Sous OpenGL SE sous Android

    static void glBindAttribLocation(int program, int index, String name);

En entrée:

program est l'identifiant de votre programme (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android)

index l'index du nouvel attribut

name le nom de l'attribut (terminé par null).

Ce nom sera ensuite réutilisable directement dans le shader vertex (cf. Linux ou Android).

 

La fonction peut retourner une erreur:

GL_INVALID_VALUE si l'index est >= GL_MAX_VERTEX_ATTRIBS.

GL_INVALID_OPERATION si le nom commence par un préfixe réservé ( "gl_"). ou si program n'est pas une valeur générée par OpenGL, n'est pas un programme ou si la fonction est utilisée entre glBegin et glEnd.

 

Affecter une valeur à un attribut

Il sera ensuite nécessaire de positionner les valeurs dans l'applications pour ces attributs

glVertexAttrib permet d'envoyer ces valeurs aux attributs d'un vertex à OpenGL. Il faudra spécifier l'index de l'attribut générique à modifier et la valeur de celui-ci.

  • Sous OpenGL 2.0 en C/C++

    Cette fonction est une fonction polyforme càd qu'il existe plusieurs fonctions glVertexAttrib() dont le nom dépendra du type de paramètres utilisés::

    void glVertexAttrib1f( GLuint index, GLfloat v0);
    void glVertexAttrib1s( GLuint index, GLshort v0);
    void glVertexAttrib1d( GLuint index, GLdouble v0);
    void glVertexAttribI1i( GLuint index, GLint v0);
    void glVertexAttribI1ui( GLuint index, GLuint v0);
    void glVertexAttrib2f( GLuint index, GLfloat v0, GLfloat v1);
    void glVertexAttrib2s( GLuint index, GLshort v0, GLshort v1);
    void glVertexAttrib2d( GLuint index, GLdouble v0, GLdouble v1);
    void glVertexAttribI2i( GLuint index, GLint v0, GLint v1);
    void glVertexAttribI2ui( GLuint index, GLuint v0, GLuint v1);
    void glVertexAttrib3f( GLuint index, GLfloat v0, GLfloat v1, GLfloat v2);
    void glVertexAttrib3s( GLuint index, GLshort v0, GLshort v1, GLshort v2);
    void glVertexAttrib3d( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2);
    void glVertexAttribI3i( GLuint index, GLint v0, GLint v1, GLint v2);
    void glVertexAttribI3ui( GLuint index, GLuint v0, GLuint v1, GLuint v2);
    void glVertexAttrib4f( GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
    void glVertexAttrib4s( GLuint index, GLshort v0, GLshort v1, GLshort v2, GLshort v3);
    void glVertexAttrib4d( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
    void glVertexAttrib4Nub( GLuint index, GLubyte v0, GLubyte v1, GLubyte v2, GLubyte v3);
    void glVertexAttribI4i( GLuint index, GLint v0, GLint v1, GLint v2, GLint v3);
    void glVertexAttribI4ui( GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
    void glVertexAttribL1d( GLuint index, GLdouble v0);
    void glVertexAttribL2d( GLuint index, GLdouble v0, GLdouble v1);
    void glVertexAttribL3d( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2);
    void glVertexAttribL4d( GLuint index, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3);
    void glVertexAttrib1fv( GLuint index, const GLfloat *v);
    void glVertexAttrib1sv( GLuint index, const GLshort *v);
    void glVertexAttrib1dv( GLuint index, const GLdouble *v);
    void glVertexAttribI1iv( GLuint index, const GLint *v);
    void glVertexAttribI1uiv( GLuint index, const GLuint *v);
    void glVertexAttrib2fv( GLuint index, const GLfloat *v);
    void glVertexAttrib2sv( GLuint index, const GLshort *v);
    void glVertexAttrib2dv( GLuint index, const GLdouble *v);
    void glVertexAttribI2iv( GLuint index, const GLint *v);
    void glVertexAttribI2uiv( GLuint index, const GLuint *v);
    void glVertexAttrib3fv( GLuint index, const GLfloat *v);
    void glVertexAttrib3sv( GLuint index, const GLshort *v);
    void glVertexAttrib3dv( GLuint index, const GLdouble *v);
    void glVertexAttribI3iv( GLuint index, const GLint *v);
    void glVertexAttribI3uiv( GLuint index, const GLuint *v);
    void glVertexAttrib4fv( GLuint index, const GLfloat *v);
    void glVertexAttrib4sv( GLuint index, const GLshort *v);
    void glVertexAttrib4dv( GLuint index, const GLdouble *v);
    void glVertexAttrib4iv( GLuint index, const GLint *v);
    void glVertexAttrib4bv( GLuint index, const GLbyte *v);
    void glVertexAttrib4ubv( GLuint index, const GLubyte *v);
    void glVertexAttrib4usv( GLuint index, const GLushort *v);
    void glVertexAttrib4uiv( GLuint index, const GLuint *v);
    void glVertexAttrib4Nbv( GLuint index, const GLbyte *v);
    void glVertexAttrib4Nsv( GLuint index, const GLshort *v);
    void glVertexAttrib4Niv( GLuint index, const GLint *v);
    void glVertexAttrib4Nubv( GLuint index, const GLubyte *v);
    void glVertexAttrib4Nusv( GLuint index, const GLushort *v);
    void glVertexAttrib4Nuiv( GLuint index, const GLuint *v);
    void glVertexAttribI4bv( GLuint index, const GLbyte *v);
    void glVertexAttribI4ubv( GLuint index, const GLubyte *v);
    void glVertexAttribI4sv( GLuint index, const GLshort *v);
    void glVertexAttribI4usv( GLuint index, const GLushort *v);
    void glVertexAttribI4iv( GLuint index, const GLint *v);
    void glVertexAttribI4uiv( GLuint index, const GLuint *v);
    void glVertexAttribL1dv( GLuint index, const GLdouble *v);
    void glVertexAttribL2dv( GLuint index, const GLdouble *v);
    void glVertexAttribL3dv( GLuint index, const GLdouble *v);
    void glVertexAttribL4dv( GLuint index, const GLdouble *v);
    void glVertexAttribP1ui( GLuint index, GLenum type, GLboolean normalized, GLuint value);
    void glVertexAttribP2ui( GLuint index, GLenum type, GLboolean normalized, GLuint value);
    void glVertexAttribP3ui( GLuint index, GLenum type, GLboolean normalized, GLuint value);
    void glVertexAttribP4ui( GLuint index, GLenum type, GLboolean normalized, GLuint value);

    Pfiou...

    En entrée:

    index: index de l'attribut du vertex

    v0,v1,v2 ou v3, les nouvelles valeurs à utiliser pour l'attribut

    v pour les fonctions avec vecteurs (glVertexAttrib*v), valeurs à utiliser

    type pour les fonctions glVertexAttribP*. Pourra être GL_INT_2_10_10_10_REV ou GL_UNSIGNED_INT_2_10_10_10_REV pour des données signées ou pas ou GL_UNSIGNED_INT_10F_11F_11F_REV si float.

    normalized pour normaliser les valeurs

    value la nouvelle valeur de l'attribut.

  • Pour OpenGL SE sous Android:

    static void glVertexAttrib1f(int index, float x)
    static void glVertexAttrib1fv(int index, FloatBuffer values)
    static void glVertexAttrib1fv(int index, float[] values, int offset)
    static void glVertexAttrib2f(int index, float x, float y)
    static void glVertexAttrib2fv(int index, float[] values, int offset)
    static void glVertexAttrib2fv(int index, FloatBuffer values)
    static void glVertexAttrib3f(int index, float x, float y, float z)
    static void glVertexAttrib3fv(int index, FloatBuffer values)
    static void glVertexAttrib3fv(int index, float[] values, int offset)
    static void glVertexAttrib4f(int index, float x, float y, float z, float w)
    static void glVertexAttrib4fv(int index, FloatBuffer values)
    static void glVertexAttrib4fv(int index, float[] values, int offset)
    static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, Buffer ptr)
    static void glVertexAttribPointer(int index, int size, int type, boolean normalized, int stride, int offset)

En sortie, des erreurs sont possibles:

GL_INVALID_VALUE si index >= GL_MAX_VERTEX_ATTRIBS.

GL_INVALID_ENUM si glVertexAttribP* utilisé avec un type autre que GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV ou GL_UNSIGNED_INT_10F_11F_11F_REV ou si glVertexAttribL si type autre que GL_DOUBLE.

 

Retrouver l'index d'un attribut via son nom

Il sera possible de récupérer l'index associé à un nom donné à un attribut:

  • OpenGL 2.0 sous Linux en C/C++

    GLint glGetAttribLocation( GLuint program, const GLchar *name);

  • OpenGL SE Sous Android

    public static int glGetAttribLocation (int program, String name)

En entrée:

program est le nom du programme dans lequel récupérer l'index de l'attribut du shader. (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android)

name est le nom de l'attribut.

Ou erreur GL_INVALID_OPERATION si program n'est pas un identifiant OpenGL, si program n'est pas un programme ou si le programme n'as pas été linké correctement.

 

Uniform variables

Ce sont des données qui sont passées depuis l'application à OpenGL, mais qui évoluent peu durant l'exécution.

Ces types de variables ne sont d'ailleurs pas initialisées entre glBegin et glEnd. Ces variables ne pourront donc changer au mieux qu'une seule fois par primitive.

Là encore, des variables sont proposées par défaut ("gl_"), d'autres pourront être définies par l'utilisateur.

Les variables uniformes pourront être utilisées aussi bien dans les vertex shader et les fragment shader.

glGetUniformLocation permet de récupérer l'index d'une variable uniforme. C'est cet identifiant qui permettra d'accéder aux données:

  • Sous OpenGL 2.0 sous Linux

    GLint glGetUniformLocation( GLuint program, const GLchar *name);

  • Sous OpenGL SE sous Android

    static int glGetUniformLocation(int program, String name)

 

En entrée:

program est l'identifiant du programme utilisée (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android).

name est le nom de la variable uniforme dans le programme utilisé (avec null à la fin de la chaîne).

En sortie:

la fonction retourne la localisation de la variable si elle existe. -1 sinon, si vous avez passé une variable commençant par 'gl_', ...

Les erreurs remontées peuvent être:

GL_INVALID_VALUE si l'identifiant de programme n'est pas un identifiant généré par OpenGL.

GL_INVALID_OPERATION si l'identifiant ne correspond pas à un programme ou celui-ci n'a pas été linké correctement.

Image non trouvée !La localisation d'une variable dans le programme ne pourra être connue qu'après linkage de ce programme !

 

Les variables pourront être alimentées avec la commande glUniform() qui est une fonction polyforme, càd qu'il existe plusieurs fonctions glUniform() dont le nom dépendra du type de paramètres utilisés:

  • Sous OpenGL sous Linux en c/C++

    void glUniform1f( GLint location, GLfloat v0);
    void glUniform2f( GLint location, GLfloat v0, GLfloat v1);
    void glUniform3f( GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
    void glUniform4f( GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
    void glUniform1i( GLint location, GLint v0);
    void glUniform2i( GLint location, GLint v0, GLint v1);
    void glUniform3i( GLint location, GLint v0, GLint v1, GLint v2);
    void glUniform4i( GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
    void glUniform1ui( GLint location, GLuint v0);
    void glUniform2ui( GLint location, GLuint v0, GLuint v1);
    void glUniform3ui( GLint location, GLuint v0, GLuint v1, GLuint v2);
    void glUniform4ui( GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
    void glUniform1fv( GLint location, GLsizei count, const GLfloat *value);
    void glUniform2fv( GLint location, GLsizei count, const GLfloat *value);
    void glUniform3fv( GLint location, GLsizei count, const GLfloat *value);
    void glUniform4fv( GLint location, GLsizei count, const GLfloat *value);
    void glUniform1iv( GLint location, GLsizei count, const GLint *value);
    void glUniform2iv( GLint location, GLsizei count, const GLint *value);
    void glUniform3iv( GLint location, GLsizei count, const GLint *value);
    void glUniform4iv( GLint location, GLsizei count, const GLint *value);
    void glUniform1uiv( GLint location, GLsizei count, const GLuint *value);
    void glUniform2uiv( GLint location, GLsizei count, const GLuint *value);
    void glUniform3uiv( GLint location, GLsizei count, const GLuint *value);
    void glUniform4uiv( GLint location, GLsizei count, const GLuint *value);
    void glUniformMatrix2fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix3fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix4fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix2x3fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix3x2fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix2x4fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix4x2fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix3x4fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
    void glUniformMatrix4x3fv( GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);

  • Sous OpenGL SE sous Andoird

    static void glUniform1f(int location, float x)
    static void glUniform1fv(int location, int count, float[] v, int offset)
    static void glUniform1fv(int location, int count, FloatBuffer v)
    static void glUniform1i(int location, int x)
    static void glUniform1iv(int location, int count, IntBuffer v)
    static void glUniform1iv(int location, int count, int[] v, int offset)
    static void glUniform2f(int location, float x, float y)
    static void glUniform2fv(int location, int count, FloatBuffer v)
    static void glUniform2fv(int location, int count, float[] v, int offset)
    static void glUniform2i(int location, int x, int y)
    static void glUniform2iv(int location, int count, IntBuffer v)
    static void glUniform2iv(int location, int count, int[] v, int offset)
    static void glUniform3f(int location, float x, float y, float z)
    static void glUniform3fv(int location, int count, float[] v, int offset)
    static void glUniform3fv(int location, int count, FloatBuffer v)
    static void glUniform3i(int location, int x, int y, int z)
    static void glUniform3iv(int location, int count, IntBuffer v)
    static void glUniform3iv(int location, int count, int[] v, int offset)
    static void glUniform4f(int location, float x, float y, float z, float w)
    static void glUniform4fv(int location, int count, FloatBuffer v)
    static void glUniform4fv(int location, int count, float[] v, int offset)
    static void glUniform4i(int location, int x, int y, int z, int w)
    static void glUniform4iv(int location, int count, int[] v, int offset)
    static void glUniform4iv(int location, int count, IntBuffer v)
    static void glUniformMatrix2fv(int location, int count, boolean transpose, FloatBuffer value)
    static void glUniformMatrix2fv(int location, int count, boolean transpose, float[] value, int offset)
    static void glUniformMatrix3fv(int location, int count, boolean transpose, float[] value, int offset)
    static void glUniformMatrix3fv(int location, int count, boolean transpose, FloatBuffer value)
    static void glUniformMatrix4fv(int location, int count, boolean transpose, float[] value, int offset)
    static void glUniformMatrix4fv(int location, int count, boolean transpose, FloatBuffer value)

En entrée:

location indique la localisation de la variable uniforme à modifier (cf. glGetUniformLocation)

count pour les fonctions sur les vecteurs (glUniform*v), indique le nombre d'élément qui sont à modifier. à 1 si la variable uniforme n'est pas un tableau, 1 ou plus pour un tableau. Idem pour les fonctions sur les matrives (glUniformMatrix*)

value pour les vecteurs ou les matrices indiquent un pointeur sur un tableau (de taille count) qui sera utilisé pour mettre à jour la variable uniform.

En sortie:

GL_INVALID_OPERATION:

  • Généré si pas de programme (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android), ou la localisation est invalide
  • la taille de la variable uniforme du shader n'est pas la même que celle déclarée dans la fonction glUniform
  • Dans le cas de passage d'entier (signé ou non) pour charger une variable uniforme de type float, vec2, vec3, vec4 ou un tableau composé de l'un de ces types. Et réciproquement, un flottant pour un type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4 ou tableau composé de l'un de ces types.
  • De signé pour des variables non signées ou inversement
  • Si count est plus grand que 1 alors que les paramètres ne correspondent pas à un tableau.
  • Enfin si un sampler est chargé dans une focntion autre que glUniform1i et glUniform1iv.

GL_INVALID_VALUE si count <= 0.

 

glGetUniform permettra de récupérer la valeur d'une variable uniforme:

  • Sous OpenGL 2.0 sous Linux en C/C++

    void glGetUniformfv(GLuint program, GLint location, GLfloat * params);
    void glGetUniformiv(GLuint program, GLint location, GLint * params);

  • Sous OpenGL SE pour Android

    static void glGetUniformfv(int program, int location, FloatBuffer params)
    static void glGetUniformfv(int program, int location, float[] params, int offset)
    static void glGetUniformiv(int program, int location, IntBuffer params)
    static void glGetUniformiv(int program, int location, int[] params, int offset)

 

En entrée:

program est l'identifiant du programme dans lequel se trouve la variable uniforme (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android).

location est l'index de la variable uniforme

Les erreurs

GL_INVALID_VALUE si l'identifiant du programme ne vient pas d'OpenGL
GL_INVALID_OPERATION si l'identifiant du programme n'est pas un programme ou n'a pas été linké correctement.

GL_INVALID_OPERATION si location n'est pas valide pour le programme

GL_INVALID_OPERATION entre glBegin et glEnd.

 

Varying variables

Il s'agit en fait des variables qui sont passées entre un processus vertex à un processus fragment (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android).

Là encore des variables sont disponibles par défaut, d'autres pourront être créées par l'utilisateur.

Il s'agit de variables dont le contenu va évoluer durant les différents appels au fragment shader, Soit une évolution pour chaque pixel dessiné. Exemple la couleur des pixels qui va évoluer entre une couleur initiale provenant d'un premier vertex vers la couleur correspondant au second vertex.

 

De nouveaux qualifieurs

D'où les nouveaux qualifieurs qui pourront être utilisés lors de la définition de variables dans vos programmes GLSL:

  • attribut
  • uniform
  • varying

Exemple: uniform float maVariable;

Il en existe cependant à 4ième: constant qualifier.

  • const

Il s'agit donc donc de constantes qui seront générées lors de la compilation (cf. Compilation/linkage des shaders sous Linux ou Compilation/linkage des shaders sous Android) et qui ne seront pas visibles en dehors du shader où la variable a été déclarée.

Exemple: const float pi=3.1415926;

 

 

Image non trouvée !Il est possible de ne pas indiquer l'un de ces qualifiers lors de la déclaration d'une variable (hors paramètre de fonction). Dans ce cas, la variable sera accessible en lecture/écriture dans le shader. De plus, si cette variable est déclarée dans le scope principal (ou global), celle-ci sera partagée avec les autres shaders d'un même programme à partir du moment où il existe le même nom de variable de même type. Mais ces variables ne seront pas visibles en dehors du programme (attribute/uniform et variables OpenGL sont les seules à le pouvoir).