Desktop effects - 22 Effekte mit BitBlt (früher Melting Desktop)

  • Jetzt gibt es von mir 22 Effekte die den Desktop verformen, wie schmelzen, fließen, wehen...
    Je nach Bedarf kann man nun auch Andys Modus einschalten, wenn es nicht richtig läuft. Eigene Effekte hinzuzufügen dürfte relativ leicht sein!

    Spoiler anzeigen
    [autoit]

    #include <ScreenCapture.au3>

    [/autoit] [autoit][/autoit] [autoit]

    ; Animation from 0 to 21
    Local $iAnimation = 0

    [/autoit] [autoit][/autoit] [autoit]

    Local $bAndyMode = False

    [/autoit] [autoit][/autoit] [autoit]

    ; m1, m2, k1, k2, z1, z2
    Local $aAnimations[22][6] = [ _
    [2,2,128,128,1,1], _ ; 0 - Melt (Good)
    [20,20,128,128,1,1], _ ; 1 - Powder Blow
    [9,9,128,128,1,1], _ ; 2 - Powder
    [0,0,128,128,1,1], _ ; 3 - Evaporate
    [3,3,128,128,1,1], _ ; 4 - Water Color
    [5,5,128,128,1,1], _ ; 5 - Accumulate
    [10000,10000,128,128,1,1], _ ; 6 - Checks
    [1000,1000,128,128,1,1], _ ; 7 - Extreme Checks (Fast)
    [10,2,128,128,1,1], _ ; 8 - Wind Blow (Good)
    [2,10,128,128,1,1], _ ; 9 - Pour Down (Quite)
    [10,10,128,128,1,1], _ ; 10 - Running
    [20,10,128,128,10,10], _ ; 11 - Crazy Smoke (Good)
    [2,2,128,128,-100,2], _ ; 12 - Super Fast Stream (Good)
    [2,2,100,10,1,1], _ ; 13 - Moving Water (Good)
    [10,8,100,10,1,1], _ ; 14 - Sort of Powder & Water
    [50,10,1,25,80,10], _ ; 15 - Dissolve
    [2,10,12,1,5,10], _ ; 16 - Blinds
    [1,1,1,1,-2,10], _ ; 17 - Stars
    [5,5,8,4,-2,10], _ ; 18 - Arrows (sort of.)
    [2,10,200,4,-2,10], _ ; 19 - Fire
    [30,30,10,10,10,10], _ ; 20 - Grained
    [25,25,25,255,250,25] _ ; 21 - Shake
    ]

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $hDwmApiDll = DllOpen("dwmapi.dll")
    Global $sChkAero = DllStructCreate("int;")
    DllCall($hDwmApiDll, "int", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($sChkAero))
    Global $aero = DllStructGetData($sChkAero, 1)
    If $aero Then DllCall($hDwmApiDll, "int", "DwmEnableComposition", "uint", False)
    ;Sleep(500)
    Opt("GUIOnEventMode",1)
    Local $c=b(0),$a=@DesktopWidth,$b=@DesktopHeight
    _ScreenCapture_Capture("m.bmp",0,0,-1,-1,False)
    $d = GUICreate(0,$a,$b,0,0,0x80000000)
    GUISetOnEvent(-3,"a")
    GUICtrlCreatePic("m.bmp",0,0,$a,$b)
    $e=b($d)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1;.
    $f=($a-$aAnimations[$iAnimation][2])*random(0,1)
    $g=($b-$aAnimations[$iAnimation][3])*random(0,1)
    $h = $aAnimations[$iAnimation][0]*random(0,1) - $aAnimations[$iAnimation][4]
    $i = $aAnimations[$iAnimation][1]*random(0,1) - $aAnimations[$iAnimation][5]
    If Not $bAndyMode Then
    DllCall("gdi32.dll","bool","BitBlt","handle",$e,"int",$f+$h,"int",$g+$i,"int",$aAnimations[$iAnimation][2],"int",$aAnimations[$iAnimation][3],"handle",$c,"int",$f,"int",$g,"dword",0x00CC0020);
    Else
    DllCall("gdi32.dll","bool","BitBlt","handle",$e,"int",int($f + $h), "int",int($g + $i),"int",128, "int",128,"handle",$e,"int",int($f),"int",int($g), "dword", 0x00CC0020) ;Andy's Variante
    EndIf
    WEnd;

    [/autoit] [autoit][/autoit] [autoit]

    DllCall("user32.dll","int","ReleaseDC","hwnd",$d,"handle",$e)
    DllCall("user32.dll","int","ReleaseDC","hwnd",0,"handle",$c)
    Func a();
    If $aero Then DllCall($hDwmApiDll, "int", "DwmEnableComposition", "uint", True)
    Exit;
    EndFunc;.
    Func b($j);
    $k=DllCall("user32.dll","handle","GetDC","hwnd",$j);
    Return $k[0];
    EndFunc;.

    [/autoit]

    2 Mal editiert, zuletzt von minx (29. Januar 2013 um 23:39)

  • Bei mir 1440x9xx. Wüsste aber nicht, woher der Geschwindigkeitsverlust kommen sollte. Weder am Random (lol) noch am Blt kanns liegen...

  • Also meine Spezigikationen nochmal deutlicher:

    MacBook mit i5 und Windows 7 in einer VBox. In der VBox läuft es wirklich rasend schnell :?:

  • Hi,
    ich habe "nur" einen AMD Athlon X2 350, und habe >400bps. bps=blits pro sekunde 8o auf XP32.

    bei einer Auflösung von 1680x1050 und einer Kachelgrösse beim blitten von 128x128 kommt man auf ca . 4-5 FPS (ein Frame ist demnach "einmal komplett (theoretisch) gekachelt")

    Ohne die "Randomization" (ausschliesslich das blitten) habe ich 180-190 FPS.

    Zitat von minx

    Weder am Random (lol)...kanns liegen...

    hehe, selfowned. Profiling FTW :rock:
    Tja, wenn das alles so einfach wäre ;)

    Lässt man nämlich testweise mit vorher per Random ermittelten Koordinaten $f,$g,$h,$i das Script (nur das BitBlt() in der Schleife) mehrmals laufen, dann stellt man fest, dass die bps (blits pro sekunde) sich ab und zu im Bereich von ca. 100 bewegen, dh. FPS<<1 !? Wie kann das sein?

    Blitten einmal mit 500FPS und einmal mit 1FPS abhängig von den Koordinaten?

    Genau so ist es!
    Wird nämlich "auf sich selbst geblittet", dann erfolgt dieser Blit sehr langsam! Warum dieser Fall beim Programmieren der BitBlt()-Funktion nicht abgefangen wird, ist mir ehrlich gesagt ein Rätsel! Was aber stattdessen gemacht wird, ist ein noch größeres Rätsel! :thumbdown:

    Sortiert man nun diesen Fall im o.g. Script aus, dann ist es "schnell" 8o

    Spoiler anzeigen
    [autoit]

    #include <ScreenCapture.au3>
    Local $1 = Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $f, $g, $h, $i
    $c = b(0)
    $a = @DesktopWidth
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $a = ' & $a / 128 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $b = @DesktopHeight
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $b = ' & $b / 128 & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $3 = _ScreenCapture_Capture("m.bmp", 0, 0, -1, -1, False)
    $d = GUICreate(0, $a, $b, 0, 0, 0x80000000)
    $4 = GUISetOnEvent(-3, "a")
    $5 = GUICtrlCreatePic("m.bmp", 0, 0, $a, $b)
    $e = b($d)

    [/autoit] [autoit][/autoit] [autoit]

    $6 = GUISetState()
    $7 = DllCall("gdi32.dll", "bool", "BitBlt", "handle", $e, "int", 0, "int", 0, "int", $a, "int", $b, "handle", $c, "int", 0, "int", 0, "dword", 0x00CC0020)

    [/autoit] [autoit][/autoit] [autoit]

    $bps = 0

    [/autoit] [autoit][/autoit] [autoit]

    AdlibRegister("fps", 1000)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $f = ($a - 128) * Random(0, 1)
    $g = ($b - 128) * Random(0, 1)
    $h = 2 * Random(0, 1) - 1
    $i = 2 * Random(0, 1) - 1
    ;If Int($g + $i) = Int($g) and Int($f + $h) = Int($f) Then ExitLoop ;saulangsam
    If Int($g + $i)<> Int($g) Then ExitLoop;sauschnell
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    $7 = DllCall("gdi32.dll", "bool", "BitBlt", "handle", $e, "int", $f + $h, "int", $g + $i, "int", 128, "int", 128, "handle", $c, "int", $f, "int", $g, "dword", 0x00CC0020)
    $bps += 1
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func fps()
    $fps = $bps / ($a * $b / 128 / 128)
    ToolTip($fps & " " & $bps)
    If $fps < 10 Then
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $f+h = ' & $f + $h & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $g+i = ' & $g + $i & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $f = ' & $f & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $g = ' & $g & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit]

    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $h = ' & $h & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $i = ' & $i & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;~ $f = ($a - 128) * Random(0, 1)
    ;~ $g = ($b - 128) * Random(0, 1)
    ;~ $h = 2 * Random(0, 1) - 1
    ;~ $i = 2 * Random(0, 1) - 1
    ;~ Else
    ;~ $f = ($a - 128) * Random(0, 1)
    ;~ $g = ($b - 128) * Random(0, 1)
    ;~ $h = 2 * Random(0, 1) - 1
    ;~ $i = 2 * Random(0, 1) - 1
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    $bps = 0
    EndFunc ;==>fps

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Local $8 = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", $d, "handle", $e)
    $9 = DllCall("user32.dll", "int", "ReleaseDC", "hwnd", 0, "handle", $c)
    Func a()
    Exit
    EndFunc ;==>a
    Func b($j)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $j = ' & $j & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    $k = DllCall("user32.dll", "handle", "GetDC", "hwnd", $j)
    ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : $k = ' & $k[0] & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
    Return $k[0]
    EndFunc ;==>b

    [/autoit]

    //EDIT
    Habe gerade gelesen, dass in einer VM das Script sehr schnell läuft. Das liegt mit Sicherheit an den optimierten Funktionen/Grafiktreibern. Ggf. ist es einem Programmierer der VM aufgefallen, und er hat den Fall "auf sich selbst blitten" abgefangen!

    ciao
    Andy


    "Schlechtes Benehmen halten die Leute doch nur deswegen für eine Art Vorrecht, weil keiner ihnen aufs Maul haut." Klaus Kinski
    "Hint: Write comments after each line. So you can (better) see what your program does and what it not does. And we can see what you're thinking what your program does and we can point to the missunderstandings." A-Jay

    Wie man Fragen richtig stellt... Tutorial: Wie man Script-Fehler findet und beseitigt...X-Y-Problem

    Einmal editiert, zuletzt von Andy (5. Januar 2013 um 14:16)

  • Das ist ne Möglichkeit ^^. In einer VBox läufts mit ~60FPS so. Kein Unterschied zu der optimierten Variante bei mir - logisch. Ich kann es nicht testen, da ich gerade keinen nativen PC habe ^^

  • Zitat

    Andy: deine geänderte Version verhält sich aber genauso wie die von minx?!?

    Dein BS?
    Bei mir getestet auf XP32, ich schau gleich mal auf Win7-64

  • Hi, teste mal bitte innerhalb der Schleife

    [autoit]

    $7 = DllCall("gdi32.dll", "bool", "BitBlt", "handle", $e, "int", int($f + $h), "int", int($g + $i), "int", 128, "int", 128, "handle", $e, "int", int($f), "int", int($g), "dword", 0x00CC0020)

    [/autoit]


    auf Win7 wars bei mir auch extrem langsam, o.g. patch hat geholfen. Woran das liegt werde ich mal analysieren müssen,
    Ggf liegt ist der Desktop in einem bestimmten Bereich im Speicher und alles was dort "rein oder raus" geht, wird extra behandelt.

    • Offizieller Beitrag

    Andy: Mit der Änderung läuft es bei mir (AMD Phenom II X4 940 Processor, 3 GHz, Ati HD 5770, Win7 64 Bit) auch flüssig (~99 fps und 13900 - 14000 bps).
    Als Debug-Infos kommt allerdings dieses:

  • Aha, jetzt sieht man den Effekt! :D

    Alternativ kann man auch Aero abschalten:

    Spoiler anzeigen
    [autoit]


    #include <ScreenCapture.au3>;....................

    [/autoit] [autoit][/autoit] [autoit]

    Global Const $hDwmApiDll = DllOpen("dwmapi.dll")
    Global $sChkAero = DllStructCreate("int;")
    DllCall($hDwmApiDll, "int", "DwmIsCompositionEnabled", "ptr", DllStructGetPtr($sChkAero))
    Global $aero = DllStructGetData($sChkAero, 1)
    If $aero Then DllCall($hDwmApiDll, "int", "DwmEnableComposition", "uint", False)
    Sleep(500)
    Local $1=Opt("GUIOnEventMode",1),$c=b(0),$a= _;..
    @DesktopWidth,$b=@DesktopHeight,$3= _;...........
    _ScreenCapture_Capture("m.bmp",0,0,-1,-1, _;.....
    False),$d = GUICreate(0,$a,$b,0,0,0x80000000), _;
    $4=GUISetOnEvent(-3,"a"),$5=GUICtrlCreatePic( _;.
    "m.bmp",0,0,$a,$b),$e=b($d),$6=GUISetState();....
    Local $f,$g,$h,$i,$7
    While 1;.........................................
    $f=($a-128)*random(0,1)
    $g=($b-128)*random(0,1)
    $h=2*random(0,1)-1
    $i=2*random(0,1) -1
    $7=DllCall("gdi32.dll","bool","BitBlt","handle",$e,"int",$f+$h,"int",$g+$i,"int",128,"int",128,"handle",$c,"int",$f,"int",$g,"dword",0x00CC0020);....................................
    ;~ $7 = DllCall("gdi32.dll","bool","BitBlt","handle",$e,"int",int($f + $h), "int",int($g + $i),"int",128, "int",128,"handle",$e,"int",int($f),"int",int($g), "dword", 0x00CC0020) ;Andy's Variante
    WEnd;............................................
    Local $8=DllCall("user32.dll","int","ReleaseDC" _
    ,"hwnd",$d,"handle",$e),$9=DllCall("user32.dll" _
    ,"int","ReleaseDC","hwnd",0,"handle",$c);........
    Func a();........................................
    If $aero Then DllCall($hDwmApiDll, "int", "DwmEnableComposition", "uint", True)
    Exit;............................................
    EndFunc;.........................................
    Func b($j);......................................
    $k=DllCall("user32.dll","handle","GetDC","hwnd" _
    ,$j);............................................
    Return $k[0];....................................
    EndFunc;.........................................

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Zitat von UEZ

    Alternativ kann man auch Aero abschalten:

    Aero, wasn das? :rofl:
    Wenn Software schon Sch*** ist, dann muss sie wenigstens gut aussehen!

    Oscar , bissl Debug-code gibts in fast allen meinen Scripten. Dann ist auch das Consolen-Fenster nicht immer so leer :D
    Würden das aber mehr Leute so machen (Debuggen meine ich), dann hätten wir sicher auch weniger Anfragen hier im Forum.
    Ctrl+Alt+z ist in diesem Fall in Scite dein Freund :D

  • Ich liebe den Aero Effekt. Leider gibt's den nicht mehr unter Win8! ;(

    Apropos Win8: das Skript läuft nicht unter Win8 auf meiner physikalischen Kiste!

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯