TD7 : couleur, etc...

Rajouter de la couleur dans votre programme

Nous disposons à l'ESSI et à l'université de nice principalement de machines ne permettant de visualiser que 256 couleurs simultanément. pourtant, si nous voulons visualiser une sphère rouge avec un lissage de Gouraud, avec la colormap dont nous diposons, nous n'avons que quelques niveaux de rouges à notre disposition.

Pour peu que nous utilisions une table de couleurs correctement construite (entendons par là, dont les couleurs sont construites de manière ordonnées, et sont facilement adressables), celle construite par la fonction Lut_16M() du fichier color.c par exemple, nous pouvons facilement retrouver la couleur la plus proche parmi les 256 disponibles d'une couleur exprimée parmi 16 millions. La macro RGBTOONE est là pour ça :
 

Malheureusement, avec cette méthode les résultats ne sont pas très jolis...
 
Colormap
Sphère en flat shading, couleurs tramées
Sphère en Gouraud shading, couleurs tramées

Il faut tramer les couleurs !!!

Pour tramer les couleurs, nous ne pouvons pas utiliser un tramage causal de type Floyd Steinberg. Nous avons vu en cours qu'il nous faut utiliser un tramage ordonné permettant d'adresser dans le désordre (random ordered dithering) n'importe quel point (X,Y).

Nous allons utiliser ce type de tramage de la manière suivante :
 

Où x et y sont les coordonnées du point à dessiner, et r, g et b les composantes rgb de la couleur choisie, chacune étant comprise entre 1 et 255, ce qui nous laisse 16 millions de possibilités.

Vous pouvez utiliser cette fonction que vous dessiniez dans des Pixmaps ou dans des Ximages.
 

Travail à faire

Aide : les fonctions de balayage que je vous ai proposées s'adaptent très facilement. Par exemple, pour faire un flat shading avec des couleurs tramées, il suffit de modifier la boucle principale de la fonction G_ambiant_polygon du TD6 comme suit :
  ...
  /* rendering all lines */
  for(; G_miny<=G_maxy; G_miny++, l_adr+=HW_SCREEN_X_SIZE) {
    adr=l_adr+(beg=G_start[G_miny]);         /* G_miny est le Y courant, 
                                                beg est le X courant, 
                                                adr est l'adresse du 1er point 
                                                    sur le cote gauche, 
                                                    pour le Y courant */
    end=G_end[G_miny]-beg+1;                 /* end est le nombre de points entre
                                                le X de gauche et le X de droite */
    /* memset((char *) adr, colour, end); <-- avant ! */

    /* Dessin point par point de la ligne courante, avec tramage */
    while(end--)
        *adr++ = CouleurTramee(beg++, G_miny, r, g, b);
  }
  ...