Accueil

CPC


 Dev C sur CPC :

  • le C sur CPC
  • SDCC débuter
  • fichier BAT pour compiler
  • Dessiner Sur CPC
  • Optimiser le dessin
  • Ecrire du texte
  • Lire un fichier
  • Ecrire un fichier
  • Swap d'écran
  • CLS ultra rapide
  • H line
  • Attaquer le CRTC
  • Full Overscan
  • Put pixel très rapide
  • Afficher une image
  • Slide show 1
  • Bézier
  • faire un fichier pour Bézier

  • Quelque fonctions utile

  • Animation
  • 3D
  • Raster
  • Manche a balais

    Le plan du Site

  •  
      Ici les nouvelle du site  
     
    Recherche ?
    Saissisez un mot clé

     
      Quelques chiffres
    Visiteurs:11260
    Visiteurs aujourd'hui:15
     
     
    Me contacter
    Donnez votre avis
     
    Le site de Steph : Le CPC

    3D temps IREEL

    Optimisation


    Comme on a vue jusqu'ici, ce qui prend le plus de temps se sont les calcules de projection et surtout de rotation, on vas optimiser un peut cela.
    On débute pas le tableau des Sinus et Cosinus, on vas les passer sur un char (soit un octets) à la place d'un float (4 octets), en plus de gagner de la place en mémoire, on vas y gagner beaucoup en temps de calcule, oui, faire un calcule sur un entier est nettement plus rapide sur un Z80 que sur des flottant.
    Mais comment passer une valeur de sinus qui va de 0 à 1 sur un entier ?
    Tout simplement en multiplient la valeur par 127. Mais il faut aussi quand on vas faire nos calcule diviser pas quelques choses, sinon les valeurs vont être beaucoup trop grande et cela sera incorrecte come calcule.
    On vas donc diviser par 128 ... tien, mais une division par 128 revient aussi à faire un décalage de 8 vers la droite non !!.
    De plus, on ne calcule plus une matrice avant de faire la rotation.

    Changement dans le code...
    Je repars du fichier cubef3.c précédent. On vas déjà modifier la définition des deux pointeurs sur les tableaux pour les sin et cos, cela devient char* TSIN; et char* TCOS; (j'ai changer le nom au passage, comme cela pas de confusion).
    Pour la fonction de rotation, on change tout aussi, vous verrez cela dans le code, le principale c'est le calcule avec les sin et cos qui prennent la forme ( (x) * TCOS[angle] + (y) * TSIN[angle] ) >> 7, on voie bien à la fin le décalage de 7 à droite... j'en profite aussi, comme les calcules sont presque à chaque fois identique par faire 2 defines comme ceci :
    #define ROT_I(a,i,j) (((i)*TCOS[a]+(j)*TSIN[a])>>RSHIFT8)
    #define ROT_J(a,i,j) ((-(i)*TSIN[a]+(j)*TCOS[a])>>RSHIFT8)

    Voici Le code des nouvelles fonctions :

    /* Tableaux precalcules de sinus et cosinus */
    char* TSIN;
    char* TCOS;
    
    #define FLOAT_MULT 127  // non utilisé ici, mais utiliser pour généré les valeurs.
    #define RSHIFT8     7	// décalage de 7 à droite  (10000000)
    
    #define DEG2RAD(a) (((a)*PI)/180.0)
    #define ROT_I(a,i,j) (((i)*TCOS[a]+(j)*TSIN[a])>>RSHIFT8)
    #define ROT_J(a,i,j) ((-(i)*TSIN[a]+(j)*TCOS[a])>>RSHIFT8)
    
    
    void Rotation(int Xa, int Ya, int Za)
    {
      int i,a,b;
      int x;
    
       for(i = 0; i < Nb_points; i++)
       {
          /*   rotation X */
          a = Sommet[i].y;
          b = Sommet[i].z;
          Point3D[i].x = Sommet[i].x;
          Point3D[i].y = ROT_I(Xa,a,b);
          Point3D[i].z = ROT_J(Xa,a,b);
    
          /*  rotation Y */
          a = Point3D[i].x;
          b = Point3D[i].z;
          Point3D[i].z = ROT_J(Ya,a,b);
    	  Point3D[i].x = ROT_I(Ya,a,b);
    
          /*  rotation Z */
          a = Point3D[i].x;
          b = Point3D[i].y;
          Point3D[i].y = ROT_J(Za,a,b);
    	  Point3D[i].x = ROT_I(Za,a,b);
       }
    }
    

    Vous trouverez dans le ZIP le fichier GenSC.c qui permet de générer le fichier SINCOSB.DAT qui contient les valeurs des sinus et cosinus utilisé dans le programme cubef4.c.

    Voyons maintenant ce que cela donne l'anim de gauche est le code avant optimisation, à droite le code optimisé :

      
    L'animation est fidèle en temps vis à vis d'un CPC


    Donc, comment dire, y'a pas photo quoi !!

    Je vais continuer mais la ce n'est pas vraiment de l'optimisation, je vais regrouper toutes les données du cube dans une structure, c'est plus une préparation pour la suite...
    On va donc créer une structure obj3D, celle ci vas contenir les valeurs des points initiaux qui se trouvais avant dans Sommet, les points pour les calcule qui se trouvait dans Point3D et les points pour l'affichage 2D qui se trouvaient dans Point2D.
    Bien sur je change aussi les fonctions pour y passer un pointeur sur la structure.
    Remarque, la structure est représenté par un pointeur, celui-ci est initialiser à la suite des tableaux de sinus et cosinus, avec plusieurs objets, il faut faire attention à sa mémoire...
    Au passage dans la structure point2D, on met x en unsigned int et y en unsigned char (la on vas gagner 8 octets).
    On change aussi dans la structure point3D le long pas int, mais la il faut changer aussi la valeurs de chaque point du cube, on les passe de la valeur 100 à la valeur 50, il faut aussi modifier la valeur de Zoff en le passent à 300 (sinon le cube est plus petit...).
    On vas aussi modifier la fonction FilDeFer, au lieux d'appeler la fonction ligne qui appel la fonction lineBresenham on appel directement la fonction lineBresenham dans la fonction FilDeFer, ce qui vas nous évité de faire 12 appel à une fonction, donc en asm 12 CALL (en plus du passage des paramètres à chaque fois), soit cela ne vas pas nous faire gagner beaucoup de temps mais quand même !
    Vous trouverez tout ces changement dans le fichier cubef5.c dans le fichier ZIP qui suit.

    Voila, comme d'hab, le tout se trouve dans se ZIP, une 3D qui est un peut plus rapide :-)

    Nous pouvons passer à la suite ... les faces pleines...