gKit2 light
|
cf tuto3GL.cpp
pour pouvoir dessiner quelque chose, il faut commencer par configurer le pipeline openGL, repassez dans introduction api 3d, openGL et pipeline graphique si nécessaire.
la configuration minimale est :
glClearColor() et glClearDepthf() définissent les valeurs par défaut utilisées pour "éffacer" l'image et le zbuffer, avec glClear( ). la taille de l'image est fournie par glViewport( ). Les images associées à la fenêtre s'appellent GL_BACK et GL_FRONT, c'est GL_FRONT qui est affichée dans la fenêtre, on dessine donc dans GL_BACK. pour une application simple, il suffit de fixer les valeurs une seule fois dans init( ) :
remarque : si la fenetre de l'application change de dimension, il ne faut pas oublier de modifier glViewport(). si vous utilisez run( ) de window.h, c'est fait automatiquement.
puis effacer l'image et le zbuffer au début de draw( ):
on peut combiner les deux, avec un OU binaire :
pour obtenir une visibilité correcte lorsque plusieurs triangles se dessinent sur le même pixel, il faut indiquer lequel garder, celui dont la profondeur est la plus petite, ou la plus grande, ou égale, etc.
remarque : pour conserver le triangle le plus loin, avec glDepthFunc(GL_GREATER), il faut initialiser le zbuffer correctement : avec la profondeur la plus petite, c'est à dire 0, dans le repère image, cf introduction api 3d, openGL et pipeline graphique.
glDepthFunc() permet de choisir le test, mais il faut aussi l'activer (ou le désactiver) :
lorsque les triangles décrivent la surface d'un objet opaque, les triangles à l'arrière de l'objet ne sont pas visibles, il est assez simple de les détecter, cf introduction api 3d, openGL et pipeline graphique, par contre, il faut donner l'orientation normale des faces, sens trigo ou horaire, et choisir lesquelles on veut supprimer (avant ou arrière) et enfin, activer le test :
le test standard s'écrit :
pour dessiner des triangles, il faut décrire les informations associées aux sommets, indiquer ou les trouver, leur organisation mémoire, et indiquer à quelles entrées du vertex shader elles sont associées.
le cas général est présenté dans configurer un format de sommet, vertex array object, pour l'instant, la solution la plus simple est d'utiliser un tableau uniform déclaré par le vertex shader, sans description de format de sommet. c'est un objet openGL, appelé vertex array object qui stocke la description du format de sommets. il suffit donc de créer un vertex array object vide / par défaut.
la création des objets openGL utilise des fonctions de la forme glGenXXX( int n, GLuint *names ). cette famille de fonctions permet de créer plusieurs objets en même temps et renvoye un tableau d'identifiants des nouveaux objets. pour en créer un seul, on peut utiliser :
il ne reste plus qu'à le sélectionner pour configurer le pipeline :
après avoir compilé et linké un shader program, cf compiler et linker un shader program, il faut le sélectionner pour configurer le pipeline :
avant de pouvoir dessiner, il faut affecter une valeur à tous les uniforms utilisés par le shader program. l'affectation se fait en 2 étapes :
attention : ne pas oublier que glUniform() affecte une valeur à un uniform du program actuellement sélectionné par glUseProgram()...
tuto3GL.glsl déclare 3 uniforms :
la démarche est identique dans les 3 cas, même pour le tableau. par contre, il faut utiliser la bonne version de glUniform() à chaque fois.
pour time, 1 float, il faut utiliser glUniform1f() pour l'affectation (cf interface C openGL pour les conventions de nommage) :
pour color, 4 float, il faut utiliser... glUniform4f() :
pour le tableau positions, les éléments du tableau sont des vec3. pour un seul vec3, on utiliserait glUniform3f( ), pour un tableau, les valeurs sont passées par pointeur, et c'est la variante glUniform3fv(location, count, data) qu'il faut utiliser. count indique le nombre d'élements vec3 à transférer.
remarque : on peut utiliser les variantes pointeurs pour une valeur unique, il suffit de donner 1 comme nombre d'éléments à affecter. par exemple :
ou encore
pour un uniform, ou un tableau, de type matrice 4x4, comme les Transform, par exemple, il faut utiliser glUniformMatrix4fv(). Transform represente les matrices par 16 floats, organises par ligne, mais openGL utilise l'autre organisation, par colonne, il faut donc transposer les matrices avant de les affecter à un uniform, c'est le role du parametre transpose de glUniformMatrix().
uniforms.h définit plusieurs surcharges de la famille glUniform() pour les types les plus courants.
attention : vérifiez que la bonne surchage soit utilisee, si l'uniform est un scalaire : int, uint ou float, n'hesitez pas utiliser les notations litterales ou les constructeurs explicites :
12.5f
ou float(12.5)
ou (float) 12.5
,4
ou int(4)
ou (int) 4
,6u
ou unsigned(6)
ou (unsigned) 6
.on peut enfin dessiner les 12 triangles, c'est à dire les indices de 0 à 36.
l'exemple complet est dans tuto3GL.cpp
il faut fixer les paramètres, pour les applications simples, une seule fois dans init( ) :
et pour dessiner, dans draw( ), il faut au minimum :
éventuellement, on peut vérifier que tous les uniforms utilisés par le program ont bien une valeur ou vérifier que les attributs déclarés par le vertex shader sont bien paramétrés, cf récupérer les uniforms et les attributs utilisés par un shader program.