Le blitter

 

C'est quoi ?

Le blitting permet de copier une partie ou une surface entièrement vers une autre surface.

Il existe deux fonctions sous directX permettant cela:

BltFas() qui permet de copier une surface vers une autre avec un éventuel effet de transparence (une couleur servira à indiquer les points transparents de l'image (un peu comme le fond bleu utilisé à la télévision pour la météo par exemple).

Blt() qui est bien plus complète est donc plus lente que la précédente fonction.

 

Les fonctions dans IDirectDrawSurface:

IDirectDrawSurface::BltFast

Permet de copier le contenu de deux surfaces de la mémoire vidéo (back buffer à back buffer ou back buffer primary buffer ou inversement).

Cependant, cette fonction ne marchera que si les surfaces n'ont pas activées le clipper.

Il sera possible d'effectuer une blitting avec transparence grâce à une source de couleur sur la surface souce ou destination.

Cette fonction n'est pas toujours présente, il faudra donc la tester.

HRESULT BltFast(
DWORD dwX,
DWORD dwY,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwTrans
);

En entrée:

dwX and dwY X et Y du point supérieur gauche du bloc à copier sur la surface de destination

lpDDSrcSurface Adresse source de la surface à blitter.

lpSrcRect Adresse sur une structure RECT permettant d'indiquer les coordonnées de l'image à copier. Pourra être NULL pour indiquer la surface totale

dwTrans Type de transfert à faire avec:

Valeur Désignation
DDBLTFAST_NOCOLORKEY Copie normale sans transparence...
DDBLTFAST_DESTCOLORKEY Couleur transparente sur l'image source
DDBLTFAST_SRCCOLORKEY Couleur transparente sur l'image destination
DDBLTFAST_WAIT Attend que le blitter soit près, et rend la main ensuite


Image non trouvée ! DDBLTFAST_WAIT, à priori, il faudra souvent positionner ce drapeau, car sinon, le traitement est asynchrone, le CPU risque ainsi d'effectuer d'autres traitements graphiques alors que la copie de surface n'est pas encore faite. Lorsque le drapeau est indiqué, alors le programme sera interrompu jusqu'à ce que le blitter soit près à effectuer la tâche demandée. Dans ce cas, ce programme pourra continuer.

Image non trouvée !Pour renseigner ou lire la couleur à utiliser comme clé pour la transparence sur une surface source ou destination, voir le chapitre DDColorKey

En sortie: DD_OK. si tout est ok, sinon l'un des messages suivants:
DDERR_EXCEPTION
DDERR_GENERIC
DDERR_INVALIDOBJECT
DDERR_INVALIDPARAMS
DDERR_INVALIDRECT
DDERR_NOBLTHW
DDERR_SURFACEBUSY
DDERR_SURFACELOST
DDERR_UNSUPPORTED
DDERR_WASSTILLDRAWING


IDirectDrawSurface::Blt

Permet aussi de faire un transfert de bloc.

Image non trouvée ! il s'agit de 2D, z-buffer ou l'utilisation du canal alpha ne sont donc pas supportés !

HRESULT Blt(
LPRECT lpDestRect,
LPDIRECTDRAWSURFACE lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwFlags,
LPDDBLTFX lpDDBltFx
);

En entrée:

lpDestRect Adresse d'une structure RECT pour indiquer la postion de l'image destination. NULL pour utiliser toute la surface destination.
lpDDSrcSurface Adresse sur une interface IDirectDrawSurface pour trouver l'objet DirectDrawSurface source.
lpSrcRect Adresse d'une structure RECT pour indiquer la postion de l'image source. NULL pour utiliser toute la surface source.
dwFlags Sert à indiquer les membre de la structure DDBLTFX à utiliser.

Valeur Désignation
DDBLT_ASYNC effectue le blitting d'une manière asynchrone (par défaut)
DDBLT_WAIT attend que le blitter soit prêt et rend la main
DDBLT_COLORFILL remplit le rectangle cible avec la couleur spécifiée dans le champs dwFillColor de la structure DDBLTFX
DDBLT_DDFX effectue les transformations demandées dans la structure DDBLTFX
DDBLT_KEYDEST utilise la clé de couleur destination pour le blitting
DDBLT_KEYSRC utilise la clé de couleur source pour le blitting
DDBLT_DDROPS Opérations raster différent de Microsoft Win32 API
DDBLT_DEPTHFILL Remplissage du rectangle destination sur l'axe z (dwFillDepth dans la structure DDBLTFX)
DDBLT_KEYDESTOVERRIDE cle de couleur à utiliser pour la surface destination (ddckDestColorkey dans la structure DDBLTFX)
DDBLT_KEYSRCOVERRIDE cle de couleur à utiliser pour la surface source (ddckSrcColorkey dans la structure DDBLTFX)
DDBLT_ROP dwROP dans la structure DDBLTFX. Les ROPs sont identiques à ceux de Win32 API
DDBLT_ROTATIONANGLE Angle de rotation de la surface (dwRotationAngle dans la structure DDBLTFX)
DDBLT_DONOTWAIT DX 7 : retour sans blitting et retourne DDERR_WASSTILLDRAWING si le blitter est occupé.

 

lpDDBltFx adresse sur une structure de type DDBLTFX.

En sortie, DD_OK si ok, sinon erreur et
DDERR_GENERIC
DDERR_INVALIDCLIPLIST
DDERR_INVALIDOBJECT
DDERR_INVALIDPARAMS
DDERR_INVALIDRECT
DDERR_NOALPHAHW
DDERR_NOBLTHW
DDERR_NOCLIPLIST
DDERR_NODDROPSHW
DDERR_NOMIRRORHW
DDERR_NORASTEROPHW
DDERR_NOROTATIONHW
DDERR_NOSTRETCHHW
DDERR_NOZBUFFERHW
DDERR_SURFACEBUSY
DDERR_SURFACELOST
DDERR_UNSUPPORTED
DDERR_WASSTILLDRAWING

 

Exemple de fonctions utilisant la méthode blt()

Dessiner un rectangle

Cette fonction va permettre de dessiner un rectangle:

Remplir une surface

Sur le même principre, on peut imaginer une fonction qui va remplir toute la surface d'une certaine couleur:

Dès que votre traitement est terminé, vous pouvez transférer le dessin du back buffer vers la primary surface:

 

Copier un bloc d'une surface vers une autre surface

bool CopySxyToSxy( int xsrc, int ysrc, int x1src, int y1src, DWORD xdest, DWORD ydest,
LPDIRECTDRAWSURFACE lpDDSSource, // source surface
LPDIRECTDRAWSURFACE lpDDSDest // destination surface
)
{
// Je n'utilise pas bltfast !!!
HRESULT hr; // Valeur retounée par DirectX

RECT rcSource, rcDest;
DDBLTFX ddbltfx;

ZeroMemory(&ddbltfx, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwDDFX = NULL; //DDBLTFX_MIRRORLEFTRIGHT;

rcSource.top = ysrc;
rcSource.left = xsrc;
rcSource.bottom = y1src;
rcSource.right = x1src;
rcDest.top = ydest;
rcDest.left = xdest;
rcDest.bottom = ydest + (y1src - ysrc);
rcDest.right = xdest + (x1src - xsrc);

hr = lpDDSDest->Blt(&rcDest,
lpDDSSource,
&rcSource,
DDBLT_KEYSRCOVERRIDE | DDBLT_WAIT /*| DDBLT_DDFX Effet miroir de gauche à droite */,
&ddbltfx);

if (hr != DD_OK)
return false;

else
return true;
}

Gérer une couleur transparente

Vous venez de voir comment copier une bloc d'une surface vers une autre surface. Cette fonction pouvant ainsi faire office de sprite.

Cependant, il reste encore une chose à dire. Les sprites dans un jeu ne sont généralement pas de la forme d'un rectangle, mais plutôt d'une forme indéterminée. Heureusement, la foncion blt va vous permettre cela.

L'idée est assez simple en fait, vous allez définir une couleur. Cette couleur sera traduite automatiquement comme une "couleur transparente" par DirectDraw. En fait, le principe est identique à celui utilisé dans le cinéma ou la météo. Dans leur cas, ils utilisent souvent un fond de couleur vert ou bleu. Dans le cas de la météo, le présentateur se déplace sur ce fond bleu ou vert. Puis la couleur de ce fond est automatiquement remplacée par la carte météo et le résultat est diffusé sur notre petit écran.

Nous allons utiliser ce même principe.

... A venir ...