Programmer Maggie3D pour Vampire

2 sujets de 1 à 2 (sur un total de 2)

  • thellier

      #376610

      Programmer Maggie3D pour Vampire

        Rappel sur Maggie3D

      C’est quoi ?
      La nouvelle fonctionnalité du chipset SAGA de la Vampire qui ajoute du traçage 3D
      Ca fonctionne comme le blitter (c’est le blitter en fait) on remplis quelques registres custom et après ca trace le nombre de pixel prévu comme le blitter

      Comme vous le savez les cartes 3D tracent des triangles texturés et là cela trace en une simple passe une ligne du triangle
      Cette ligne est texturée avec correction de perspective, filtrée (bilinear) et gère le zbuffer et un gouraud

      ( Néanmoins il a que quelques possibilité de mode de traçage : une seule couleur de lampe, un seul mode de zbuffer, un seul blending (transparence/mélange de couleurs) c’est beaucoup moins que Warp3D )

      ————-
      —-X——-
      —-#X——
      —-X#X—– <— Maggie trace une ligne texturée du triangle comme celle ci
      —-#X#X—-
      —-X#X#X—-
      —————–

      Ca parait peu mais ça peut être des centaines de pixels d’un coup dans cette ligne pour de gros triangles ??

      Il suffit donc de tracer toutes les lignes pour obtenir un triangle
      et de tracer tout les triangles pour tracer un objet 3D
      et tout les objets 3D pour obtenir la scene 3D du jeu

        Les Registres Maggie3D

      Il s’agit des nouveaux registres du blitter qui servent à Maggie ce sont des » custom registers » comme ceux des anciens Amiga ils sont à l’adresse 0xdff250 et suivantes et ont tous un nom commencant par TEX

      // Maggie chip registers vu comme une C structure (j’ai enlevé les « TEX » en début de noms)

      struct Maggie3D {
      ULONG TPT; /* 32bit compressed texture source Addr*/
      ULONG DPT; /* 32bit Destination Screen Addr */
      ULONG ZPT; /* 32bit ZBuffer Addr */
      UWORD unused1; /* ??? */
      UWORD STRT; /* 16bit LENGHT (and START) */
      UWORD MIP; /* 16bit MIP texture size (9=512/8=256/7=128/6=64) */
      UWORD MODE; /* 16bit MODE (Bit0=Bilinear) (Bit1=Zbuffer) (Bit2=16bit output) */
      UWORD unused2; /* ??? */
      UWORD DMOD; /* 16bit Destination Step */
      ULONG unused3; /* ??? */
      ULONG unused4; /* ??? */
      LONG UUuu; /* 32bit UUuu (16:16) */
      LONG VVvv; /* 32bit VVvv (16:16) */
      LONG dUUuu; /* 32bit dUUuu (16:16) */
      LONG dVVvv; /* 32bit dVVvv (16:16) */
      WORD Light; /* 16bit Light Ll (8:8) */
      WORD dLight; /* 16bit Light dLl (8:8) */
      ULONG Lightcolor; /* 32bit Light color (ARGB) */
      LONG ZZzz; /* 32bit ZZzz (16:16) */
      LONG dZZzz; /* 32bit Delta ZZZZzzzz (16:16) */
      };
      on peut alors alors décrire un pointeur dessus et les manipuler en C sans aucune instructions ASM

      struct Maggie3D *MAGGIE=(APTR)0xdff250;

      et y écrire des valeurs simplement en C comme ceci
      MAGGIE->STRT=dx;

      Comme ce sont des custom register il est plus subtil de les joindre aux autres custom registers dans une structure unique ainsi

      #include <hardware/custom.h>
      struct Custom2{
      struct Custom reg;
      UWORD unknown;
      UBYTE unknowns[80];
      struct Maggie3D maggie;
      };

      custom= (struct Custom2 *)0xdff000 ;

      et ainsi d’accéder aux anciens registres classiques et à ceux de Maggie de la même façon via un seul pointeur sur les custom registers

      custom->reg.dmacon=0x7fff;
      custom->maggie.STRT=dx;

        Et ça marche comment ?

      L’idée c’est de tracer une ligne horizontale de pixels d’un point P1 à un point P2
      Ces points ont une position « x y z » et des coordonnées sur la texture « u v » et un niveau d’éclairage « light »

      TPT est l’adresse du pixel de l’écran où commence la ligne donc du point P1 en x y
      donc c’est typiquement
      custom->maggie.TPT= adresse_ecran+y*large*bpp+x*bpp;
      avec bpp le nombre d’octets par pixels: 2 en 16 bits RGB565 , 4 en 32 bits ARGB32

      DMOD est la valeur bpp soit 2 ou 4
      custom->maggie.DMOD=bpp;

      ZPT est l’adresse du Zbuffer qui est en 16 bits donc
      custom->maggie.ZPT= adresse_zbuffer+y*large*2+x*2;

      TPT est l’adresse de début de la texture, celle ci doit être compressée en DXT ce qui est problématique
      custom->maggie.TPT=adresse_texturedxt;

      MIP est la taille de la texture y mettre 9 pour 512 pixels ,8 pour 256,7 pour 128,6 pour 64
      custom->maggie.TPT=8;

      Lightcolor est la couleur de l’éclairage, c’est juste une valeur 32 bits ARGB cad 8 bits pour, 8 bits pour R, etc….
      custom->maggie.Lightcolor=255<<24+255<<16+255<<8+255; // blanc

      MODE contient certains flags sur comment on trace
      Bit0=Filtrage Bilinear
      Bit1=Zbuffer utilisé
      Bit2=Ecrit des pixels RGB565 (donc DMOD = 2)
      Bit3=écriture Zbuffer desactivée
      custom->maggie.MODE=1+2+4;

      Ensuite toutes les autres valeurs u,v,light,z,du,dv,dlight,dz suivent la même logique: ce sont des nombres à virgules fixe
      qui sont stockés dans 32 bits les premiers 16 bits sont la partie entiére, le restant 16 bits la partie décimale
      exemple: x=32.0; serait x=32<<16;
      Curieusement light,dlight sont stockés sur 16 bits dont 8 partie entiére et 8 décimale
      u,v,light,z sont ceux du 1er point de départ P1
      custom->maggie.UUuu= P1->u;
      custom->maggie.VVvv= P1->v;
      custom->maggie.ZZzz= P1->z;
      custom->maggie.Light= P1->light;

      par contre les valeurs en d contiennent le « delta » ou « pas » entre P1 et P2
      Donc on calcule la longueur de la ligne en horizontale dans dx
      dx=P2->x – P1->x+1;
      custom->maggie.dUUuu=(P2->u – P1->u)/dx;
      custom->maggie.dVVvv=(P2->v – P1->v)/dx;
      custom->maggie.dZZzz=(P2->z – P1->z)/dx;
      custom->maggie.dLight=(P2->light – P1->light)/dx;

      STRT démarre enfin maggie avec la longueur de la ligne à tracer donc dx
      MAGGIE->STRT=dx;

        Et on trace comment ?

      Attention avant de toucher Maggie il faut s’approprier l’OS donc tout désactiver, on peut donc faire typiquement ceci

      SaveDMACON=custom->reg.dmaconr; //Save DMA
      custom->reg.dmacon=0x7fff; //Disable All DMA

      SaveINTENA=custom->reg.intenar; //Save INTENA
      custom->reg.intena=0x7fff; //All INTENA OFF

      custom->reg.dmacon=0x8040; //Blit DMA On

      Puis remplir les registres Maggie ne changeant pas avec selon la ligne Y que l’on trace

      MIP
      TPT
      DMOD
      MODE
      Lightcolor

      puis faire la boucle pour toutes les lignes du triangles en Y
      while(dy)
      {
      en remplissant à chaque fois les registres Maggie changeant avec Y
      ZPT
      DPT
      ZZzz
      dZZzz
      UUuu
      dUUuu
      VVvv
      dVVvv
      Light
      dLight

      attendre que le blitter soit dispo
      waitblit:
      if(BTST(custom->reg.dmaconr,14)) // bbusy bit 14 for Waitblit!
      goto waitblit;

      Lancer enfin Maggie pour une distance de dx pixels
      custom->maggie.STRT=dx;

      prendre une nouvelle ligne horizontale P1, P2 et boucler
      P1++, P2++; dy–;
      }

      et on restaure l’OS

      BSET(SaveINTENA,15);
      custom->reg.intena=SaveINTENA;

      BSET(SaveDMACON,15);
      custom->reg.dmacon=SaveDMACON;

      logo

        #376717

        Merci pour ces explications Alain ! Les dernières amėliorations de Maggie semblent prometteuses et ton travail indispensable pour y donner accès à plus de développeurs. J’ai hâte de voir ce que tu pourras obtenir comme puissance de rendu.

        PowerMac - G5 2.0 GHz - 1.7 Go RAM - Radeon 9600P 128 Mo - MorphOs 3.13 et Peg2 - G4 RIP
        Mac mini - G4 1.42 GHz - 1 Go RAM - Radeon 9200 32 Mo - MorphOs 3.9
        WinUAE sur HP Core2 Quad 8200
        Epave de Mist FPGA remplacé par un Sidi
        A1200 malade 😉 et A500 512+512Ko RAM Kickstart 1.3

      2 sujets de 1 à 2 (sur un total de 2)

      • Vous devez être connecté pour répondre à ce sujet.

      Forums AmigaOS, MorphOS et AROS Développement Programmer Maggie3D pour Vampire

      Amiga Impact