begin process at 2010 02 10 12:53:32
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

API

 > EFFET D'EAU AVEC GETDIBITS ET SETDIBITS

EFFET D'EAU AVEC GETDIBITS ET SETDIBITS


 Information sur la source

Note :
9 / 10 - par 1 personne
9,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :API Classé sous :watereffect, getdibits, setdibits, effetdeau, image Niveau :Initié Date de création :25/04/2007 Date de mise à jour :26/04/2007 15:13:17 Vu / téléchargé :6 050 / 1 139

Auteur : barbichette

Ecrire un message privé
Site perso
Commentaire sur cette source (16)
Ajouter un commentaire et/ou une note

 Description

Cliquez pour voir la capture en taille normale
Voilà un petit exemple des deux fonctions GetDiBits etSetDiBits qui permettent de transferer une série de bits de la mémoire à une image (tbitmap, timage,...)
dans l'exemple, on applique un effet d'eau sur une image de fond.
On peut par ailleurs déplacer les cailloux qui sont sous l'eau.
On vois donc la rapidité et la simplicité par rapport à scanline ou encore Pixels[]

Sinon, juste pour info, la bouton Tsunami, qui déclache une grosse vague ne marche pas toujours...
Je n'ai pas cherché à savoir pourquoi puisque le reste marche bien...

alors, si quelq'un a une solution, à bonne entendeur salut...


 Conclusion

Alors, ce code propose un exemple d'utilisation de deux fonctions, Getdibits et Setdibits. Pour l'effet d'eau, j'ai trouvé ça sur internet.

En gros, le principe tient en quelques points
1 - ne travailler que sur des valeurs en mémoire (tableaux) et n'afficher le résultat qu'une fois le traitement terminé.
2 - pour une rapidité d'affichage, transfert de l'image finale par setdibits, qui envoie d'un seul coup tous les octets de l'image. Donc, bien plus rapide qu'un scanline[n] ou encore un pixels[x,y]
3 - Donc, on charge les images et on transfert les octets de pixels vers une zone mémoire préalablement affecté (via getdibits). Une seule fois lors de la création de la fiche. Puis traitement direct en mémoire et affichage à chaque itération en transférant via setdibits

Pour l'effet en lui même, vous trouverez sûrement sur Internet des tas d'info dessus mais je vais résumer :
1 – On a un buffer qui contient l'élévation de l'eau à l'instant T et T-1.
A chaque itération, on applique un effet dessus.
On fait une moyenne des élévations des 8 cases autour d’un point au temps T et on retranche l’élévation au temps T-1 de cette même case.
L’élévation ainsi calculée donnera la valeur à T+1.
Pour créer une vague, il suffit ) un instant donné, de mettre une forte élévation en un point et l’effet sur le buffer va se charger de propager l’onde.

2 – dessin avec une texture de fond :
Pour chaque point de l’image (x,y), on calcule la déviation du à une vague en calculant la pente à cette endroit. Donc dx=buffer[x,y]- buffer[x+1,y] et dy=buffer[x,y]- buffer[x,y+1]
On placera comme couleur de pixel à l’endroit (x,y) le pixel de l’image originale (x+dx,y+dy)

Enfin, pour trouver les contours d’un caillou, je parcours le dessin de caillou et je repère les points qui sont dans le caillou et où un des quatre points adjacents sont en dehors.

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

25 avril 2007 21:00:58 :
contour des pierres dans l'eau lors du déplacement et libération de la mémoire pour ce qui ne sert plus
26 avril 2007 15:13:17 :
- rajout d'une petite explication - correction de quelques Bugs sur l'affichage (onde autour des cailloux à l'opposé sur l'écran) - séparation et reduction du buffer de vague (de integer vers smallint => 2 fois moins de place)

 Sources du même auteur

Source avec Zip Source avec une capture THREAD ET BITMAP (DESSIN AU CRAYON)
Source avec Zip Source avec une capture ÉCRAN DE VEILLE FEU D'ARTIFICE
Source avec Zip Source avec une capture MESSAGE EN FEU D'ARTIFICE
Source avec Zip Source avec une capture ENCORE LOUPÉ
Source avec Zip Source avec une capture JEU LOGICOLOR

 Sources de la même categorie

Source avec Zip NEXTGENS -> UNITÉS DE TYPES ÉVOLUÉS NOUVELLE GÉNÉRATION (DE... par f0xi
Source avec Zip Source avec une capture AUTO-COMPLÉTION D'UN CONTRÔLE DE SAISIE par Bacterius
Source avec Zip CARDS GAME SDK 1.0.0.0 par f0xi
Source avec Zip Source avec une capture TRAYICON - VOTRE ICONE DANS LA BARRE DES TACHES par Bacterius
Source avec Zip Source avec une capture WINHIDER _ CACHER UN PROGRAMME DE L'ÉCRAN ET DE LA BARRE DE ... par soldier8514

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture ANAGLYPHEUR OU COMMENT VOIR EN RELIEF LES STÉRÉOSCOPES ANCES... par jfs59
Source avec Zip Source avec une capture DÉFORMER UNE IMAGE AUX DIMENSIONS D'UN QUADRANGLE QUELCONQUE... par FFCAST
Source avec Zip Source avec une capture IMAGE DANS UN TDBGRID par HAFTARIFOUAD
Source avec Zip Source avec une capture IMAGE WEBCAM SUR SITE WEB. par titout2
Source avec Zip Source avec une capture GETDIBITS/SETDIBITS - DEMO SIMPLE! par MAURICIO

Commentaires et avis

Commentaire de cirec le 25/04/2007 18:50:51 administrateur CS

Salut,

chez moi j'ai pas le problème que cite Florenth ???

Et le bouton Tsunami fonctionne ???

Par contre au niveau perte de mémoire ... Aïe aïe aïe ;)

Unexpected Memory Leak
---------------------------
An unexpected memory leak has occurred. The unexpected small block leaks are:



21 - 28 bytes: TBrush x 1, TPen x 1

29 - 36 bytes: TFont x 1, Unknown x 2

53 - 60 bytes: TBitmap x 2

61 - 68 bytes: Unknown x 1

93 - 100 bytes: TBitmapCanvas x 1

109 - 116 bytes: TBitmapImage x 2


---------------------------
OK  
---------------------------

Il faut penser à liberer les objets :)

Sinon l'effet est joli ... Bravo
Je regarderai le code de plus près dès que possible.

@+
Cirec

Commentaire de barbichette le 25/04/2007 19:08:16

pour l'erreur d'étendu, on peut remplacer array[0..0] par array[0..MAXINT div 4]
Et normalement, il n'y a plus de problème.

Sinon, Cirec, il me semblait que la libération était automatique lorsque l'on sort de la porté de cette objet.
Ainsi, quand on quitte une procédure, un object tbitmap ou autre créé dans cette procédure, l'objet est détruit à la sortie de cette procédure.
Peut-être que c'est que dans Borland, ou alors, ça n'existe plus, ou alors, j'ai rêvé...

Commentaire de Ali_usto le 25/04/2007 19:57:21

SALUT , bravo l'effet est vraiment tres joli et ça marche tres bien chez moi
  bonne continuation...

Commentaire de Harvester_ le 25/04/2007 20:09:32

Très beau mais consomme énormément niveau CPU... 75% qui passe à presque 100 avec le Tsunami... P4 2Ghz...

Commentaire de barbichette le 25/04/2007 20:49:42

je vais donc regarder les problèmse d'allocation, même si au finale, il ne prend en gros que 6Mo en mémoire, mais pour une programmation propre, no problemo.

Pour la forme de la pierre, je vais me pencher aussi sur le problème.
A l'origine, je pensais que la pierre restait sous l'eau lors du déplacement, mais avec un effet de bord, ça serai surement plus joli...

Je poste tout ça d'ici peu...

Sinon, pour les 75% de CPU, c'est souvent le cas pour les effets visuelles comme ceux là... ça paraît rien comme ça mais ça bouf pas mal de cpu.
On peut d'ailleurs optimiser le tout en assembleur mais pour la lecture des néofites, bof bof...

Bon, merci a tous, même si, il faut bien le dire, cet effet n'a rien de révolutionnaire...

Commentaire de Francky23012301 le 26/04/2007 12:03:00

Salut,

L'effet est superbe et coté code pas grand chose à redire.

Juste une petite remarque : quand on fait ce genre de chose (effets graphiques), il serait toujours intéressant de faire initialement un petit commentaire pour expliquer le principe, la stratégie, ainsi que les formules utilisées, hors c'est rarement le cas et ca manque cruellement.

@+

Commentaire de Forman le 26/04/2007 16:17:47

Salut,

ton code fonctionne avec les images fournies, mais je pense que
1/Tu as de la chance.
2/Ce ne serait pas le cas avec des images de taille différente (en particulier plus grande).

Je m'explique: les fonctions GetDIBits et SetDIBits travaillent avec des pointeurs vers un tableau de pixels. Bien que ce ne soit précisé nulle part sur MSDN, et pour des raisons connues de Microsoft seules (à supposer qu'il y en ait vraiment, d'ailleurs) le tableau qu'on leur passe en paramètre doit être situé sur une seule page de la mémoire virtuelle (il ne doit pas chevaucher 2 pages par exemple).

La fonction native de Delphi que tu utilises ici, GetMem à la ligne 175:
getmem(cailloux,bit.Width*bit.Height*4);
ne garantit absolument pas ce comportement-là. Pour être sûr que ça fonctionne, il existe une méthode:

procedure WinGetMem(var p:Pointer;Size:Cardinal);
begin
  p:=VirtualAlloc(nil,Size,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE);
  if not Assigned(p) then
    RaiseLastOSError;
end;

procedure WinFreeMem(p:Pointer);
begin
  if Assigned(p) and not VirtualFree(p,0,MEM_RELEASE) then
    RaiseLastOSError;
end;

En utilisant respectivement WinGetMem et WinFreeMem à la place de GetMem et FreeMem ça fonctionnera de la même façon et ça rendra ton code plus sûr. Essaie avec des images de taille plus grande, pas exemple 800x600 et tu verras que tu auras sûrement un problème (je le sais pour avoir passé des heures à m'arracher les cheveux pour essayer de comprendre pkoi ça marchait pas avec l'un de mes codes). Ce problème est pas exemple mentionné implicitement ici:
http://lists.ibiblio.org/pipermail/sm-spell-submit/2006-April/003307.html

En plus de corriger un éventuel bug, ça pourrait même accélérer ton code.

Commentaire de MAURICIO le 04/05/2007 16:21:42

Salut Barbichette,

j' avoue que ton source m' a bleuffé en terme de rapidité d' execution.
Par contre, difficile t' en tirer quelques chose vu la complexité du code.

Pourrais tu donner une nouvelle source d' utilisation de GetDiBits/SetDiBits beaucoup plus simple pour que l' on puisse plus facilement exploiter ces fonctions(et prendre en consideration le post de notre expert en images que je nomme Forman)?
Genre, on clique sur un bitmap et le bitmap subit une quelconque transformation dans la zone du clique (effet flou par exemple) ?

En tout cas, c' est du bon boulot!
A+

Commentaire de barbichette le 05/05/2007 01:03:44

Alors,
Mauricio, je vais voir pour faire un exemple plus simple,
Forman, j'ai essayé de mettre tes fonctions wingetmem et winfreemem à la place de getmem et freemem.
Malheureusement, j'ai maintenant un bug à la fermeture. Soit, j'écris en dehors d'un tableau, soit il y a un autre bug.
Je vais chercher le problème avant de poster la modif.
Merci pour l'info, c'est sûr que je n'aurai jamais cherché ici un bug pour des images plus grande...

a+

Commentaire de Forman le 05/05/2007 10:56:07

Oui effectivement ça doit être un problème d'écriture à l'extérieur d'un tableau. Je n'ai pas regardé en détails, mais en faisant ça:

WinGetMem(Pointer(im),wi*he*4*2*2);

au lieu de :

WinGetMem(Pointer(im),wi*he*4*2);

ça règle apparemment le problème (mais ça utilise 2x plus de mémoire aussi     :-S)

Commentaire de jpt le 25/08/2007 18:39:56

Hi !

@Barbichette : [quote]Malheureusement, j'ai maintenant un bug à la fermeture[/quote]
M'en suis sorti avec SetLength(vagues, wi*he*2*2); plutôt que le GetMem d'origine.
Et il y a un truc qui sert à rien :
//??  image1.Picture.Bitmap := tbitmap.Create;
Et Memcheck est pas content du tout si je décommente, ;-)

Dommage qu'il n'y ait pas plus de commentaires, difficile de démonter pour comprendre (et régler ce problème de "dépassement des limites" qui apparaît dans le timer si l'option est activée -- et si elle ne l'est pas, qu'est-ce que ça cache ?)
Bravo pour l'effet visuel, en tout cas !
--
jpt

PS : le lien cité par forman le 26/04 à 16:17 pointe sur un truc qui n'a rien à voir...

Commentaire de Forman le 25/08/2007 19:14:18

Ben si quand même ça a à voir, si tu lis à partir de la 3° phrase:

"The changes in this release are as follows:
Fixes an fxkeyboard.cpp build problem on Windows and a sporadic core
dump due to SetDIBits() reacting poorly to malloc()-allocated memory.
It is now using VirtualAlloc() instead of malloc(), which gives whole
pages. "

ça veut dire qu'ils ont corrigé un bug dans leur programme en utilisant "VirtualAlloc() instead of malloc()"

Commentaire de Forman le 25/08/2007 19:17:46

Ah oui: l'équivalent du malloc du C en Delphi c'est GetMem (peut être que le rapport est plus clair comme ça).

Commentaire de mcapp le 30/07/2008 02:31:25

bonjour,
j'ai "types incompatibles" ligne 215 !

Commentaire de barbichette le 30/07/2008 09:32:11

dans les options de delphi, il doit y avoir un truc pour corriger ça.
Je ne sais plus où...
essaie déjà :
getmem(pointer(vagues),wi*he*2*2);

Commentaire de mcapp le 30/07/2008 13:34:25

OK ! Merci Barbichette !
Pb corrigé ! Je vais pouvoir apprécier la qualité de travail !
Merci !

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Image de fond dans un TreeView [ par Valérie ] Bonjour, J'utilise une application DELPHI6 CLX et je n'aarive pas à avoir une image de fond dans mon TreeView. L'événement OnPaint n'existe pas. Si image du bureau a intervalle regulier [ par tarik ] salut je voudrais faire des sauvegardes de l'etat du bureau (une sorte d'imprime ecran) a intervalle regulier image ds un richedit [ par sebrs1 ] comment inserer une image ds un richedit? tbitbtn avec image format jpeg [ par vib ] existe il un composant ou une solution pour avoir un bouton du genre bitbtn avec une image au format jpeg ?A+ Image dans une TStatusBar !!! [ par MAsterC ] Comment fait-on pour mettre un Tprogresbar et un petit dessin dans l'item TStatusBar ????POUR PLUS DE DÉTAILS ALLER VOIR DANS INTERNET EXPLORER EN BAS Sacré Mikey, c jamais ou il est! :: Prob localisation souris [ par Gysmo ] Salut a tous!Voila j'ai creer sur mon prog des bontons avec des TImage superposé. Kan on click ca change d'image, une image bouton normal, une image b Texte sur une image [ par Gysmo ] Comment arrivé à écrir du texte sur une image puis la sauvegarder comme tel??!Merci Imprimer une image et un texte sur la même feuille [ par zeusnul ] Bonjour,J'aimerais pouvoir imprimer une image et un texte sur la même feuille, mais je suis dans l'incapacité de trouver ça dans l'aide de delphi. Je ImageList ... Help ! ;-) [ par HEproduct ] Bonjour, je voudrai stocker des images de trés petites tailles dans une image lit et récupérer les noms dans une list box. Après quoi l'utilisateur en Image [ par sebastienbro ] Comment faire pour effacer le contenu d'une image ?


Nos sponsors


Sondage...

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 1,014 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales