mercredi 3 janvier 2018

Chapitre 14 : dessiner avec le frameBuffer : II



Dans mon dernier post, je vous ai laissé un peu brutalement en vous demandant d’écrire les autres primitives pour dessiner. Je vais donc continuer de voir les possibilités de dessin en suivant toujours le site de raspberrycompote et en adaptant les programmes données en C. Aujourd’hui, nous partons d’un programme qui affiche des trames de couleurs (tiens c’était un exercice précèdent) dans les différentes résolutions possibles. Mais je vous préviens tout de suite, seuls les résultats en 32 bits par pixel sont concluants. Je ne suis pas arrivé à avoir des résultats corrects en 8 bits et 16 bits (et je n’ai pas essayé en 24 bits). Voici le source du programme en 32 bits
Nous reprenons la même démarche que précédemment pour ouvrir le périphérique /dev/fb0 et lire les données variables, mais nous modifions la résolution pour la placer en 8 bits et nous appelons la fonction système IOCTL pour écrire toute la structure variable dans les données du périphériques. Avant cette modification, nous avons recopié la structure variables dans une zone mémoire, ce qui nous permettra de restaurer ces données en fin de programme (et d’ailleurs il serait aussi bon de sauvegarder tout l’écran pour le restaurer en fin de travail).
Puis nous lisons les données fixes du périphérique et nous remarquons que la taille mémoire nécessaire au mapping (1 octet * résolution x * résolution y) est différente de celle du programme précédent (4 octets * x * y).
Nous effectuons le mapping comme précédemment puis nous écrivons 2 boucles pour balayer une partie de l’écran. La première va balayer la moitié des lignes (registre r6 position y) et l’autre va balayer chaque pixel de chaque ligne registre r0 position x). Nous devons calculer la position du pixel (x,y) dans la zone mémoire allouée par le mapping soit y * résolution de la ligne + x et calculer une couleur qui sera attribué à ce pixel. Pour cela nous multiplions la position en x par le nombre de couleur désiré (6) et nous le divisons par la résolution de la ligne. Ainsi lors du balayage les positions de x de 0 à (800 /6 soit 133) auront la couleur 0, de 133 à 266 la couleur 1 etc.
Normalement en 8 bits par pixel, le code calculé correspond à une couleur de la palette par défaut. Mais mes premiers tests n’ont rien donné (que du noir !!!!) et j’ai donc recherché sur Internet pour avoir une solution. Il semblerait que la gestion du frameBuffer sur le Raspberry n’est pas très correcte pour les résolutions 8bits, 16 bits et 24 bits : bref que seule la résolution 32 bits fonctionne correctement. Et comme le dit un intervenant pourquoi programmer des couleurs dans ces résolutions qui datent de l’ancien temps !!!!!
Donc j’ai trouvé des propositions de calcul mais cela ne me donne pas grand-chose même en changeant les dimensions x et y de l’affichage. J’ai aussi essayé en 16 bits mais là les couleurs sont vraiment bizarres et seules les couleurs en 32 bits sont correctes. Pour les courageux qui veulent tester et améliorer ces programmes, je vous donne les 2 autres sources.
Le programme se termine en écrivant les données variables qui avaient été sauvegardées en début pour remettre la bonne résolution et en fermant proprement le mapping et le périphérique (et toujours fermer une entité dans la même procédure qui l’a ouverte).
En continuant la lecture du site raspberrycompote, je me rends compte que ces problèmes d’affichage sont indiqués et que cela semble aussi dépendre des versions Linux distribuées.
Le programme suivant du site affiche 3 cercles rouge vert bleu d’un plus bel effet et donc je me laisse tenter par son écriture en assembleur (et je testerais aussi la résolution en 24 bits par pixel). Voici le source du programme.
Le programme reprend comme précédemment l’ouverture, la lecture des données fixes et variables et le mapping (c’est bien rodé tout ça maintenant) et seule la partie dessin est modifiée.  Dans cette partie, il s’agit essentiellement de calcul pour déterminer la couleur rouge (1 octet) verte (1 octet) et bleue (1 octet) de chaque pixel de l’écran en fonction de sa position. Tous les registres seront utilisés dans la procédure !! et nous serons obligés d’écrire une petite routine de calcul de racine carrée (méthode de Héron).
En fin de calcul de chaque pixel, nous appellerons 3 routines différentes suivant les résolutions 32, 24 et 16 bits.
En 32 et 24 bits, les 3 octets des couleurs seront stockés dans les 3 octets de la zone mémoire mmap et pour le 32 bits, le 4ième octet sera mis à zéro.
Pour le 16 bits, la routine s’appelle put_pixel_RGB565 car le rouge occupe les 5 premiers bits, le vert les 6 bits centraux et le bleu les 5 derniers bits (ou inversement !!!).
Voici le résultat en 32 bits :  magnifique non !!!

Pour les autres résolutions, il faut positionner l’affichage par l’instruction fbset –depth 16 ou 24 avant de lancer votre programme (vous pouvez vérifier la résolution en tapant simplement fbset). Les résultats sont curieux !! ou les routines sont erronées !!!
Exercices :  afficher l’ensemble de Mandelbrot (attention calculs en virgule flottante et c’est du boulot).
                 Afficher un cercle coloré qui change progressivement de couleur ;
                 Afficher le cercle précèdent (et couleur soleil) et lui faire décrire une courbe comme le lever et coucher du soleil d’un bord à l’autre de l’écran. Faire évoluer sa couleur ou sa luminosité.
               Si les programmes sont lents !! cherchez des solutions d’optimisation !!!

Aucun commentaire:

Enregistrer un commentaire