Mes contributions pour CPC / Amiga

Mes contributions pour l'Amstrad CPC et accessoirement l'Amiga
 
AccueilAccueil  PortailPortail  FAQFAQ  RechercherRechercher  S'enregistrerS'enregistrer  MembresMembres  GroupesGroupes  Connexion  

Partagez | 
 

 La 3D en faces pleines sur CPC

Voir le sujet précédent Voir le sujet suivant Aller en bas 
AuteurMessage
Demoniak
Rang: Administrateur


Nombre de messages : 158
Age : 47
Localisation : Dunkerque (Nord)
Date d'inscription : 21/07/2005

MessageSujet: La 3D en faces pleines sur CPC   Dim 9 Jan - 21:03

J'ai eu envie d'ouvrir ce sujet parce que ça me plairai bien d'animer des objets en 3D face pleine sur CPC.
Je vais donc ici vous faire part de mes réflexions sur le sujet...

En fait la majorité des logiciels de 3D utilisent des objets définis sous la forme de "triangles".
Par exemple, un cube, composé de 6 faces carrées, peut être représenté par 12 triangles (2 triangles par faces).
Il en va ainsi pour n'importe quel objet.
Evidemment, si l'on veut des objets 'fin", on définira beaucoup plus de triangles et plus petits.

Donc l'idée m'est venue de créer une routine de tracé de triangles sur CPC. Cela permettrai ensuite de représenter (en théorie) n'importe quel objet 3D sur CPC.

J'ai donc fait quelques recherches sur le net pour trouver un algorithme de tracé de triangles rapide, pour pouvoir ensuite l'adapter au CPC.
Celui que j'ai retenu est le suivant :
On peut décomposer chaque triangle en 2 triangles, le premier ayant une base horizontale, le second ayant un côté horizontal (le suivant du premier). En fait, c'est comme si l'on "coupait" le triangle avec une ligne horizontale passant par l'un de ses sommets.
Pour cela, il faut tout d'abord "trier" les coordonnées des 3 points du triangle suivant leur ordonnées (Y)
En supposant que l'on nome les coordonnées du triangle (X1,Y1), (X2,Y2), (X3,Y3), on "coupera" donc le triangle avec une droite horizontale passant par Y2.
Ensuite, c'est assez simple. Nous avons donc deux triangles avec un côté horizontal.
Il suffit de remplir ces deux triangles avec des lignes horizontales pour obtenir le résultat voulu.

Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://cpc-pja.forumactif.com
Demoniak
Rang: Administrateur


Nombre de messages : 158
Age : 47
Localisation : Dunkerque (Nord)
Date d'inscription : 21/07/2005

MessageSujet: Re: La 3D en faces pleines sur CPC   Lun 17 Jan - 20:10

L'algorithme de remplissage de triangles

Voici l'algorithme en language C. C'est ce que je préfère, ça permet une traduction vers tous les autres langages je trouve.
Pour fonctionner, il est nécessaire que les couples de coordonnées soient triées du y le plus petit au y le plus grand.

Code:
void FillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color) {
   int dx1 = x3 - x1;
   int dy1 = y3 - y1;
   int sgn1 = Sign(dx1);
   dx1 = Abs(dx1);
   int err1 = 0;
   int dx2 = x2 - x1;
   int dy2 = y2 - y1;
   int sgn2 = Sign(dx2);
   dx2 = Abs(dx2);
   int err2 = 0;
   int xl = x1;
   int xr = x1;
   if (y1 == y2)
      xr = x2;

   for (int y = y1; y < y3; y++) {
      DrawLine(xl, y, xr, y, color);
      err1 += dx1;
      while (err1 > dy1) {
         xl += sgn1;
         err1 -= dy1;
      }
      if (y == y2) { // On passe au tracé du second "demi-triangle"
         dx2 = x3 - x2;
         dy2 = y3 - y2;
         sgn2 = Sign(dx2);
         dx2 = Abs(dx2);
         err2 = 0;
      }
      err2 += dx2;
      while (err2 > dy2) {
         xr += sgn2;
         err2 -= dy2;
      }
   }
}

Nous verrons plus tard qu'il est facilement transciptable en assembleur Z80.

Avec cet algorithme, on peut maintenant tracer des triangles remplis avec une couleur déterminée.
Pour pouvoir tracer des objets un peu plus complexe, il suffira de tracer tous les triangles définissant ces objets.

Ensuite, seconde partie: animer un objet.
Pour cela, j'ai ajouté une option à Make3DFrame qui me permet de générer une suite de coordonnées de triangles,
pour définir un objet, et ce pour chaque image (que je nomerai "frame" par la suite).

Ensuite s'est posé un problème:
pour animer un objet, il faut donc créer une suite d'images définissant la position et/ou la forme de cet objet.
Ce pour quoi Make3DFrame est prévu, jusque là pas de problème.
Mais côté CPC, il faudra ensuite:
- Afficher la frame 0,
- Effacer la frame 0,
- Afficher la frame 1,
- Effacer la frame 1,
- Afficher la frame 2,
- Effacer la frame 2...
Et ainsi de suite jusqu'à la dernière frame, puis reboucler sur la première.
Dans l'idéal, On pourrait dire que l'algorithme d'animation est le suivant:
- Effacer frame n-1
- Afficher frame n
- Incrémenter n
- Si n > dernière frame, alors n=0 (pour rebouclage)
Ce qui nous fait en gros une boucle.
Sur CPC, on ajouterai même un "wait vbl" au début de la boucle, pour synchroniser notre animation avec le balayage écran.
Oui mais voilà, si la routine d'effacement + d'affichage dépasse le temps d'affichage d'une image (environ 20 milli secondes sur CPC),
on obtient un clignottement très désagréable...
La routine de tracé de triangle est rapide, mais malheureusement pas assez pour permettre ce genre de chose.
Il a donc fallu utiliser une "astuce" : le double buffering.
Cette technique consiste en gros à utiliser 2 pages écran, à dessiner dans une page pendant que l'autre est affichée, puis faire un "échange" de
la page affichée.
Ceci fonctionne très bien sur CPC, grace au CRTC, qui permet de définir justement l'adresse de la page écran (qui par défaut est en #C000).
Ensuite, plutôt que d'effacer "bêtement" tout l'écran, il suffit d'effacer que ce qui a été dessiné.
Pour cela j'ai donc utilisé au début la même routine de tracé de triangles, simplement en lui passant en paramètre une couleur égale à zéro.
Ceci semble logique, vu que je connais les coordonnées des triangles à effacer (ils sont dans la liste).
Mais la routine de tracé de triangles utilise pas mal le processeur, et je me suis dit qu'il serait plus rapide d'effacer un "rectangle"
dans lequel serait contenus tous les triangles affichés.
Facile également, vu que l'on connait les coordonnées de tous les triangles de la "frame".
Il n'y a qu'à déterminer les bornes xmin, ymin et xmax, ymax de la frame en parcourant les coordonnées de tous les triangles.
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://cpc-pja.forumactif.com
Demoniak
Rang: Administrateur


Nombre de messages : 158
Age : 47
Localisation : Dunkerque (Nord)
Date d'inscription : 21/07/2005

MessageSujet: Re: La 3D en faces pleines sur CPC   Mer 19 Jan - 21:04

L'algorithme de tracé de lignes horizontales

L'algorithme précédent se résumait à quelques instruction arithmétiques simples (additions, soustractions, comparaisons), mais utilisait la fonction DrawLine(x1,y1,x2,y2,color).

Cette fonction doit nous permettre de tracer une ligne verticale d'ordonnée Y1 (Y2=Y1) depuis l'abscisse X1 jusqu'à l'abscisse X2.

J'ai choisi de travailler en mode 1, car c'est le mode qui nous donnes des pixels plus ou moins "carrés".
A priori tracer une ligne horizontale en mode 1 en assembleur peut sembler facile, mais on doit quand même se poser quelques questions :
1) Déterminer l'adresse de début de la mémoire vidéo
Ceci peut se faire facilement, à l'aide de la formule suivante :
adresse écran = (X>>2)+(Y>>3)*NbCols+(Y&7)*#800
avec X l'abscisse de départ, Y l'ordonnée, NbCols le nombre de colonnes caractères (équivalent à la valeur du registre 1 du CRTC multiplié par 2). A cette adresse il faut ajouter biensur l'adresse de base de la mémoire vidéo, qui est #C000 par défaut sur le CPC.

2) Déterminer quel est le pixel de départ
Oui, car en faisant X>>2 (ou X/4), on obtient une adresse écran, mais un octet en mode 1 peut contenir 4 pixels. Notre pixel de départ correspond en fait au reste de la division entière de X/4.

3) Déterminer quel est le pixel de fin
Pareil que pour le pixel de départ, on doit savoir quand on s'arrète.

4) Choisir en fonction de la couleur les valeurs à écrire en mémoire écran
Evidemment, tracer une ligne avec le stylo 1 sera différent de tracer une ligne avec le stylo 2 ou 3.

Prenons un exemple concret:
Si je veux exécuter la fonction suivante : DrawLine( 2, 100, 10, 100, 1 )

1) Je calcule l'adresse de départ.
adresse écran = (X>>2)+(Y>>3)*NbCols+(Y&7)*#800
= (2>>2)+(100>>3)*80+(100&7)*#800
= 0 + 12*80 + 4*#800
= 9152, ou #23C0 en hexa.
Soit #23C0+#C000 = #E3C0 sur le cpc.
2) Je détermine le pixel de départ
X MOD 4 = 2 MOD 4 = 2. Le pixel de départ sera le numéro 2 (en numérotant les pixels de 0 à 3).

3) Je détermine le pixel d'arrivée
Là c'est un peu plus complexe. Je dois tracer au total 10-2 (X2-X1) soit 8 pixels.
Je commence au pixel numéro 2 sur le premier octet. Je vais donc dessiner 2 pixels (le 2 et le 3) sur le premier octet.
Octet suivant, pas de soucis, je remplis les 4 pixels.
Octet suivant, j'ai déjà tracé 6 pixels, il m'en reste donc 2.

4) Choix des octets à écrire en fonction de la couleur déterminée.
Je ne ferai pas ici un cours sur l'organisation de la mémoire vidéo du CPC en mode 1, mais un petit rappel:
4 pixels en stylo 1 = #F0 (octet de mémoire vidéo)
4 pixels en stylo 2 = #0F (octet de mémoire vidéo)
4 pixels en stylo 3 = #FF (octet de mémoire video)
Pas facile donc de faire une fonction "universelle" de tracé de lignes en mode 1.
Sauf en utilisant une "table" de couleurs.
En gros, une table indexée par le numéro de stylo, qui contiendrai les octets à écrire en mémoire vidéo.

Voilà le principe général de cette fonction de tracé de lignes horizontales.
Pour des questions de rapidité, plutôt que de calculer l'adresse mémoire écran, j'ai préféré passer par une table précalculée.
Ceci à quand même l'inconvénient d'utiliser 400 octets (200 mots de 16 bits).
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://cpc-pja.forumactif.com
mac_gyve
Invité



MessageSujet: pfiou la la   Mar 22 Mar - 16:01

salut demo

encore un super projet

moi je me rappelle avoir fait en Basic un cube en 3D avec un A en filligramme sur une des face

que tu pouvais deformer,faire tourner,deplacer

bon c'etait du filaire (pas de face pleine)

mais plutot que de charger des images les unes la suite de autres

je tracais des lignes en les ayant auparavant calculer en coordonnée polaire

ce qui me permettait des les animer en ayant defini des touches clavier pour la rotation,le deplacement,l'angle de vue etc...

un espece d'axe (X,Y,Z) servant d'origine

Revenir en haut Aller en bas
Demoniak
Rang: Administrateur


Nombre de messages : 158
Age : 47
Localisation : Dunkerque (Nord)
Date d'inscription : 21/07/2005

MessageSujet: Re: La 3D en faces pleines sur CPC   Mar 22 Mar - 16:03

Hello Mac !

Oui, en basic on peut faire aussi des trucs sympas.
Si tu as encore les sources de ton programme, ça m'intéresse, je pourrais l'adapter en assembleur Bad)
Revenir en haut Aller en bas
Voir le profil de l'utilisateur http://cpc-pja.forumactif.com
mac_gyver
Nouveau


Nombre de messages : 1
Date d'inscription : 16/02/2006

MessageSujet: Re: La 3D en faces pleines sur CPC   Mer 23 Mar - 11:43

je t'ai envoyé un mp privé avec le lien du dsk
Revenir en haut Aller en bas
Voir le profil de l'utilisateur
Contenu sponsorisé




MessageSujet: Re: La 3D en faces pleines sur CPC   

Revenir en haut Aller en bas
 
La 3D en faces pleines sur CPC
Voir le sujet précédent Voir le sujet suivant Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Les bonnes offres du dé à 3 faces
» [2200pts] Les Faces Bleues
» [28] - Bailleau-le-Pin - Les 20 faces du jeu
» niveau tout en 3D oui en 3D
» Château de Gilles de Rais et machines de guerre en photos !

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Mes contributions pour CPC / Amiga :: Le forum-
Sauter vers: