Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
730 connectés 

  FORUM HardWare.fr
  Graphisme

  Programassion Grafik : kréassion d'1 moteur 3D...

 


 Mot :   Pseudo :  
 
 Page :   1  2  3
Page Précédente
Auteur Sujet :

Programassion Grafik : kréassion d'1 moteur 3D...

n°206
Dav Vador
Posté le 19-09-2001 à 18:37:35  profilanswer
 

Salut à tous,  
je rentre du boulo et oh miracle le forum Grafizm!
Depui le tps kon l'attendai, sa fai super plézir!
Merci donc à tou ceux qui nou zon soutenu et qui on fai en sorte keu ce forum voi le jour!
 
  Je présenterai sou peu dans ce topic les sources et explications sur la création d'un moteur 3D entièrement en software... :sol:

 

[edtdd]--Message édité par Dav Vador--[/edtdd]

mood
Publicité
Posté le 19-09-2001 à 18:37:35  profilanswer
 

n°337
Dav Vador
Posté le 19-09-2001 à 21:40:57  profilanswer
 

En attendant la mise en place de ce topic,
j'aimerais avoir votre avis sur mon petit moteur 3D.
Voilà les liens :
 
"Pour Dos (320x200) totalement en software :"
(faire 22 au menu et me donner les tps svp)
 
"Pour Win (640x480) accéléré 2D avec DirectDraw :"
(me donner les fps avec fraps svp)
 
"Pour Win (démo 320x240) accéléré 2D avec DirectDraw :"
(me donner les fps avec fraps svp)
 
"La liste des commandes"
 
"Fraps (v1.4)"
 
 
Merci d'avance. :jap:

n°891
Dav Vador
Posté le 20-09-2001 à 21:27:13  profilanswer
 
n°1374
Dav Vador
Posté le 21-09-2001 à 22:21:32  profilanswer
 

Le premier Tutorial :
 
I) La théorie :
 
  Tout d'abord il faut décomposer l'objet 3D en polygones. On utilisera pour cela des triangles car c'est la seule figure avec laquelle on peut modéliser n'importe quel volume.  
 
  De plus , la projection de 3 points de l'espace sur un plan donne aussi 3 points . Un triangle en 3D nous donnera donc un triangle en 2D.  
 
 
 
1) Les repères utilisés :  
 
  On utilisera 3 repères (orthonormés) différents pour les coordonnées de chacun des sommets des objets :  
- R qui est le repère réel à 3 dimension de centre O (0,0,0). On supposera connaître toutes les coordonnées dans ce repère.  
- R' qui est le repère à 3 dimension associé à la caméra de centre C (cx, cy, cz) et défini par 3 vecteurs (vx, vy, vz).  
- E qui est le repère écran à 2 dimensions de centre le coin supérieur gauche de l'écran.  
  En fait, le repère R' n'est pas nécessaire mais il nous simplifiera un peu les calculs.  
   
 
2) Projection d'un sommet sur l'écran : Passage du repère R à 3 dimension au repère E à 2 dimension :  
  En fait, il faut imaginer l'écran comme étant la fenêtre à travers laquelle on regarde le monde que l'on a modélisé.
 
  A chaque affichage, on calcule les coordonnées de chaque sommet de chaque polygone dans le repère R' afin de simplifier les calculs ultérieurs.  
 
 
http://www.multimania.com/davvador2416/cpp/images/schema_01.gif
 
 
 
 
  On pose d la distance (arbitraire) à laquelle est placé l'écran.
 
  On commence par calculer l'équation dans le repère R' de la droite (D) qui passe par C (le centre de la caméra) et A (un des sommets de l'objet).
 
  -> Son équation est donc Z = Z'/X' * X  
 
  Or la coordonnée Xe (projeté de A sur l'écran) est donnée par l'intersection de (D) et (D';).  
On a donc Z = Z'/X' * X = d  <=> X = X'/Z' * d         où d est une constante.  
 
 
  On obtient donc les formules suivantes :  
 
    - Xe = Xr'/Zr' * d  
    - Ye = Yr'/Zr' * d'     (de la même façon).  
   On a donc des coordonnées qui rétrécissent lorsque l'objet s'éloigne. C'est donc une projection perspective, et c'est la projection la plus réaliste possible.
 
 
 
  Voilà, avec ces 2 petites formules, on peut déjà afficher n'importe quel objet en mode sommets ou arrêtes (en reliant simplement les sommets entre eux).
 
 
 
3) Notre premier moteur 3D : affichage des sommets ou des arrêtes
 
http://www.multimania.com/davvador2416/cpp/images/voiture1hi.jpg
 
Dans ce premier exemple, nous allons afficher un cube.
Ce cube sera décomposé en 12 polygones (6 faces composées de 2 triangles) formés à partir des 8 sommets suivants :
s0 (50,50,100)
s1 (50,90,100)
s2 (90,90,100)
s3 (90,50,100)
s4 (50,50,140)
s5 (50,90,140)
s6 (90,90,140)
s7 (90,50,140)
 
Les sommets seront représentés par le tableau sommets[8] de point_3DD.
Où point_3DD est défini par :
typedef struct
{
   // Coordonnées réelles (repère R)
 
   float xr;
   float yr;
   float zr;
 
   // Coordonnées de la vue (repère R';)
 
   float xv;
   float yv;
   float zv;
 
   // Coordonnées à l'écran (repère E)
 
   int xe;
   int ye;
} point_3DD;
 
Les 12 polygones seront formés des sommets suivants :
p0 (0,1,2)
p1 (0,2,3)
p2 (0,1,5)
p3 (0,4,5)
p4 (1,2,5)
p5 (2,5,6)
p6 (2,3,6)
p7 (3,6,7)
p8 (4,5,6)
p9 (4,6,7)
p10 (0,3,4)
p11 (3,4,7)
 
Les polygones seront représentés par la matrice polys[12][3] d'entiers correspondant aux indices des sommets.
 
La couleur du cube sera représentée par le unsigned char (entier de 0 à 255) couleur et sera rose.
 
Le cube sera le type regroupant tous ces éléments et sera défini de cette façon :
typedef struct
{
   point_3DD sommets[8];
   unsigned int nb_sommets;
   unsigned int polys[12][3];
   unsigned int nb_polys;
   unsigned char couleur;
} cube;
 
 
La camera sera placée à la position (70,70,0) et sera représenté par le point_3D camera.
Où point_3D est défini par :
typedef struct
{
   // Coordonnées réelles (repère R)
 
   float xr;
   float yr;
   float zr;
} point_3D;
 
 
Notre programme principal sera le suivant:
 
initialisation
tant que non fin faire
{
   calculer les coordonnées du cube dans R'
   calculer les coordonnées du cube dans E
   si (affichage==sommet) afficher tous les sommets
   sinon afficher toutes les arrêtes
 
   si "Echap" a été pressé alors fin=vrai
   si "4", "6", "2" ou "8" alors rotation du cube
   si "." alors affichage sommets
   si "/" alors affichage arrêtes
}
 
 
Calcul des coordonnées du cube dans R':
void calcul_r_prime(cube *mon_cube,const point_3D &camera)
{
   Pour chaque sommet du cube
   {
      // On aclcul les coordonnées dans le repère caméra
 
      xv=xr-camera.xr;
      yv=yr-camera.yr;
      zv=zr-camera.zr;
   }
}
 
Calcul des coordonnées du cube dans E:
void calcul_e(cube *mon_cube)
{
   Pour chaque sommet du cube
   {
      // On a un écran au format 4/3 or la résolution  
      // est au format 8/5 (320*200)
      // Pour avoir une résolution au format 4/3,  
      // il nous faut du 320*240 au lieu du 320*200 utilisé
 
      // De plus, on veut que le point de coordonnée (0,0)  
      // soit au mileu de l'écran au lieu d'en haut à gauche
 
      // On utilise la formule donnée en 2)  
      // avec d=240 et d'=200 pour avoir le format 4/3
 
      xe=(240*xv/zv) + maxx/2;     // où maxx=résolution en x
      ye=maxy/2 - (200*yv/zv);     // et maxy=résolution en y
   }
}
 
Affichage de tous les sommets:
Il suffit d'afficher les pixels correspondant à chaque (xe,ye) du cube.
 
Affichage de toutes les arrêtes:
Il suffit de tracer les arrêtes (lignes) de chaque polygone en reliant simplement les sommets.
 
 
4) Les sources :
 
"3d_1.cpp"
"3d_1.h"
"graphique.cpp"
"graphique.h"
"infos_compilation.h (utilisé par graphique.h)"
"main.cpp"
 
 
 
"La feuille de projet pour Borland C++"
 
"L'exécutable"

 

[edtdd]--Message édité par dav vador--[/edtdd]

n°1375
KromaXamor​K
Kesse tu veux???
Posté le 21-09-2001 à 22:29:26  profilanswer
 

y a pas a dire mais les lignes de commandes comme ca c'est rude


---------------
[:pop%20satory]Close the Net, Open the World...
n°1383
Dav Vador
Posté le 21-09-2001 à 22:50:24  profilanswer
 

KromaXamorK a écrit a écrit :

y a pas a dire mais les lignes de commandes comme ca c'est rude  



Ok, je vais essayer d'améliorer un peu...
Merci de me l'avoir signaler  :jap:

n°1385
KromaXamor​K
Kesse tu veux???
Posté le 21-09-2001 à 22:53:55  profilanswer
 

Dav Vador a écrit a écrit :

Ok, je vais essayer d'améliorer un peu...
Merci de me l'avoir signaler  :jap:  



non non c'etait juste ne remarque en l'air c'est parce que j'aime pas ca :D


---------------
[:pop%20satory]Close the Net, Open the World...
n°1390
Dav Vador
Posté le 21-09-2001 à 23:05:56  profilanswer
 

KromaXamorK a écrit a écrit :

non non c'etait juste ne remarque en l'air c'est parce que j'aime pas ca :D  



C pa grave, G essayé darranG un peu kan même.

n°1416
parappa
taliblanc
Posté le 22-09-2001 à 00:02:58  profilanswer
 

J'ai beaucoup de mal à me représenter un dessin à partir de lignes de code.

n°1421
Dav Vador
Posté le 22-09-2001 à 00:19:01  profilanswer
 

parappa a écrit a écrit :

J'ai beaucoup de mal à me représenter un dessin à partir de lignes de code.  



Je voi po ce keu tu veu dire...  :sarcastic:

mood
Publicité
Posté le 22-09-2001 à 00:19:01  profilanswer
 

n°1425
parappa
taliblanc
Posté le 22-09-2001 à 00:25:48  profilanswer
 

Dav Vador a écrit a écrit :

Je voi po ce keu tu veu dire...  :sarcastic:  




 
Bah si je comprend bien - je peux me tromper hein, je suis pas certain de bien suivre -, ton moteur 3D te permet de dessiner des formes grâce à des fonctions que tu définis (c'est le principe non ?).  
 
Ce que je voulais dire, c'est que j'ai du mal à assimiler ce genre de travail. Pour moi un cube se dessine, il ne "s'écrit" pas.
 
J'ai pas l'impression d'être très clair, ce doit être l'heure...

n°1433
Dav Vador
Posté le 22-09-2001 à 00:41:09  profilanswer
 

"Bah si je comprend bien - je peux me tromper hein, je suis pas certain de bien suivre -, ton moteur 3D te permet de dessiner des formes grâce à des fonctions que tu définis (c'est le principe non ?)."
 
Il permet de les afficher, il ne les dessine pa.
En fait, tu "dessine" (créer serai + aproprié) tes objet dans un modeleur genre 3DS Max, Maya,... (ou tu rentres toi même les coordonnées des sommets ds un fichier) et le moteur ne fai keu les afficher. Il ne cré rien du tou, si ce n'est l'image.
Le moteur te permet simplement de passer de 3D à 2D, C tou.

n°1437
parappa
taliblanc
Posté le 22-09-2001 à 00:52:44  profilanswer
 

Dav Vador a écrit a écrit :

 
Il permet de les afficher, il ne les dessine pa.
En fait, tu "dessine" (créer serai + aproprié) tes objet dans un modeleur genre 3DS Max, Maya,... (ou tu rentres toi même les coordonnées des sommets ds un fichier) et le moteur ne fai keu les afficher. Il ne cré rien du tou, si ce n'est l'image.
Le moteur te permet simplement de passer de 3D à 2D, C tou.  




 
Ok.

n°3989
Dav Vador
Posté le 05-10-2001 à 10:03:55  profilanswer
 

Tutorial n°2 :
 
II) Affichage d'un objet en face pleines :  
 
Là c'est une autre histoire.  
  En fait, pour remplir les faces en affichant seulement celles qui sont visibles, on utilisera la technique du Z Buffer.  
 
  C'est un tampon des coordonnées Zr' de chaque point de l'objet affiché à l'écran.  
  Il sera donc représenté par une matrice de la taille de l'écran et sera initialisé avec la plus grande valeur de Zr' possible.  
   
  On affichera tous les triangles un par un, et pour chaque pixel qui devra être affiché, on regardera le Zr' de ce point :  
- s'il est inférieur au Zr' du Z_buffer on affiche le pixel à l'écran et on stocke le Zr' du point dans le Z_buffer.  
- s'il est supérieur , on ne fait rien.  
  C'est une technique très simple, rapide mais qui hélas demande pas mal de mémoire (fonction de la résolution d'affichage et de la précision de Zr';).
 
  Cette technique a en plus l'avantage de traiter en même temps les collisions entre les polygones (C'est ti pas bien tout ça!).  
 
 
http://www.multimania.com/davvador2416/cpp/images/voiture%207hi.jpg
 
 
 
 
1) Remplissage d'un polygone :
 
  Le seul problème est qu'il nous faut trouver les coordonnées Xe, Ye et Zr' de chaque point de chaque polygone à afficher, connaissant seulement ces 3 coordonnées dans le repère R' pour chacun des 3 sommets du polygone.
 
 
 
http://www.multimania.com/davvador2416/cpp/images/schema_02.gif
 
 
 
  Le remplissage se fera ligne par ligne ( horizontale ) en partant de A jusqu'à B puis de la même manière de B jusqu'à C .
 
On aura donc à chaque étape du remplissage ly = my qui s'incrémentera de 1 à chaque fois.  
 
  Pour trouver les coordonnés de P, on procèdera par interpolation.  
On commencera par calculer les coordonnées de L et M par interpolation aussi.  
  A l'aide des coordonnées de A et de C, on calculera l'équation de la droite (AC)  
- sous la forme Y = aX + b  
- et sous la forme Y = aZ + b.  
  Connaissant ly et my, on trouvera donc lx et mx grace à la première équation et lz et mz grace à la seconde.
 
  Il ne nous reste plus qu'à trouver les coordonnées de P.  
 
  On sait déjà que py = ly = my puisqu'il s'agit d'une ligne horizontale.  
On connaît les coordonnées de L et de M, on peut donc calculer l'équation de la droite (LM) sous la forme Z = aX+b.  
  On connaîtra X qui commencera à lx au début du tracé de la ligne et sera incrémenté de 1 à chaque fois jusqu'à mx.  
  On trouvera donc sans problème la coordonnée pz de P.  
   
  Maintenant que nous avons les 3 coordonnées de P, il ne nous reste plus qu'à regarder dans le  
 Z Buffer si le point doit être affiché ou non.  
 
 
 
http://www.multimania.com/davvador2416/cpp/images/voiture%204hi.jpg
 
 
Voilà à quoi devrait ressembler notre fonction d'affichagage de polygone :
 
void afficher_polygone()
{
 /* On remplit le polygone ( ligne par ligne ) */
 
 
 // Initialisation des variables temporaires
 
 xa=sommet_0_du_polygone.xe;
 ya=sommet_0_du_polygone.ye;
 za=sommet_0_du_polygone.ze;
 
 xb=sommet_1_du_polygone.xe;
 yb=sommet_1_du_polygone.ye;
 zb=sommet_1_du_polygone.ze;
 
 xc=sommet_2_du_polygone.xe;
 yc=sommet_2_du_polygone.ye;
 zc=sommet_2_du_polygone.ze;
 
 
    // Tri des 3 sommets de haut en bas
 
 si (ya>yb) échanger xa,ya,za avec xb,yb,zb
 si (ya>yc)) échanger xa,ya,za avec xc,yc,zc
 si (yb>yc)) échanger xb,yb,zb avec xc,yc,zc
 
 
 // Calcul des équations des 3 arrêtes du polygone
 
 si (ya différent de yb)
 {
  x_pente_ab=(xb-xa)/(yb-ya);  /* Détermination de la droite (ab) : x=ay+b */
  z_pente_ab=(zb-za)/(yb-ya);  /* Détermination de la droite (ab) : z=ay+b */
 }
 si (yb différent de yc)
 {
  x_pente_bc=(xc-xb)/(yc-yb);  /* Détermination de la droite (bc) : x=ay+b */
  z_pente_bc=(zc-zb)/(yc-yb);  /* Détermination de la droite (bc) : z=ay+b */
 }
 si (ya différent de yc)
 {
  x_pente_ac=(xc-xa)/(yc-ya);  /* Détermination de la droite (ac) : x=ay+b */
  z_pente_ac=(zc-za)/(yc-ya);  /* Détermination de la droite (ac) : z=ay+b */
 }
 
 xd=xa;
 xf=xa;
 zd=za;
 zf=za;
 
 
 // Première partie de l'affichage
 
 Pour chaque ligne de coordonnée yi de ya à yb-1
 {
  afficher_ligne(couleur,xd,xf,zd,zf,yi);
 
  xd+=x_pente_ab;
  xf+=x_pente_ac;
  zd+=z_pente_ab;
  zf+=z_pente_ac;
 }
 afficher_ligne(couleur,xb,xf,zb,zf,yb);  /* Ligne de yb */
 
 xd=xb+x_pente_bc;
 xf+=x_pente_ac;
 zd=zb+z_pente_bc;
 zf+=z_pente_ac;
 
 
 // Deuxième partie de l'affichage
 
 Pour chaque ligne de coordonnée yi de yb+1 à yc
 {
  afficher_ligne(couleur,xd,xf,zd,zf,yi);
 
  xd+=x_pente_bc;
  xf+=x_pente_ac;
  zd+=z_pente_bc;
  zf+=z_pente_ac;
 }
}
 
 
2) Et maintenant la fonction d'affichage de la ligne avec l'algorithme de Bresenham :
 
void afficher_ligne(couleur, x1, x2, z1, z2, y)
{  
 /* Trace une ligne horizontale en testant le z_buffer par l'algorithme de Bresenham */
 
 x=x1
 z=z1
 
 
 // Affichage du premier point de la ligne
 
 // Test du z_buffer + clipping en x et en y
 si ((z_buffer[x1][y]>z) & (x1>-1) & (x1<maxx) & (y>-1) & (y<maxy) & (z>0))  
 {
  afficher_pixel(couleur,x1,y)
  z_buffer[x1][y]=z1
 }
   
 
 // Affichage du dernier point de la ligne
 
 // Test du z_buffer + clipping en x et en y
 si ((z_buffer[x2][y]>z) & (x2>-1) & (x2<maxx) & (y>-1) & (y<maxy) & (z>0))  
 {
  afficher_pixel(couleur,x2,y)
  z_buffer[x2][y]=z2;
 }
 
 
    // Algorithme de Bresenham pour le tracé de la ligne
 
 dx=abs(x2-x1);
 dz=fabs(z2-z1);
 s1=signe(x1,x2);
 s2=signe(z1,z2);
 
 si (dz>dx)
 {
  tmp=dx;
  dx=dz;
     dz=tmp;
     ech=1;
 }
 else ech=0;
 
 v=2*dz-dx;
 
 Pour i de 1 à dx
 {
     Tant que (v>=0)
     {
      if(ech) x=x+s1;
      else z=z+s2;
      v=v-2*dx;
  }
 
     si (ech) z=z+s2;
     sinon x=x+s1;
 
     v=v+2*(int)dz;
 
  // Test du z_buffer + clipping en x et en y
  si ((z_buffer[x][y]>z) & (x>-1) & (x<maxx) & (y>-1) & (y<maxy) & (z>0))  
  {
 
   afficher_pixel(couleur,x,y)
         z_buffer[x][y]=z;
     }
 }
}
 
 
3) Les structures de données :
 
Quelques petites modifications mineures...
 
Ajout d'un type polygone :
typedef struct
{
 unsigned short int num_sommet[3];  // Indices des 3 sommets du polygone
 unsigned char couleur;     // Couleur du polygone
} polygone;
 
Et modification du type cube qui devient objet_3D :
typedef struct
{
   unsigned int   nb_sommets; // Nombre des sommets
   point_3DD   sommets[8]; // Tableau des sommets
   unsigned int   nb_polys;  // Nombre de polygones
   polygone   polys[12];  // Tableau des polygones
} objet_3D;
 
 
4) Les sources :
 
"3d_2.cpp"
"3d_2.h"
"graphique.cpp"
"graphique.h"
"infos_compilation.h (utilisé par graphique.h)"
"main.cpp"
 
 
"La feuille de projet pour Borland C++"
 
"L'exécutable"
 
 
 
Pour les explications sur l'algorithme de Bresenham, j'essaie de faire au plus vite...
 
Prochaine étape : Rotations et translations des objets et de la caméra sans utiliser de matrices (pour ceux qui n'aiment pas ces bêtes là)...

 

[edtdd]--Message édité par dav vador--[/edtdd]

n°4502
Dav Vador
Posté le 09-10-2001 à 12:48:05  profilanswer
 

Tutorial n°0 : MAJ du 15/10/2001
 
ZERO) Initialisation et utilisation du mode graphique sous Dos et sous Direct Draw :  
 
On m'a demandé récemment comment cela marchait, alors voici quelques explications...
 
 
 
1) Sous Dos :
Le Dos présente de nombreux modes graphique dont les plus courants sont le 320x200 en 256 couleurs (mode 13h), le 640x480 en 16 couleurs (mode 12h) et le 320x240 en 256 couleurs (aussi appelé mode X car non documenté).
Nous n'étudierons pas le mode X car il est beaucoup plus complexe que les 2 autres. Par contre, il faut savoir qu'il est bien plus rapide et peut même permettre d'atteindre une résolution de 320x480 en 256 couleurs !!!
Le mode 12h ne nous intéressera pas non plus par son manque cruel de couleurs.
Nous allons donc nous concentrer sur le mode 13h...
 
a) Initialisation :
Rien de tel que d'utiliser l'assembleur dans notre code C :
 
asm // Signale au compilateur qu'il s'agit de code Assembleur
{
 mov ax,19 // 19 en décimal (base 10) = 13 en héxadécimal (base 16)
 INT 10h  // Appel de l'interruption 10h
}
 
 
b) Retour au mode texte :
C'est la même chose sauf qu'à la place de mettre 19, on met 3 qui correspond au mode texte.
 
 
c) Les couleurs :
Ce mode fonctionne avec des couleurs dont les caractéristiques sont en fait stoquées dans une palette de 256 couleurs.
Pour insérer une couleur dans la palette, il nous faudra donner ses 3 composantes (RVB) et la position à laquelle on souhaite la stoquer (0 à 255).
On procédera donc de la façon suivante pour chaque couleur à insérer dans la palette :
 
outp(0x3c8,position); // où position est un unsigned char compris entre 0 et 255
outp(0x3c9,R);  // où R (la composante en rouge) est un unsigned char compris entre 0 et 63  
outp(0x3c9,V);  // où V (la composante en vert) est un unsigned char compris entre 0 et 63
outp(0x3c9,B);  // où B (la composante en bleu) est un unsigned char compris entre 0 et 63
 
 
d) Affichage d'un pixel :
Pour cela, on accedera directement à la mémoire vidéo (située à l'adresse 0xA000).
On utilisera donc un pointeur vers cette dernière initialisé de la façon suivante :
unsigned char far *Video=(unsigned char *)(MK_FP(0xA000,0));
 
Pour afficher un pixel de la couleur c à la position x,y il suffira donc de faire :
*(Video+(y*320)+x)=c;
 
 
e) Double Buffering :
Pour éviter de voir la scène s'afficher petit à petit, on peut utiliser la méthode du double buffering qui consiste en fait à dessiner la scène dans une page temporaire avant de l'afficher à l'écran. Ainsi la scène apparait d'un coup et on ne voit pas les faces éloignées qui sont ensuite recouvertes par des faces plus proches.
Il suffit donc simplement de créer une variable page_tmp de la taille de l'écran :
unsigned char far page_tmp[64000]; // 320*200 = 64000
et d'afficher tous nos pixels dans cette page.
Une fois la scène entièrement dessinée, il ne nous reste plus qu'à copier chaque pixel de page_tmp vers Video. C'est le flipping.
 
 
f) Synchronisation horizontale :
Afin d'éviter des scintillements de l'écran lors de la permutation des pages, on peut attendre un retour de trame horizontale avant de commencer à écrire dans la mémoire vidéo.
Pour cela, avant de permuter (flipper) les pages videos, il faut faire :
asm
{
 mov dx,0x3da;
 hbl:
 in al,dx;
 test al,8;
 jz hbl;
}
 
 
2) La même chose pour Direct Draw :
Avant de commencer, il nous faut 3 variables :
LPDIRECTDRAW7  lpDD;  // Pointeur sur l'objet DirectDraw
LPDIRECTDRAWSURFACE7 Video;  // Pointeur sur la mémoire vidéo (primary surface)
LPDIRECTDRAWSURFACE7 page_tmp; // Pointeur sur la page temporaire (back buffer)
qui seront initialisées à NULL.
 
 
a) Création de l'objet DirectDraw :
 
 
DirectDrawCreateEx(NULL, (VOID**)&lpDD, IID_IDirectDraw7, NULL);
Retourne DD_OK en cas de réussite.
 
 
Passage en mode exclusif en plein écran :
lpDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
Retourne DD_OK en cas de réussite.
 
 
Activation du mode graphique RES_X x RES_Y x N bits :
lpDD->SetDisplayMode(RES_X, RES_Y, N, 0, 0);
Retourne DD_OK en cas de réussite.
 
 
b) Création de la surface primaire avec 1 page temporaire (back buffer) :
Il nous faut 1 variable supplémentaire :
DDSURFACEDESC2  ddsd;  // Description de la surface à créer
 
 
Initialisation de la description de surface :
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;   // Nombre de pages temporaires
 
 
Création de la surface primaire :
lpDD->CreateSurface(&ddsd, &Video, NULL); // Video est le pointeur sur la surface primaire (mémoire vidéo)
Retourne DD_OK en cas de réussite.
 
 
Attacher un pointeur sur la page temporaire :
Il nous faut 1 variable supplémentaire :
DDSCAPS2 ddscaps;   // flags divers
 
ZeroMemory(&ddscaps, sizeof(ddscaps));
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
Video->GetAttachedSurface(&ddscaps, &page_tmp); // page_tmp est le pointeur sur la page temporaire
Retourne DD_OK en cas de réussite.
 
 
c) Les couleurs :
Tant que l'on reste en 8 bits (256 couleurs), on utilisera une palette.
LPDIRECTDRAWPALETTE  lpDDPal = NULL;  // Pointeur sur la palette de 256 couleurs en RVB
PALETTEENTRY   pal[256];   // Palette de couleurs temporaire
 
for (i=0;i<256;i++)  /* Dégradé du noir au cyan */
{
 pal[i].peRed = (BYTE) 0; // Intensité de la composante rouge de 0 à 255
 pal[i].peGreen = (BYTE) i; // Intensité de la composante vert de 0 à 255
 pal[i].peBlue = (BYTE) i; // Intensité de la composante bleu de 0 à 255
 pal[i].peFlags = (BYTE) 0; // Composante alpha (inutilisée ici)
}
lpdd->CreatePalette(DDPCAPS_8BIT, pal, &lpDDPal, NULL);
 
 
d) Affichage d'un pixel :
Pour cela, on accedera directement à la mémoire vidéo.
On utilisera donc un pointeur vers cette dernière.
 
DDSURFACEDESC2   DDSurfaceDesc; // Description de la surface
int    bytes_pixel; // Si 8 bits alors = 1 (octet), 16 bits = 2,....
 
// Initialisation de la description de la surface
ZeroMemory(&DDSurfaceDesc, sizeof(DDSurfaceDesc));
DDSurfaceDesc.dwSize = sizeof(DDSurfaceDesc);
 
// Détermination du nombre d'octets utilisés pour stoquer 1 pixel
switch (DDSurfaceDesc.ddpfPixelFormat.dwRGBBitCount)
{
 case 8: bytes_pixel = 1;
 break;
 case 16: bytes_pixel = 2;
 break;
 case 24: bytes_pixel = 3;
                break;
 case 32: bytes_pixel = 4;
                break;
}
 
// On interdit aux autres application l'accés à la surface  
// et on retourne dans DDSurfaceDesc.lpSurface un pointeur sur la mémoire vidéo où est stoquée la page
page_tmp->Lock(NULL,&DDSurfaceDesc,DDLOCK_WAIT,NULL);
 
// On affiche le (ou les pixels) désiré(s)
if ((x>-1)&&(x<maxx)&&(y>-1)&&(y<maxy)) /* Clipping en x et en y */
 ((unsigned char*)(DDSurfaceDesc.lpSurface)) [y*(DDSurfaceDesc.lPitch) + x*bytes_pixel] = couleur;
 
// On débloque l'accès à la surface
page->Unlock(NULL);
 
 
e) Double Buffering et Synchronisation horizontale :  
Création d'une page temporaire (voir b).
Affichage des pixels dans la page temporaire.
Le flipping s'effectue de la façon suivante :
Video->Flip(NULL,DDFLIP_WAIT);  // DDFLIP_WAIT pour la synchronisation horizontale
 
 
4) Les sources :
 
"graphique.cpp"
"graphique.h"
"moteur_3d_v0.cpp"
 
 
"La feuille de projet pour Borland C++"
 
"L'exécutable"
 
Dans l'exécutable, appuyer sur <d> pour activer/désactiver le double buffering, appuyer sur <h> pour activer/désactiver la synchronisation horizontale et sur <v> pour activer/désactiver la synchro verticale.
 
Les sources pour Direct Draw :
"graphique.cpp"
"graphique.h"
"resource.h"
"infos_compilation.h"
"main.cpp"
 
 
"Les ressources du projet"
 
"La feuille de projet pour Visual C++"
"La feuille de workspace pour Visual C++"
 
"L'exécutable"
 
Dans l'exécutable, appuyer sur <d> pour activer/désactiver le double buffering, et la synchronisation horizontale.

 

[edtdd]--Message édité par Dav Vador--[/edtdd]

n°4509
koulip31
Posté le 09-10-2001 à 13:50:29  profilanswer
 

la :ouch:  
:jap: dav vador :jap:  
 
une tite tuto sur les rotations matricielles si teu plais  
 :D

n°4539
asterix
Teigneux inside ! ©
Posté le 09-10-2001 à 16:07:56  profilanswer
 

impressionnant !
 
il n'y a pas moyen d'interroger (facilement) la carte graphique, via directx sous windows afin d'obtenir le code pour passer dans les modes super vga ?
 
pasque ce limiter à 320*200 (ou 320*400) en 256 couleur, c pô un peu juste (enfin, gâcher) pour les carte graphiques actuelles ?


---------------
Je vous le dis : il faut porter du chaos en soi pour pouvoir donner naissance à une étoile dansante. Frédéric Nietzsche
n°4707
Dav Vador
Posté le 11-10-2001 à 10:42:02  profilanswer
 

AsTeRiX a écrit a écrit :

impressionnant !
 
il n'y a pas moyen d'interroger (facilement) la carte graphique, via directx sous windows afin d'obtenir le code pour passer dans les modes super vga ?
 
pasque ce limiter à 320*200 (ou 320*400) en 256 couleur, c pô un peu juste (enfin, gâcher) pour les carte graphiques actuelles ?  



Pour les résolutions supérieures, il faut sous Windows avec DirectDraw remplacer RES_X, RES_Y et N (2a du Tutorial 0): lpDD->SetDisplayMode(RES_X, RES_Y, N, 0, 0);
par la résolution que tu veux et N=nombre de bits.
Sinon pour les couleurs, je ne me suis limité qu'a du 8bits pour utiliser ma palette de couleurs, mais tu peux passer en 32bits en remplacant N par 32.
La dernière version de mon moteur doit tourner en 640x480 sous Windows, mais en modifiant la résolution dans le fichier "infos_compilation.h" et en recompilant, tu peux le faire marcher en 1600x1200 si tu veux, mais ça risque de ramer grave...car il n'est qu' "accéléré" 2D par la carte. La 3D se fait entièrement en soft.
 
Koulip>> Pour les rotations, translations et changements de repère sous forme matricielle ou non, je suis en train de préparer ça...

n°4711
koulip31
Posté le 11-10-2001 à 11:07:08  profilanswer
 

dav>> ben le travil sur les martices  
multiplication addition .... dans le but de fiare des rot, translation koi :) c'est la base ...

n°4757
_ftbx_
Posté le 11-10-2001 à 15:14:35  profilanswer
 

Alors ça c'est cool....
 
Bon j'ai pas tout lu mais il vient d'ou ton moteur ?? c'est du 'fait maison'  ?? J'avais commencé un moteur aussi dans le genre y'a 2 ans mais j'avais pas trop me temps. Eventuellement, si y'a besoin, j'avais commencer une interface avec VC++...

n°5367
Dav Vador
Posté le 15-10-2001 à 14:46:33  profilanswer
 

_ftbx_ a écrit a écrit :

Alors ça c'est cool....
 
Bon j'ai pas tout lu mais il vient d'ou ton moteur ?? c'est du 'fait maison'  ?? J'avais commencé un moteur aussi dans le genre y'a 2 ans mais j'avais pas trop me temps. Eventuellement, si y'a besoin, j'avais commencer une interface avec VC++...  



Ca fai un peu + d'1 an keu je lai komancé (juillet 2000 je crois). G komancé en turbo pascal (juste l'affichage des arrêtes) pui je sui passé au C en entrant en Licence (C la keu G apri le C) et au C++ au 2ème semestre (c'étai mon projet...). Depui cet été, G ajouté l'afichage 2D avec DirectDraw et biento avec OpenGL.
Pour le momen (version 114), tou est fai maison, mai pour les ombrages (pour Phong et Gouraud) et l'optimisation du remplissage de polygone, je komance franchemen à bloké, donc je sui en trin de me documenté. Les seul docs keu G utilisé concernai l'initialisation du mode graphique et l'algo de Bresenham pour le tracé de ligne. Pour l'algo du Z Buffer, je n'ai pa été cherché de doc, mai je ne l'ai pa pondu non plu (je saV déja koman sa marchai...). Pour l'instan, je ne m'intéress ka la partie graphique du moteur, mai je pense de + en + m'intéresser aussi a tou ce ki concerne la fysik (bcp + tard...) kan j'oré fini tou sa :
- ombrage de Phong et de Gouraud
- import/export 3DS
- textures
- OpenGL
- et surement d'otre choz okel je ne pense pa enkor...
Vu le peu de tps keu je passe dessu par semaine, je croi keu C pa 2min la veille!
 
Koulip>> Je pense poster le tut sur les matrices 2min ou après 2min o + tar.

n°5368
koulip31
Posté le 15-10-2001 à 14:59:40  profilanswer
 

pour le chargement des .3DS
www.whotsit.org dav :) ji ais trouve la doc complete sur le format .3DS apres pour choper les vertexs.... c'est trivial :p

n°5511
Dav Vador
Posté le 16-10-2001 à 12:36:25  profilanswer
 

koulip31 a écrit a écrit :

pour le chargement des .3DS
www.whotsit.org dav :) ji ais trouve la doc complete sur le format .3DS apres pour choper les vertexs.... c'est trivial :p  



Merci, mai on m'a déja filé des liens pour le forma 3DS. Me reste plu ka l'impémenter...
 
Je te met kks infos sur les transformation avec les matrice.
C'est pa enkor fini, mai ya l'essentiel.

 

[edtdd]--Message édité par Dav Vador--[/edtdd]

n°5512
Dav Vador
Posté le 16-10-2001 à 12:38:51  profilanswer
 

Tutorial n°3 : MAJ du 24/10/2001
 
III) Translations, rotations, changements de repères :  
 
On considèrera tout le long que l'axe X est l'axe dirigé vers la droite, l'axe Y celui dirigé vers le haut et l'axe Z dirigé de l'écran vers nous.
 
Pour toutes ces transformations, 2 possibilités s'offrent à nous :
- calcul des nouvelles coordonnées sous la forme x' = f(x, y, z)  y' = g(x, y, z)  z' = h(x, y, z).
- calcul à l'aide de matrices sous la forme P' = M.P où P est le vecteur coordonnées.
 
 
1) Quelques rappels (ou plutôt quelques notions) sur les matrices...
 
a) Addition de matrices :
 
Soit une matrice A de taille (n=nb_lignes, m=nb_colonnes), une matrice B de même taille.
La matrice C telle que C = A + B est telle que c[i, j] = a[i, j] + b[i, j]   (i allant de 1 à n et j de 1 à m).
 
Exemple :
Soit A = 2 1 5 6 de taille (3, 4)
         3 2 1 4
         4 2 4 3
 
  et B = 5 1 2 3
         1 2 5 4
         7 8 2 1
 
On a alors C = 2+5 1+1 5+2 6+3 =  7  2  7  9
               3+1 2+2 1+5 4+4    4  4  6  8
               4+7 2+8 4+2 3+1   11 10  6  4
 
Remarque : On a A+B = B+A (toujours)
 
 
b) Multiplication de matrices :
 
Soit une matrice A de taille (n1, m1), une matrice B de taille (m1, m2).
La matrice C telle que C = A.B est telle que c[i,j] = Somme (pour k=1 à m1) a[i, k] + b[k, j]   (i allant de 1 à n1 et j de 1 à m2) et est de taille (n1, m2). En clair, on multiplie la ligne i de la matrice A par la colonne j de la matrice B.
 
Exemple :
Soit A = 2 1 5 6 de taille (2, 4)
         3 2 1 4
 
  et B = 5 1 7 de taille (4, 3)
         1 2 6
         7 8 2
         9 1 5
 
On a alors :
 c[1, 1] = 2*5 + 1*1 + 5*7 + 6*9 = 100
 c[1, 2] = 2*1 + 1*2 + 5*8 + 6*1 = 50
 ...
 c[2, 1] = 3*5 + 2*1 + 1*7 + 4*9 = 60
 ...
 
Et C = 100 50 60 de taille (2, 3)   (sauf erreur de calcul de ma part...)
        60 19 55  
 
 
Remarque : On a A.B différent de B.A (en général)
 
Voilà pour les quelques notions nécessaires...
Passons maintenant aux choses sérieuses (enfin plutôt intéressantes que sérieuses).
 
 
2) Les coordonnées homogènes :
 
Soit le point p de coordonnée (x, y, z) reprensenté par le vecteur P = x
                                                                       y
                                                                       z
 
Le vecteur X = xh représente aussi le point p mais en coordonnées homogènes
               yh
               zh
                w
à condition que xh/w = x, yh/w = y et zh/w = z.
En  général, on pose w=1.
Cette représentation nous permettra de représenter toutes nos transformations par des produits de matrices (4,4).
 
Pour chacune des transformations suivantes, on posera :
p le point de coordonnée (x, y, z) reprensenté par le vecteur P = x
                                                                  y
                                                                  z
 
et p' le point image de coordonnée (x', y', z';) reprensenté par le vecteur P' = x'
                                                                                y'
                                                                                z'
On posera X tel que X = xh=x
                        yh=y
                        zh=z
                         w=1
 
et de même X' tel que X' = xh'=x'
                           yh'=y'
                           zh'=z'
                            w'=1
 
 
3) Les transformations :
 
a) Translations :
 
p' est l'image de p par la translation de vecteur T = tx
                                                      ty
                                                      tz
Première solution :
On a sans les matrices :
x' = x + tx
y' = y + ty
z' = z + tz
 
D'où P' = P + T sous forme matricielle
 
 
Deuxième solution (coordonnées homogènes):
T' = 1 0 0 tx
     0 1 0 ty
     0 0 1 tz
     0 0 0  1
 
 On a alors X' = T'.X
 
 
b) Rotations :
On utilisera les angles d'Eulers pour les matrices de rotation :
Rotation autour de X: sens positif = de Y vers Z
Rotation autour de Y: sens positif = de Z vers X
Rotation autour de Z: sens positif = de X vers Y
 
* rotation d'angle a autour de l'axe des Z:
 
Première solution :
On a sans les matrices :
x' = xcos(a) - ysin(a)
y' = xsin(a) + ycos(a)
z' = z
 
Petite preuve :
Cela revient à faire une rotation dans le plan défini par l'axe des X et l'axe des Y.
On pose p = x+i*y (forme complexe).
On a p' = exp(i*a)*p = (cos(a)+i*sin(a)).(x+i*y) = ... = (xcos(a)-ysin(a)) + i*(xsin(a)+ycos(a))
D'où le résultat voulu...
 
En posant R = cos(a)  -sin(a)  0
              sin(a)   cos(a)  0
                   0        0  1
 
On a donc P' = R.P sous forme matricielle
 
Deuxième solution (coordonnées homogènes):
C'est la même chose avec w' = w.
On pose donc R' = cos(a)  -sin(a)  0  0
                  sin(a)   cos(a)  0  0
                       0        0  1  0
                       0        0  0  1
 
On a donc X' = R'.X
 
* rotation d'angle a autour de l'axe des X:
 
Première solution :
On a sans les matrices :
x' = x
y' = ycos(a) - zsin(a)
z' = ysin(a) + zcos(a)
 
En posant R =      1      0         0
                   0  cos(a)  -sin(a)
                   0  sin(a)   cos(a)
 
On a donc P' = R.P sous forme matricielle
 
Deuxième solution (coordonnées homogènes):
On pose donc R' =  1       0        0  0
                   0  cos(a)  -sin(a)  0
                   0  sin(a)   cos(a)  0
                   0       0        0  1
 
On a donc X' = R'.X
 
* rotation d'angle a autour de l'axe des Y:
 
Première solution :
On a sans les matrices :
x' = xcos(a) + zsin(a)
y' = y
z' = -xsin(a) + zcos(a)
 
En posant R =  cos(a)  0  sin(a)
                    0  1       0
              -sin(a)  0  cos(a)
 
On a donc P' = R.P sous forme matricielle
 
Deuxième solution (coordonnées homogènes):
On pose donc R' =   cos(a)  0  sin(a)  0
                         0  1       0  0
                   -sin(a)  0  cos(a)  0
                         0  0       0  1
 
On a donc X' = R'.X
 
 
c) Composition de transformations :
 
Exemple 1: Effectuer une rotation R puis une translation T
Dans le cas des coordonnées "normales", on a P' = T + (R.P) qui ne se simplifie pas.
Par contre pour les coordonnées homogènes, on a X' = T.R.X = M.X où M=T.R
On a M = r r r tx   où R est la matrice (3, 3)
         r r r ty   correspondant à la rotation voulue
         r r r tz   dans les coordonnées "normales".
         0 0 0  1
 
Exemple 2: Passage des coordonnées réelles aux coordonnées écran :
 
c1) Passage du repère R au repère Caméra :
On suppose connaître les coordonnées de chaque sommet dans le repère R.
On connaît aussi les coordonnées de la caméra (cx,cy,cz) dans le repère R.
On supposera aussi que la caméra ne peut effectuer des rotations qu'autour de l'axe des Y.
 
http://www.multimania.com/davvador2416/moteur_3d/3/images/schema_1.bmp
 
Pour passer du repère R au repère caméra, il nous suffira donc d'effectuer une translation de vecteur (-cx,-cy,-cz),
puis d'effectuer une rotation d'angle -a autour de l'axe des Y.
On aura donc X' = R.T1.X
où T1 = 1 0 0 -cx
        0 1 0 -cy
        0 0 1 -cz
        0 0 0   1
 
et R =  cos(-a) 0 sin(-a) 0
              0 1       0 0
       -sin(-a) 0 cos(-a) 0
              0 0       0 1
 
c2) Projection :
On souhaite projeter les points exprimés dans le repère caméra sur le plan E.
 
http://www.multimania.com/davvador2416/moteur_3d/3/images/schema_2.bmp
 
Le point A a projeté sur E a pour coordonnées (x,y,z).
Le plan E étant situé à une distance f (distance focale) de la caméra,
on a par le théorème de Thales :
x'/x = f/z <=> x' = f.x/z
De même y' = f.y/z
et z' = f
Ce qui revient à mettre w'=z/f, x'=x, y'=y et z'=z.
 
On aura donc la matrice de projection suivante :
P = 1 0   0 0
    0 1   0 0
    0 0   1 0
    0 0 1/f 0
 
c3) Passage du repère du plan E aux coordonnées écran :
Le problème est que l'écran (de taille tx,ty) à son point d'origine situé en haut à gauche et que l'axe des Y est dirigé vers le bas.
 
http://www.multimania.com/davvador2416/moteur_3d/3/images/schema_3.bmp
 
On aura donc x' = x+tx/2
et y' = -y+ty/2
 
D'ou la matrice correspondante :
T2 = 1  0 0 tx/2
     0 -1 0 ty/2
     0  0 1    0
     0  0 0    1
 
 
Pour avoir les coordonnées écran de chaque point à partir des coordonnées réelles, il suffira donc de faire :
X' = T2.P.R.T1.X = M.X
 
où M = cos(a)+tx.sin(a)/2f  0 -sin(a)+tx.cos(a)/2f -cx.cos(a)+cz.sin(a)-tx.(cx.sin(a)+cz.cos(a))/2f
       ty.sin(a)/2f        -1         ty.cos(a)/2f                   cy-ty.(cx.sin(a)+cz.cos(a))/2f
       sin(a)               0               cos(a)                           -(cx.sin(a)+cz.cos(a))
       sin(a)/f             0             cos(a)/f                         -(cx.sin(a)+cz.cos(a))/f
 
En posant ca=cos(a), sa=sin(a), TX=tx/2f, TY=ty/2f, cxz=cx.sa+cz.ca, on obtient :
M = ca+TX.sa  0 TX.ca-sa -cx.ca+cz.sa-TX.cxz
    TY.sa    -1    TY.ca           cy-TY.cxz
    sa        0       ca                -cxz
    sa/f      0     ca/f              -cxz/f
 
D'où w' = (x.sa + z.ca -cxz)/f
     xe = ((ca+TX.sa).x + (TX.ca-sa).z - cx.ca + cz.sa - TX.cxz)/w'
  et ye = ((TY.sa).x -y + (TY.ca).z + cy - TY.cxz)/w'
 
Dernière remarque : lorsque l'on est en 320x200, le format de l'écran est 4/3=8/6 et celui de la résolution est 8/5.
Il faut donc multiplier ye par 5/6.

 

[edtdd]--Message édité par Dav Vador--[/edtdd]

n°5654
koulip31
Posté le 17-10-2001 à 10:19:07  profilanswer
 

:bounce:  
mais gloups le doute sur la multiplication matricielle
 
[1 2 3]   [10 11 12]    
[4 5 6] * [13 14 15]  
[7 8 9]   [16 17 18]
 
nous donne koi? en detail
 
car jai vue des articles sur le net ki pour detail de l'operation
1 * 10 + 1 * 13 + 1 * 16 (pour la case en haut a g)
2 * 11 + 2 * 14 + 2 * 17 (pour celle d'a cote)  
....
 
ke toi tu fait
1 * 10 + 2 * 11 + 3 * 12
4 * 13 + 5 * 14 + 6 * 15
...
(ta facon de faire est pour moi la plus logique mais comme jai vue l'autre facon ... je doute (ct sur != articles gamedev)

n°5662
Hercule
Posté le 17-10-2001 à 11:14:52  profilanswer
 

[1 2 3]   [10 11 12]  
[4 5 6] * [13 14 15]  
[7 8 9]   [16 17 18]  
 
 
1 * 10 + 2 * 13 + 3 * 16 (pour la case en haut a g)  
1 * 11 + 2 * 14 + 3 * 17 (pour celle d'a cote sur la droite "2" )

n°5664
koulip31
Posté le 17-10-2001 à 11:18:59  profilanswer
 

donc dav c'est gouré   :sweat:  
 
tu est sur de toi a 100% ?

n°5665
koulip31
Posté le 17-10-2001 à 11:20:01  profilanswer
 

et pour la division de 2 matrices ?? car la on as vue  
l add  
la sous
la mul  
 
mais en manque un :) de signe

n°5674
Hercule
Posté le 17-10-2001 à 12:18:53  profilanswer
 

non il s'est pas trompé.
diviser des matrices je sais pas trop si ca se fait.
On multiplie par l'inverse .  
L'inversion de matrice c'est pas aussi simple.


---------------
Ils veulent la jouer hard, on va la jouer hard  
n°5767
sombresong​e
Posté le 18-10-2001 à 02:34:13  profilanswer
 

hercule a écrit a écrit :

non il s'est pas trompé.
diviser des matrices je sais pas trop si ca se fait.
On multiplie par l'inverse .  
L'inversion de matrice c'est pas aussi simple.  




 
Il faut déjà que la matrice soit inversible! c n'est pas le cas de toute les matrices! :sweat:  
 
le plus simple pour calculer l'inverse d'une matrice inversible c:
 
soit A une matrice
det(A) le determinant de celle ci
A' l'inverse de A
 
A'=1/det(A) * Com(A)
 
ou com(A) est la comatrice de A (cad la matrice des cofacteurs)
 
Voilà une méthode simple pour calculer l'inverse d'une matrice (si elle est inversible évidemment....)

n°5771
Dav Vador
Posté le 18-10-2001 à 09:43:39  profilanswer
 

Koulip>>
1 2 3]   [10 11 12]    
[4 5 6] * [13 14 15]  
[7 8 9]   [16 17 18]
 
Ca fait 1*10+2*13+3*16, 1*11+2*14+3*17, 1*12+2*15+3*18
        4*10+5*13+6*16, 4*11+5*14+6*17, 4*12+5*15+6*18
        7*10+8*13+9*16, 7*11+8*14+9*17, 7*12+8*15+9*18
C sur à 100%. (je sé pa ou il zon appri à calculer les matrices sur gamedev, mai sa me parai louche...).
 
Pour l'inversion de matrice, je ne l'ai pa présenté car bcp tro compliqué. Il fo connaitre le déterminan pui calculer la comatrice et C vraimen lon et chian à faire...
Si tu y tien vraimen, je peu essayer de te préparer une explication, mai la fo keu je retrouve mes cour de Deug.

n°5774
koulip31
Posté le 18-10-2001 à 10:03:52  profilanswer
 

pour lamul javais compris mais a comptre coup :p  
javis pas mate ke ct un matrice de 3*4 ke tavais pris :lol: alors gloups... mais bon ce soit jimplemente ca a mon chti moteur graphique (pour linstant pas 3D mais graphique :p) et zou je vais calculer mes points de dep et d'arrivée :p maint ke jai tout capiche sur les matrices :) mais bon donc jai vue sur le net des articles faux ....  :sweat:  pas cool ca

n°5778
Dav Vador
Posté le 18-10-2001 à 10:20:40  profilanswer
 

koulip31 a écrit a écrit :

pour lamul javais compris mais a comptre coup :p  
javis pas mate ke ct un matrice de 3*4 ke tavais pris :lol: alors gloups... mais bon ce soit jimplemente ca a mon chti moteur graphique (pour linstant pas 3D mais graphique :p) et zou je vais calculer mes points de dep et d'arrivée :p maint ke jai tout capiche sur les matrices :) mais bon donc jai vue sur le net des articles faux ....  :sweat:  pas cool ca  



Fo parfois ce méfier...
J'essaie de rajouter kks truc sur les matrices (changement de repère, compositions de transformations,...) pour très bientôt...

n°5780
koulip31
Posté le 18-10-2001 à 10:45:40  profilanswer
 

trop cool de ta part :p
 
faut ke je joue avec mes verex moi ..... mais voit pas comment faire pour le colision detection car les vertez c'est ke les angles :/ mais bon

n°5785
Dav Vador
Posté le 18-10-2001 à 12:54:33  profilanswer
 

koulip31 a écrit a écrit :

trop cool de ta part :p
 
faut ke je joue avec mes verex moi ..... mais voit pas comment faire pour le colision detection car les vertez c'est ke les angles :/ mais bon  



Je croi pa keu je V pouvoir t'aider. Je ne me sui pa encor intéressé à ce sujet...
Bon courage!

n°5789
koulip31
Posté le 18-10-2001 à 13:34:16  profilanswer
 

jvais en avoir besoin :) lol  
mais bon jai ma chtite idee car on bosse face par face donc une face c'est plat :p ... sufi de lalgo qui donne si 2 droites se coupent et pense pouvoir me demerder avec ca :p ... pour l'instant fait pas kke chose de complexe :p je fait un pong en 3D (cad la balle et les raquettes se baladent en x,y,z (les raquettes en gros se deplacent selon une sphere :p (voir topic algo/math dans prog pur les details :p)) donc pense pas complique koike :lol:

n°5795
koulip31
Posté le 18-10-2001 à 15:33:45  profilanswer
 

:( encore un chti pb  :(  
 
[x] [1 0 0 xh]
[y]*[0 1 0 yh]  
[z] [0 0 1 zh]
[w] [0 0 0  1]
 
ca nous donne une matrice de 1*4 ou de 4*4 ???
normalement une de 1*4 .... mais kan je fait le tout
 
ca me donne comme matrice d'arrivée
 
[x x x x.xh]
[y y y y.yh]
[z z z z.zh]
[w w w    w]
 
ce ki me plais pas du tout :( bon je prend la derniere colone mais bon pour les rotation ca le ferras po

n°5797
Hercule
Posté le 18-10-2001 à 15:37:34  profilanswer
 

essaie comme ca ca va tout de suite mieux.
 
             [1 0 0 xh]  
[x][y][z][w]*[0 1 0 yh]    
             [0 0 1 zh]  
             [0 0 0  1]


---------------
Ils veulent la jouer hard, on va la jouer hard  
n°5813
Nicolagnak​'
Dr Jekyl ...
Posté le 18-10-2001 à 17:36:55  profilanswer
 

:ouch:  
 
 :jap: Dav  
 
 
trop cool ce topic,  surtout ne pas l'effacer !   je le sauvegarde tout de suite au cas où


---------------
             www            
n°5849
sombresong​e
Posté le 18-10-2001 à 22:28:37  profilanswer
 

Pour l'histoire de l'inverse d'une matrice je me suis trompé dans la formule la bonne étant:
 
A'=1/det(A)* t(Com(A))
 
où t(Com(A)) est la Transposée de la comatrice de A ;)

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Graphisme

  Programassion Grafik : kréassion d'1 moteur 3D...

 

Sujets relatifs
Plus de sujets relatifs à : Programassion Grafik : kréassion d'1 moteur 3D...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR