ARBRE2D: UN PROGRAMME GÉNÉRANT DES ARBRES

acx01b Messages postés 280 Date d'inscription dimanche 7 septembre 2003 Statut Membre Dernière intervention 8 juillet 2014 - 15 janv. 2008 à 22:22
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 16 janv. 2008 à 17:54
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/45434-arbre2d-un-programme-generant-des-arbres

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 janv. 2008 à 17:54
Regarde un exemple:
ABOUTBOX SINUSOIDE (WIN32)
http://www.cppfrance.com/code.aspx?id=10630
ndubien Messages postés 557 Date d'inscription dimanche 25 septembre 2005 Statut Membre Dernière intervention 10 mai 2014 4
16 janv. 2008 à 17:46
Bonjour RenField,
Lorsque vous dites "stockes la dans un hBMP tampon"...
hBMP veut-il bien dire HBITMAP?
si oui, celà signifie que je dois stocker mon "image" crée sur un HDC dans HBITMAP...
comment faut-il que je procède?
Merci d'avance...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
16 janv. 2008 à 16:25
WM_PAINT est envoyé chaque fois que Windows a besoin d'afficher une partie de ton image.

c'est dommage (pour ne pas dire plus) d'y recalculer ton image.

calcule ton image une bonne fois, stockes la dans un hBMP tampon et rebalance cette image via BitBlt, à l'ecran quand demandé.

(je n'ai fait que reformuler ce qu'a conseillé BruNews)
ndubien Messages postés 557 Date d'inscription dimanche 25 septembre 2005 Statut Membre Dernière intervention 10 mai 2014 4
16 janv. 2008 à 16:19
Bonjour Brunews,
merci pour le code de TracerTraitVert en ASM...
Sinon, pour l'utilisation des fonctions dans WM_PAINT, il est vrai que ce n'est pas conseillé pour ce genre de fonction qui peut prendre du temps mais c'était juste pour tester les fonctions et en voir le résultat.
Que me conseillez-vous de moins lourd?
Merci d'avance et à bientôt...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 janv. 2008 à 15:59
Très clair que GDIquement parlant ça ne va absolument pas, il faut écrire sur un contexte mémoire et le plaquer direct en 1 passe (BitBlt() par exemple).
Idem on ne traite pas une boucle lourde sur WM_PAINT, c'est un event qui peut être réçu des dizaines de fois par seconde.
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
16 janv. 2008 à 10:14
voire peut etre même passer par la manipulation des bits d'un DIB directement...
pas de SetPixel en boucle, quoi... (GetDibBits / SetDibBits)

SetPixelV serait même une petite amélioration interessante (pas de retour de l'ancienne valeur)
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
16 janv. 2008 à 01:05
La même en mieux finalisée:

__declspec(naked) void __stdcall TracerTraitVert(HDC hdc, double Ax, double Ay, double Bx, double By)
{
__asm {
push ebx
push ebp
push esi
push edi
;// hdc [esp+20], Ax [esp+24], Ay [esp+32], Bx [esp+40], By [esp+48]
cvttsd2si eax, [esp+24] ;// x1 = round(Ax)
cvttsd2si ecx, [esp+32] ;// y1 = round(Ay)
cvttsd2si ebx, [esp+40] ;// EBX = x2 = round(Bx)
cvttsd2si esi, [esp+48] ;// ESI = y2 = round(By)
push eax
push ecx
mov edi, eax
cvtsi2sd xmm3, ebx ;// xmm3 = x2
cvtsi2sd xmm4, esi ;// xmm4 = y2
mov eax, ebx
sub eax, edi ;// x2 - x1
cdq
mov edi, eax
xor edi, edx
mov eax, esi
sub edi, edx ;// EDI nbBoucles abs(x2-x1)
sub eax, ecx ;// y2 - y1
cdq
xor eax, edx
sub eax, edx ;// eax = abs(y2-y1)
xor ebx, ebx ;// EBX = x1*i
xor esi, esi ;// ESI = y1*i
cmp edi, eax
jae short bclOK
mov edi, eax ;// EDI = nbBoucles
bclOK: ;// EDI nbBoucles, EBX x2, ESI = y2
;// hdc [esp+28], x1 [esp+4], y1 = [esp]
xor ebp, ebp ;// EBP = i
test edi, edi
je short tracerEXIT
cvtsi2sd xmm5, edi
forITOBCL: ;// xmm3 dbl(x2), xmm4 dbl(y2), xmm5 = dbl(nbBoucles)
cvtsi2sd xmm6, ebp ;// i
movsd xmm7, xmm5
cvtsi2sd xmm0, ebx ;// xmm0 = x1*i
subsd xmm7, xmm6 ;// xmm7 = nbBoucles - i
cvtsi2sd xmm1, esi ;// xmm1 = y1*i
movsd xmm2, xmm7 ;// xmm2 = nbBoucles - i
divsd xmm0, xmm5 ;// (x1*i) / nbBoucles
mulsd xmm7, xmm3 ;// xmm7 = x2 * (nbBoucles - i)
mulsd xmm2, xmm4 ;// xmm2 = y2 * (nbBoucles - i)
divsd xmm7, xmm5
divsd xmm2, xmm5
divsd xmm1, xmm5 ;// (y1*i) / nbBoucles
addsd xmm0, xmm7 ;// x
addsd xmm1, xmm2 ;// y
mov eax, [esp+28] ;// EAX = hdc
cvttsd2si ecx, xmm1 ;// ECX = y
cvttsd2si edx, xmm0 ;// EDX = x
push 0 ;// deja dispo pour SetPixel(hdc, x, y, 0)
push ecx
push edx
push eax ;// params SetPixel OK
push ecx
push edx
push eax
call dword ptr GetPixel
mov edx, eax ;// EAX EDX temp
and eax, 0FFFFFFh
add dh, 1 ;// GetGValue(temp)+1
cmp eax, 0FFFFFFh
je short goSETPIX
mov [esp+12], edx
goSETPIX:
call dword ptr SetPixel
inc ebp
add ebx, [esp+4] ;// x1*i
add esi, [esp] ;// y1*i
cmp ebp, edi
jle short forITOBCL
tracerEXIT:
add esp, 8
xor eax, eax ;// dummy
pop edi
pop esi
pop ebp
pop ebx
ret 36
}
}
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
15 janv. 2008 à 23:58
ndubien, je sens que vais être désagréable (non non je plaisante, quoi que...).
COLORREF temp = GetPixel( hdc, x, y );
if(GetRValue(temp) 255 && GetGValue(temp) 255 && GetBValue(temp) == 255) SetPixel(hdc, x, y, RGB(0,0,0));
Une aussi énorme horreur dans la boucle critique, NONNNNNNN !!!
Va donc voir l'ASM du compilo, tu seras dégouté.
if((tmp & 0xFFFFFF) 0xFFFFFF) tmp 0;
else tmp = ... je te le laisse celui ci
SetPixel(hdc, x, y, tmp);

Maintenat juste pour le fun, teste ceci qui booste sérieusement le dessin.
J'ai commenté autant que j'ai pu.
__declspec(naked) void __stdcall TracerTraitVert(HDC hdc, double Ax, double Ay, double Bx, double By)
{
__asm {
push ebx
push ebp
push esi
push edi
;// hdc [esp+20], Ax [esp+24], Ay [esp+32], Bx [esp+40], By [esp+48]
cvttsd2si eax, [esp+24] ;// x1 = round(Ax)
cvttsd2si ecx, [esp+32] ;// y1 = round(Ay)
cvttsd2si ebx, [esp+40] ;// EBX = x2 = round(Bx)
cvttsd2si esi, [esp+48] ;// ESI = y2 = round(By)
push eax
push ecx
mov edi, eax
cvtsi2sd xmm3, ebx ;// xmm3 = x2
cvtsi2sd xmm4, esi ;// xmm4 = y2
mov eax, ebx
sub eax, edi ;// x2 - x1
cdq
mov edi, eax
xor edi, edx
mov eax, esi
sub edi, edx ;// EDI nbBoucles abs(x2-x1)
sub eax, ecx ;// y2 - y1
cdq
xor eax, edx
sub eax, edx ;// eax = abs(y2-y1)
push 0 ;// x1*i
push 0 ;// y1*i
cmp edi, eax
jae short bclOK
mov edi, eax ;// EDI = nbBoucles
bclOK: ;// EDI nbBoucles, EBX x2, ESI = y2
;// hdc [esp+36], x1 [esp+12], y1 = [esp+8], x1*i = [esp+4], y1*i = [esp]
xor ebp, ebp ;// EBP = i
test edi, edi
je short tracerEXIT
cvtsi2sd xmm5, edi
forITOBCL: ;// xmm3 dbl(x2), xmm4 dbl(y2), xmm5 = dbl(nbBoucles)
cvtsi2sd xmm6, ebp ;// i
movsd xmm7, xmm5
cvtsi2sd xmm0, [esp+4] ;// xmm0 = x1*i
subsd xmm7, xmm6 ;// xmm7 = nbBoucles - i
cvtsi2sd xmm1, [esp] ;// xmm1 = y1*i
movsd xmm2, xmm7 ;// xmm2 = nbBoucles - i
divsd xmm0, xmm5 ;// (x1*i) / nbBoucles
mulsd xmm7, xmm3 ;// xmm7 = x2 * (nbBoucles - i)
mulsd xmm2, xmm4 ;// xmm2 = y2 * (nbBoucles - i)
divsd xmm7, xmm5
divsd xmm2, xmm5
divsd xmm1, xmm5 ;// (y1*i) / nbBoucles
addsd xmm0, xmm7 ;// x
addsd xmm1, xmm2 ;// y
mov eax, [esp+36] ;// EAX = hdc
cvttsd2si ebx, xmm1 ;// EBX = y
cvttsd2si esi, xmm0 ;// ESI = x
push 0 ;// deja dispo pour SetPixel(hdc, x, y, 0)
push ebx
push esi
push eax ;// params SetPixel OK
push ebx
push esi
push eax
call dword ptr GetPixel
mov edx, eax ;// EAX EDX temp
and eax, 0FFFFFFh
add dh, 1 ;// GetGValue(temp)+1
cmp eax, 0FFFFFFh
je short goSETPIX
mov [esp+12], edx
goSETPIX:
call dword ptr SetPixel
inc ebp
mov eax, [esp+12] ;// x1
cmp ebp, edi
jg short tracerEXIT
mov edx, [esp+8] ;// y1
add [esp+4], eax ;// x1*i
add [esp], edx ;// y1*i
jmp short forITOBCL
tracerEXIT:
add esp, 16
xor eax, eax ;// dummy
pop edi
pop esi
pop ebp
pop ebx
ret 36
}
}
acx01b Messages postés 280 Date d'inscription dimanche 7 septembre 2003 Statut Membre Dernière intervention 8 juillet 2014 6
15 janv. 2008 à 22:22
salut

tu n'as jamais vu ceci ?
http://fr.wikipedia.org/wiki/L-System
Rejoignez-nous