π
<-
Chat plein-écran
[^]

[Programme C] Algorithme de traçage de pixel

C, C++, ASM...

[Programme C] Algorithme de traçage de pixel

Message non lude Levak » 04 Fév 2010, 11:02

Bonjour à tous !
Depuis bientôt 2 semaines, un vénérable membre de UTI nous a donné la voie pour commencer à programmer en C++ compilé pour le faire fonctionner avec l'émulateur de Goplat :
http://www.unitedti.org/forum/index.php ... stp=139981

Sur cette belle occasion, et histoire de mettre à l'épreuve ma logique, j'ai essayé de programmer une fonction pour afficher un pixel.

A première vue, ça parait simple, x et y, et clic clac pouf paf, on déplace le pointeur et on met la couleur... AAAAA, pas si vite petit ! Car quand on se penche dessus de plus près, on remarque que les pixels sont codés deux par deux dans un même octet... Je dois reprendre depuis le début, vous m'avez laché ?

Rappel :
Un octet est une séquence de 8 bits, en binaire cela donne : 0b00000000 ou encore 0b11111111, ou encore 0b01110110
puis en hexa : 0x00 ou encore 0xFF ou encore 76
en décimal : 0 ou encore 255 ou encore 118

De plus, on sait que l'écran de la nspire est codé entre les adresses mémoire 0xA4000100 et 0xA40096FF (cf Hackspire)
Or si l'on fait le calcul, en sachant que l'écran comporte 240*320 pixels, soit 76800 pixels, en hexa 12C00. Or 12C00 + 100 = 12D00 octets de décallage, ce qui est beaucoup trop par rapport à la limite 96FF de l'écran !!
En fait, chaque octet code deux pixels, c'est à dire que les bits de poids fort (les 4 premiers) vont coder le pixel de gauche, et les pixels de poids faible (les 4 derniers) le pixel de droite.
En effet : (240*(320/2)) = 38400, en hexa = 9600, et 9600 + 100 = 9700. Comme on commence à 0 et pas à 1 dans l'adressage mémoire, cela donne 96FF, ce qui convient.
Cette méthode était dure à gérer en C, on ne peux pas couper un octet en deux, il faut obligatoirement gérer les deux pixels en même temps, soit en les valorisant deux par deux, soit en utilisant un peu de logique (et tellement de logique que je suis assez fier de mon exploit, même si d'autres l'ont déjà fait avant :p).


Enfin, une subtilité qui m'a fait bien des soucis est la couleur. En effet, il y a 16 niveaux de gris (0 à 15, puisque de 0b0000 à 0b1111 puisque de 0x0 à 0xF). Mais, logiquement, il y a un problème en termes d'algorithme. Comme on ne peut pas exploiter un demi octet seulement (ou alors je sais pas faire et je me suis compliqué la vie pour rien), on doit utiliser les opération AND/OR/XOR/NOT. J'utiliserais ce que j'appelle des masques. De plus, pour effacer l'écran on utilise une boucle qui va donner la valeur FF à chaque octet (dual-pixel si vous voulez) et là pas besoin de masque, puisque c'est partout pareil.

exemples :
# pour noir, - pour blanc
[tableborder=1]pixels....................-.-.-.##-.##[/table]
[tableborder=1]valeur des octets...255240.15...0................................FF..F0..0F..00.[/table]

Alors maintenant, imaginez que vous voulez afficher UN et UN seul pixel ? Comment ça "facile" ?
Oh que non, car une autre contrainte est que vous devez conserver la valeur du précédent octet, tout en assignant au bon endroit notre demi octet.
Vous comprenez ? non ? Allez... imaginons un unique octet pour notre écran :
[tableborder=1]pixels....................-.-.[/table]
[tableborder=1]valeur des octets...255..............................FF.[/table]

Et là on veut assigner le deuxième pixel à # (noir), donc cela revient à valoriser l'octet à 240 :
[tableborder=1]pixels....................-.#[/table]
[tableborder=1]valeur des octets...240..............................F0.[/table]

Maintenant, on veut allumer le 1er pixel, mais on ne sait pas si le deuxième pixel est allumé, on donne la valeur 15 à l'octet :
[tableborder=1]pixels....................#-.[/table]
[tableborder=1]valeur des octets...15..............................0F.[/table]

Et là... catastrophe ! Il aurait fallut assigner la valeur 0 !
[tableborder=1]pixels....................##[/table]
[tableborder=1]valeur des octets.....0................................00.[/table]

C'est donc là que l'opération AND rentre en jeux, mais avec d'autres opérandes, comme le décalage de bit et le masque pour éviter la perte de valeur, étant donné que le 1 est universel (il n'influence pas sur la valeur) pour cette opérande.

Allez, trêve de bavardage, voilà la solution, qui affiche un magnifique dégradé :
http://pastebin.com/f435c1bbb
 
Show/Hide spoilerAfficher/Masquer le spoiler
En version non colorée et non commentée
Code: Tout sélectionner
asm ("mov sp,#0x12000000");
void main(void)
{
   unsigned char ligne = 0xA0;
   unsigned char *ptr;
   unsigned int ini = 0xa4000100;
   unsigned int x = 0;
   unsigned int y = 0;
   unsigned char color, colorf = 0;
   unsigned int xf;

   ptr = (unsigned char *) ini;
   
   while (ptr  (unsigned char *) (ini+240*ligne)) {
      *ptr++= 0xFF;
    }
   
   while (y  240){   
      while (x  320){   
         while (color = 15){
            xf = x1;
            if (xf1==x){colorf = (color4)+0b1111;} 
            else {colorf = color+0b11110000;}     
            ptr = (unsigned char*) (ini+(xf+ligne*y));
            *ptr = *ptrcolorf;           
            color++;
            x++;
         }
         color = 0;
      }
      x = 0;
      y++;   
   }
   b:
   goto b;
}

et le résultat :
Image

@+ !
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)

Re: [Programme C] Algorithme de traçage de pixel

Message non lude critor » 04 Fév 2010, 13:11

Levak, je suis heureux de voir que tu as suivi mes conseils, notamment en terme de masques et de logique (ce qui n'empêche pas que l'ensemble du travail te revient).


Superbe exposé, nous te remercions tous. :#top#:

J'ai tout suivi de A à Z, ou plutôt de A à F devrais-je dire :#langue#:


Maintenant, ce serait bien que tu programmes un convertisseur d'images.
Il prendrait une image (BMP, GIF, TIFF... je vais pas te demander de gérer du JPEG :;): ) et afficherait sur la calculatrice une image en niveaux de gris.

Ce serait vraiment génial comme programme.
Image
Avatar de l’utilisateur
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Prochain niv.: 42.6%
 
Messages: 41500
Images: 14703
Inscription: 25 Oct 2008, 00:00
Localisation: Montpellier
Genre: Homme
Calculatrice(s):
MyCalcs profile
YouTube: critor3000
Twitter/X: critor2000
GitHub: critor

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Adriweb » 04 Fév 2010, 16:20

Super cool :D

Sisi ,franchement :D
Image

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
Avatar de l’utilisateur
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 80.3%
 
Messages: 14617
Images: 1218
Inscription: 01 Juin 2007, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Twitter/X: adriweb
GitHub: adriweb

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Levak » 04 Fév 2010, 17:18

critor2000 a écrit:Levak, je suis heureux de voir que tu as suivi mes conseils, notamment en terme de masques et de logique (ce qui n'empêche pas que l'ensemble du travail te revient).


Superbe exposé, nous te remercions tous. :#top#:

J'ai tout suivi de A à Z, ou plutôt de A à F devrais-je dire :#langue#:


Oups ! J'ai oublié de te citer Critor ! Effectivement, n'ayant pas de maitrise complète en C/C++ (je n'avais fait auparavant que sur les traitements de donnés et échanges d'informations avec des PIC16F et 18F = Robots) j'ai demandé pleins de choses et pleins de conseils il m'a donné ! Merci Critor !


Maintenant, ce serait bien que tu programmes un convertisseur d'images.
Il prendrait une image (BMP, GIF, TIFF... je vais pas te demander de gérer du JPEG :;): ) et afficherait sur la calculatrice une image en niveaux de gris.

Ce serait vraiment génial comme programme.


Aaaah je l'avais oublié celui-là :#langue#:
J'essaierais, mais plein de questions encore te demander je ferais ^^

Adri merci ^^

@+ !
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Ciwtron » 04 Fév 2010, 17:31

Levak a écrit:
critor2000 a écrit:Maintenant, ce serait bien que tu programmes un convertisseur d'images.
Il prendrait une image (BMP, GIF, TIFF... je vais pas te demander de gérer du JPEG :;): ) et afficherait sur la calculatrice une image en niveaux de gris.

Ce serait vraiment génial comme programme.


Aaaah je l'avais oublié celui-là :#langue#:
J'essaierais, mais plein de questions encore demander je ferais ^^


Si tu as quelques questions sur le bmp, je pourrais peut-être y répondre.

Sinon, bravo pour ce que tu as fait!
Avatar de l’utilisateur
Ciwtron
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Prochain niv.: 36.7%
 
Messages: 1332
Inscription: 29 Nov 2009, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: 1S

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Levak » 04 Fév 2010, 17:56

critor2000 a écrit:Maintenant, ce serait bien que tu programmes un convertisseur d'images.
Il prendrait une image (BMP, GIF, TIFF... je vais pas te demander de gérer du JPEG :;): ) et afficherait sur la calculatrice une image en niveaux de gris.
Ce serait vraiment génial comme programme.


Je me suis concerté à moi-même et je me suis rappelé d'une chose. Ce code en C est le code pour la calculatrice. en gros, si je dois faire un code qui soit capable de transposer une image en affichant les pixels, il faudra qu'il interprète une image on-calc... vous voyez ce que je veux dire ? En gros ce code est transposé en code machine (compilation), mais les actions restent à faire, elles ne sont pas déjà machées. Si il doit y avoir échange de données, il faut que ce soit la calculette (ici l'émulateur) qui doit gérer cet échange. Or en l'absence d'OS, ça risque d'être plus couteux en temps de réflexion...
De plus, ce code marche car c'est une boucle simple, si vous regardez bien, il n'utilise aucune fonction, que des variables et un pointeur. Or j'ai déjà tenté de créer une fonction "affpix" mais où que je la mette, avant le main(), après avec déclaration *.h ou dedans, il y a toujours une chose qui ne lui plait pas (je parle de l'émulateur, le compilateur ne vois aucune erreur et compile). C'est souvent l'erreur "Bad adress".
Quelqu'un a-t-il une idée là dessus ?
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)

Re: [Programme C] Algorithme de traçage de pixel

Message non lude JayTe » 04 Fév 2010, 19:30

Pas mal Levak! :#top#:
Mais perso j'aurai écrit ça comme ça (ça fait exactement la même chose):
Code: Tout sélectionner
asm("mov sp,#0x12000000");

void main()
{
    static unsigned char *ptr = (unsigned char*) 0xa4000100;
    unsigned int x, y, color;

    for(x = 0; x  240*160; x ++)
    ptr[x] = 0xFF;

    for(y = 0; y  240; y ++)
        for(x = 0; x  320; x ++)
        {
            color = x % 15;
            ptr[y*160+x/2]=x%2?ptr[y*160+x/2]0xF0+color:ptr[y*160+x/2]0x0F+(color 4);
        }
    while(1);
}


(plus court :#langue#: mais aussi plus réutilisable (il n'y a qu'une ligne interessante, et on peut la copier où on veut des qu'on a besoin d'afficher un pixel))

Quand on on met color =x*y%15 au lieu de x % 15 ça donne ça: (jolie illusion d'optique au passge :): )
Image

a+
JayTe

ps: Levak je viens de voir ton nouveau message et j'ai le meme prob que toi (j'ai ausi essayé de créer la fonction setpixel :): ), mais dès que j'essaie d'utiliser une fonction (même si elle ne fait rien) l'émulateur plante en sortant une Bad Address (emu ver 0.21).
même ce code plante:
Code: Tout sélectionner
asm("mov sp,#0x12000000");
void foo(){}
void main(){foo();while(1);}

difficile de faire plus simple et pourtant...
Quelqu'un a une idée?
TabVar - Etude de fonctions sur Nspire!
Image
Avatar de l’utilisateur
JayTePremium
Niveau 8: ER (Espèce Rare: nerd)
Niveau 8: ER (Espèce Rare: nerd)
Prochain niv.: 81.6%
 
Messages: 207
Inscription: 26 Jan 2010, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: Polytechnique

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Levak » 04 Fév 2010, 19:34

Des semi-fractales ! bien joué !

JayTe a écrit:ps: Levak je viens de voir ton nouveau message et j'ai le meme prob que toi (j'ai ausi essayé de créer la fonction setpixel :): ), mais dès que j'essaie d'utiliser une fonction (même si elle ne fait rien) l'émulateur plante en sortant une Bad Address (emu ver 0.21).
même ce code plante:
Code: Tout sélectionner
asm("mov sp,#0x12000000");
void foo(){}
void main(){foo();while(1);}

difficile de faire plus simple et pourtant...
Quelqu'un a une idée?

Oui, je pense que c'est à cause de la ligne : " asm("mov sp,#0x12000000"); "
J'ai beau chercher comment l'exploiter, je ne vois aucune piste, a part qu'il s'agit du stack pointer (sp) = pile = souvent un label
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)

Re: [Programme C] Algorithme de traçage de pixel

Message non lude JayTe » 04 Fév 2010, 19:57

j'ai trouvé une demi-solution :): :
Code: Tout sélectionner
asm("mov sp,#0x12000000");

void main()
{
   static unsigned char *ptr = (unsigned char*) 0xa4000100;
    unsigned int x = 0, y = 0, color = 0;
   
   void setpixel(unsigned int x, unsigned int y, unsigned int color)
   {
      ptr[y * 160 + x / 2] = x % 2 ? ptr[y * 160 + x / 2]  0xF0 + color : ptr[y * 160 + x / 2]  0x0F + (color  4);
   }
   
   for(x = 0; x  240*160; x ++)
      ptr[x] = 0xFF;
      
    for(y = 0; y  240; y ++)
        for(x = 0; x  320; x ++)
      {
          color = (x * y) % 15;
            setpixel(x, y, color);
      }
   while(1);
}

il faut définir les fonctions dans le main
mais c'est pas génial parce qu'il faut que les variables que la fonction prend comme arguments soient déjà définies au moment où on appelle la fonction, et a priori la fonction s'execute une fois au moment où on la définit :s: (et puis bon on perd un peu l'avantage des fonctions qui est de pouvoir séparer le code en plusieurs fichiers)
TabVar - Etude de fonctions sur Nspire!
Image
Avatar de l’utilisateur
JayTePremium
Niveau 8: ER (Espèce Rare: nerd)
Niveau 8: ER (Espèce Rare: nerd)
Prochain niv.: 81.6%
 
Messages: 207
Inscription: 26 Jan 2010, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: Polytechnique

Re: [Programme C] Algorithme de traçage de pixel

Message non lude Levak » 04 Fév 2010, 19:59

JayTe a écrit:j'ai trouvé une demi-solution :): :

il faut définir les fonctions dans le main
mais c'est pas génial parce qu'il faut que les variables que la fonction prend comme arguments soient déjà définies au moment où on appelle la fonction, et a priori la fonction s'execute une fois au moment où on la définit :s: (et puis bon on perd un peu l'avantage des fonctions qui est de pouvoir séparer le code en plusieurs fichiers)

Raté, essaye d'appeler la fonction deux fois, tu verras l'embrouille ^^

edit: pardon, j'avais mal lu ta phrase, tu l'avais aussi vu ^^
Responsable design/graphique de TI-Planet
I do not get mad at people, I just want them to learn the way I learnt.
ImageTNOC [topic][DL]
nClock [topic][DL]
HideManager [topic][DL]
ZLock [topic][DL]
Theme Editor [topic][DL]
Mes programmes
Avatar de l’utilisateur
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 98.9%
 
Messages: 6414
Images: 22
Inscription: 27 Nov 2008, 00:00
Localisation: 0x1AACC355
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: BAC+5: Epita (ING3)

Suivante

Retourner vers Native: Ndless, Linux, ...

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 40 invités

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
Phi NumWorks jailbreak
123
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1423 utilisateurs:
>1407 invités
>11 membres
>5 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)