Traiter une surface

 

La surface est maintenant créée, vous savez donc comment elle est constituée. Mais vous pouvez aussi récupérer les informations si vous les avez oublié !

A partir de ces informations, vous pourrez accéder directement à la surface.

Comme il s'agit de faire du graphisme, la première chose sera de convertir une couleur dans le format utilisé par la surface (plus simplement suivant le type de palette utilisée):

Les couleurs : En général on utilise des couleurs codées en 16 bits ou 24 bits: Les composantes sont toujours les mêmes le rouge, le vert et le bleu.

Dans le mode 24 bits, les composantes (Rouge, vert et bleu) sont caractérisées par un octet, et peut donc avoir une valeur entre 0 et 255.

Dans le mode 16 bits, les composantes rouge et bleu sont sur 5 bits (valeurs comprises entre 0 et 31) et la composante verte est codée sur 6 bits (valeur comprise entre 0 et 63).


Je laisse tomber le cas d'une palette à 256 couleurs, qui ne doit pas être bien souvent utilisée. En effet, il faut alors prévoir une routine qui va rechercher dans la palette la couleur se rapprochant le plus de la couleur passée en paramètre. Voire gérer le cas d'une création d'une couleur dans la palette parmis celles qui ne sont pas encore utilisées...

Autre remarque: Je pense que l'on peut rester à un codage sur 16 bits des couleurs, la palette étant suffisement intéressante dans ce cas.

iBpp doit donc contenir le codage des couleurs. On peut récupérer cette information en faisant:

hr= lpDDSSurface->Lock( NULL, &ddsd, DDLOCK_WAIT, NULL );

// Récupération du nombre de couleurs
iBpp = ddsd.ddpfPixelFormat.dwRGBBitCount;

// Dévérouillage de la surface
hr=lpDDSSurface->Unlock( NULL );

Voilà deux nouvelles fonctions : Lock et Unlock.

Il faut en effet vérouiller la surface avant de l'utiliser, cela évite les accès concurrents.

De plus, la fonction Lock va retourner dans une structure de type DDSURFACEDESC2 (ici ddsd) les informations concernant la surface. Vous pouvez ainsi lire le type de codage des couleurs utilisé.

Maintenant que vous avez votre couleur, vous pouvez dessiner dans votre surface. Là aussi, celle-ci doit être vérouillée. vous obtenez de cette manière d'autres informations comme:

L'adresse de début de la surface : Adresse= (WORD *)ddsd.lpSurface ;

Ainsi que la taille réelle d'une ligne taille= ddsd.lPitch/2; (Si vous avez déjà programmé sous DOS avec le VESA par exemple, vous devriez comprendre facilement pourquoi).

Ce qui va vous permettre de calculer via des coordonnées (x,y) la position de votre point dans la surface:

Adresse= (WORD *)ddsd.lpSurface + ddsd.lPitch/2*y + x;

Vous pouvez écrire dans la surface, mais de la même manière, vous pouvez aussi lire la couleur d'un point dans une surface.

Remarque, rien ne vous empêche d'utiliser l'assembleur (non, non ne vous sauvez pas !)

Rapidement, car ce n'est pas le sujet:

BOOL FAR PASCAL asm_aff (LPDIRECTDRAWSURFACE lpDDS)

{

_asm {
push cx
push esi

mov esi, DWORD PTR lpDDS


... la suite du code

pop esi
pop cx

} // Fin du code assembleur

return TRUE;

}