OpenGL

création d'objets opengl :
configuration du pipeline :
- activer un shader program,
- assemblage d'attributs de sommets,
- assemblage de primitives non indexées,
- assemblage de primitives indexées,
- unités de textures et samplers,
- élimination des primitives non orientées vers la camera (back face culling),
- fragmentation des primitives,
- tests (depth, etc.), transparence et mélange (blend),
- activer un framebuffer (dessiner dans une texture),
- transform feedback.
création d'objets opengl :
buffers :
création des identifiants :
GLuint buffers[];
glGenBuffers(n,
buffers);
//
generation
des identifiants de buffers
glBindBuffer(target,
buffer);
//
activer
un buffer
glBufferData(target,
size,
data,
usage);
// creer un buffer et initialiser
son contenu
destruction :
activation (cf configuration du
pipeline) :
modification d'une partie du contenu
du buffer après sa création :
copie entre 2 buffers :
glCopyBufferSubData(read_target,
write_target, read_offset, write_offset, length);
éventuellement, on peut activer les buffers
sur GL_COPY_READ_BUFFER ou GL_COPY_WRITE_BUFFER, s'il ne sont pas deja
actifs, cf glBindBuffer()
adressage virtuel :
void *
glMapBuffer(target,
access); // obtient une adresse "cpu" sur le debut du
buffer
void *
glMapBufferRange(target,
offset, length, access); // obtient une adresse "cpu"
sur une region du buffer
glUnmapBuffer(target);
// transfere les modifications apportees au contenu du buffer
glFlushMappedBufferRange(target,
offset, length); // transfere les modifications
apportees a une region du buffer, a utiliser avec glMapBufferRange()
textures :
création des identifiants :
GLuint textures[];
glGenTextures(n,
textures);
//
generation
des identifiants de textures
creation d'une texture 1d :
glBindTexture(GL_TEXTURE_1D,
texture);
//
activer
une texture 1d (sur l'unite de
texture courante)
glTexImage1D(GL_TEXTURE_1D,
level,
internal,
width,
border, format, type, data);
creation d'une texture 2d :
glBindTexture(GL_TEXTURE_2D,
texture);
//
activer
une texture 2d (sur l'unite de
texture courante)
glTexImage2D(GL_TEXTURE_2D,
level,
internal,
width,
height, border, format, type, data);
creation d'une texture 3d :
glBindTexture(GL_TEXTURE_3D,
texture);
//
activer
une texture 2d (sur l'unite de
texture courante)
glTexImage3D(GL_TEXTURE_3D,
level,
internal,
width,
height, depth, border, border, format, type,
data);
création des versions
pre-filtrées / pyramide de mipmaps :
glActiveTexture(GL_TEXTURE0
+
unit);
//
activer une unite de texture, si
necessaire
glBindTexture(target,
texture);
//
activer
la texture sur l'unite de
texture, si necessaire
destruction :
activation sur l'unité de
texture courante (cf
configuration du pipeline) :
activation d'une texture sur une
unité de texture d'indice 'unit' (cf configuration du pipeline) :
modification d'une partie du contenu
de la texture apres sa creation :
glTexSubImage1D(GL_TEXTURE_1D,
level,
xoffset,
width,
format, type, data);
glTexSubImage2D(GL_TEXTURE_2D,
level,
xoffset,
yoffset,
width, height, format, type, data);
glTexSubImage3D(GL_TEXTURE_3D,
level,
xoffset,
yoffset,
zoffset, width, height, depth, format, type,
data);
samplers :
création des identifiants :
destruction :
paramètres de filtrage :
par défaut, les parametres de filtrage sont configures pour
utiliser la pyramide de mipmaps de la texture, cf. glGenerateMipmap()
dans la section texture.
activation sur l'unité de
texture d'indice 'unit' (cf
configuration du pipeline) :
utilisation avec un shader program (cf configuration du pipeline) :
le sampler doit etre parametre et active sur une unite de texture
d'indice 'unit', cf glBindSampler()
une texture doit etre activee sur la meme unite de texture, cf.
glActiveTexture() et glBindTexture()
GLint location=
glGetUniformLocation(program,
"sampler");
glUniform1i(location,
unit);
//
le
shader program doit etre actif, cf
glUseProgram() ou glProgramUniform().
framebuffers :
creation des identifiants :
destruction :
activation (cf configuration du
pipeline) :
attacher une texture à un
framebuffer :
vérifier que la configuration
du framebuffer est valide :
vertex array objects :
création des identifiants :
activation (cf. configuration du pipeline) :
glBindVertexArray(array);
associer un vertex buffer et un attribut du vertex shader (cf. configuration du pipeline / assemblage d'attributs de sommets ) :
glBindVertexArray(); // si necessaire
glBindBuffer(GL_ARRAY_BUFFER, buffer); // d'autre choix de target sont possibles
glVertexAttribPointer();
glEnableVertexAttribArray();
associer un index buffer (cf. configuration du pipeline / assemblage de primitives indexees ) :
glBindVertexArray(); // si necessaire
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer); //
d'autre choix de target sont possibles
shader objects :
création d'un identifiant :
GLuint shader=
glCreateShader(type);
avec type GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, etc.
destruction:
compiler un shader :
état de la compilation :
GLint status;
glGetShader(shader,
GL_COMPILE_STATUS,
&status);
si status == GL_TRUE la compilation a reussi,
sinon recuperer les messages d'erreurs et les
afficher.
récupérer les erreurs
de compilation en cas d'echec :
GLint length;
glGetShader
(shader,
GL_INFO_LOG_LENGTH,
&length);
if(length > 0)
{
GLchar *log= new GLchar[length];
glGetShaderInfoLog
(shader,
length,
NULL,
log);
printf("status:\n%s\ncompilation failed.\n", log);
delete [] log;
}
shader programs :
creation d'un identifiant :
destruction :
attacher un shader au program :
pre-déclarer / imposer
l'indice d'un attribut (avant le link) :
glBindAttribLocation(program,
index,
name);
on peut obtenir le meme résultat en modifiant la
déclaration de l'attribut dans le source du vertex shader :
layout(location= index) in type name;
pre-déclarer / imposer le draw
buffer d'un varying du fragment shader (avant le link) :
glBindFragDataLocation(program,
index,
name);
on peut obtenir le meme résultat en modifiant
la déclaration du varying dans le source du fragment shader :
layout(location= index) out type name;
glBindFragDataLocationIndexed(program,
index,
blend_index, name);
transform feedback, déclarer
les varyings à enregistrer :
glTransformFeedbackVaryings(program,
count, varyings, mode);
l'ordre des varyings definit leur indexation pour
tout le pipeline, par exemple l'index a utiliser pour activer un
buffer, cf configuration du pipeline,
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index, ...)
édition des liens (link) des
shaders attaches au program :
état de l'édition de
liens (link) :
GLint status;
glGetProgramiv(program,
GL_LINK_STATUS,
&status);
si status == GL_TRUE l'edition de liens a reussi,
sinon recuperer les erreurs et les afficher.
récupérer les erreurs
d'édition de liens :
GLint length;
glGetProgramiv
(program,
GL_INFO_LOG_LENGTH,
&length);
if(length > 0)
{
GLchar *log= new GLchar[length];
glGetProgramInfoLog
(program,
length,
NULL,
log);
printf("status:\n%s\nlink failed.\n", log);
delete [] log;
}
activation (cf configuration du
pipeline)
paramétrer un uniform du
shader program (le shader program doit etre actif, cf configuration du
pipeline) :
paraméter un tableau
d'uniforms du shader program
(le shader program doit etre actif, cf configuration du pipeline) :
GLint location=
glGetUniformLocation(program,
"uniforms[0]");
glUseProgram(program);
//
activer le shader program, si necessaire
glUniformXXv(location,
count,
values);
cas particuliers pour les matrices (le shader program doit etre actif, cf
configuration du pipeline) :
GLint location=
glGetUniformLocation(program,
"uniform_mat");
glUseProgram(program);
//
activer le shader program, si necessaire
glUniformMatrixXXv(location,
1,
transpose,
matrix);
remarque: le booleen
transpose
indique qu'il est nécessaire (ou pas) de transposer la matrice au format interne utilisé par openGL,
ce qui est le cas pour une matrice représentée par
float mat[lignes][colonnes]
;
(GL4) paramétrer un uniform du
shader program (le shader program n'a pas besoin d'etre actif sur le
pipeline):
(GL4) transform feedback objects :
création :
GLuint feedbacks[];
destruction :
activation (cf configuration du
pipeline) :
configuration du pipeline :
shader program :
activation :
déterminer les attributs
nécessaires à l'exécution du vertex shader
(connaissant leur nom) :
GLint location=
glGetAttribLocation(program,
name);
si location < 0, l'attribut n'est pas
utilisé par le shader program.
itération sur les attributs
réellement utilisés par le vertex shader :
GLint length;
glGetProgramiv
(program,
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
&length);
GLchar *name= new GLchar[length];
GLint attribute_count;
glGetProgramiv
(program,
GL_ACTIVE_ATTRIBUTES,
&attribute_count);
for(int index= 0; index < attribute_count; index++)
{
// recupere les informations sur l'attribut
GLenum glsl_size= 0;
GLint glsl_type= 0;
glGetActiveAttrib
(program,
index,
NULL,
length,
glsl_size, glsl_type, name);
GLint location= glGetAttribLocation(program, name);
// glsl_size > 1 pour les tableaux,
// glsl_type est le type GLSL de l'attribut : GL_FLOAT_VEC3 pour un vec3, par exemple.
// attention: openGL et GLSL n'utilisent
pas la meme convention pour decrire les types, un vec3 correspond a :
// gl_size= 3
// gl_type= GL_FLOAT
// on peut maintenant associer l'attribut au contenu d'un vertex buffer :
glVertexAttribPointer(location, gl_size, gl_type, GL_FALSE, stride, offset);
glEnableVertexAttribArray(location);
}
delete [] name;
assemblage d'attributs de sommets :
associer un buffer à un
attribut utilisé par le shader
program :
GLint location=
glGetAttribLocation(program,
name);
ou parcourir les attributs
utilisés par le program.
glBindVertexArray(array); // selectionne le vertex array contenant l'association attribut / buffer
glBindBuffer(GL_ARRAY_BUFFER,
buffer);
//
selectionne le
buffer contenant les donnees
glVertexAttribPointer(location,
size,
type,
normalized,
stride, offset); // associe le buffer a
l'attribut et indique comment interpreter le contenu du buffer
glEnableVertexAttribArray(location);
//
active l'utilisation du buffer
glDisableVertexAttribArray(location); // desactive
l'utilisation du buffer
les paramètres size, type permettent d'interpréter le
contenu du buffer.
attention : ce sont les representations openGL, pas GLSL !
les paramètres stride, offset permettent d'itérer sur le
contenu du buffer selectionné par le glBindBuffer.
cf exemples d'utilisation complet :
exemple1,
exemple2
selection d'un ensemble d'attributs (déja configurés) :
glBindVertexArray(array);
remarque: un vertex array peut aussi conserver un index buffer:
glBindVertexArray(array);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
assemblage d'attributs d'instances :
associer un buffer à un
attribut d'instance utilisé par le shader
program :
GLint location= glGetAttribLocation(program,
name);
ou parcourir les attributs
utilisés par le program.
glBindVertexArray(array); // selectionne le vertex array contenant l'association attribut / buffer
glBindBuffer(GL_ARRAY_BUFFER,
buffer);
//
selectionne le
buffer contenant les donnees
glVertexAttribPointer(location,
size,
type,
normalized,
stride, offset); // associe le buffer a
l'attribut et indique comment interpreter le contenu du buffer
glEnableVertexAttribArray(location);
//
active l'utilisation du buffer
glVertexAttribDivisor(location, 1); // spécifie que l'attribut est lié à une instance
c'est la meme chose que pour les attributs de
sommets, seul glVertexAttribDivisor(..., 1) permet de differencier un
attribut d'instance.
assemblage de primitives non
indexées + exécution du pipeline :
glBindVertexArray(array); // selectionne un ensemble d'attributs et de buffers deja configure, cf assemblage d'attributs de sommets.
glDrawArrays(primitive_mode, first, count);
exemple complet:
GLuint position_buffer; // identifiant d'un buffer contenant les positions des sommets
GLuint program;
// identifiant d'un shader program. le vertex shader declare un
attribut: in vec3 position;
GLuint buffers;
// identifiant d'un vertex array
int init( ) {
...
glGenVertexArrays(1, &buffers);
glBindVertexArray(buffers);
GLint location= glGetAttribLocation(program, "position");
if(location < 0)
return "erreur l'attribut n'existe pas."
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(location);
// nettoyage
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// desactiver le vertex array avant, sinon on modifie son etat.
...
}
int draw( ) {
glUseProgram(program)
;
...
glBindVertexArray(buffers);
glDrawArrays(GL_TRIANGLES, 0, count);
// nettoyage
glBindVertexArray(0);
glUseProgram(0);
...
}
assemblage de primitives indexées + exécution du
pipeline :
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
buffer); // selectionne un ensemble d'attributs et de buffers deja configure, cf
assemblage d'attributs de sommets.
glBindVertexArray(array);
glDrawElements(primitive_mode,
count,
type,
offset);
type est souvent GL_UNSIGNED_INT, les indices sont
non signés et GL_INT n'est
pas utilisable.
exemple complet:
GLuint position_buffer; // identifiant d'un buffer contenant les positions des sommets
GLuint index_buffer; // identifiant d'un buffer contenant les indices des triangles
GLuint program;
// identifiant d'un shader program. le vertex shader declare un
attribut: in vec3 position;
GLuint buffers;
// identifiant d'un vertex array
int init( ) {
...
glGenVertexArrays(1, &buffers);
glBindVertexArray(buffers);
GLint location= glGetAttribLocation(program, "position");
if(location < 0)
return "erreur l'attribut n'existe pas."
glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(location);
// associe egalement l'index buffer au vertex array
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
// nettoyage
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// desactiver le vertex array avant, sinon on modifie son etat.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // desactiver le vertex array avant, sinon on modifie son etat.
...
}
int draw( ) {
glUseProgram(program)
;
...
glBindVertexArray(buffers);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_INT, 0);
// nettoyage
glBindVertexArray(0);
glUseProgram(0);
...
}
visibilité des primitives :
glEnable(GL_CULL_FACE);
//
active le test de visibilite des primitives
glDisable(GL_CULL_FACE); // desactive le test de
visibilite des primitives
glCullFace(mode);
//
configure le test de visibilite des primitives
glFrontFace(mode);
//
indique quelle orientation conserver / eliminer
fragmentation :
glPolygonMode( ) // remplir les primitives (GL_FILL), ne
dessiner que les aretes (GL_LINE) ou que les sommets (GL_POINT)
tests et mélange :
activer / desactiver
l'écriture des composantes r, g, b, a, z dans le framebuffer :
glColorMask(r,
g,
b, a); // active / desactive l'ecriture des
composantes r, g, b, a dans le framebuffer
glColorMaski(index,
r,
g, b,a); // active / desactive l'ecriture des
composantes r, g, b, a dans le drawbuffer 'index' du framebuffer
glDepthMask(flag);
//
active / desactive l'ecriture du z / de la profondeur dans le
framebuffer
glEnable(GL_DEPTH_TEST);
//
active / desactive le test de visibilite sur le z / la profondeur
glDepthFunc(GL_LESS);
//
configure le test de profonduer utilise
activer / desactiver le
mélange entre les varyings du fragment shader et le contenu du
framebuffer :
glEnable(GL_BLEND);
//
active / desactive le melange des couleurs du fragment avec le pixel
du framebuffer
glBlendColor(red,
green,
blue, alpha); // configure le melange
glBlendFunc(sfactor,
dfactor);
// configure le melange
glBlendFuncSeparate(sRGB,
dRGB,
sAlpha, dAlpha); // configure le melange pour
les composantes rgb et alpha
glBlendEquation(mode);
//
configure le melange
glBlendEquationSeparate(modeRGB,
modeAlpha);
// configure le melange pour les
composantes rgb et alpha
framebuffer :
dessiner dans un framebuffer :
dessiner dans le framebuffer par
defaut (cree lors de la creation du contexte / de la fenetre de
l'application) :
sélectionner quels buffers /
textures du framebuffer sont modifiés par l'éxecution du
pipeline :
glDrawBuffers(count,
buffers);
buffers est un tableau de constantes GL_NONE ou
GL_COLOR_ATTACHMENT0 + index permettant d'associer un varying du
fragment shader à une texture attachee au framebuffer, si un
framebuffer est actif, cf glBindFramebuffer.
effacer le framebuffer :
glClear(buffer_flags);
//
efface les buffers du framebuffer actif
glClearBuffer(buffer_type,
drawbuffer,
value); // efface un seul type de buffer
(color, depth, stencil) du framebuffer actif
glClearColor(r,
g,
b, a); // couleur utilisee pour effacer les buffers
glClearDepth(depth);
//
profondeur utilisee pour effacer les zbuffers
transform feedback :
sélectionner les buffers
utilisés pour enregistrer les varyings :
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER,
index, buffer);
index est la position du varying dans la liste de
varyings déclarée lors de l'édition de lien du
shader program, cf glTransformFeedbackVaryings()
commencer le transform feedback :
glBeginTransformFeedback(primitive_mode);
primitive_mode doit correspondre au type de
primitives émises par le geometry shader, ou GL_POINTS s'il n'y
a pas de geometry shader dans le shader program actif.
arreter :
(GL4) activer / desactiver
l'enregistrement 'auto' du nombre d'éléments
stockés dans les buffers par le transform feedback :
(GL4) dessiner les primitives
stockées dans les buffers par le transform feedback
(plus efficace que la version GL3 qui nécessite une requete et
une synchronisation entre cpu et gpu) :
glDrawTransformFeedback(primitive_mode,
feedback);
primitive_mode est le meme que pour glDraw(),
le nombre de primitives dessinées est
stocké dans l'objet feedback qui etait actif lors de
l'enregistrement dans les buffers :
exemple:
// activer les buffers pour stocker le resultat
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, index, buffer);
...
GLuint feedback;
glGenTransformFeedback(1, &feedback);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, feedback);
glBeginTransformFeedback(primitive_mode);
glDrawXXX();
// dessiner quelquechose
glEndTransformFeedback();
// activer buffer comme 'source' de donnees / d'index, etc.
glBindBuffer(XXX, buffer);
glDrawTransformFeedback(primitive_mode, feedback);
unités de textures :
activer une unité 'index' :
activer une texture sur
l'unité de texture active :
activer un sampler /
paramètres de filtrage sur une unité de texture 'index' :
associer une unité de texture
à un sampler du shader program :
GLint location=
glUniformLocation(program,
"sampler");
glUseProgram(program);
//
active le program, si nécessaire
glUniform1i(location,
unit);
//
le
shader program doit etre actif, cf
glUseProgram() ou utiliser glProgramUniform().