Hi Mischa, ...
dank Deines klasse Tips und Deinem 'Effects' Source (*Big ThanXXX*

), hab ich die Rotationsroutine nun durch WinAPI-Befehle 'ein klein wenig' beschleunigen können.
Um besser zwischen der original Routine mit reinen PB-Befehlen (siehe erste Seite in diesem Thread) und der neuen Routine mit WinAPI-Aufrufen (dadurch leider nicht Plattform unabhängig

) habe ich sowohl in die neue als auch noch nachträglich in die alte Routine eine min/max FPS Routine eingebaut.
Code: Alles auswählen
Zum Vergeich (auf meinem 2.8GHz P4):
Alte Routine - mit Filter : 19 - 98 FPS (mit reinen PB-Befehlen)
Alte Routine - ohne Filter : 20 - 121 FPS (also Plattform unabhängig)
Neue Routine - mit Filter : 131 - 327 FPS (mit WinAPI Aufrufen)
Neue Routine - ohne Filter : 219 - 392 FPS (also NICHT Plattform unabhängig)
Wie gesagt: Die neue ist nur 'ein klein wenig' schneller !!!
Anbei mal der neue Code:
Wie immer mit Kommentaren zum besseren Verständnis.
Code: Alles auswählen
DefType.w OrigBreite,OrigHoehe,OrigXDrehpunkt,OrigYDrehpunkt,ZielBreite,ZielHoehe,Rand,x,y
Structure _LTI_BITMAPINFO
bmiHeader.BITMAPINFOHEADER
bmiColors.RGBQUAD[1]
EndStructure
; Standardvariablen definieren
#GFX_Mittelwertfilter = 1
OrigBreite=200
OrigHoehe=200
OrigXDrehpunkt=40
OrigYDrehpunkt=45
ZielBreite=OrigBreite
ZielHoehe=OrigHoehe
Rand=20
Filterung.b=0
MaxFPS = 0
MinFPS = 999
Dim OrigPoint.l(OrigBreite+1,OrigHoehe+1)
Dim ZielPoint.l(ZielBreite-1,ZielHoehe-1)
If OpenWindow(0,10,10,OrigBreite*2+Rand*3,OrigHoehe+Rand*2,0," 2D Image-Rotation <ESC>-Ende <Space>-Pause <F>-Filter")
If CreateImage(1,OrigBreite,OrigHoehe)
; original Ausgangsbild erzeugen
If StartDrawing(ImageOutput())
Box(1,1,OrigBreite-2,OrigHoehe-2,RGB(255,255,255))
Box(20,30,OrigBreite-40,30,RGB(20,200,200))
Circle(OrigXDrehpunkt,OrigYDrehpunkt,4,RGB(0,0,255))
Circle(OrigXDrehpunkt,OrigYDrehpunkt,2,RGB(255,255,255))
Circle(40,OrigHoehe-41,30,RGB(200,33,33))
; Daten des Originalbildes in einem Array zwischenspeichern
For x.w = 1 To OrigBreite
For y.w = 1 To OrigHoehe
OrigPointRGB.l=Point(x-1,y-1)
; Da die später benutzte WinAPI-Routine die Daten im BGR statt RGB-Format benötigt, werden die RGB-Werte in BGR-Werte umgewandelt
OrigPoint(x,y)=RGB(Blue(OrigPointRGB),Green(OrigPointRGB),Red(OrigPointRGB))
Next y
Next x
StopDrawing()
EndIf
If StartDrawing(WindowOutput())
Hintergrundfarbe = Point(1,1)
HintergrundfarbeBGR = RGB(Blue(Hintergrundfarbe),Green(Hintergrundfarbe),Red(Hintergrundfarbe))
; Im Bildpuffer einen Rahmen in Hintergrundfarbe um das Bild legen (für Filter)
For x=0 To OrigBreite : OrigPoint(x,0)=Hintergrundfarbe : OrigPoint(x,OrigHoehe+1)=Hintergrundfarbe : Next x
For Y=0 To OrigHoehe : OrigPoint(0,y)=Hintergrundfarbe : OrigPoint(OrigBreite+1,y)=Hintergrundfarbe : Next y
; Originalbild auf Fenster ausgeben
OrigImageID=UseImage(1)
DrawImage(OrigImageID,Rand,Rand)
StopDrawing()
EndIf
If CreateImage(2,ZielBreite,ZielHoehe)
hdc=GetDC_(GetDesktopWindow_())
hBmp=UseImage(2)
bmi._LTI_BITMAPINFO
bmi\bmiHeader\biSize = SizeOf(BITMAPINFOHEADER)
bmi\bmiHeader\biWidth = ZielBreite
bmi\bmiHeader\biHeight = ZielHoehe
bmi\bmiHeader\biPlanes = 1
bmi\bmiHeader\biBitCount = 32
bmi\bmiHeader\biCompression = #BI_RGB
DisableDebugger ; Debugger ausschalten, falls nötig
Repeat
StartTimer = ElapsedMilliseconds()
For w = 0 To 359
Winkel.f = 3.141/180*w
; mehrfach benutzte Berechnungen puffern
SinWinkel.f = Sin(Winkel)
CosWinkel.f = Cos(Winkel)
ZielImageID=UseImage(2)
If StartDrawing(ImageOutput())
For x.w = 1 To ZielBreite
; mehrfach benutzte Berechnungen puffern
xSinWinkel.f = (x-OrigXDrehpunkt)*SinWinkel
xCosWinkel.f = (x-OrigXDrehpunkt)*CosWinkel
For y.w = 1 To ZielHoehe
zx.f=(xCosWinkel-(y-OrigYDrehpunkt)*SinWinkel)+OrigXDrehpunkt
zy.f=(xSinWinkel+(y-OrigYDrehpunkt)*CosWinkel)+OrigYDrehpunkt
Select Filterung
Case #GFX_Mittelwertfilter
; Berechnung mit Filter
If zx>0 And zx<OrigBreite+1 And zy>0 And zy<OrigHoehe+1
zxi = Int(zx+0.5)
zyi = Int(zy+0.5)
PixelFarbe1 = OrigPoint(zxi,zyi)
If zx<zxi
PixelFarbe2 = OrigPoint(zxi-1,zyi)
Else
PixelFarbe2 = OrigPoint(zxi+1,zyi)
EndIf
Gewichtung2.f=Abs(zx-zxi)
If zy>zyi
PixelFarbe3 = OrigPoint(zxi,zyi+1)
Else
PixelFarbe3 = OrigPoint(zxi,zyi-1)
EndIf
Gewichtung3.f=Abs(zy-zyi)
Gewichtung1.f=1-Gewichtung2-Gewichtung3
; Pixelgewichtung berechnen
PixelRed=Red(PixelFarbe1)*Gewichtung1+Red(PixelFarbe2)*Gewichtung2+Red(PixelFarbe3)*Gewichtung3
PixelGreen=Green(PixelFarbe1)*Gewichtung1+Green(PixelFarbe2)*Gewichtung2+Green(PixelFarbe3)*Gewichtung3
PixelBlue=Blue(PixelFarbe1)*Gewichtung1+Blue(PixelFarbe2)*Gewichtung2+Blue(PixelFarbe3)*Gewichtung3
ZielPoint(ZielHoehe-y,x-1)=RGB(PixelRed,PixelGreen,PixelBlue)
Else
ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR
EndIf
Default
; Berechnung ohne Filter
If zx>=1 And zx<OrigBreite+1 And zy>=1 And zy<OrigHoehe+1
ZielPoint(ZielHoehe-y,x-1)=OrigPoint(Int(zx),Int(zy))
Else
ZielPoint(ZielHoehe-y,x-1)=HintergrundfarbeBGR
EndIf
EndSelect
Next y
Next x
StopDrawing()
SetDIBits_(hdc,hBmp,0,ZielHoehe,ZielPoint(),bmi,#DIB_RGB_COLORS)
EndIf
If StartDrawing(WindowOutput())
; gedrehtes Image auf Fenster ausgeben
DrawImage(ZielImageID,rand*2+OrigBreite,Rand)
StopDrawing()
EndIf
Event=WindowEvent()
If Event = #WM_KEYDOWN
; Tastendrücke auswerten
If EventwParam() = #VK_SPACE
Repeat
Event=WaitWindowEvent()
Until Event = #WM_KEYDOWN
ElseIf EventwParam() = #VK_F
Filterung = #GFX_Mittelwertfilter-Filterung
ElseIf EventwParam() = #VK_ESCAPE
Break 2
EndIf
ResetFPS = 1
EndIf
If w%20=19
; Berechnung der FPS (Bilder pro Sekunde)
If ResetFPS
MaxFPS = 0
MinFPS = 999
ResetFPS = 0
Else
AktFPS = 20000/(ElapsedMilliseconds()-StartTimer+1)
If AktFPS < MinFPS : MinFPS = AktFPS : EndIf
If AktFPS > MaxFPS : MaxFPS = AktFPS : EndIf
SetWindowTitle(0," 2D Image-Rotation <ESC>-Ende <Space>-Pause <F>-Filter "+Str(MinFPS)+"-"+Str(MaxFPS)+" FPS")
EndIf
StartTimer = ElapsedMilliseconds()
EndIf
Next w
ForEver
ReleaseDC_(GetDesktopWindow_(),hdc)
EnableDebugger ; Debugger wieder aktivieren
EndIf
EndIf
EndIf
End
Tastenkommandos:
<F> - Filter ein/aus
<Space> - Pause
<Esc> - Programm beenden
(Criticism and Comments are welcome)
Greetz, Luke.