π
<-

[Programme C] Algorithme de traçage de pixel

C, C++, ASM...

[Programme C] Algorithme de traçage de pixel

Unread postby Levak » 04 Feb 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: Select all
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
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

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

Unread postby critor » 04 Feb 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
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 51.4%
 
Posts: 42257
Images: 16712
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

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

Unread postby Adriweb » 04 Feb 2010, 16:20

Super cool :D

Sisi ,franchement :D

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...)
My calculator programs
Mes programmes pour calculatrices
User avatar
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 79.7%
 
Posts: 14820
Images: 1131
Joined: 01 Jun 2007, 00:00
Location: France
Gender: Male
Calculator(s):
MyCalcs profile
Twitter: adriweb
GitHub: adriweb

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

Unread postby Levak » 04 Feb 2010, 17:18

critor2000 wrote: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
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

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

Unread postby Ciwtron » 04 Feb 2010, 17:31

Levak wrote:
critor2000 wrote: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!
User avatar
Ciwtron
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Level up: 36.7%
 
Posts: 1332
Joined: 29 Nov 2009, 00:00
Gender: Male
Calculator(s):
MyCalcs profile
Class: 1S

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

Unread postby Levak » 04 Feb 2010, 17:56

critor2000 wrote: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
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

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

Unread postby JayTe » 04 Feb 2010, 19:30

Pas mal Levak! :#top#:
Mais perso j'aurai écrit ça comme ça (ça fait exactement la même chose):
Code: Select all
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: Select all
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
User avatar
JayTePremium
Niveau 8: ER (Espèce Rare: nerd)
Niveau 8: ER (Espèce Rare: nerd)
Level up: 81.6%
 
Posts: 207
Joined: 26 Jan 2010, 00:00
Gender: Male
Calculator(s):
MyCalcs profile
Class: Polytechnique

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

Unread postby Levak » 04 Feb 2010, 19:34

Des semi-fractales ! bien joué !

JayTe wrote: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: Select all
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
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

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

Unread postby JayTe » 04 Feb 2010, 19:57

j'ai trouvé une demi-solution :): :
Code: Select all
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
User avatar
JayTePremium
Niveau 8: ER (Espèce Rare: nerd)
Niveau 8: ER (Espèce Rare: nerd)
Level up: 81.6%
 
Posts: 207
Joined: 26 Jan 2010, 00:00
Gender: Male
Calculator(s):
MyCalcs profile
Class: Polytechnique

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

Unread postby Levak » 04 Feb 2010, 19:59

JayTe wrote: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
User avatar
LevakAdmin
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 98.9%
 
Posts: 6414
Images: 22
Joined: 27 Nov 2008, 00:00
Location: 0x1AACC355
Gender: Male
Calculator(s):
MyCalcs profile
Class: BAC+5: Epita (ING3)

Next

Return to Native: Ndless, Linux, ...

Who is online

Users browsing this forum: ClaudeBot [spider] and 7 guests

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1518 utilisateurs:
>1504 invités
>8 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)