Suivez-nous sur X
|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Amiga C Manual - Les routines graphiques de bas niveau
(Article écrit par Anders Bjerin et extrait d'Amiga C Manual - mars 1990)
|
|
Note : traduction par Serge Hammouche.
12. Les routines graphiques de bas niveau
12.1 Introduction
Dans ce chapitre, nous examinerons les routines graphiques de bas
niveau. Comme nous l'avons vu au chapitre 3 - Les graphismes,
l'Amiga gère deux niveaux de graphisme différents. D'un côté,
vous pourrez employer les routines graphiques de haut niveau qui
utilisent des structures donnant de la flexibilité à votre
programme, de l'autre, vous pourrez employer les routines
graphiques de bas niveau qui permettent à votre programme un
contrôle total sur tout le système graphique. Dans ce chapitre,
nous verrons les routines graphiques de bas niveau.
On traitera des routines graphiques de bas niveau en deux parties.
La première traitera de la manière dont on génère l'affichage.
Ici, nous décrirons comment on choisit la définition d'un écran,
son nombre de couleurs, s'il est en mode entrelacé ou non
entrelacé, la taille des viewports, etc. La seconde partie
traitera des outils de dessin qu'offre l'Amiga. Nous décrirons
ici comment dessiner un seul point, des lignes, des polygones,
comment changer la couleur, comment utiliser les patrons et les
masques et nous verrons aussi les différents types de routines de
remplissage, etc.
12.2 La création de l'affichage
Maintenant, nous jetons un coup d'oeil sur la manière dont
on génère l'affichage. Cependant, avant de commencer à parler
de ceci, il vaudra mieux que nous donnions des renseignements
génériques sur les ordinateurs et le graphisme.
12.2.1 Une information d'ensemble
Nous décrirons ici comment est générée une image à l'affichage.
Nous verrons aussi certains modes particuliers d'affichage comme
le mode entrelacé, respectivement en haute et basse définition.
Pour finir, nous parlerons du pixel et de l'emploi des plans de bits ("bitplanes" en anglais).
12.2.1.1 Comment fonctionne un moniteur (ou un poste de télévision)
L'image vidéo affichée sur un moniteur ou un téléviseur est
réellement "dessinée" par un petit faisceau vidéo. Le faisceau
vidéo commence son action dans le coin supérieur gauche de l'écran.
Au fur et à mesure qu'il se déplace sur la droite, son intensité
varie pour dessiner des points plus clairs ou plus foncés. Dès que
ce faisceau a atteint le bord droit de l'écran, il se déplace vers
le bord gauche et se positionne un peu plus bas. Puis, il se
déplace à nouveau sur la droite et ainsi de suite.
Dans un affichage américain (NTSC), le faisceau se déplace de
gauche à droite 262 fois (dans un affichage européen de type PAL,
il se déplace 312 fois). Dès que le faisceau a atteint le bas de
l'écran, il revient vers le coin supérieur gauche et tout le
processus recommence. L'écran est ainsi "dessiné" 60 fois par
seconde sur un moniteur NTSC et 50 fois par seconde sur un moniteur PAL.
Voici l'image vidéo sur un moniteur américain (NTSC) :
1 ->---->---->----> |
2 ->---->---->----> |
3 ->---->---->----> |
| et ainsi de suite...|
261 ->---->---->----> |
262 ->---->---->----> V
|
Comme vous pouvez le constater, vous pourriez avoir un affichage
de plus de 262 (312) lignes, mais, habituellement, on n'utilise
pas les toutes premières et dernières lignes car on pourrait
difficilement les discerner. On vous recommande l'emploi d'un
affichage de 200 lignes (256 en PAL) au maximum. Cependant, si
vous souhaitiez utiliser des effets vidéo particuliers ou faire
en sorte que l'écran cache l'intégralité de l'affichage, vous
pourrez vous servir des 262 lignes (312). On fait référence à ce
type d'effet particulier en parlant de suraffichage ("overscan" en anglais).
12.2.1.2 Le mode entrelacé
Un affichage américain normal a une taille totale de 200 lignes
(un affichage PAL de 256). Cependant, l'Amiga a la particularité
unique de pouvoir doubler cette quantité de lignes dans un même
affichage, c'est-à-dire 400 lignes (512 en PAL). On appelle ce
mode spécial le mode entrelacé.
La première fois que le faisceau se déplace sur l'écran, il trace
toutes les lignes impaires (1, 3, 5, 7 ... 397, 399) et, la
deuxième fois, toutes les lignes paires (2, 4, 6, 8 ... 398, 400).
Ce mode spécial peut engendrer un "scintillement" de l'écran,
tout particulièrement si le contraste est élevé. Cela provient du
fait que les lignes impaires sont dessinées 30 fois par seconde
(25 fois en PAL) et que les lignes paires le sont 30 fois par
seconde (25 fois en PAL). Si vous avez un écran avec une haute
rémanence, vous n'aurez aucun problème, mais sur des moniteurs
normaux à bon marché le scintillement peut devenir ennuyeux.
Première fois Deuxième fois
1 -------------
------------- 2
3 -------------
------------- 4
5 -------------
------------- 6
7 -------------
------------- 8
et ainsi de suite ...
|
12.2.1.3 La haute et la basse résolution
Il existe deux types de résolution horizontale différents. La
basse résolution est de 320 pixels par ligne et la haute
résolution de 640 (nombre de pixels double).
Il y a une différence importante entre ces deux modes de
résolution. En basse résolution, vous pourrez avoir jusqu'à 32
couleurs et même utiliser le mode HAM ou Extra Half Bright
(nous donnerons des explications plus loin), tandis qu'en
haute résolution, vous pourrez employer seulement 16 couleurs ou moins.
Vous pourrez même employer l'affichage spécial en mode suraffichage.
L'affichage aura alors une largeur maximale de 352 pixels en
basse résolution et de 704 pixels en haute résolution.
12.2.1.4 Les pixels
L'affichage est constitué de petits points qu'on appelle "pixels".
Comme nous l'avons expliqué ci-dessus, il peut y avoir 320 ou
640 pixels dans une ligne, ainsi que 200 ou 400 lignes (256 ou
512 en PAL).
Lorsque vous créez un affichage, vous allouez des zones de mémoire
rectangulaires qui s'appellent plans de bits. Chaque octet de cette
zone de mémoire représente un pixel.
Un affichage américain en haute résolution non entrelacé de
640x200 pixels aura besoin de 16 000 octets de mémoire pour
chaque plan de bits.
Pour générer un tout petit écran (de 8x9 pixels) qui affichera
un "A", le plan de bits ressemblera à ceci :
Ligne Plan de bits 1
----------------------
1 00000000
2 00111100
3 01000010
4 01000010
5 01111110
6 01000010
7 01000010
8 01000010
9 00000000
|
12.2.1.5 Les couleurs
Si vous voulez vous servir de différentes couleurs dans un écran,
vous devrez employer plusieurs plans de bits. Tous les bits se
trouvant au même emplacement dans chaque plan de bits représenteront
alors un pixel. Avec deux plans de bits, vous pourrez avoir quatre
combinaisons différentes pour chaque pixel. Trois plans de bits vous
permettront huit combinaisons. Quatre plans de bits, seize
combinaisons et, pour finir, cinq plans de bits trente-deux
combinaisons.
Voici un exemple. Nous avons réservé de la mémoire pour deux
plans de bits qui permettront de construire un tout petit affichage
de 10 pixels par ligne, et d'une hauteur de quatre lignes.
Ligne Plan de bits 1 Plan de bits 2 Affichage (Couleur)
----------------------------------------------------------
1 0000000000 0000000000 0000000000
2 1111111111 0000000000 1111111111
3 0000000000 1111111111 2222222222
4 1111111111 1111111111 3333333333
|
Dans la première ligne, il y a de dix pixels de couleur 0 (00[b]=0[d]).
Dans la deuxième ligne, il y a de dix pixels de couleur 1 (01[b]=1[d]).
Dans la troisième ligne, il y a de dix pixels de couleur 2 (10[b]=2[d]).
Dans la quatrième ligne, il y a de dix pixels de couleur 3 (11[b]=3[d]).
Plus vous aurez de plans de bits, plus vous pourrez afficher de
couleurs. Cependant, étant donné que vous aurez besoin d'un plus
grand nombre de plans de bits, vous devrez allouer plus de mémoire.
Plans de bits Couleurs
-----------------------
1 2
2 4
3 8
4 16
5 32
|
12.2.2 Les éléments d'un affichage
12.2.2.1 Le raster
La zone dans laquelle vous pouvez dessiner s'appelle "raster". Elle
est constituée de différents plan de bits les uns au-dessus des autres.
Plus vous aurez de plans de bits, plus vous pourrez employer de couleurs
en même temps. La largeur maximale du raster (RWidth) peut aller
jusqu'à 1024 pixels ; sa hauteur (RHeight) aussi.
La partie du raster qui sera affichée s'appelle "ViewPort". Une
structure de nom RasInfo contient les valeurs RxOffset et RyOffset
qui déterminent quelle partie du raster on devra afficher dans le
ViewPort. Le ViewPort a une largeur de DWide pixels et une
hauteur de DHeight pixels (simple, n'est-ce pas ?).
Le raster :
<- RxOffset ->
--------------------------- A
| D ViewPort | | RyOffset
| H ------------ | V
R | e |XXXXXXXXXX| |
H | i |XXXXXXXXXX|-+-- Affichage de cette partie
e | g |XXXXXXXXXX| |
i | h ------------ |
g | t DWidth |
h | |
t | |
| |
| |
---------------------------
RWidth
|
12.2.2.2 Le View
L'affichage vidéo est une zone où vous pourrez avoir un ou
plusieurs ViewPorts. Cette zone s'appelle le "View" et les valeurs
DxOffset et DyOffset de la structure View déterminent où il faudra
positionner ce View dans l'affichage vidéo.
Vous pourrez donner à DxOffset et à DyOffset des valeurs négatives.
Dans ce cas, le View sera plus à gauche et plus haut que d'habitude.
La partie supérieure gauche du dessin sera difficile à discerner,
par conséquent ce mode n'est pas recommandé dans des programmes
d'affaires. Cependant, si vous écrivez des programmes de jeu ou
vidéo, ce mode d'affichage particulier pourra s'avérer souvent
utile.
Le View :
<--> DxOffset
------------------------ A
| AFFICHAGE VIDEO | | DyOffset
| ------------------ | V
| | | |
| | | |
| | | |
| | VIEW | |
| | | |
| | | |
| | | |
| ------------------ |
| |
------------------------
|
12.2.2.3 Le ViewPort
Comme nous l'avons dit ci-dessus, le View peut avoir un ou
plusieurs ViewPorts. Les valeurs DxOffset et DyOffset de la
structure ViewPort indiquent où il faudra positionner le ViewPort
dans le View.
<--> DxOffset
------------------ A
| VIEW | | DyOffset
| ------------ | V
| | | |
| | VIEWPORT | |
| | | |
| ------------ |
| |
------------------
|
Il y a d'importantes restrictions sur le nombre de ViewPorts qu'on
peut placer dans un View. Ces ViewPorts doivent être placés les
uns au-dessous des autres, et espacés d'au moins une ou plusieurs
lignes. Dès que le faisceau vidéo aura fini de dessiner la dernière
ligne d'un ViewPort, l'Amiga aura besoin d'un peu de temps pour
régler sa nouvelle définition, etc. dans le ViewPort suivant.
Pendant que l'Amiga est en train de travailler sur l'écran suivant,
le faisceau vidéo sera déjà descendu d'au moins une ligne (peut-être
de plusieurs).
Le View (L'affichage)
--------------------------
| Couleur d'arrière-plan |
| -------------- |
| | ViewPort 1 | |
| | | |
| -------------- | ==> Une ligne au minimum devra
| -------------- | séparer les ViewPorts.
| | ViewPort 2 | |
| -------------- |
--------------------------
|
La zone autour des ViewPorts sera remplie avec la couleur
d'arrière-plan des ViewPorts.
Voici trois exemples :
1. Correct ! Les ViewPorts ne se chevauchent pas l'un l'autre, et il y a assez
de place entre eux.
------------------------
| -------------------- |
| | | |
| -------------------- |
| ------------- |
| | | |
| ------------- |
| -------------------- |
| | | |
| -------------------- |
------------------------
|
2. Incorrect ! On doit placer les ViewPorts les uns
au-dessous des autres, et non les uns à côté des autres.
------------------------
| --------- --------- |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| --------- --------- |
------------------------
|
3. Incorrect ! Il doit y avoir de l'espace entre les divers
ViewPorts (au minimum une ligne, peut-être plus d'une).
------------------------
| -------------------- |
| | | |
| | | |
| | | |
| -------------------- |
| | | |
| | | |
| | | |
| -------------------- |
------------------------
|
12.2.2.4 La BitMap
La zone dans laquelle vous pouvez dessiner s'appelle (comme nous
l'avons déjà dit) le raster. Le raster lui-même est constitué
d'une ou plusieurs bitmaps. Une bitmap est une zone de mémoire
rectangulaire. Chaque bit de cette zone représente un petit point
(le pixel). Vous pouvez employer plusieurs bitmaps, ce qui veut
dire que chaque point est constitué de différents bits (un bit
pour chaque bitmap) et que la valeur binaire de ces bits
détermine la couleur qui sera employée.
BitMap 0 BitMap 1 BitMap 2 Couleur
-------------------------------------------------------------
0000011111 0000000000 0000000000 | 0000011111
0000011111 1111111111 0000000000 | 2222233333
0000011111 0000000000 1111111111 | 4444455555
0000011111 1111100000 1111111111 | 6666677777
|
De binaire à décimal
-----------------------------------------
| Binaire Décimal | Binaire Décimal |
|-------------------+-------------------|
| 00000 0 | 10000 16 |
| 00001 1 | 10001 17 |
| 00010 2 | 10010 18 |
| 00011 3 | 10011 19 |
| | |
| 00100 4 | 10100 20 |
| 00101 5 | 10101 21 |
| 00110 6 | 10110 22 |
| 00111 7 | 10111 23 |
| | |
| 01000 8 | 11000 24 |
| 01001 9 | 11001 25 |
| 01010 10 | 11010 26 |
| 01011 11 | 11011 27 |
| | |
| 01000 12 | 11000 28 |
| 01101 13 | 11101 29 |
| 01110 14 | 11110 30 |
| 01111 15 | 11111 31 |
-----------------------------------------
|
Plus vous aurez de bitmaps, plus vous pourrez employer de couleurs.
L'Amiga vous permet d'avoir jusqu'à six plans de bits avec certaines
restrictions :
- Un plan de bits (deux couleurs) : pas de restriction.
- Deux plans de bits (quatre couleurs) : pas de restriction.
- Trois plans de bits (huit couleurs) : pas de restriction.
- Quatre plans de bits (16 couleurs) : un seul champ de jeu (playfield).
- Cinq plans de bits (32 couleurs) : un seul champ de jeu (playfield), basse résolution.
- Six plans de bits (64 couleurs) : un seul champ de jeu (playfield), basse résolution, Half Bright.
- Six plans de bits (4096 couleurs) : un seul champ de jeu (playfield), basse résolution, HAM.
12.2.3 La création d'un affichage
Lorsque vous créerez un affichage, vous devrez d'abord déclarer et
initialiser un certain nombre de structures importantes. Ces
structures sont les suivantes :
- Structure View
- Structure ViewPort
- Structure ColorMap
- Structure BitMap
- Structure RasInfo
Dès que vous aurez initialisé ces structures, vous pourrez appeler
trois fonctions [MakeVPort(), MrgCop() et LoadView()] et votre
nouvel affichage sera mis en place.
12.2.3.1 Le View
Un View peut être constitué d'un ou plusieurs ViewPorts. Vous
aurez même la possibilité d'avoir plusieurs Views en même temps
dans la mémoire de l'Amiga, mais vous pourrez faire afficher un seul
View à la fois. L'avantage d'avoir plusieurs Views est que vous
pourrez montrer à l'utilisateur une image (un View) tandis que
l'ordinateur dessine une autre image (dans un autre View).
Le View est doté d'un nombre de variables importantes qui indiquent
la position du View, s'il doit être ou non en mode entrelacé, ainsi
que les pointeurs sur le premier ViewPort, etc.
12.2.3.1.1 La structure View
La structure View ressemble à ceci [telle qu'elle est définie dans
le fichier d'en tête "view.h"] :
struct View
{
struct ViewPort *ViewPort;
struct cprlist *LOFCprList;
struct cprlist *SHFCprList;
short DyOffset, DxOffset;
UWORD Modes;
};
|
- ViewPort : pointeur sur le premier ViewPort de l'affichage.
- LOFCprList : pointeur sur une structure cprlist utilisée par le Copper (expliquée plus loin).
- SHFCprList : pointeur sur une structure cprlist utilisée par le
Copper, si la structure est en mode entrelacé (lorsque l'affichage est en mode entrelacé, on
utilise LOFCprList et SHFCprList).
- DyOffset : ordonnée Y de l'affichage.
- DxOffset : abscisse X de l'affichage.
- Modes : si l'affichage doit être en mode entrelacé, vous
mettrez à 1 le drapeau LACE. Si l'affichage devait être
relié à un signal vidéo externe, à l'aide d'un Genlock,
vous mettrez à 1 le drapeau GENLOCK_VIDEO.
12.2.3.1.2 Préparation d'une structure View
Après avoir déclaré une structure View, vous devrez la préparer.
Pour ce faire, vous appellerez la fonction InitView() avec un
pointeur sur une structure View comme seul paramètre :
struct View my_view; /* Déclaration d'une structure View. */
InitView( &my_view ); /* Préparation de celle-ci. */
|
Si vous souhaitez positionner le View à un endroit précis de
l'affichage, vous devrez donner des valeurs DxOffset et DyOffset
en rapport. Par exemple :
my_view.DxOffset = 20; /* 20 pixels à droite. */
my_view.DyOffset = 50; /* 50 lignes plus bas. */
|
Si vous souhaitez utiliser un affichage en mode entrelacé, vous
devrez aussi mettre à 1 le drapeau "LACE". Par exemple :
12.2.3.2 Les Viewports
Comme nous l'avons dit auparavant, chaque View peut être composé
d'un ou plusieurs ViewPorts. Chaque ViewPort peut avoir sa propre
résolution, un nombre de couleurs et une taille qui lui seront
propres.
12.2.3.2.1 La structure Viewport
La structure ViewPort ressemble à ceci [telle qu'elle est définie
dans le fichier d'en-tête "view.h"] :
struct ViewPort
{
struct ViewPort *Next;
struct ColorMap *ColorMap;
struct CopList *DspIns;
struct CopList *SprIns;
struct CopList *ClrIns;
struct UCopList *UCopIns;
SHORT DWidth, DHeight;
SHORT DxOffset, DyOffset;
UWORD Modes;
UBYTE SpritePriorities;
UBYTE reserved;
struct RasInfo *RasInfo;
};
|
- Next : pointeur sur le prochain ViewPort dans le View,
s'il y en a plusieurs, autrement NULL.
- ColorMap : pointeur sur une structure ColorMap qu'on utilise
pour ce ViewPort (voir ci-dessous pour avoir plus de renseignements sur la structure ColorMap).
- DspIns : utilisé par le Copper.
- SprIns : instructions de couleur propres aux sprites.
- ClrIns : instructions de couleur propres aux sprites.
- UCopIns : utilisé par le Copper.
- DWidth : taille horizontale du ViewPort.
- DHeight : taille verticale du ViewPort.
- DxOffset : abscisse X du ViewPort dans le View.
- DyOffset : ordonnée Y du ViewPort dans le View.
- Modes : mode d'affichage pour ce ViewPort. On pourra
employer les drapeaux suivants :
- HIRES : mettez ce drapeau à 1 si vous
voulez avoir un ViewPort en haute résolution, autrement
le système emploiera la basse résolution.
- LACE : mettez ce drapeau à 1 si vous
voulez avoir un ViewPort en mode entrelacé, autrement
le système le mettra en mode non entrelacé.
- SPRITES : mettez ce drapeau à 1 si vous voulez avoir des sprites dans ce ViewPort.
- HAM : mettez ce drapeau à 1 si vous
voulez employer le mode d'affichage spécial "Hold And Modify". L'affichage devra être
en basse résolution et employer six plans de bits. Permet d'afficher 4096 couleurs en même temps.
- EXTRA_HALFBRITE : mettez ce drapeau à 1 si vous voulez employer le mode
d'affichage spécial "Extra Half Bright". L'affichage devra être en basse résolution et employer
six plans de bits. Permet d'utiliser 64 couleurs.
- DUALPF : mettez ce drapeau à 1 si vous voulez vous servir d'un double champ de jeu.
- PFBA : mettez ce drapeau à 1 si vous souhaitez que le champ de jeu 1 se trouve au-dessus du champ de jeu 2.
Si vous ignorez ce drapeau, les priorités seront inversées.
- GENLOCK_VIDEO : mettez ce drapeau à 1 si on doit pouvoir mélanger l'affichage
à un autre signal vidéo, à l'aide d'un genlock.
Remarque : vous pourrez combiner plusieurs de ces
modes, si vous le souhaitez. Seulement, n'oubliez
pas de mettre un "|" entre chaque drapeau. Par
exemple, pour créer un ViewPort en haute résolution
en mode entrelacé, vous devrez mettre ce champ à "HIRES|LACE".
- SpritePriorities : priorité des sprites de ce ViewPort.
- reserved : quels sprites sont réservés ; il ne peut être
utilisé (voir le chapitre sprites et
VSprites pour plus de renseignements).
- RasInfo : pointeur sur une structure RasInfo.
12.2.3.2.2 Préparation d'une structure ViewPort
Après avoir déclaré une structure ViewPort, vous devrez la préparer
(comme nous l'avons fait pour la structure View). Pour ce faire, vous
appelerez la fonction InitVPort() avec un pointeur sur une structure
ViewPort comme seul paramètre :
/* Déclaration de la structure View: */
struct ViewPort my_view_port;
/* Préparation de celle-ci: */
InitVPort( &my_view_port );
|
Une fois que vous aurez préparé la structure, vous pourrez placer
les valeurs voulues dans les différents champs (voici à titre d'exemple) :
- my_view_port.Next = NULL; : si nous avons plusieurs
ViewPorts dans le même View, nous les relierons ensemble, autrement mettre NULL.
- my_view_port.DWidth = WIDTH; : fixe la largeur voulue.
- my_view_port.DHeight = HEIGHT; : fixe la hauteur voulue.
- my_view_port.DxOffset = 0; : coordonnées X du ViewPort dans le View
- my_view_port.DyOffset = 0; : coordonnées Y du ViewPort dans le View.
- my_view_port.Modes = HIRES|LACE; : mettre les drapeaux voulus (par exemple, haute résolution entrelacée).
- my_view_port.RasInfo = &my_ras_info; : pointeur sur la structure RasInfo de ce ViewPort.
12.2.3.3 La ColorMap
Chaque ViewPort a sa propre liste de couleurs. Celles-ci sont
stockées dans une structure ColorMap qui renferme des
informations du type suivant : le nombre de couleurs utilisant
l'affichage, quelles couleurs, et - pour chaque couleur - ses
valeurs RVB (intensité de Rouge + Vert + Bleu).
12.2.3.3.1 La structure ColorMap
La structure ColorMap ressemble à ceci [telle qu'elle est définie
dans le fichier d'en-tête "view.h"] :
struct ColorMap
{
UBYTE Flags;
UBYTE Type;
UWORD Count;
APTR ColorTable;
};
|
12.2.3.3.2 Déclaration et initialisation d'une structure ColorMap
Pour déclarer et initialiser une structure ColorMap, vous n'aurez
qu'à appeler la fonction GetColorMap(). Celle-ci s'occupera de
tout : vous n'aurez qu'à indiquer à la fonction combien de couleurs
vous souhaitez utiliser.
Voici comment on se réserve une liste de couleurs et on la relie à ViewPort :
my_view_port.ColorMap = GetColorMap( 32 );
|
Vous ne devrez pas oublier de vérifier que le système vous a bien
réservé la liste (map) de couleurs demandée. Par exemple :
if( my_view_port.ColorMap == NULL )
clean_up(); /* sortir */
|
12.2.3.3.3 Fixer les valeurs RVB
Dès que vous avez obtenu votre structure ColorMap, vous devrez
fixer les valeurs RVB (Rouge, Vert, Bleu) de chaque couleur.
Chaque couleur peut être un mélange de rouge, de vert et de bleu
dans un rapport allant de 0 à 15. En hexa, cela ira de 0x0 à 0xF.
Voici quelques exemples :
valeur RVB Couleur
-----------------------
0xF00 Rouge
0x0F0 Vert
0x00F Bleu
0x600 Rouge foncé
0x060 Vert foncé
0x006 Bleu foncé
0xFF0 Jaune
0x000 Noir
0x444 Gris foncé
0x888 Gris clair
0xFFF Blanc
|
Étant donné que chaque valeur RVB peut prendre seize niveaux
différents, vous pourrez définir jusqu'à 16*16*16=4096 couleurs différentes.
Si vous préparez une structure ColorMap devant utiliser quatre
couleurs, vous devrez lui fournir une table de couleurs avec des valeurs RVB.
/* 1. Déclaration d'une table de couleurs RVB : */
UWORD my_color_table[] =
{
0x000, /* Noir */
0xF00, /* Rouge */
0x0F0, /* Vert */
0x00F, /* Bleu */
};
/* 2. Déclaration du pointeur : */
UWORD *pointer;
/* 3. Fixer le pointeur pour qu'il pointe sur la table de couleurs : */
pointer = (UWORD *) my_view_port.ColorMap->ColorTable;
/* 4. Fixez les couleurs : */
for( loop = 0; loop < 4; loop++ )
*pointer++ = my_color_table[ loop ];
|
12.2.3.3.4 Libérer la mémoire occupée par la ColorMap
Lorsque votre programme ferme un ViewPort, vous ne devrez pas
oublier de libérer la mémoire occupée par la ColorMap. Vous pourrez
le faire à l'aide de la fonction FreeColorMap() :
FreeColorMap( my_view_port.ColorMap );
|
12.2.3.4 La BitMap
Comme nous l'avons déjà dit, la BitMap est une zone de mémoire
rectangulaire où chaque bit représente un pixel. Par la combinaison
de deux ou plusieurs BitMaps, chaque pixel sera représenté par
une combinaison de deux ou plusieurs bits qui déterminent les
couleurs qu'il faudra employer. Le pointeur sur chaque BitMap,
les renseignements concernant sa taille, etc. sont tous stockés
dans la structure BitMap.
12.2.3.4.1 La structure BitMap
La structure BitMap ressemble à ceci [telle qu'elle est définie
dans le fichier d'en-tête "gfx.h"] :
struct BitMap
{
UWORD BytesPerRow;
UWORD Rows;
UBYTE Flags;
UBYTE Depth;
UWORD pad;
PLANEPTR Planes[ 8 ];
};
|
- BytesPerRow : combien d'octets on utilise pour chaque rangée.
- Rows : combien il y a de rangées.
- Flags : renseignements supplémentaires sur les BitMaps (actuellement non utilisés).
- Depth : combien il y a de plans de bits.
- pad : espace supplémentaire.
- Planes : une liste de huit pointeurs (PLANEPTR est un pointeur sur une BitMap).
12.2.3.4.2 Déclaration et initialisation d'une structure BitMap
Vous déclarez la structure comme d'habitude et vous l'initialisez
à l'aide de la fonction InitBitMap(). Vous devrez fournir à cette
fonction un pointeur sur votre structure BitMap ainsi que tout
renseignement concernant sa taille et sa profondeur (combien de
plans de bits seront utilisés).
- Synopsis : InitBitMap( bitmap, profondeur, largeur, hauteur );
- bitmap : (struct BitMap *). Pointeur sur la BitMap.
- profondeur : (long). Combien de plans de bits seront utilisés.
- largeur : (long). Largeur du raster.
- hauteur : (long). Hauteur du raster.
Les renseignements concernant la taille et la profondeur d'une
BitMap sont utilisés dans un programme en plusieurs endroits,
par conséquent, je vous recommande de définir un certain nombre
de constantes au début du programme et de les employer par la
suite au lieu d'écrire explicitement ces valeurs, lors de
l'appel. Ceci vous permettra de changer plus facilement quelque
chose, du moment que vous aurez à changer le code à un seul
endroit, et ceci vous évitera beaucoup de fautes d'écriture.
Exemple :
#define WIDTH 320 /* largeur 320 pixels. */
#define HEIGHT 200 /* hauteur 200 lignes. */
#define DEPTH 5 /* 5 plans de bits permettent d'avoir 32 couleurs. */
struct BitMap my_bit_map;
InitBitMap( &my_bit_map, DEPTH, WIDTH, HEIGHT );
|
12.2.3.4.3 Réservation de mémoire pour le raster
Dès que vous aurez initialisé la structure Bitmap, il sera temps
de réserver de la mémoire pour chaque plan de bits. Vous pourrez
réserver la mémoire nécessaire à l'affichage par la fonction
AllocRaster() :
- Synopsis : pointeur = AllocRaster( largeur, hauteur );
- pointeur : (PLANEPTR). Pointeur sur la zone de mémoire demandée ou
NULL s'il n'y a pas assez de mémoire.
- largeur : (long). Largeur de la BitMap.
- hauteur : (long). Hauteur de la BitMap.
Étant donné que vous pourriez avoir à réserver plusieurs
plans de bits, le mieux serait d'inclure la fonction AllocRaster()
dans une boucle. N'oubliez pas de vérifier que le système vous
a bien alloué la mémoire que vous avez demandée ! Pour terminer,
il est probable que la mémoire obtenue soit remplie d'octets
inutiles et il vaudra mieux la vider avant de vous en servir.
L'emploi du Blitter est la méthode plus rapide pour vider
une zone de mémoire rectangulaire de grande taille; pour ce
faire appelez la fonction BltClear() :
- Synopsis : BltClear( pointeur, octets, drapeaux );
- pointeur : (char *). Pointeur sur la zone de mémoire à vider.
- octets : (long). Les 16 bits de rang inférieur informent le
Blitter sur nombre d'octets existant par rangée
et les 16 bits de rang supérieur l'informent sur
le nombre de rangées existantes. Cette valeur est
calculée automatiquement pour vous à l'aide de la
macro RASSIZE(). Donnez seulement à RASSIZE() la
largeur et la hauteur correctes et la macro
retournera une valeur correcte. La définition de
[RASSIZE() se trouve dans le fichier "gfx.h".]
- flags : (long). Met à 1 le bit 0 pour obliger la fonction
à attendre tant que le Blitter n'en a pas terminé
avec votre demande.
Voici un exemple de comment on alloue la mémoire d'affichage,
on en vérifie la disponibilité et on la vide (n'oubliez pas
que vous devrez libérer toute la mémoire que vous aurez demandée !
voir ci-dessous pour plus de renseignements)
for( loop = 0; loop < DEPTH; loop++ )
{
my_bit_map.Planes[ loop ] = AllocRaster( WIDTH, HEIGHT );
if( my_bit_map.Planes[ loop ] == NULL )
clean_up(); /* Sortir */
BltClear( my_bit_map.Planes[ loop ], RASSIZE( WIDTH, HEIGHT ), 0 );
}
|
12.2.3.5 Le RasInfo
La structure RasInfo contient des renseignements sur l'endroit où
se trouve la structure BitMap, ainsi que sur les valeurs x/y du
raster. Si vous utilisez le mode d'affichage spécial double champ de jeu
(dual playfields), la structure contiendra aussi un pointeur sur le
deuxième champ de jeu.
12.2.3.5.1 La structure RasInfo
La structure RasInfo ressemble à ceci [telle qu'elle est définie
dans le fichier d'en-tête "view.h"] :
struct RasInfo
{
struct RasInfo *Next;
struct BitMap *BitMap;
SHORT RxOffset, RyOffset;
};
|
- Next : si vous employez le mode d'affichage spécial double champ de jeu,
ce pointeur contiendra l'adresse du deuxième champ de jeu (la structure
RasInfo du premier champ de jeu contiendra un pointeur sur la structure
RasInfo du deuxième champ de jeu dont le pointeur pointera sur NULL).
- BitMap : pointeur sur la BitMap.
- RxOffset : valeur X du raster (en changeant les valeurs RxOffset
et RyOffset, vous aurez la possibilité de faire défiler rapidement tout le raster à l'écran).
- RyOffset : valeur Y du raster.
12.2.3.5.2 Déclaration et initialisation d'une structure RasInfo
Voici un exemple de déclaration et d'initialisation d'une structure RasInfo :
/* Déclaration d'une structure RasInfo : */
struct RasInfo my_ras_info;
/* Préparation de la structure RasInfo : */
my_ras_info.BitMap = &my_bit_map; /* Pointeur sur la structure */
/* BitMap. */
my_ras_info.RxOffset = 0; /* Le coin supérieur gauche */
my_ras_info.RyOffset = 0; /* du raster sera situé dans */
/* le coin supérieur gauche */
/* de l'affichage. */
my_ras_info.Next = NULL; /* Champ de jeu unique - une */
/* seule structure RasInfo */
/* sera nécessaire. */
|
12.2.3.6 MakeVPort()
Dès que vous aurez initialisé toutes les structures nécessaires,
vous devrez préparer le matériel de l'Amiga (tout particulièrement
le Copper) pour que ces structures puissent créer l'affichage
voulu. Chaque ViewPort pourra avoir sa résolution propre, sa
taille, sa liste de couleurs, etc. et par conséquent, vous
devrez préparer chaque ViewPort par un appel de la fonction
MakeVPort().
- Synopsis : MakeVPort( view, viewport );
- view : (struct View *). Pointeur sur le View du ViewPort.
- viewport : (struct ViewPort *). Pointeur sur le ViewPort.
Note : vous devez préparer chaque ViewPort que vous emploierez.
12.2.3.7 MrgCop()
Toutes les instructions destinées à un affichage particulier du
ViewPort, en même temps que les instructions utilisées par les
registres matériels des sprites devront être reliées avant que
vous puissiez réaliser un affichage. Toutes ces instructions sont
reliées les unes aux autres par le simple appel de la fonction
MrgCop(). MrgCop() réunira dans une liste toutes les instructions
d'affichage des coprocesseurs.
- Synopsis : MrgCop( view );
- view : (struct View *). Pointeur sur le View.
12.2.3.8 LoadView()
A la fin, vous pourrez alors montrer l'affichage. Vous pourrez le
faire en appelant la fonction LoadView() :
- Synopsis : LoadView( view );
- view : (struct View *). Pointeur sur le View.
Vous devrez vous souvenir qu'à partir de maintenant, vous avez créé
votre propre affichage et qu'à la fin du programme vous devez
restaurer l'affichage d'origine ! Pour ceci, vous devrez sauvegarder
le pointeur sur l'affichage d'origine avant de lancer votre propre
affichage. Vous trouverez un pointeur sur le View courant dans
la structure GfxBase.
struct View *old_view;
old_view = GfxBase->ActiView;
|
12.2.4 La fermeture d'un affichage
Quand vous arrêterez votre affichage, vous ne devrez pas oublier
qu'il vous faut restaurer le View d'origine en appelant la
fonction LoadView() avec un pointeur sur la structure View
d'origine :
Vous devrez aussi rendre la mémoire qui vous a été réservée
automatiquement lors de l'appel aux fonctions MakeVPort() et
MrgCop(). Par conséquent, vous devrez appeler la fonction
FreeVPortCopLists() pour chaque ViewPort que vous aurez créé.
- Synopsis : FreeVPortCopLists( viewport );
- view : (struct ViewPort *). Pointeur sur le ViewPort.
Vous devrez aussi appeler la fonction FreeCprList() pour chaque
View que vous aurez créé. Vous transmettrez à la fonction un
pointeur sur la structure CprList (LOFCprList). Si vous avez
crée un View en mode entrelacé, vous devrez aussi libérer une
structure CprList particulière (SHFCprList) que le système
utilise seulement pour les Views en mode entrelacé.
- Synopsis : FreeCprList( cprlist );
- cprlist : (struct cprlist *). Pointeur sur la structure CprList
(LOFCprList) du View. Si le View était en mode
entrelacé vous devrez aussi appeler la fonction
FreeCprList() avec un pointeur sur la SHFCprList.
Vous devrez aussi libérer la mémoire d'affichage que vous aviez
demandée pour le raster. Vous pourrez libérer le raster en
appelant la fonction FreeRaster() avec un pointeur sur un plan de bits.
Il vous faudra faire appel à cette fonction pour chaque plan de bits
que vous aviez alloué !
- Synopsis : FreeRaster( bitplane, width, height );
- bitplane : (PLANEPTR). Pointeur sur un plan de bits.
- width : (long). Largeur du plan de bits.
- height : (long). Hauteur du plan de bits.
Pour finir, vous devrez libérer la structure ColorMap qui a
été allouée et initialisée automatiquement par la fonction
GetColorMap(). Vous libérerez une liste de couleurs en appelant
la fonction FreeColorMap().
- Synopsis : FreeColorMap( colormap );
- colormap : (struct ColorMap *). Pointeur sur la structure ColorMap.
Voici un exemple de comment on met fin à un affichage :
/* 1. Restaurer le View d'origine : */
LoadView( old_view );
/* 2. Désallouer les instructions d'affichage du ViewPort : */
FreeVPortCopLists( &my_view_port );
/* 3. Désallouer les instructions d'affichage du View : */
FreeCprList( my_view.LOFCprList );
/* 4. Désallouer la mémoire d'affichage, pour chaque plan de bits : */
for( loop = 0; loop < DEPTH; loop++ )
FreeRaster( my_bit_map.Planes[ loop ], WIDTH, HEIGHT );
/* 5. Désallouer la ColorMap: */
FreeColorMap( my_view_port.ColorMap );
|
12.2.5 Un exemple
Voici un exemple de comment ouvrir un affichage NTSC (américain)
en haute résolution. Voilà ce qu'il faut faire :
- Préparer le View.
- Préparer le ViewPort.
- Préparer la ColorMap.
- Préparer la BitMap.
- Préparer le RasInfo.
- Préparer le matériel de l'Amiga avec MakeVPort() et MrgCop().
- Montrer le nouveau View.
- Le View est en place et vous en faites ce que vous voulez.
- Restaurer le View d'origine.
- Libérer toutes les ressources et sortir.
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#define WIDTH 640 /* Largeur 640 pixels (haute résolution). */
#define HEIGHT 200 /* Hauteur 200 lignes (NTSC non entrelacé). */
#define DEPTH 3 /* trois plans de bits, ce qui donne huit couleurs.*/
#define COLOURS 8 /* 2^3 = 8 */
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct View my_view;
struct View *my_old_view;
struct ViewPort my_view_port;
struct RasInfo my_ras_info;
struct BitMap my_bit_map;
struct RastPort my_rast_port;
UWORD my_color_table[] =
{
0x000, /* Couleur 0, Noir */
0x800, /* Couleur 1, Rouge */
0xF00, /* Couleur 2, Rouge clair */
0x080, /* Couleur 3, Vert */
0x0F0, /* Couleur 4, Vert clair */
0x008, /* Couleur 5, Bleu */
0x00F, /* Couleur 6, Bleu clair */
0xFFF, /* Couleur 7, Blanc */
};
void clean_up();
void main();
void main()
{
UWORD *pointer;
int loop;
/* Ouverture de la bibliothèque Intuition : */
IntuitionBase = (struct IntuitionBase *)
OpenLibrary( "intuition.library", 0 );
if( !IntuitionBase )
clean_up( "Impossible d'ouvrir la bibliothèque Intuition !" );
/* Ouverture de la bibliothèque Graphics : */
GfxBase = (struct GfxBase *)
OpenLibrary( "graphics.library", 0 );
if( !GfxBase )
clean_up( "Impossible d'ouvrir la bibliothèque Graphics !" );
/* Sauvegarde du View courant, afin de le restaurer par la suite : */
my_old_view = GfxBase->ActiView;
/* 1. Préparation de la structure View et attribution d'un */
/* pointeur sur le premier ViewPort : */
InitView( &my_view );
my_view.ViewPort = &my_view_port;
/* 2. Préparation de la structure ViewPort structure et affectation */
/* d'un certain nombre de valeurs importantes : */
InitVPort( &my_view_port );
my_view_port.DWidth = WIDTH; /* Fixer la largeur. */
my_view_port.DHeight = HEIGHT; /* Fixer la hauteur. */
my_view_port.RasInfo = &my_ras_info; /* Fournit un pointeur sur */
/* RasInfo. */
my_view_port.Modes = HIRES; /* Haute résolution. */
/* 3. Prendre la liste de couleurs, la relier au ViewPort et la */
/* préparer : */
my_view_port.ColorMap = (struct ColorMap *) GetColorMap( COLOURS );
if( my_view_port.ColorMap == NULL )
clean_up( "IMPOSSIBLE de prendre une ColorMap!" );
/* Prendre un pointeur sur la liste de couleurs : */
pointer = (UWORD *) my_view_port.ColorMap->ColorTable;
/* Fixer les couleurs : */
for( loop = 0; loop < COLOURS; loop++ )
*pointer++ = my_color_table[ loop ];
/* 4. Préparer la BitMap : */
InitBitMap( &my_bit_map, DEPTH, WIDTH, HEIGHT );
/* Allouer la mémoire pour le raster: */
for( loop = 0; loop < DEPTH; loop++ )
{
my_bit_map.Planes[ loop ] = (PLANEPTR) AllocRaster( WIDTH, HEIGHT );
if( my_bit_map.Planes[ loop ] == NULL )
clean_up( "IMPOSSIBLE d'allouer assez de mémoire pour le raster !" );
/* Vide la mémoire d'affichage à l'aide du Blitter : */
BltClear( my_bit_map.Planes[ loop ], RASSIZE( WIDTH, HEIGHT ), 0 );
}
/* 5. Préparer la structure RasInfo : */
my_ras_info.BitMap = &my_bit_map; /* Pointeur sur la structure BitMap. */
my_ras_info.RxOffset = 0; /* Le coin supérieur gauche du raster */
my_ras_info.RyOffset = 0; /* se situera dans le coin supérieur */
/* de l'affichage. */
my_ras_info.Next = NULL; /* Un seul plan - on aura besoin */
/* d'une seule structure RasInfo. */
/* 6. Création de l'affichage : */
MakeVPort( &my_view, &my_view_port );
MrgCop( &my_view );
/* 7. Préparer le RastPort et lui fournir un pointeur sur la BitMap. */
InitRastPort( &my_rast_port );
my_rast_port.BitMap = &my_bit_map;
/* 8. Afficher le nouveau View : */
LoadView( &my_view );
/* 9. Votre View est affiché et vous pouvez */
/* en faire ce que bon vous en semblera. */
/* 10. Restaurer le View d'origine : */
LoadView( my_old_view );
/* 11. Libérer toutes les ressources allouées et sortir. */
clean_up( "THE END" );
}
/* Retourne toutes les ressource allouées : */
void clean_up( message )
STRPTR message;
{
int loop;
/* Libère automatiquement les structures d'affichage allouées : */
FreeVPortCopLists( &my_view_port );
FreeCprList( my_view.LOFCprList );
/* Désalloue la mémoire d'affichage, un plan de bits après l'autre : */
for( loop = 0; loop < DEPTH; loop++ )
if( my_bit_map.Planes[ loop ] )
FreeRaster( my_bit_map.Planes[ loop ], WIDTH, HEIGHT );
/* Désalloue la ColorMap : */
if( my_view_port.ColorMap ) FreeColorMap( my_view_port.ColorMap );
/* Fermeture de la bibliothèque Graphics : */
if( GfxBase ) CloseLibrary( GfxBase );
/* Fermeture de la bibliothèque Intuition : */
if( IntuitionBase ) CloseLibrary( IntuitionBase );
/* Affiche le message et sort : */
printf( "%s\n", message );
exit();
}
|
12.3 Le dessin
Nous avons déjà dit comment on crée et on ouvre un affichage ;
maintenant, nous verrons les différentes routines de dessin
présentes dans l'Amiga. L'Amiga vous permet non seulement de
tracer des points et des lignes simples, mais aussi des images
complexes. Pour augmenter l'effet, on peut combiner ces routines
avec des masques et avec des modèles multicolores. L'Amiga offre
en outre trois méthodes différentes pour dessiner des objets
pleins. Vous pourrez en outre faire défiler, copier et combiner
logiquement des zones rectangulaires grâce à la rapidité du Blitter.
12.3.1 Le RastPort
Avant de commencer à utiliser les routines de dessin, vous aurez
encore à déclarer et à initialiser une structure supplémentaire
("pas plus d'une !", je vous entends dire). La raison pour
laquelle nous avons besoin d'une structure supplémentaire est
que la majorité des routines de dessin auront besoin de connaître
la couleur du crayon, le masque et le modèle (j'en parlerai plus
loin dans ce chapitre) que vous aurez choisis. Ce type de
renseignement est par conséquent renfermé dans une structure qui
s'appelle RastPort.
12.3.1.1 La structure RastPort
La structure RastPort ressemble à ceci [telle qu'elle est définie
dans le fichier d'en-tête "rastport.h"] (par chance, en général,
vous n'aurez pas à vous préoccuper beaucoup pour cette structure).
struct RastPort
{
struct Layer *Layer;
struct BitMap *BitMap;
USHORT *AreaPtrn;
struct TmpRas *TmpRas;
struct AreaInfo *AreaInfo;
struct GelsInfo *GelsInfo;
UBYTE Mask;
BYTE FgPen;
BYTE BgPen;
BYTE AOlPen;
BYTE DrawMode;
BYTE AreaPtSz;
BYTE linpatcnt;
BYTE dummy;
USHORT Flags;
USHORT LinePtrn;
SHORT cp_x, cp_y;
UBYTE minterms[8];
SHORT PenWidth;
SHORT PenHeight;
struct TextFont *Font;
UBYTE AlgoStyle;
UBYTE TxFlags;
UWORD TxHeight;
UWORD TxWidth;
UWORD TxBaseline;
WORD TxSpacing;
APTR *RP_User;
ULONG longreserved[2];
UWORD wordreserved[7];
UBYTE reserved[8];
};
|
- Layer : pointeur sur une structure Layer.
- BitMap : pointeur sur la structure BitMap de ce RastPort.
- AreaPtrn : pointeur sur un tableau de valeurs USHORT utilisé
pour créer le modèle de remplissage de la zone à dessiner.
- TmpRas : pointeur sur une structure TmpRas. Celle-ci est
utilisée par les fonctions AreaMove(), AreaDraw()
et AreaEnd() (voir ci-dessous pour plus de renseignements).
- AreaInfo : pointeur sur une structure AreaInfo. Celle-ci
aussi est utilisée par les fonctions AreaMove(), AreaDraw() and AreaEnd().
- GelsInfo : pointeur sur une structure GelsInfo. Celle-ci est
utilisée par les routines d'animation (VSprite et BOS).
- Mask : ce masque vous permet de déterminer quels plans de bits
devront être concernés par les routines de dessin.
Le premier bit représente le plan de bits 0, le
deuxième représente le plan de bits 1 et ainsi de
suite. Si ce bit est activé (1), le plan de bits sera
concerné. Si ce bit n'est pas activé (0), le
plan de bits ne sera pas concerné par les routines
de dessin.
Par exemple, si la valeur du masque est fixée à 0xFF
(0xFF en hexadécimal = 11111111 en binaire), tous les
plans de bits seront concernés par les routines de
dessin. Si la valeur du masque est fixée à 0xF6
(0xF6 en hexadécimal = 11110110 en binaire), le
plan de bits zéro et le trois ne seront pas concernés.
- FgPen : couleur du crayon de premier plan.
- BgPen : couleur du crayon d'arrière-plan.
- AOlPen : couleur du crayon pour AreaFill Outline.
- DrawMode : il existe quatre types de modes différents de dessin :
- JAM1 : là où vous écrirez, le système emploiera
le crayon de premier champ de jeu pour restaurer la couleur d'origine et, là où vous
n'écrirez pas, l'arrière-plan ne sera pas modifié. Par exemple, fixons FgPen à la
couleur cinq et le mode de dessin à JAM1. Maintenant, si vous écrivez un pixel,
celui-ci aura la couleur cinq et la couleur d'arrière-plan ne sera pas
modifiée (une couleur reste "bloquée" dans le raster).
- JAM2 : là où vous écrirez, le système emploiera
le crayon de premier champ de jeu pour restaurer la couleur d'origine et, là où vous
n'écrirez pas, l'arrière-plan ne sera pas modifié. Par exemple, fixons FgPen à la
couleur cinq, BgPen à la couleur six et le mode de dessin à JAM2. Maintenant, si
vous écrivez un pixel, ce pixel aura la couleur cinq, si vous écrivez un caractère,
ce caractère aura la couleur cinq et la couleur d'arrière-plan aura la couleur
six (deux couleurs restent "bloquées" dans le raster).
- COMPLEMENT : chaque pixel que vous dessinerez sera
dessiné dans la couleur binaire complémentaire. Là où vous écrirez des
1, les bits correspondants dans le raster seront inversés. L'avantage avec ce mode
de dessin est que si vous écrivez deux fois au même endroit, le dessin d'origine
sera restauré.
- INVERSVID : on emploie ce mode seulement avec du texte
et il est combiné soit avec JAM1 soit avec JAM2.
- INVERSVID|JAM1 : seul l'arrière-plan est dessiné avec FgPen.
- INVERSVID|JAM2 : l'arrière-plan est dessiné avec FgPen et les caractères avec BgPen.
- AreaPtSz : la hauteur d'un modèle devra être une puissance de
deux et cette valeur (2^x) est stockée ici. Si AreaPtSz est fixé à 4, le modèle aura une hauteur
égale à 2^4=16 lignes (si vous utilisez des modèles multicolores, la valeur d'AreaPtSz devra
être négative. Mettez AreaPtSz à -3 si vous voulez employer un modèle multicolore d'une hauteur de
huit lignes. 2^3=8).
- linpatcnt : utilisé pour créer le modèle de ligne.
- dummy : zone de mémoire de vidange où le système stocke les valeurs "bidon".
- Flags : si le drapeau AREAOUTLINE est mis à 1 toutes les
"routines AreaFill" traceront un filet autour des
zones remplies par l'intermédiaire de AOlPen.
Si le RastPort à un double tampon le drapeau, DBUFFER est mis à 1.
- LinePtrn : 16 bits utilisés pour le modèle de ligne. Une valeur
0x9669 (en hexadécimal) créera le modèle suivant : 1001011001101001.
- cp_x : position courante X du crayon.
- cp_y : position courante Y du crayon.
- minterms : espace mémoire supplémentaire.
- PenWidth : largeur du crayon (les routines de dessin ne s'en servent pas).
- PenHeight : hauteur du crayon (les routines de dessin ne s'en servent pas).
- Font : pointeur sur une structure TextFont.
- AlgoStyle : mode de jeu de caractères généré de manière
algorithmique (par exemple, si la fonte n'accepte
pas le mode souligné, gras ou italique, l'Amiga
pourra les générer en utilisant certains algorithmes).
- TxFlags : drapeaux spéciaux pour le texte.
- TxHeight : hauteur du jeu de caractères.
- TxWidth : largeur nominale du jeu de caractères.
- TxBaseline : position de la ligne de base du texte.
- TxSpacing : intervalle entre caractères.
- RP_User : variables spéciales et zones de mémoire qui ne nous
sont pas utiles. Réservées pour l'usage interne de
l'Amiga et pour les versions à venir du système graphique.
- longreserved : idem.
- wordreserved : idem.
- reserved : idem.
Remarque : vous aurez rarement besoin de changer ou d'examiner ces
valeurs directement. Normalement, pour changer certaines valeurs,
vous emploierez (et devrez employer) les fonctions décrites par
la suite.
12.3.1.2 La préparation d'un RastPort
Pour préparer un RastPort, vous devrez déclarer une structure
RastPort et l'initialiser en appelant la fonction InitRastPort()
avec un pointeur sur le RastPort comme seul paramètre.
- Synopsis : InitRastPort( rast_port );
- rast_port : (RastPort *). Pointeur sur le RastPort qui doit être initialisé.
La dernière chose que vous aurez à faire, ce sera de fournir à
votre RastPort un pointeur sur votre structure BitMap. Voici un
court exemple :
/* 1. Déclaration d'une structure RastPort : */
struct RastPort my_rast_port;
/* 2. Initialisation du RastPort par l'intermédiaire */
/* de la fonction InitRastPort() : */
InitRastPort( &my_rast_port );
/* 3. Fournir au RastPort un pointeur sur votre structure BitMap : */
/* [Nous partons du principe que la structure BitMap a été */
/* déclarée et initialisée de manière correcte, comme expliqué */
/* ci-dessus]. */
my_rast_port.BitMap = &my_bit_map;
|
12.3.2 Les crayons pour dessiner
Pour dessiner, les routines de dessin de bas niveau emploient
trois types différents de crayons :
- FgPen : le crayon de premier champ de jeu est celui qu'on emploie le plus couramment.
- BgPen : le crayon d'arrière-plan est employé habituellement
pour dessiner dans l'arrière-plan, par exemple si vous êtes en train d'écrire un texte.
- AOlPen : le crayon Areaoutline est employé pour encadrer des zones
qui seront remplies par les routines AreaFill.
Remarque : le mode de dessin détermine quels crayons seront employés.
Vous utiliserez la fonction SetAPen() pour changer la couleur de FgPen :
- Synopsis : SetAPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). La valeur d'une nouvelle couleur.
Vous utiliserez la fonction SetBPen() pour changer la couleur de BgPen :
- Synopsis : SetBPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). La valeur d'une nouvelle couleur.
Vous emploierez la macro SetOPen() pour changer la couleur de AOlPen.
Remarque : il ne s'agit pas d'une fonction. Il s'agit réellement
d'une macro qui est définie dans le fichier en-tête "gfxmacros.h".
Si vous voulez vous servir de cette macro, vous ne devrez pas
oublier d'inclure ce fichier dans votre programme.
- Synopsis : SetOPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). La valeur d'une nouvelle couleur.
12.3.3 Les modes de dessin
Cinq modes de dessin différents sont acceptés par l'Amiga :
- JAM1 : FgPen sera employé, l'arrière-plan est inchangé
(une couleur est "bloquée" dans un raster).
- JAM2 : FgPen sera employé comme crayon de premier champ de jeu
tandis que l'arrière-plan (là où, par exemple,
vous êtes en train d'écrire un texte) sera rempli
avec la couleur de BgPen (deux couleurs sont
"bloquées" dans un raster).
- COMPLEMENT : chaque pixel concerné sera dessiné dans sa couleur
binaire complémentaire. Là où vous aurez écrit des 1, les bits correspondants dans le raster seront inversés.
- INVERSVID|JAM1 : ce mode est employé seulement avec du texte. Seul
l'arrière-plan du texte sera dessiné avec FgPen.
- INVERSVID|JAM2 : ce mode est employé seulement avec du texte.
L'arrière-plan du texte sera dessiné avec FgPen, tandis
que les caractères seront dessinés avec BgPen.
Pour fixer le mode de dessin, vous emploierez la fonction SetDrMd() :
- Synopsis : SetDrMd( rast_port, new_mode );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_mode : (long). Le nouveau mode de dessin. Mettre l'un des modes
suivants : JAM1, JAM2, COMPLEMENT, INVERSVID|JAM1 ou INVERSVID|JAM2.
12.3.4 Les modèles
Les routines de dessin de l'Amiga vous offrent la possibilité
d'employer des modèles. Vous pourrez employer aussi bien des modèles
de ligne que des modèles de bloc ; ces derniers pourront être en
deux ou plusieurs couleurs. Les modèles de ligne sont parfaits pour
dessiner des diagrammes, des bords, etc. On pourra employer les
modèles de bloc pour remplir n'importe quel type d'objet à l'écran
par l'intermédiaire des routines de remplissage. La variété des
couleurs et les divers modèles vous offrent une grande flexibilité
pour créer des affichages intéressants et plaisants à regarder.
12.3.4.1 Les modèles de ligne
Les modèles de ligne ont une largeur de 16 bits et chaque bit
représente un point. Au démarrage, les modèles de ligne sont mis
à 0xFFFF (1111111111111111), ce qui génère des lignes pleines.
Pour créer un modèle qui alterne deux points et deux espaces, puis
à nouveau deux points et ainsi de suite, vous devrez mettre le
modèle de ligne à 0xCCCC (1100110011001100).
Vous pourrez changer le modèle de ligne en vous servant de la
macro SetDrPt(). Remarque : il ne s'agit pas d'une fonction. Il
s'agit réellement d'une macro qui est définie dans le fichier
en-tête "gfxmacros.h". Si vous souhaitez employer cette macro,
vous n'oublierez pas d'inclure ce fichier dans votre programme.
- Synopsis : SetDrPt( rast_port, line_pattern );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- line_pattern : (UWORD). Le modèle. Chaque octet représente un point.
Pour créer des lignes pleines vous mettrez la valeur
de modèle à 0xFFFF [en hexadécimal] (1111111111111111 [en binaire]).
Voici quelques modèles couramment employés, ainsi que leurs valeurs correspondantes :
Description Modèle [bin] Valeur du modèle [hex]
---------------------------------------------------------------------
ligne pleine 1111111111111111 0xFFFF
ligne largement pointillée 1111000011110000 0xF0F0
ligne moyennement pointillée 1100110011001100 0xCCCC
ligne peu pointillée 1000100010001000 0x8888
ligne fantôme 1010101010101010 0xAAAA
|
12.3.4.2 Les modèles de bloc
Les modèles de bloc ont une largeur de 16 bits et une hauteur de
lignes égale à une puissance de deux (1, 2, 4, 8, 16, 32, ... ).
Par conséquent, pour créer un modèle de bloc, vous devrez déclarer
et initialiser une matrice de UWORDS. Chaque bit de la matrice
représentera un point. Pour créer un modèle avec beaucoup de petits
carrés, vous devrez déclarer et initialiser une matrice plus ou
moins de la manière suivante :
UWORD area_pattern =
{
0xF0F0, /* 1111000011110000 */
0xF0F0, /* 1111000011110000 */
0xF0F0, /* 1111000011110000 */
0xF0F0, /* 1111000011110000 */
0x0F0F, /* 0000111100001111 */
0x0F0F, /* 0000111100001111 */
0x0F0F, /* 0000111100001111 */
0x0F0F, /* 0000111100001111 */
};
|
Pour fixer le modèle, vous appellerez la macro SetAfPt() en lui
donnant comme paramètres un pointeur sur votre RastPort et le
nouveau modèle. Remarque : il ne s'agit pas d'une fonction. Il
s'agit réellement d'une macro qui est définie dans le fichier
en-tête "gfxmacros.h". Si vous souhaitez employer cette macro,
n'oubliez pas d'inclure ce fichier dans votre programme.
- Synopsis : SetAfPt( rast_port, area_pattern, pow2 );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- area_pattern : (UWORD) Pointeur sur une matrice de UWORDS qui créera
le modèle. Chaque bit de la matrice représente un point.
- pow2 : (BYTE). Le modèle sera égal à deux à la puissance de
la hauteur de lignes pow2. Si la hauteur du modèle est
égale à une ligne, on devra mettre pow2 à 0, si elle
est égale à deux lignes, on devra mettre pow2 à 1, si
elle est égale à quatre lignes, on devra mettre pow2
à 2, et ainsi de suite (si vous employez des modèles
multicolores, pow2 devra avoir une valeur négative.
Par conséquent, pour un modèle multicolore ayant une
hauteur de seize lignes, vous devrez donner à pow2
une valeur de -4 [2^4 = 16]).
12.3.4.3 Les modèles multicolores
Vous pourrez même créer des modèles multicolores. Dans ce cas,
vous devrez déclarer une matrice avec une profondeur de deux ou
supérieure à deux. Plus grande sera la profondeur de la matrice,
plus on pourra utiliser de couleurs. Chaque niveau représente
un plan de bits.
Voici une matrice de modèles de bloc qui produit huit carrés de
couleur différente. Pour avoir huit couleurs, vous aurez besoin
d'une matrice avec une profondeur de trois. Le modèle ressemblera
à ceci (les nombres indiquent les registres de couleur qui seront
employés) :
0123
0123
4567
4567
UWORD area_pattern =
{
{ /* Plane 0 */
0x0F0F, /* 0000111100001111 */
0x0F0F, /* 0000111100001111 */
0x0F0F, /* 0000111100001111 */
0x0F0F /* 0000111100001111 */
},
{ /* Plane 1 */
0x00FF, /* 0000000011111111 */
0x00FF, /* 0000000011111111 */
0x00FF, /* 0000000011111111 */
0x00FF /* 0000000011111111 */
},
{ /* Plane 2 */
0x0000, /* 0000000000000000 */
0x0000, /* 0000000000000000 */
0xFFFF, /* 1111111111111111 */
0xFFFF /* 1111111111111111 */
}
};
|
Lorsque vous emploierez les modèles multicolores, la valeur de
pow2 dans la macro SetAfPt() devra être négative. Mettez tout
simplement un signe moins devant la valeur en question et les
routines de dessin comprendront que vous allez employer des
modèles multicolores.
Lors de l'emploi des modèles multicolores, le mode de dessin
devra être fixé à JAM2, FgPen à la couleur 255 et BgPen à la
couleur 0 :
/* Préparation pour dessiner avec des modèles multicolores : */
SetDrMd( &my_rast_port, JAM2 );
SetAPen( &my_rast_port, 255 );
SetBPen( &my_rast_port, 0 );
/* Fixe le modèle : (hauteur 4 lignes -> pow2 = 2 [2^2], multicol. -2)
SetAfPt( &my_rast_port, area_pattern, -2 );
|
12.3.5 Le masque de modèle
Pour créer des effets particuliers, vous pourrez "déconnecter"
les plans de bits de votre raster de sorte qu'ils ne soient pas
concernés par les routines de dessin. Le premier bit du masque
représente le premier plan de bits, le deuxième bit le deuxième
plan de bits et ainsi de suite. Un 1 signifie que le plan de bits pourra
être concerné, tandis qu'un 0 voudra dire que le plan de bits ne
sera aucunement concerné. Pour "déconnecter" les plans de bits zéro
et deux, il faudra mettre la valeur du masque à 0xFA [en hexa] =
11111010 [en binaire].
On trouve la variable de masque "Mask" dans la structure RastPort :
my_rast_port.Mask = 0xFF (on pourra modifier tous les plans de bits).
12.3.6 Dessiner un seul pixel
On dessine un seul pixel en employant la fonction WritePixel().
- Synopsis : WritePixel( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Abscisse X du pixel.
- y : (long). Ordonnée Y du pixel.
12.3.7 Lire un seul pixel
Vous emploierez la fonction ReadPixel() afin de déterminer la
couleur d'un pixel donné. Vous lui fournirez seulement un pointeur
sur votre RastPort, ainsi que les coordonnées du pixel, et la
fonction retournera la valeur de la couleur du pixel.
- Synopsis : colour = ReadPixel( rast_port, x, y );
- colour : (long). ReadPixel retourne la valeur de la couleur du
pixel indiqué (couleur qui va de 0 à 255 ) ou -1 si
les coordonnées se situent en dehors du raster.
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui
contient le pixel que vous souhaitez examiner.
- x : (long). Abscisse X du pixel.
- y : (long). Ordonnée Y du pixel.
12.3.8 Positionnement du curseur
Avant de commencer à tracer des lignes ou à écrire un texte, il
vous faudra positionner le curseur (l'endroit à partir duquel la
ligne/le texte seront dessinés). Le curseur n'est pas quelque
chose de visible à l'utilisateur, il n'est représenté que par les
coordonnées du crayon qui sert à dessiner. Vous pourrez trouver
la position du curseur dans les variables cp_x et cp_y du
RastPort.
On modifie la position du curseur en appelant la fonction Move().
- Synopsis : Move( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle valeur de l'abscisse X.
- y : (long). Nouvelle valeur de l'ordonnée Y.
12.3.9 Le texte
Dans ce chapitre, nous n'entrerons pas dans le détail sur la manière
dont on écrit des caractères/un texte. Cependant, je voudrais
au moins expliquer l'affichage à l'écran des caractères courants.
Pour afficher du texte, vous emploierez la fonction Text().
Celle-ci a besoin d'un pointeur sur le RastPort concerné, d'un
pointeur sur une chaîne de caractères de texte et, pour finir,
d'une valeur qui l'informe sur le nombre de caractères qu'on
souhaite afficher. A chaque appel de la fonction on pourra
afficher seulement une ligne ; la fonction ne fait ni formatage
ni ajustement de la ligne.
- Synopsis : Text( rast_port, string, nr_of_chr );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- string : (char *). Pointeur sur la chaîne de caractères de texte qui doit être affichée.
- nr_of_chr : (long). Le nombre de caractères à afficher.
Cet exemple affiche "Hello" à l'écran :
Text( &my_rast_port, "HELLO", 5 );
|
12.3.10 Dessiner des lignes simples
Vous pourrez dessiner des lignes simples en faisant appel à la
fonction Draw(). Celle-ci tracera une ligne à partir de l'abscisse
X courante jusqu'à une ordonnée Y à n'importe quel endroit à
l'intérieur du Raster.
- Synopsis : Draw( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle valeur de l'abscisse X.
- y : (long). Nouvelle valeur de l'ordonnée Y.
Voici un exemple qui dessinera un triangle à l'écran :
Move( &my_rast_port, 100, 100 ); /* Aller à la position de démarrage. */
Draw( &my_rast_port, 300, 100 ); /* Dessiner les trois lignes. */
Draw( &my_rast_port, 200, 200 );
Draw( &my_rast_port, 100, 100 );
|
12.3.11 Dessiner plusieurs lignes
Pour dessiner plusieurs lignes, nous emploierons la fonction
PolyDraw(). Celle-ci a besoin d'un pointeur sur une matrice de
coordonnées, d'une valeur qui l'informe du nombre de paires de
coordonnées (x,y) qui seront employées et naturellement d'un
pointeur sur le RastPort qui est concerné. La fonction dessine
une ligne à partir de l'abscisse X courante jusqu'à la première
ordonnée Y. Puis une deuxième ligne jusqu'à la deuxième
ordonnée Y et ainsi de suite.
- Synopsis : PolyDraw( rast_port, number, coordinates );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- number : (long). Le nombre de coordonnées (x,y) indiquées dans la matrice.
- coordinates : (short *). Pointeur sur une matrice de coordonnées.
Voici un exemple qui dessine lui aussi un triangle à l'écran :
/* Trois coordonnées : */
WORD coordinates[] =
{
300, 100,
200, 200,
100, 100
};
/* Aller à la position de démarrage : */
Move( &my_rast_port, 100, 100 );
/* Dessiner des lignes : */
PolyDraw( &my_rast_port, 3, coordinates );
|
12.3.12 Dessiner des rectangles pleins
Pour dessiner des rectangles pleins, vous emploierez la fonction
RectFill() (remarquez que, dans ce cas, les modèles de bloc sont
opérationnels).
- Synopsis : RectFill( rast_port, minx, miny, maxx, maxy );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- minx : (long). Coin gauche du rectangle.
- miny : (long). Coin supérieur du rectangle.
- maxx : (long). Coin droit du rectangle.
- maxy : (long). Coin inférieur du rectangle.
12.3.13 Le remplissage "flood"
Quand on doit remplir des objets complexes, on emploiera le
remplissage flood. Il existe deux types différents de remplissage
flood. Le mode Délimitation et le mode Couleur. En mode
délimitation, la nouvelle couleur remplira toute la surface : le
flood s'arrêtera seulement lorsqu'il rencontrera un bord de la
même couleur que AOlPen. En mode couleur, seront concernés tous
les pixels de la même couleur se trouvant l'un près de l'autre.
Le flood prendra fin dès qu'il rencontrera une couleur différente.
Vous pourrez faire le remplissage flood d'un objet, en employant la fonction Flood().
- Synopsis : Flood( rast_port, mode, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- mode : (long). Le mode qu'on devra employer. Si vous souhaitez
employer le mode Couleur, mettez la variable de mode à
1, pour vous servir du mode Délimitation, mettez la variable de mode à 0.
- x : (long). Abscisse X où devra commencer le remplissage flood.
- y : (long). Ordonnée Y où devra commencer le remplissage flood.
Voici un exemple qui permettra de dessiner et de remplir un
rectangle. Nous donnerons à AOlPen la même couleur qu'à FgPen,
ainsi le remplissage flood s'arrêtera dès qu'il rencontrera les
bords, en mode Délimitation.
/* Donner à AOlPen la même couleur que FgPen : */
SetOPen( &my_rast_port, my_rast_port.FgPen );
/* Dessiner un triangle : */
Move( &my_rast_port, 100, 100 );
Draw( &my_rast_port, 300, 100 );
Draw( &my_rast_port, 200, 200 );
Draw( &my_rast_port, 100, 100 );
/* Le remplir (en utilisant le mode Délimitation) : */
Flood( &my_rast_port, 0, 200, 150 );
|
12.3.14 Dessiner des surfaces déjà remplies
L'Amiga permet de dessiner des surfaces qui seront directement
remplies. Vous choisissez un emplacement et l'Amiga commence à
dessiner l'objet que vous avez choisi. Cependant, l'utilisateur
ne s'apercevra de rien étant donné que l'Amiga ne tracera aucune
ligne. En effet, les lignes sont stockées dans la liste d'un vecteur
et seront dessinées lorsque vous aurez terminé l'objet (quand vous
le "fermerez").
12.3.14.1 Les structures AreaInfo et TmpRas
Pour gérer ces structures il vous faudra faire un certain nombre de choses :
1. Créer un tampon où sera stockée la liste de tous vos sommets.
Vous aurez besoin de cinq octets par sommet, ainsi, pour
créer un tampon de 100 lignes, vous aurez besoin de 500 octets.
Naturellement, le tampon devra être aligné "au mot", par
conséquent vous devrez déclarer le tampon en tant que suite de
mots et non en tant que suite d'octets. Du moment qu'il y a
deux octets dans chaque mot, 500 octets signifiera 250 mots.
Exemple :
2. Déclarer une structure AreaInfo (declarée dans le fichier "rastport.h".).
Exemple :
struct AreaInfo my_area_info;
|
3. Combiner le tampon et la structure AreaInfo par l'intermédiaire
de la fonction InitArea(). Celle-ci a besoin d'un pointeur sur
une structure AreaInfo, d'un pointeur sur un tampon de mémoire
et d'une valeur qui l'informera sur le nombre de sommets qui
pourront être stockés dans le tampon.
Exemple :
InitArea( &my_area_info, my_buffer, 100);
|
4. Déclarer une structure TmpRas (déclarée elle aussi dans le
fichier "rastport.h".). Exemple :
struct TmpRas my_tmp_ras;
|
5. Réserver un plan de bits assez grand pour pouvoir y stocker tous vos
objets. Normalement, vous créerez un plan de bits qui aura la même
taille que votre affichage. Exemple :
PLANEPTR my_bit_plane;
my_bit_plane = AllocRaster( 320, 200 );
if( my_bit_plane == NULL )
exit();
|
6. Initialiser et relier la structure TmpRas et la mémoire
supplémentaire en faisant appel à la fonction InitTmpRas().
Celle-ci a besoin d'un pointeur sur une structure TmpRas, d'un
pointeur sur une zone de mémoire d'affichage supplémentaire
et, pour finir, d'une valeur qui l'informera sur la taille de
la mémoire supplémentaire, taille qu'on pourra calculer par
l'intermédiaire de la macro RASSIZE(). Exemple :
InitTmpRas( &my_tmp_ras, my_bit_plane, RASSIZE( 320, 200 ) );
|
7. Informer le RastPort de l'endroit où il pourra trouver les
structures AreaInfo et TmpRas. Exemple :
my_rast_port.AreaInfo = &my_area_info;
my_rast_port.TmpRas = &my_tmp_ras;
|
8. Avant la fin de votre programme, vous devrez désallouer la
mémoire d'affichage que vous aviez réservée. Utilisez la
fonction FreeRaster(). Exemple :
FreeRaster( my_bit_plane, 320, 200 );
|
12.3.14.2 AreaMove(), AreaDraw() et AreaEnd()
Une fois que les structures TmpRas et AreaInfo auront été
initialisées et que le RastPort sait où il pourra les trouver,
vous pourrez commencer à employer les fonctions AreaFill.
La première chose que vous voudrez probablement faire sera de
vous déplacer à un nouvel endroit où vous voudrez commencer à
dessiner. Ceci se fait, en faisant appel à la fonction
AreaMove().
- Synopsis : AreaMove( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Abscisse X de démarrage.
- y : (long). Ordonnée Y de démarrage.
Maintenant, vous pouvez commencer à dessiner en employant la
fonction AreaDraw(). Remarque : l'utilisateur ne s'apercevra de
rien, vous verrez le résultat lorsque vous "fermerez" le
polygone. A ce moment, l'Amiga le dessinera et le remplira.
- Synopsis : AreaDraw( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle abscisse X.
- y : (long). Nouvelle ordonnée Y.
Faites attention à ne pas dessiner en dehors du raster, ceci pourrait bloquer le système !
Dès que votre objet est prêt, appelez la fonction AreaEnd() :
l'Amiga fermera le polygone et le remplira. Il ne vous faudra pas
nécessairement fermer le polygone, l'Amiga dessinera la dernière
ligne automatiquement, si cela est nécessaire (si vous appelez
AreaMove(), avant d'avoir fermé le polygone, l'Amiga le fermera
automatiquement avant de commencer à dessiner le nouveau polygone).
- Synopsis : AreaEnd( rast_port );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
12.3.14.3 Mettre hors service la fonction Outline
Les surfaces qu'on remplit par l'intermédiaire des fonctions
AreaFill seront délimitées avec AOlPen. Cependant, vous pourrez
mettre hors service la fonction Outline, si vous n'en avez pas
besoin. Il vous suffira simplement d'appeler la macro BNDROFF()
(déclarée dans le fichier d'en-tête "gfxmacros.h") en lui
fournissant comme seul paramètre un pointeur sur votre RastPort.
- Synopsis : BNDROFF( rast_port );
- rast_port : pointeur sur le RastPort où on devra désactiver la fonction Outline.
12.3.14.4 Un exemple
Voici un exemple :
#define WIDTH 320
#define HEIGHT 200
/* Déclaration des structures AreaInfo et TmpRas : */
struct AreaInfo my_area_info;
struct TmpRas my_tmp_ras;
/* Tampon pour les sommets : (100 lignes, 5 octets par sommet, soit */
/* 500 octets, autrement dit 250 mots. Tampon aligné "au mot". */
UWORD my_buffer[ 250 ];
/* Pointeur sur la mémoire d'affichage qu'on devra allouer : */
PLANEPTR my_bit_plane;
/* Initialisation de la structure AreaInfo. */
/* Préparation pour les 100 sommets : */
InitArea( &my_area_info, my_buffer, 100);
/* Allocation de la mémoire d'affichage : */
my_bit_plane = AllocRaster( WIDTH, HEIGHT );
/* Avons-nous réussi à nous faire allouer la mémoire? */
if( my_bit_plane == NULL )
exit();
/* Préparation de la structure TmpRas : */
InitTmpRas( &my_tmp_ras, my_bit_plane, RASSIZE( WIDTH, HEIGHT ) );
/* Informer le RastPort de l'endroit où il pourra trouver */
/* ces structures : */
my_rast_port.AreaInfo = &my_area_info;
my_rast_port.TmpRas = &my_tmp_ras;
/* Dessiner un carré plein : */
AreaMove( my_rast_port, 0, 0 );
AreaDraw( my_rast_port, 100, 0 );
AreaDraw( my_rast_port, 100, 100 );
AreaDraw( my_rast_port, 0, 100 );
AreaEnd( my_rast_port );
/* Désallouer la mémoire supplémentaire : */
FreeRaster( my_bit_plane, WIDTH, HEIGHT );
|
12.3.15 Mettre le raster à une couleur donnée
Vous pouvez mettre tout le raster à une couleur donnée en faisant appel à la fonction SetRast().
- Synopsis : SetRast( rast_port, colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- colour : (long). Le registre de couleur avec lequel vous voulez remplir tout le raster.
12.3.16 Le Blitter
Le Blitter est une puce à l'intérieur de l'Amiga qui est
spécialisée dans le déplacement et la combinaison logique de
grandes zones de mémoire rectangulaires. Il déplace et travaille
avec une énorme quantité de données et peut, par conséquent,
effectuer beaucoup de travail pénible qui exigerait beaucoup de
temps du processeur principal. A la place, celui-ci peut se
concentrer sur des tâches plus importantes.
Le Blitter, qui est dans Agnus/Fat Agnus,
est le héros des possibilités graphiques fascinantes de l'Amiga.
On pourra l'employer pour remettre à zéro, pour faire défiler et
pour copier d'importantes zones de mémoire. A la différence
d'autres Blitters, il peut aussi combiner logiquement des zones
de mémoire (nous en parlerons plus loin) et par conséquent il
peut faire un tas de choses bien plus intéressantes que le
simple déplacement des données.
12.3.16.1 Vidage de zones mémoire rectangulaires
Vous pourrez remettre à zéro des zones mémoire en faisant
appel à la fonction BltClear(). L'avantage représenté par l'emploi
de cette fonction est que celle-ci travaille avec le Blitter qui
est une puce rapide pour la remise à zéro de la mémoire.
- Synopsis : BltClear( memory, count, drapeaux );
- memory : (char *). Pointeur sur la zone de mémoire qu'on doit remettre à zéro.
- count : (long). Nombre d'octets qu'on doit remettre à zéro.
Si vous remettez à zéro la mémoire d'affichage, vous
pourrez employer la macro RASSIZE() pour calculer
combien d'octets sont utilisés par l'affichage.
- flags : (long). Écrire 0 pour permettre à l'ordinateur de
continuer pendant que le blitter travaille ou écrire
1 pour forcer le programme à attendre le Blitter.
12.3.16.2 Défilement d'une zone rectangulaire
En utilisant la fonction ScrollRaster(), vous ferez défiler à
l'écran une partie du raster. Cette fonction travaille en
collaboration avec le Blitter et par conséquent elle est très
rapide. On pourra faire défiler une partie du raster horizontalement
ou verticalement. Cette partie du raster sera perdue et la nouvelle
partie sera remplie avec BgPen.
- Synopsis : ScrollRaster( rp, dx, dy, minx, miny, maxx, maxy );
- rp : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- dx : (long). Déplacement delta sur le plan des X (un chiffre
positif déplacera la zone vers la droite, un chiffre
négatif la déplacera sur la gauche).
- dy : (long). Déplacement delta sur le plan des Y (un chiffre
positif déplacera la zone vers le bas, un chiffre
négatif la déplacera vers le haut).
- minx : (long). Coin gauche du rectangle.
- miny : (long). Coin supérieur du rectangle.
- maxx : (long). Coin droit du rectangle.
- maxy : (long). Coin inférieur du rectangle.
12.3.16.3 Copier des surfaces rectangulaires
Lorsque vous aurez à copier des zones mémoire rectangulaires,
vous pourrez employer aussi bien BltBitMap() que ClipBlit().
Tout simplement on devra employer BltBitMap() lorsque vous aurez
à copier des données sans vouloir vous embêter avec les couches ("layers")
de recouvrement (fenêtres), etc. En cas contraire, vous emploierez
ClipBlit() si vous voulez faire attention aux couches de recouvrement, etc.
BltBitMap() copie les BitMaps directement sans faire attention aux couches de recouvrement.
- Synopsis : BltBitMap( sbm, sx, sy, dbm, dx, dy, w, h, flag, m, t );
- sbm : (struct BitMap *). Pointeur sur la BitMap "source".
- sx : (long). Décalage dans le plan des X de la source.
- sy : (long). Décalage dans le plan des Y de la source.
- dbm : (struct BitMap *). Pointeur sur la BitMap "destination".
- dx : (long). Décalage dans le plan des X de la destination.
- dy : (long). Décalage dans le plan des Y de la destination.
- w : (long). Largeur de la zone mémoire qui devra être copiée.
- h : (long). Hauteur de la zone mémoire qui devra être copiée.
- flag : (long). Cette valeur informe le Blitter du type
d'opérations logiques à effectuer. Voir ci-dessous
pour plus de renseignements.
- m : (long). Ici, vous pourrez définir un masque de BitMap
et dire au Blitter quels plans de bits devront et ne
devront pas être employés. Le premier bit représente
le premier plan de bits, le deuxième bit représente le
deuxième plan de bits et ainsi de suite. Si le bit est
activé (1) on emploiera le plan de bits correspondant,
autrement (0) on n'emploiera pas ce plan de bits. Pour
mettre hors service les plans de bits zéro et deux,
mettez la valeur de masque à 0xFA (11111010). Pour
employer tous les plans de bits mettez la valeur de
masque à 0xFF (11111111).
- t : (char *). Si la copie fait des recouvrements et si
ce pointeur pointe sur une partie de la mémoire Chip,
la mémoire sera employée pour y stocker une zone
temporaire. Cependant, normalement, vous n'aurez pas
à vous occuper de cette valeur.
ClipBlit() copie les BitMaps en se servant des Rastports, par
conséquent, la fonction fera attention aux couches de recouvrement
et on devra l'employer s'il y a des fenêtres dans l'affichage.
- Synopsis : ClipBlit( srp, sx, sy, drp, dx, dy, w, h, drapeau );
- srp : (struct RastPort *). Pointeur sur le RastPort "source".
- sx : (long). Valeur dans le plan des X de la source.
- sy : (long). Valeur dans le plan des X de la source.
- drp : (struct RastPort *). Pointeur sur le RastPort "destination".
- dx : (long). Valeur dans le plan des X de la destination.
- dy : (long). Valeur dans le plan des X de la destination.
- w : (long). Largeur de la zone de mémoire qui devra être copiée.
- h : (long). Hauteur de la zone de mémoire qui devra être copiée.
- flag : (long). Cette valeur informe le Blitter du type
d'opérations logiques à effectuer. Voir ci-dessous pour plus de renseignements.
Comme nous l'avons dit ci-dessus, le Blitter peut combiner des
données entre la zone source et la zone destination. Le premier
des quatre bits les plus à gauche dans le champ drapeau détermine
quels calculs devront être effectués.
Si le bit le plus à gauche est mis (valeur égale à 0x80), le
résultat sera une combinaison de la source et de la destination.
Si le second bit le plus à gauche est mis (valeur égale à 0x40),
le résultat sera une combinaison de la source et de la
destination inversée. Si le troisième bit le plus à gauche est
mis (valeur égale à 0x20), le résultat sera une combinaison de
la source inversée et de la destination. Si le quatrième bit
le plus à gauche est mis (valeur égale à 0x10), le résultat
sera égal à une inversion de la source et de la destination.
Voir la table suivante :
Bit Valeur Log
----------------------
1000 0000 0x80 SD
_
0100 0000 0x40 SD
_
0010 0000 0x20 SD
__
0001 0000 0x10 SD
|
Pour effectuer une copie normale, le résultat devra être
seulement S. Vous pourrez l'avoir en mettant la valeur du drapeau
à 0xc0 [en hexadécimal] (11000000 [en binaire]).
La formule mathématique serait alors la suivante :
_ _
SD + SD = S(D + D) = S
|
Si vous voulez que la source soit inversée (S), mettez la valeur
du drapeau à 0x30 [en hexadécimal] (00110000 [en binaire]). La formule
mathématique serait alors la suivante :
_ __ _ _ _
SD + SD = S(D + D) = S
|
Si vous voulez que la destination soit inversée (D), mettez la
valeur du drapeau à 0x50 [en hexadécimal] (01010000 [en binaire]). La formule
mathématique serait alors la suivante :
_ __ _ _ _
SD + SD = D(S + S) = D
|
Voici un exemple qui copie une zone rectangulaire d'un RastPort
de nom "source_rp" dans un autre RastPort de nom "destination_rp". La
zone rectangulaire a une largeur de WIDTH pixels et une hauteur de
HEIGHT lignes.
ClipBlit( &source_rp, /* RastPort source. */
0, 0, /* Coin supérieur gauche de source. */
&destination_rp, /* RastPort destination. */
0, 0, /* Coin supérieur gauche de destination. */
WIDTH, HEIGHT, /* Taille de la zone de mémoire. */
0xC0 ); /* Copie normale. */
|
12.4 Les fonctions
InitView()
Cette fonction initialisera une structure View.
- Synopsis : InitView( view );
- view : (struct View *). Pointeur sur le View qui doit être initialisé.
InitVPort()
Cette fonction initialisera une structure ViewPort.
- Synopsis : InitVPort( view_port );
- view_port : (struct ViewPort *). Pointeur sur le ViewPort qui devra être initialisé.
GetColorMap()
Cette fonction alloue et initialise une structure ColorMap.
- Synopsis : colormap = GetColorMap( colours );
- colormap : (struct ColorMap *). GetColorMap retourne un pointeur
sur la structure ColorMap qu'elle a allouée et
initialisée ou NULL s'il n'y a pas assez de mémoire.
- colours : (long). Une valeur qui indique le nombre de couleurs
voulu que devra stocker la structure ColorMap (1, 2, 4, 8, 16, 32).
FreeColorMap()
Cette fonction désalloue la mémoire fournie par la fonction
GetColorMap(). N'oubliez pas de libérer toute la mémoire que
vous avez réservée. Pour chaque fonction GetColorMap(), il
devrait y avoir une fonction FreeColorMap().
- Synopsis : FreeColorMap( colormap );
- colormap : (struct ColorMap *). Pointeur sur la structure ColorMap
retournée par GetColorMap() que maintenant vous voulez désallouer.
InitBitMap()
Cette fonction initialise une structure BitMap.
- Synopsis : InitBitMap( bitmap, depth, width, height );
- bitmap : (struct BitMap *). Pointeur sur la BitMap.
- depth : (long). Nombre de plans de bits utilisés.
- width : (long). Largeur du raster.
- height : (long). Hauteur du raster.
AllocRaster()
Cette fonction réserve la mémoire d'affichage (un plan de bits).
- Synopsis : pointer = AllocRaster( width, height );
- pointer : (PLANEPTR). Pointeur sur la zone de mémoire allouée ou
NULL si le système n'a pu réserver assez de mémoire.
- width : (long). Largeur de la BitMap.
- height : (long). Hauteur de la BitMap.
BltClear()
Cette fonction remet à zéro des grandes zones rectangulaires de
mémoire. Cette fonction travaille avec le Blitter et, par conséquent,
elle est très rapide.
- Synopsis : BltClear( pointer, bytes, drapeaux );
- pointer : (char *). Pointeur sur la zone de mémoire.
- bytes : (long). Les 16 bits de poids faible informent le
Blitter du nombre d'octets par rangée et les 16 bits
de poids fort du nombre de rangées. Cette valeur
est calculée automatiquement pour vous par
l'intermédiaire de la macro RASSIZE(). Fournissez
seulement à RASSIZE() la largeur et la hauteur
correctes et celle-ci retournera une valeur correcte
[RASSIZE() est définie dans le fichier en-tête "gfx.h".].
- flags : (long). Mettez le bit 0 pour forcer la fonction à attendre
tant que le Blitter n'a pas fini son travail.
MakeVPort()
Cette fonction prépare le matériel de l'Amiga (tout particulièrement
le Copper) pour afficher un ViewPort. Remarque : vous devrez préparer
chaque ViewPort que vous allez utiliser !
- Synopsis : MakeVPort( view, viewport );
- view : (struct View *). Pointeur sur le View du ViewPort.
- viewport : (struct ViewPort *). Pointeur sur le ViewPort.
MrgCop()
Cette fonction réunit toutes les instructions de l'affichage et
prépare le View pour l'afficher.
- Synopsis : MrgCop( view );
- view : (struct View *). Pointeur sur le View.
LoadView()
Cette fonction fait démarrer l'affichage d'un View. N'oubliez pas,
en fermant votre View, qu'il vous faudra revenir au View d'origine
(voir les exemples pour plus de détails).
- Synopsis : LoadView( view );
- view : (struct View *). Pointeur sur le View.
FreeVPortCopLists()
Cette fonction rendra au système toute la mémoire qui aura été
allouée automatiquement par la fonction MakeVPort(). N'oubliez pas
d'appeler FreeVPortCopLists() pour chaque ViewPort que vous aurez créé !
- Synopsis : FreeVPortCopLists( viewport );
- view : (struct ViewPort *). Pointeur sur le ViewPort.
FreeCprList()
Cette fonction rendra au système toute la mémoire qui aura été
allouée automatiquement par la fonction MrgCop().
- Synopsis : FreeCprList( cprlist );
- cprlist : (struct cprlist *). Pointeur sur la structure cprlist
(LOFCprList) du View. Si le View était en mode entrelacé,
vous devrez aussi appeler la fonction FreeCprList avec un pointeur sur SHFCprList.
FreeRaster()
Cette fonction désallouera la mémoire d'affichage (un plan de bits).
N'oubliez pas de désallouer tous les plans de bits !
- Synopsis : FreeRaster( bitplane, width, height );
- bitplane : (PLANEPTR). Pointeur sur un plan de bits.
- width : (long). Largeur du plan de bits.
- height : (long). Hauteur du plan de bits.
FreeColorMap()
Cette fonction rendra au système toute la mémoire qui aura été
allouée par la fonction GetColorMap(). N'oubliez pas de désallouer
toute la mémoire que vous aurez réservée. Pour chaque fonction
GetColorMap() il devrait y avoir une fonction FreeColorMap().
- Synopsis : FreeColorMap( colormap );
- colormap : (struct ColorMap *). Pointeur sur la structure ColorMap
retournée par GetColorMap() que maintenant vous voulez désallouer.
InitRastPort()
Cette fonction initialise un RastPort.
- Synopsis : InitRastPort( rast_port );
- rast_port : (RastPort *). Pointeur sur le RastPort qui doit être initialisé.
SetAPen()
Cette fonction changera la couleur de FgPen.
- Synopsis : SetAPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). Une nouvelle valeur de couleur.
SetBPen()
Cette fonction changera la couleur de BgPen.
- Synopsis : SetBPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). Une nouvelle valeur de couleur.
SetOPen()
Cette macro changera la couleur de AOlPen. Remarque : il ne s'agit
pas d'une fonction. En réalité, il s'agit d'une macro définie dans
le fichier en-tête "gfxmacros.h". Si vous souhaitez utiliser cette
fonction, il vous faudra vous souvenir d'inclure ce fichier dans
votre programme.
- Synopsis : SetOPen( rast_port, new_colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_colour : (long). Une nouvelle valeur de couleur.
SetDrMd()
Cette fonction changera le mode de dessin.
- Synopsis : SetDrMd( rast_port, new_mode );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- new_mode : (long). Le nouveau mode de dessin. Mettre l'un des modes
suivants : JAM1, JAM2, COMPLEMENT, INVERSVID|JAM1 ou INVERSVID|JAM2.
- JAM1 : FgPen sera employé, l'arrière-plan est inchangé (une couleur est "bloquée" dans un raster).
- JAM2 : FgPen sera employé comme crayon de premier champ de jeu tandis que l'arrière-plan
(là où vous êtes en train d'écrire un texte) sera rempli avec la couleur de
BgPen (deux couleurs sont "bloquées" dans un raster).
- COMPLEMENT : chaque pixel concerné sera dessiné dans sa couleur binaire complémentaire. Là
où vous aurez écrit des 1, les bits correspondants dans le raster seront inversés.
- INVERSVID|JAM1 : ce mode est employé seulement avec du texte. Seul l'arrière-plan du texte sera
dessiné avec FgPen.
- INVERSVID|JAM2 : ce mode est employé seulement avec du texte. L'arrière-plan du texte sera
dessiné avec FgPen, tandis que les caractères seront dessinés avec BgPen.
SetDrPt()
Cette fonction fixera le modèle de ligne.
- Synopsis : SetDrPt( rast_port, line_pattern );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- line_pattern : (UWORD). Le modèle. Chaque bit représente un point.
Pour créer des lignes pleines, vous mettrez la valeur de modèle à 0xFFFF [en hexadécimal]
(1111111111111111 [en binaire]).
SetAfPt()
Cette fonction fixera les modèles de bloc.
- Synopsis : SetAfPt( rast_port, area_pattern, pow2 );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- area_pattern : (UWORD). Pointeur sur une matrice de UWORDS qui créera
le modèle. Chaque bit de la matrice représente un point.
- pow2 : (BYTE). Le modèle sera égal à deux à la puissance de
la hauteur de lignes pow2. Si la hauteur du modèle est
égale à une ligne, on devra mettre pow2 à 0, si elle
est égale à deux lignes, on devra mettre pow2 à 1, si
elle est égale à quatre lignes, on devra mettre pow2
à 2, et ainsi de suite (si vous employez des modèles
multicolores, pow2 devra avoir une valeur négative.
Par conséquent, pour un modèle multicolore ayant une
hauteur de seize lignes, vous devrez donner à pow2
une valeur de -4 [2^4 = 16]).
WritePixel()
Cette fonction dessinera un seul pixel.
- Synopsis : WritePixel( rast_port, x, y );
- rast_port : (struct RastPort *) Pointeur sur le RastPort qui est concerné.
- x : (long). Abscisse X du pixel.
- y : (long). Ordonnéé Y du pixel.
ReadPixel()
Cette fonction lit la valeur de la couleur d'un pixel.
- Synopsis : colour = ReadPixel( rast_port, x, y );
- colour : (long). ReadPixel retourne la valeur de la couleur du
pixel indiqué (couleur qui va de 0 à 255 ) ou -1 si
les coordonnées se situent en dehors du raster.
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui
contient le pixel que vous souhaitez examiner.
- x : (long). Abscisse X du pixel.
- y : (long). Ordonnée Y du pixel.
Move()
Cette fonction change la position du crayon graphique.
- Synopsis : Move( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle valeur de l'abscisse X.
- y : (long). Nouvelle valeur de l'ordonnée Y.
Text()
Cette fonction affiche du texte dans le raster.
- Synopsis : Text( rast_port, string, nr_of_chr );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- string : (char *). Pointeur sur la chaîne de caractères de texte qui doit être affichée.
- nr_of_chr : (long). Le nombre de caractères à afficher.
Draw()
Cette fonction dessine des lignes simples de la position courante
jusqu'à la nouvelle position indiquée.
- Synopsis : Draw( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle valeur de l'abscisse X.
- y : (long). Nouvelle valeur de l'ordonnée Y.
PolyDraw()
Cette fonction dessinera des lignes multiples.
- Synopsis : PolyDraw( rast_port, number, coordinates );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- number : (long). Le nombre de coordonnées (x,y) indiquées dans la matrice.
- coordinates : (short *). Pointeur sur une matrice de coordonnées.
RectFill()
Cette fonction dessinera des rectangles pleins.
- Synopsis : RectFill( rast_port, minx, miny, maxx, maxy );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- minx : (long). Coin gauche du rectangle.
- miny : (long). Coin supérieur du rectangle.
- maxx : (long). Coin droit du rectangle.
- maxy : (long). Coin inférieur du rectangle.
Flood()
Cette fonction effectuera un remplissage flood pour des objets complexes.
- Synopsis : Flood( rast_port, mode, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- mode : (long). Le mode qu'on devra employer. Si vous souhaitez
employer le mode Couleur, mettez la variable de mode à
1, pour vous servir du mode Délimitation, mettez la variable de mode à 0.
- x : (long). Abscisse X où devra commencer le remplissage flood.
- y : (long). Ordonnée Y où devra commencer le remplissage flood.
AreaMove()
Cette fonction fera démarrer le processus pour un nouveau polygone.
- Synopsis : AreaMove( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Abscisse X de démarrage.
- y : (long). Ordonnée Y de démarrage.
AreaDraw()
Cette fonction ajoutera un nouveau sommet dans la liste du vecteur.
- Synopsis : AreaDraw( rast_port, x, y );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- x : (long). Nouvelle abscisse X.
- y : (long). Nouvelle ordonnée Y.
AreaEnd()
Cette fonction mettra fin au processus, dessinera et remplira le polygone.
- Synopsis : AreaEnd( rast_port );
- rast_port : (struct RastPort *) Pointeur sur le RastPort qui est concerné.
BNDROFF()
Cette macro (déclarée dans le fichier "gfxmacro.h") mettra hors service le mode Outline.
- Synopsis : BNDROFF( rast_port );
- rast_port : Pointeur sur le RastPort où l'on devra désactiver la fonction Outline.
SetRast()
Cette fonction met tout un Raster à la couleur indiquée.
- Synopsis : SetRast( rast_port, colour );
- rast_port : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- colour : (long). Le registre de couleur avec lequel vous voulez remplir tout le raster.
ScrollRaster()
Cette fonction fera défiler sur l'écran une zone rectangulaire d'un raster.
- Synopsis : ScrollRaster( rp, dx, dy, minx, miny, maxx, maxy );
- rp : (struct RastPort *). Pointeur sur le RastPort qui est concerné.
- dx : (long). Déplacement delta sur le plan des X (un chiffre positif déplacera la zone vers la
droite, un chiffre négatif la déplacera sur la gauche).
- dy : (long). Déplacement delta sur le plan des Y (un chiffre positif déplacera la zone vers le
bas, un chiffre négatif la déplacera vers le haut).
- minx : (long). Coin gauche du rectangle.
- miny : (long). Coin supérieur du rectangle.
- maxx : (long) Coin droit du rectangle.
- maxy : (long) Coin inférieur du rectangle.
BltBitMap()
Cette fonction copie des parties des BitMaps directement sans s'occuper des couches (layers) de recouvrement.
- Synopsis : BltBitMap( sbm, sx, sy, dbm, dx, dy, w, h, flag, m, t );
- sbm : (struct BitMap *). Pointeur sur la BitMap "source".
- sx : (long). Décalage dans le plan des X de la source.
- sy : (long). Décalage dans le plan des Y de la source.
- dbm : (struct BitMap *). Pointeur sur la BitMap "destination".
- dx : (long). Décalage dans le plan des X de la destination.
- dy : (long). Décalage dans le plan des Y de la destination.
- w : (long) Largeur de la zone de mémoire qui devra être copiée.
- h : (long). Hauteur de la zone de mémoire qui devra être copiée.
- flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à
effectuer. Voir ci-dessous pour plus de renseignements.
- m : (long). Ici, vous pourrez définir un masque de BitMap et dire au Blitter quels
plans de bits devront et ne devront pas être employés. Le premier bit représente
le premier plan de bits, le deuxième bit représente le deuxième plan de bits et ainsi de suite. Si le bit est
activé (1), on emploiera le plan de bits correspondant, autrement (0) on n'emploiera pas ce plan de bits. Pour
mettre hors service les plans de bits zéro et deux, mettez la valeur de masque à 0xFA (11111010). Pour employer
tous les plans de bits, mettez la valeur de masque à 0xFF (11111111).
- t : (char *). Si la copie fait des recouvrements et si ce pointeur pointe sur une partie de la mémoire Chip,
la mémoire sera employée pour y stocker une zone temporaire. Cependant, normalement, vous n'aurez pas
à vous occuper de cette valeur.
ClipBlit()
ClipBlit() copie les BitMaps en se servant des Rastports, par conséquent, la fonction fera attention
aux couches de recouvrement et on devra l'employer s'il y a des fenêtres dans l'affichage.
- Synopsis : ClipBlit( srp, sx, sy, drp, dx, dy, w, h, drapeau );
- srp : (struct RastPort *). Pointeur sur le RastPort "source".
- sx : (long). Décalage dans le plan des X de la source.
- sy : (long). Décalage dans le plan des Y de la source.
- drp : (struct RastPort *) Pointeur sur le RastPort "destination".
- dx : (long). Décalage dans le plan des X de la destination.
- dy : (long). Décalage dans le plan des Y de la destination.
- w : (long). Largeur de la zone de mémoire qui devra être copiée.
- h : (long). Hauteur de la zone de mémoire qui devra être copiée.
- flag : (long). Cette valeur informe le Blitter du type d'opérations logiques à effectuer. Voir ci-dessous
pour plus de renseignements.
12.5 Exemples
Voici des exemples
(dans le répertoire "Amiga_C_Manual/12.LowLevelGraphics") montrant des routines graphiques de bas niveau :
Exemple 1
Cet exemple vous montre comment créer votre propre affichage et comment on le remplit avec un tas
de pixels de sept couleurs différentes.
Exemple 2
Cet exemple vous montre comment créer un grand raster et un petit affichage. Nous remplissons le
raster avec un tas de pixels de sept couleurs différentes et, en modifiant les valeurs de RxOffset
et de RyOffset, dans la structure RasInfo, le raster défilera dans toutes les directions. Cette
méthode pour faire défiler un grand dessin à grande vitesse est employée dans beaucoup de jeux
et je l'ai moi-même employée dans mon jeu de course automobile "Car".
Exemple 3
Cet exemple vous montre comment créer un affichage qui couvre tout l'écran. On appelle cette méthode
"Suraffichage" et on l'utilise en premier lieu dans les programmes vidéo et graphiques, mais on peut
aussi s'en servir dans des jeux pour rendre un affichage plus attrayant.
Exemple 4
Cet exemple montre comment ouvrir deux ViewPorts différents dans un même affichage. Le premier ViewPort
est en basse résolution et emploie 32 couleurs, tandis que le deuxième est en haute résolution
et emploie seulement deux couleurs.
Exemple 5
Cet exemple montre comment ouvrir un ViewPort en mode entrelacé.
Exemple 6
Cet exemple montre comment ouvrir un ViewPort en mode double champ de jeu. Le champ de jeu
1 utilise quatre couleurs et a été placé au-dessous du champ de jeu 2 qui utilise seulement deux couleurs
(transparent et gris). Le champ de jeu 1 est rempli d'un tas de points et défile dans tout l'écran,
tandis que le champ de jeu 2 est fixe et est rempli de cinq rectangles gris.
Exemple 7
Cet exemple montre comment créer un ViewPort en utilisant le mode d'affichage spécial "Hold And Modify".
Exemple 8
Cet exemple montre coment on utilise les fonctions suivantes :
SetAPen(), SetBPen(), SetOPen(), SetDrMd(), SetDrPt(), WritePixel(),
ReadPixel(), Move(), Draw(), Text() et, pour finir, PolyDraw().
Exemple 9
Cet exemple montre comment faire le remplissage "flood" d'un dessin
et comment dessiner des rectangles pleins (avec des modèles simples et multicolores).
Exemple 10
Cet exemple montre comment on emploie les fonctions Area Fill. [ AreaMove(), AreaDraw() et AreaEnd() ].
Exemple 11
Cet exemple montre comment on copie des zones de mémoire rectangulaires en se servant du Blitter.
|