Entwickler-Ecke

Multimedia / Grafik - Es schneit auf dem Desktop, aber zu langsam.


Tony-S - So 03.01.10 00:15
Titel: Es schneit auf dem Desktop, aber zu langsam.
Hallo Forum, vor einem Jahr oder so, zur Weihnachtszeit haben wir uns in der Schule mal mit grafischen Spielereien in Delphi beschäftigt.
Bei mir entstand eine Art Bildschirmschoner, der es so aussehen lassen hat das es schneit.

Jetzt hab ich das auch mal auf anderen PC´s gestartet und musste feststellen, es ist viel zu langsam und resourcenfressend,
ich weiß nicht so recht, wie ich das ganze schneller oder effizienter schreiben könnte, so mal es auch ein bissl her ist:

Nach dem langen Vorwort poste ich einfache mal Textausschnitte, vllt gibt es ja andere Wege so etwas zu realisieren, bitte tipps :).


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var
  Form1         :TForm1;
  temp          :tbitmap;
  x,y,u,v       :array [0..2000of single;
  grad          :single;
  scl           :array [0..2000of byte;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TForm1.FormCreate(Sender: TObject);
var i:word;
begin

// Erstmal das canvas und die bitmap auf die Größe des Bildschirms anpassen
form1.canvas.create;
form1.top       := 0;
form1.left      := 0;
form1.width     := screen.width;
form1.height    := screen.Height;

temp            := tbitmap.create;
temp.width      := form1.width;
temp.height     := form1.height;
temp.pixelformat:= pf1bit;
// 1bit deswegen, da Schnee ja eh nur weiß ist

for i := 0 to 2000 do
// 2.000 Schneeflocken
        begin
        x[i]    := random(screen.width);
        y[i]    := random(screen.height) - screen.height;
        u[i]    := random(360);
        v[i]    := (20 + random(50)) / 20;
        scl[i]  := random(2) + 1;
        end;
end;



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
procedure TForm1.Timer1Timer(Sender: TObject);
var 
i:word;
offset:single;
begin

temp.canvas.brush.color := 0;
temp.canvas.pen.color   := 16777215;
temp.canvas.fillrect (rect(0,0,screen.width,screen.height));
temp.canvas.brush.color := 16777215;

grad := grad + 3;

for i := 0 to 2000 do
        begin
        offset := sin(degtorad(grad+u[i])) * 5;
        y[i] := y[i] + v[i];
        if y[i] > screen.height then y[i] := y[i] - screen.height;
        // ich vermute ja das diese Zeile alles so langsam macht
        temp.canvas.fillrect (rect(     round(x[i] + offset),
                                        round(y[i]),
                                        round(x[i] + scl[i] + offset),
                                        round(y[i] + scl[i]))   );
        end;
form1.canvas.draw (0,0,temp);
form1.top := not(form1.top);
end;


Vllt fällt ja jemandem was dazu ein :)


Jakob_Ullmann - So 03.01.10 15:27

Wie sieht es denn aus? Transparentes Formular, sodass es auf dem Desktop schneit, oder schwarzer Grund oder sowas? Und das mit dem temporären Bitmap würde ich versuchen zu umgehen. Warum nutzt du das denn? Eigentlich müsstest du doch alles auch direkt auf den Canvas zeichnen können. Und wenn es schneller schneien soll, erhöhe doch einfach die Schrittweite.


FinnO - So 03.01.10 16:02

du kannst auch einfach direkt auf den Desktop zeichnen :

Delphi-Quelltext
1:
2:
3:
4:
c := TCanvas.Create;
c.Handle := getDC(0);

c.TextOut(200,200,'runs');


jaenicke - So 03.01.10 16:12

user profile iconTony-S hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
form1.top := not(form1.top);                    
Was soll das bringen? Das not wird bitweise durchgeführt, da kann doch nix sinnvolles herauskommen... :gruebel:

user profile iconTony-S hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
// Erstmal das canvas und die bitmap auf die Größe des Bildschirms anpassen
form1.canvas.create;
Du erzeugst ein neues Objekt vom Typ TCanvas und wirfst das gleich wieder weg? Wozu? :gruebel:

user profile iconTony-S hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
temp.canvas.pen.color   := 16777215;                    
clWhite ist dir wohl zu offensichtlich, wenn jemand anderes den Quelltext anschaut?!? Warum schreibst du das als Zahl hin?

user profile iconJakob_Ullmann hat folgendes geschrieben Zum zitierten Posting springen:
Und das mit dem temporären Bitmap würde ich versuchen zu umgehen.
Damit es mehr flackert? ;-)
Das sieht dann vermutlich schrecklich aus.
Solche eine Offscreen-Bitmap [http://www.michael-puff.de/Developer/Delphi/Code-Snippets/OffScreenBitmap.shtml] hat durchaus einen Sinn.

Was die Geschwindigkeit angeht:
Bei mir läuft das so im Vollbild ohne Probleme mit ca. 6% CPU-Auslastung bei 30 Millisekunden Timer-Takt. Und das sieht ziemlich flüssig aus.


Tony-S - So 03.01.10 22:36

user profile iconFinnO hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
c := TCanvas.Create;
c.Handle := getDC(0);

c.TextOut(200,200,'runs');

Also x und y ist ja sicher der Startpunkt ab wo gezeichnet werden soll, ja?
Aber was für einen Vorteil hat das ganze denn?

Zu Jaenicke, du hast recht in einigen Punkten ^^.
Aber 6%?! Also ich hab n X26000+ mit 3 GHz am laufen und n Quadcore auf Arbeit hatte auch gut zu tun damit,
bei mir ist der Timer auf 10 ms und ich hab eine Auslatung von 1-5% aaaaber dwm.exe = Desktopfenster-Manager schnellt auf 30% hoch (von vorher 1%),
das hab ich vorher nicht beachtet, weiß nicht ob es die exe auch unter xp gibt..

Moderiert von user profile iconNarses: Zitat kenntlich gemacht.


jaenicke - So 03.01.10 22:54

user profile iconTony-S hat folgendes geschrieben Zum zitierten Posting springen:
Desktopfenster-Manager schnellt auf 30% hoch (von vorher 1%),
das hab ich vorher nicht beachtet, weiß nicht ob es die exe auch unter xp gibt..
Den gibts erst ab Vista und ist genau eines der Probleme was die gefühlte geringere Geschwindigkeit von Vista angeht.

10 Millisekunden kannst du dir schenken, weniger als 15ms geht mit dem normalen Timer praktisch nicht und das auch nur mit Glück. Mit 30ms sieht es bei mir gut aus, wenn es mehr sein soll würde ich eine echte 2D Engine wie Andorra empfehlen.