ndubien
Messages postés557Date d'inscriptiondimanche 25 septembre 2005StatutMembreDernière intervention10 mai 20144 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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és557Date d'inscriptiondimanche 25 septembre 2005StatutMembreDernière intervention10 mai 20144 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és21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 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és17287Date d'inscriptionmercredi 2 janvier 2002StatutModérateurDernière intervention27 septembre 202174 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és21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 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és21040Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 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és280Date d'inscriptiondimanche 7 septembre 2003StatutMembreDernière intervention 8 juillet 20146 15 janv. 2008 à 22:22
16 janv. 2008 à 17:54
ABOUTBOX SINUSOIDE (WIN32)
http://www.cppfrance.com/code.aspx?id=10630
16 janv. 2008 à 17:46
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...
16 janv. 2008 à 16:25
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)
16 janv. 2008 à 16:19
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...
16 janv. 2008 à 15:59
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.
16 janv. 2008 à 10:14
pas de SetPixel en boucle, quoi... (GetDibBits / SetDibBits)
SetPixelV serait même une petite amélioration interessante (pas de retour de l'ancienne valeur)
16 janv. 2008 à 01:05
__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
}
}
15 janv. 2008 à 23:58
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
}
}
15 janv. 2008 à 22:22
tu n'as jamais vu ceci ?
http://fr.wikipedia.org/wiki/L-System