tu lance le code, tu regarde le temps obtenu, tu bidouille et si tu va plus vite, tu as gagné
Librairie Effect
-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Oui, on cherche à optimiser ma lib Effect, plus précisement les fonctions de rotation de symétrie.
tu lance le code, tu regarde le temps obtenu, tu bidouille et si tu va plus vite, tu as gagné
tu lance le code, tu regarde le temps obtenu, tu bidouille et si tu va plus vite, tu as gagné
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
La dernière est celle de mon dernier post (du moins la plus rapide pour l'instant) 
Toutes les idées sont les bienvenue au niveau des fonctions a ajouté ou a améliorée.
je pense déjà que je vais ajouté des fonctions pour tracé des cercles ou des lignes avec lissage
Toutes les idées sont les bienvenue au niveau des fonctions a ajouté ou a améliorée.
je pense déjà que je vais ajouté des fonctions pour tracé des cercles ou des lignes avec lissage
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Bon voilà ma première version modifiée.
C'est une version avec des entiers que je vous montre car c'est la seule dont la vitesse se rapproche de celle de soldat... Par contre, j'avais fait une version avec des flottants, contenant moins d'instructions et qui était plus lente. Il y a clairement un problème d'ALIGNEMENT du code dans pure (ou peut-être d'allocation de registres), et je ne sais pas comment le résoudre! Enfin j'essaierai encore demain
C'est une version avec des entiers que je vous montre car c'est la seule dont la vitesse se rapproche de celle de soldat... Par contre, j'avais fait une version avec des flottants, contenant moins d'instructions et qui était plus lente. Il y a clairement un problème d'ALIGNEMENT du code dans pure (ou peut-être d'allocation de registres), et je ne sais pas comment le résoudre! Enfin j'essaierai encore demain
Code : Tout sélectionner
#Pi.f=3.14159265
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
DefType.f x1,y1
DefType.l x1b,y1b,fxl,fyl,f00l,f01l,f10l,f11l
Angle = Angle * #Pi / 180 ; On convertit en radian
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi2\bmiHeader\biWidth = Int(bm\bmWidth * Abs(Cos(Angle)) + bm\bmHeight * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biHeight = Int(bm\bmHeight * Abs(Cos(Angle)) + bm\bmWidth * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
Hdc = CreateCompatibleDC_(GetDC_(ImageID))
If Hdc
GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
CX1 = (bm\bmWidth - 1) * 512 / 2
CY1 = (bm\bmHeight - 1) * 512 / 2
CX2 = (bmi2\bmiHeader\biWidth - 1) * 512 / 2
CY2 = (bmi2\bmiHeader\biHeight - 1) * 512 / 2
;un seul Dim est surement plus rapide que 2
If bmi2\bmiHeader\biWidth>bmi2\bmiHeader\biHeight
Dim tabxy2.f(bmi2\bmiHeader\biWidth,4)
Else
Dim tabxy2.f(bmi2\bmiHeader\biHeight,4)
EndIf
x2.f=-CX2
sin.f=Sin(angle)
cos.f=Cos(angle)
For i = 0 To bmi2\bmiHeader\biWidth - 1
tabxy2(i,0)=CX1+x2*cos
tabxy2(i,1)=CY1+x2*sin
x2+512.0
Next
y2.f=-CY2
For i = 0 To bmi2\bmiHeader\biHeight - 1
tabxy2(i,2)=y2*sin
tabxy2(i,3)=y2*cos
y2+512.0
Next
i.l=mem2
w.l=bmi2\bmiHeader\biWidth*4
maxx.l=bm\bmWidth*4
maxy.l=mem+(bm\bmWidth-1 + (bm\bmHeight-1) * bm\bmWidth) * 4
For o.l = 0 To bmi2\bmiHeader\biWidth - 1
u.l=i
i+4
x2cos.f=tabxy2(o,0)
x2sin.f=tabxy2(o,1)
For oo.l = 0 To bmi2\bmiHeader\biHeight - 1
x1b = x2cos - tabxy2(oo,2)
y1b = x2sin + tabxy2(oo,3)
x1=x1b/512.0
y1=y1b/512.0
If x1b<0 : x1b=-x1b:EndIf
If y1b<0 : y1b=-y1b:EndIf
fxl = x1b & $000001FF
fyl = y1b & $000001FF
f00l = (511- fxl) * (511-fyl)
f01l = (511- fxl) * fyl
f10l = fxl * (511 - fyl)
f11l = fxl * fyl
f00l>>9
f01l>>9
f10l>>9
f11l>>9
If x1 < 0 : PasX.l = -4 : Else : PasX = 4 : EndIf
If y1 < 0 : PasY.l = -maxx : Else : PasY = maxx : EndIf
xx1.l=Int(x1)
xx1*4
xx2=xx1+PasX
yy1.l=Int(y1)
yy1*maxx
pos1.l=mem+xx1 + yy1
pos2.l=pos1 + PasX
pos3.l=pos1 + PasY
pos4.l=pos3 + PasX
If xx1<0 Or xx1>maxx
c00=0
c01=0
Else
If pos1>=mem And pos1<=maxy
c00 = PeekL(pos1)
Else
c00=0
EndIf
If pos3>=mem And pos3<=maxy
c01 = PeekL(pos3)
Else
c01=0
EndIf
EndIf
If xx2<0 Or xx2>maxx
c10=0
c11=0
Else
If pos2>=mem And pos2<=maxy
c10 = PeekL(pos2)
Else
c10=0
EndIf
If pos4>=mem And pos4<=maxy
c11 = PeekL(pos4)
Else
c11=0
EndIf
EndIf
r.l = (Red(c00) * f00l)>>9 + (Red(c10) * f10l)>>9 + (Red(c01) * f01l)>>9 + (Red(c11) * f11l)>>9
g.l = (Green(c00) * f00l)>>9 + (Green(c10) * f10l)>>9 + (Green(c01) * f01l)>>9 + (Green(c11) * f11l)>>9
b.l = (Blue(c00) * f00l)>>9 + (Blue(c10) * f10l)>>9 + (Blue(c01) * f01l)>>9 + (Blue(c11) * f11l)>>9
PokeL(u , RGB(r, g, b))
u+w
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
If Hdc
SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;-----------------------------------------
;- Test de rapidité
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
For nn = 0 To 999
Plot(n, nn, Random($FFFFFF))
Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)
#NbTest = 2
Temps1 = ElapsedMilliseconds()
For n = 1 To #NbTest
ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next
Temps2 = ElapsedMilliseconds()
Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()
MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)
;-----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100)
StartDrawing(ImageOutput())
Box(0, 0, 80, 100, $6F6F6F)
Box(5, 5, 35, 45, $FF)
Box(40, 5, 35, 45, $FF00)
Box(5, 50, 35, 45, $FF0000)
Box(40, 50, 35, 45, $FFFFFF)
StopDrawing()
ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0
End
EndIf
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale))
TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow
End-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Bon, ben moi, je suis descendu à 1030 ms au lieu de 1200 sur mon 900mhz
Message Edité le 15/02/05 à 12h09
Code : Tout sélectionner
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
Angle = Angle * #Pi / 180 ; On convertit en radian
cos.f = Cos(Angle)
sin.f = Sin(Angle)
CouleurFond = 0
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(cos) + bm\bmHeight * Abs(sin)
bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(cos) + bm\bmWidth * Abs(sin)
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
Hdc = CreateCompatibleDC_(GetDC_(ImageID))
If Hdc
GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
CX1 = bm\bmWidth - 1
CY1 = bm\bmHeight - 1
CX2 = bmi2\bmiHeader\biWidth - 1
CY2 = bmi2\bmiHeader\biHeight - 1
For n = 0 To CX2
x1b.l = (n << 1) - CX2
Temp1.f = CX1 + x1b * cos
Temp2.f = CY1 + x1b * sin
For nn = 0 To CY2
y1b.l = (nn << 1) - CY2
x1.f = (Temp1 - y1b * sin) / 2
y1.f = (Temp2 + y1b * cos) / 2
x2.l = x1
y2.l = y1
fx.f = Abs(x1 - x2)
fy.f = Abs(y1 - y2)
f00.f = (1 - fx) * (1 - fy)
f01.f = (1 - fx) * fy
f10.f = fx * (1 - fy)
f11.f = fx * fy
If x1 < x2 : x2b = x2 - 1 : Else : x2b = x2 + 1 : EndIf
If y1 < y2 : y2b = y2 - 1 : Else : y2b = y2 + 1 : EndIf
If x2 < 0 Or x2 > CX1
c00 = 0
c01 = 0
Else
If y2 < 0 Or y2 > CY1
c00 = 0
Else
c00 = PeekL(Mem + (x2 + y2 * bm\bmWidth) * 4)
EndIf
If y2b < 0 Or y2b > CY1
c01 = 0
Else
c01 = PeekL(Mem + (x2 + y2b * bm\bmWidth) * 4)
EndIf
EndIf
If x2b < 0 Or x2b > CX1
c10 = 0
c11 = 0
Else
If y2 < 0 Or y2 > CY1
c10 = 0
Else
c10 = PeekL(Mem + (x2b + y2 * bm\bmWidth) * 4)
EndIf
If y2b < 0 Or y2b > CY1
c11 = 0
Else
c11 = PeekL(Mem + (x2b + y2b * bm\bmWidth) * 4)
EndIf
EndIf
r = Red(c00) * f00 + Red(c10) * f10 + Red(c01) * f01 + Red(c11) * f11
g = Green(c00) * f00 + Green(c10) * f10 + Green(c01) * f01 + Green(c11) * f11
b = Blue(c00) * f00 + Blue(c10) * f10 + Blue(c01) * f01 + Blue(c11) * f11
PokeL(Mem2 + (n + nn * bmi2\bmiHeader\biWidth) * 4, RGB(r, g, b))
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
If Hdc
SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;-----------------------------------------
;- Test de rapidité
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
For nn = 0 To 999
Plot(n, nn, Random($FFFFFF))
Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)
#NbTest = 3
Temps1 = ElapsedMilliseconds()
For n = 1 To #NbTest
ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next
Temps2 = ElapsedMilliseconds()
Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()
MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)
;-----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100)
StartDrawing(ImageOutput())
Box(0, 0, 80, 100, $6F6F6F)
Box(5, 5, 35, 45, $FF)
Box(40, 5, 35, 45, $FF00)
Box(5, 50, 35, 45, $FF0000)
Box(40, 50, 35, 45, $FFFFFF)
StopDrawing()
ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0
End
EndIf
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale))
TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow
EndJe ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Yo! Bien mais je crois que j'ai un peu plus rapide!

Code : Tout sélectionner
#Pi.f=3.14159265
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
DefType.f x1,y1
DefType.l x1b,y1b,fxl,fyl,f00l,f01l,f10l,f11l
Angle = Angle * #Pi / 180 ; On convertit en radian
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi2\bmiHeader\biWidth = Int(bm\bmWidth * Abs(Cos(Angle)) + bm\bmHeight * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biHeight = Int(bm\bmHeight * Abs(Cos(Angle)) + bm\bmWidth * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
Hdc = CreateCompatibleDC_(GetDC_(ImageID))
If Hdc
GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
CX1 = (bm\bmWidth - 1) * 512 / 2
CY1 = (bm\bmHeight - 1) * 512 / 2
CX2 = (bmi2\bmiHeader\biWidth - 1) * 512 / 2
CY2 = (bmi2\bmiHeader\biHeight - 1) * 512 / 2
;un seul Dim est surement plus rapide que 2
If bmi2\bmiHeader\biWidth>bmi2\bmiHeader\biHeight
Dim tabxy2.l(bmi2\bmiHeader\biWidth,4)
Else
Dim tabxy2.l(bmi2\bmiHeader\biHeight,4)
EndIf
x2.f=-CX2
sin.f=Sin(angle)
cos.f=Cos(angle)
For i = 0 To bmi2\bmiHeader\biWidth - 1
tabxy2(i,0)=CX1+x2*cos
tabxy2(i,1)=CY1+x2*sin
x2+512.0
Next
y2.f=-CY2
For i = 0 To bmi2\bmiHeader\biHeight - 1
tabxy2(i,2)=y2*sin
tabxy2(i,3)=y2*cos
y2+512.0
Next
i.l=mem2
w.l=bmi2\bmiHeader\biWidth*4
tailleligne=bm\bmWidth * 4
maxx.l=(bm\bmWidth-1)*4
maxy.l=(bm\bmHeight-1) * tailleligne
For o.l = 0 To bmi2\bmiHeader\biWidth - 1
u.l=i
i+4
x2cos.l=tabxy2(o,0)
x2sin.l=tabxy2(o,1)
For oo.l = 0 To bmi2\bmiHeader\biHeight - 1
x1b = x2cos - tabxy2(oo,2)
y1b = x2sin + tabxy2(oo,3)
; If xx1<0 : xx1=-xx1:EndIf
If yy1<0 : yy1=-yy1:EndIf ;!!!!!!!!!
If xx1 < 0 : PasX.l = -4 : Else : PasX = 4 : EndIf
If yy1 < 0 : PasY.l = -tailleligne: Else : PasY = tailleligne: EndIf
xx1.l=x1b>>9
xx1*4
yy1.l=y1b>>9
yy1*tailleligne
xx2=xx1+PasX
yy2=yy1+PasY
fxl = x1b & $000001FF
fyl = y1b & $000001FF
f00l = (511- fxl) * (511-fyl)
f01l = (511- fxl) * fyl
f10l = fxl * (511 - fyl)
f11l = fxl * fyl
f00l>>9
f01l>>9
f10l>>9
f11l>>9
If xx1<0 Or xx1>maxx
c00=0
c01=0
Else
pos1.l=mem+xx1 + yy1
If yy1<0 Or yy1>maxy
c00 = 0
Else
c00 =PeekL(pos1)
EndIf
If yy2<0 Or yy2>maxy
c01 = 0
Else
c01 = PeekL(pos1+PasY)
EndIf
EndIf
If xx2<0 Or xx2>maxx
c10=0
c11=0
Else
pos1.l=mem+xx2 + yy1
If yy1<0 Or yy1>maxy
c10 = 0
Else
c10 = PeekL(pos1)
EndIf
If yy2<0 Or yy2>maxy
c11 = 0
Else
c11 = PeekL(pos1+PasY)
EndIf
EndIf
r.l = (Red(c00) * f00l)>>9 + (Red(c10) * f10l)>>9 + (Red(c01) * f01l)>>9 + (Red(c11) * f11l)>>9
g.l = (Green(c00) * f00l)>>9 + (Green(c10) * f10l)>>9 + (Green(c01) * f01l)>>9 + (Green(c11) * f11l)>>9
b.l = (Blue(c00) * f00l)>>9 + (Blue(c10) * f10l)>>9 + (Blue(c01) * f01l)>>9 + (Blue(c11) * f11l)>>9
PokeL(u , RGB(r, g, b))
u+w
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
If Hdc
SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;-----------------------------------------
;- Test de rapidité
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
For nn = 0 To 999
Plot(n, nn, Random($FFFFFF))
Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)
#NbTest = 2
Temps1 = ElapsedMilliseconds()
For n = 1 To #NbTest
ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next
Temps2 = ElapsedMilliseconds()
Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()
MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)
;-----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100)
StartDrawing(ImageOutput())
Box(0, 0, 80, 100, $6F6F6F)
Box(5, 5, 35, 45, $FF)
Box(40, 5, 35, 45, $FF00)
Box(5, 50, 35, 45, $FF0000)
Box(40, 50, 35, 45, $FFFFFF)
StopDrawing()
ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0
End
EndIf
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale))
TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow
End-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
Bon voilà un peu d'asm. On peut faire mieux, mais je fais une pause 
Code : Tout sélectionner
#Pi.f=3.14159265
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP, Temp1, Temp2
DefType.f x1,y1
DefType.l x1b,y1b,fxl,fyl,f00l,f01l,f10l,f11l
Angle = Angle * #Pi / 180 ; On convertit en radian
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi2\bmiHeader\biWidth = Int(bm\bmWidth * Abs(Cos(Angle)) + bm\bmHeight * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biHeight = Int(bm\bmHeight * Abs(Cos(Angle)) + bm\bmWidth * Abs(Sin(Angle)) + 0.5)
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
Hdc = CreateCompatibleDC_(GetDC_(ImageID))
If Hdc
GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
CX1 = (bm\bmWidth - 1) * 512 / 2
CY1 = (bm\bmHeight - 1) * 512 / 2
CX2 = (bmi2\bmiHeader\biWidth - 1) * 512 / 2
CY2 = (bmi2\bmiHeader\biHeight - 1) * 512 / 2
;un seul Dim est surement plus rapide que 2
If bmi2\bmiHeader\biWidth>bmi2\bmiHeader\biHeight
Dim tabxy2.l(bmi2\bmiHeader\biWidth,4)
Else
Dim tabxy2.l(bmi2\bmiHeader\biHeight,4)
EndIf
x2.f=-CX2
sin.f=Sin(angle)
cos.f=Cos(angle)
For i = 0 To bmi2\bmiHeader\biWidth - 1
tabxy2(i,0)=CX1+x2*cos
tabxy2(i,1)=CY1+x2*sin
x2+512.0
Next
y2.f=-CY2
For i = 0 To bmi2\bmiHeader\biHeight - 1
tabxy2(i,2)=y2*sin
tabxy2(i,3)=y2*cos
y2+512.0
Next
i.l=mem2
w.l=bmi2\bmiHeader\biWidth*4
tailleligne=bm\bmWidth * 4
maxx.l=(bm\bmWidth-1)*4
maxy.l=(bm\bmHeight-1) * tailleligne
For o.l = 0 To bmi2\bmiHeader\biWidth - 1
u.l=i
i+4
x2cos.l=tabxy2(o,0)
x2sin.l=tabxy2(o,1)
For oo.l = 0 To bmi2\bmiHeader\biHeight - 1
x1b = x2cos - tabxy2(oo,2)
y1b = x2sin + tabxy2(oo,3)
; If xx1<0 : xx1=-xx1:EndIf
If yy1<0 : yy1=-yy1:EndIf ;!!!!!!!!!
If xx1 < 0 : PasX.l = -4 : Else : PasX = 4 : EndIf
If yy1 < 0 : PasY.l = -tailleligne: Else : PasY = tailleligne: EndIf
xx1.l=x1b>>9
xx1*4
yy1.l=y1b>>9
yy1*tailleligne
xx2=xx1+PasX
yy2=yy1+PasY
fxl = x1b & $000001FF
fyl = y1b & $000001FF
f00l = (511- fxl) * (511-fyl)
f01l = (511- fxl) * fyl
f10l = fxl * (511 - fyl)
f11l = fxl * fyl
f00l>>9
f01l>>9
f10l>>9
f11l>>9
If xx1<0 Or xx1>maxx
c00=0
c01=0
Else
pos1.l=mem+xx1 + yy1
If yy1<0 Or yy1>maxy
c00 = 0
Else
MOV eax,pos1
MOV eax,[eax]
MOV c00,eax
;c00 =PeekL(pos1)
EndIf
If yy2<0 Or yy2>maxy
c01 = 0
Else
MOV eax,pos1
ADD eax,PasY
MOV eax,[eax]
MOV c01,eax
;c01 = PeekL(pos1+PasY)
EndIf
EndIf
If xx2<0 Or xx2>maxx
c10=0
c11=0
Else
pos1.l=mem+xx2 + yy1
If yy1<0 Or yy1>maxy
c10 = 0
Else
MOV eax,pos1
MOV eax,[eax]
MOV c10,eax
;c10 = PeekL(pos1)
EndIf
If yy2<0 Or yy2>maxy
c11 = 0
Else
MOV eax,pos1
ADD eax,PasY
MOV eax,[eax]
MOV c11,eax
;c11 = PeekL(pos1+PasY)
EndIf
EndIf
; r.l = (Red(c00) * f00l)>>9 + (Red(c10) * f10l)>>9 + (Red(c01) * f01l)>>9 + (Red(c11) * f11l)>>9
;(Red(c00) * f00l)>>9
MOV eax,c00
AND eax,$FF
IMUL eax,f00l
;(Red(c10) * f10l)>>9
MOV ebx,c10
AND ebx,$FF
IMUL ebx,f10l
ADD eax,ebx
;(Red(c01) * f01l)>>9
MOV ebx,c01
AND ebx,$FF
IMUL ebx,f01l
ADD eax,ebx
;(Red(c11) * f11l)>>9
MOV ebx,c11
AND ebx,$FF
IMUL ebx,f11l
ADD eax,ebx
SAR eax,9
AND eax,$000000FF
MOV ecx,eax
; g.l = (Green(c00) * f00l)>>9 + (Green(c10) * f10l)>>9 + (Green(c01) * f01l)>>9 + (Green(c11) * f11l)>>9
;(Green(c00) * f00l)>>9
MOV eax,c00
AND eax,$00FF00
IMUL eax,f00l
;(Green(c10) * f10l)>>9
MOV ebx,c10
AND ebx,$00FF00
IMUL ebx,f10l
ADD eax,ebx
;(Green(c01) * f01l)>>9
MOV ebx,c01
AND ebx,$00FF00
IMUL ebx,f01l
ADD eax,ebx
;(Green(c11) * f11l)>>9
MOV ebx,c11
AND ebx,$00FF00
IMUL ebx,f11l
ADD eax,ebx
SAR eax,9
AND eax,$0000FF00
OR ecx,eax
; b.l = (Blue(c00) * f00l)>>9 + (Blue(c10) * f10l)>>9 + (Blue(c01) * f01l)>>9 + (Blue(c11) * f11l)>>9
;ici les opérations font déborder le registre, aussi je décale tout de 8 vers la gauche pour garder un peu de marge
;(Blue(c00) * f00l)>>9
MOV eax,c00
BSWAP eax
AND eax,$FF00
IMUL eax,f00l
;(Blue(c10) * f10l)>>9
MOV ebx,c10
BSWAP ebx
AND ebx,$FF00
IMUL ebx,f10l
ADD eax,ebx
;(Blue(c01) * f01l)>>9
MOV ebx,c01
BSWAP ebx
AND ebx,$FF00
IMUL ebx,f01l
ADD eax,ebx
;(Blue(c11) * f11l)>>9
MOV ebx,c11
BSWAP ebx
AND ebx,$FF00
IMUL ebx,f11l
ADD eax,ebx
SAR eax,9
BSWAP eax
AND eax,$00FF0000
OR ecx,eax
;PokeL(u , r|g|b)
MOV eax,u
MOV [eax],ecx
u+w
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
If Hdc
SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;-----------------------------------------
;- Test de rapidité
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
For nn = 0 To 999
Plot(n, nn, Random($FFFFFF))
Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)
#NbTest = 2
Temps1 = ElapsedMilliseconds()
For n = 1 To #NbTest
ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next
Temps2 = ElapsedMilliseconds()
Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()
MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)
;-----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100)
StartDrawing(ImageOutput())
Box(0, 0, 80, 100, $6F6F6F)
Box(5, 5, 35, 45, $FF)
Box(40, 5, 35, 45, $FF00)
Box(5, 50, 35, 45, $FF0000)
Box(40, 50, 35, 45, $FFFFFF)
StopDrawing()
ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0
End
EndIf
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale))
TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow
End-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
-
Le Soldat Inconnu
- Messages : 4312
- Inscription : mer. 28/janv./2004 20:58
- Localisation : Clermont ferrand OU Olsztyn
- Contact :
AMD
bon, de toute façon, j'ai 800ms sur mon 900mhz
Sachant que 225 ms sont fixes dû a l'API utilisé pour récupèrer et envoyer l'image. la marge de progression se réduit
Je suis parti de 4.5 secondes
j'aurai jamais pensé pouvoir atteindre ce stade. plus de 5 fois plus rapide
bon, de toute façon, j'ai 800ms sur mon 900mhz
Sachant que 225 ms sont fixes dû a l'API utilisé pour récupèrer et envoyer l'image. la marge de progression se réduit
Je suis parti de 4.5 secondes
Code : Tout sélectionner
ProcedureDLL.l RotateImageEx2(ImageID, Angle.f) ; Rotation d'une image d'un angle en °
Protected bmi.BITMAPINFO, bmi2.BITMAPINFO, Hdc.l, NewImageID, Mem, n, nn, bm.BITMAP
Angle = Angle * #Pi / 180 ; On convertit en radian
Cos.f = Cos(Angle)
Sin.f = Sin(Angle)
CouleurFond = 0
GetObject_(ImageID, SizeOf(BITMAP), @bm.BITMAP)
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = bm\bmWidth
bmi\bmiHeader\biHeight = bm\bmHeight
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
bmi2\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi2\bmiHeader\biWidth = bm\bmWidth * Abs(Cos) + bm\bmHeight * Abs(Sin)
bmi2\bmiHeader\biHeight = bm\bmHeight * Abs(Cos) + bm\bmWidth * Abs(Sin)
bmi2\bmiHeader\biPlanes = 1
bmi2\bmiHeader\biBitCount = 32
bmi2\bmiHeader\biCompression = #BI_RGB
Mem = AllocateMemory(bm\bmWidth * bm\bmHeight * 4)
If Mem
Mem2 = AllocateMemory(bmi2\bmiHeader\biWidth * bmi2\bmiHeader\biHeight * 4)
If Mem2
Hdc = CreateCompatibleDC_(GetDC_(ImageID))
If Hdc
GetDIBits_(Hdc, ImageID, 0, bm\bmHeight, Mem, @bmi, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
CX1 = bm\bmWidth - 1
CY1 = bm\bmHeight - 1
CX2 = bmi2\bmiHeader\biWidth - 1
CY2 = bmi2\bmiHeader\biHeight - 1
Mem01 = Mem + bm\bmWidth * 4
Mem10 = Mem + 4
Mem11 = Mem01 + 4
For n = 0 To CX2
x1b.l = n * 2 - CX2
Temp1.f = CX1 + x1b * Cos
Temp2.f = CY1 + x1b * Sin
For nn = 0 To CY2
y1b.l = nn * 2 - CY2
x1.f = (Temp1 - y1b * Sin) / 2
y1.f = (Temp2 + y1b * Cos) / 2
x2.l = x1
y2.l = y1
If x1 < x2
DEC x2
EndIf
If y1 < y2
DEC y2
EndIf
x2b = x2 + 1
y2b = y2 + 1
If x2b >= 0 And x2 <= CX1 And y2b >= 0 And y2 <= CY1 ; On filtre si on est completement en dehors de l'image
fx.f = x1 - x2
fy.f = y1 - y2
f00.f = (1 - fx) * (1 - fy)
f01.f = (1 - fx) * fy
f10.f = fx * (1 - fy)
f11.f = fx * fy
MemTemp = (x2 + y2 * bm\bmWidth) * 4
If x2 >= 0 And x2 <= CX1
If y2 >= 0 And y2 <= CY1
c00 = PeekL(Mem + MemTemp)
Else
c00 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c01 = PeekL(Mem01 + MemTemp)
Else
c01 = 0
EndIf
Else
c00 = 0
c01 = 0
EndIf
If x2b >= 0 And x2b <= CX1
If y2 >= 0 And y2 <= CY1
c10 = PeekL(Mem10 + MemTemp)
Else
c10 = 0
EndIf
If y2b >= 0 And y2b <= CY1
c11 = PeekL(Mem11 + MemTemp)
Else
c11 = 0
EndIf
Else
c10 = 0
c11 = 0
EndIf
r = Red(c00) * f00 + Red(c10) * f10 + Red(c01) * f01 + Red(c11) * f11
g = Green(c00) * f00 + Green(c10) * f10 + Green(c01) * f01 + Green(c11) * f11
b = Blue(c00) * f00 + Blue(c10) * f10 + Blue(c01) * f01 + Blue(c11) * f11
PokeL(Mem2 + (n + nn * bmi2\bmiHeader\biWidth) * 4, RGB(r, g, b))
Else
PokeL(Mem2 + (n + nn * bmi2\bmiHeader\biWidth) * 4, 0)
EndIf
Next
Next
; On crée la nouvelle image
NewImageID = CreateImage(#PB_Any, bmi2\bmiHeader\biWidth, bmi2\bmiHeader\biHeight)
Hdc = CreateCompatibleDC_(GetDC_(ImageID()))
If Hdc
SetDIBits_(Hdc, ImageID(), 0, bmi2\bmiHeader\biHeight, Mem2, @bmi2, #DIB_RGB_COLORS) ; on envoie la liste dans l'image
ReleaseDC_(0, Hdc)
EndIf
FreeMemory(Mem2)
EndIf
FreeMemory(Mem)
EndIf
ProcedureReturn NewImageID
EndProcedure
;-----------------------------------------
;- Test de rapidité
ImageOrigine = CreateImage(0, 1000, 1000)
StartDrawing(ImageOutput())
For n = 0 To 999
For nn = 0 To 999
Plot(n, nn, Random($FFFFFF))
Next
Next
StopDrawing()
Dim Liste(ImageWidth() - 1, ImageHeight() - 1)
#NbTest = 4
Temps1 = ElapsedMilliseconds()
For n = 1 To #NbTest
ImageModifiee = RotateImageEx2(ImageOrigine, 30)
Next
Temps2 = ElapsedMilliseconds()
Vitesse = (Temps2 - Temps1) / #NbTest
NbPixel = ImageHeight() * ImageWidth()
MessageRequester("Temps", Str(Vitesse) + " ms" + Chr(10) + "Image de " + Str(ImageWidth()) + " * " + Str(ImageHeight()) + " pixels" + Chr(10) + "Nb pixels traités = " + Str(NbPixel), 0)
;-----------------------------------------
;- Test d'affichage d'image avec rotation
; On dessine une image
ImageNormale = CreateImage(#PB_Any, 80, 100)
StartDrawing(ImageOutput())
Box(0, 0, 80, 100, $6F6F6F)
Box(5, 5, 35, 45, $FF)
Box(40, 5, 35, 45, $FF00)
Box(5, 50, 35, 45, $FF0000)
Box(40, 50, 35, 45, $FFFFFF)
StopDrawing()
ImageRotation = RotateImageEx2(UseImage(ImageNormale), 30)
; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 250, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Effect - Rotation d'image") = 0 Or CreateGadgetList(WindowID()) = 0
End
EndIf
TextGadget(#PB_Any, 10, 10, 100, 15, "Image normale")
ImageGadget(#PB_Any, 10, 25, 0, 0, UseImage(ImageNormale))
TextGadget(#PB_Any, 10, 135, 100, 15, "Rotation de 30")
ImageGadget(#PB_Any, 10, 150, 0, 0, UseImage(ImageRotation))
Repeat
Event = WaitWindowEvent()
Until Event = #PB_EventCloseWindow
End
Dernière modification par Le Soldat Inconnu le mer. 16/févr./2005 22:55, modifié 1 fois.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]