Announcement

Collapse
No announcement yet.

Kann BitBlt fuer Schatteneffekte genutzt werden?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Kann BitBlt fuer Schatteneffekte genutzt werden?

    Hi Delphianer,
    ich bastel an meinem ersten Bildschirmschoner und moechte Teile des Desktops abdunkeln (wie z.B. beim Beenden von Windoofs zu sehen ist). Die Teile sind leider nicht rechteckig und nun stellt sich die Frage, ob man die API BitBt() + Masken (wie von der Sprite-Programmierung bekannt) benutzen kann, um Schatteneffekte im gewuenschten Bereich zu erzeugen. Falls jemand Erfahrung hat, welches ROP muss man benutzen und welche Farbe muss die Maske haben. Vielleicht gibt es ja aber auch bessere Wege Schatten auf den Desktop zu zaubern.

    Gruss

    HartmuT

  • #2
    Hallo,

    es sollte nicht an den nicht-eckigen Bereichen scheitern. Mit Win32 kann man beliebig geformte Fenster erzeugen (Stichwort <b>Region</b>), die durchaus auch "Löcher" oder sonstige Formen enthalten dürfen. In meinem Buch <i>Delphi Win32-Lösungen</i> sind dazu zwei Beispielprojekte zu finden. Während das Erste ein rundes Programmfenster erzeugt, sorgt das Zweite dafür, dass das eigene Programmfenster die Form von "ausgestanzten Buchstaben" hat, bei denen im Zwischenraum der Hintergrund sichtbar ist

    Comment


    • #3
      Hi

      Um Schatten, ich meine reale Schatten, zu erzeugen sollte der Bildschirm mit mehr als 256 Farben arbeiten. Das sollte heutzutage kein Problem sein. Unter 256 Farben nimmt man normalerweise ein "Lochmaske", also wie beim Windowsbeenden.

      Ich nehme mal an das Du Schatten auf dem kompletten Desktop zeichnen willst. Zuerst holst Du Dir den aktuallen Desktopinhalt und kopierst diesen in eine Bitmap. Danach wird die Bitmap bearbeitet. Sollte diese nur <= 256 Farben haben wird einfach mit einem "gelochten" Brush (Pinsel) in diese Bitmap gezeichnet.
      Sollte die Bitmap mehr als 256 Farben haben greifst Du direkt auf die Bitmappixel zu, und verringerst einfach die Farbwerte.

      <pre>

      function Shadow(Color: TColor): TColor;
      const
      Delta = 0.5;
      begin
      Color := ColorToRGB(Color);
      Result := RGB(Round(GetRValue(Color) * Delta),
      Round(GetGValue(Color) * Delta),
      Round(GetBValue(Color) * Delta));
      end;

      var
      DC: hDC;
      begin
      with Bitmap, Canvas do
      begin
      DC := Handle;
      for Y := 0 to Height -1 do
      for X := 0 to Width -1 do
      SetPixelV(DC, X, Y, Shadow(GetPixel(DC, X, Y)));
      end;
      end;

      </pre>

      obige Routine verdunkelt um ca. 50% die Bitmap. Die Funktion Shadow kann wesentlich optimiert werden, bzw. Du solltest beachten das die psychischen Helligkeitwerte der Farbanteile von Rot, Grün und Blau ungefähr 0.3 für Rot, 0.59 für Grün und 0.11 für Blua sind.
      Willst Du also eine Farbbitmap in eine Graustufenbitmap umwandeln solltest Du die Funktion Shadow umschreiben in:

      <pre>

      B := Round((0.30 * GetRValue(Color)) +
      (0.59 * GetGValue(Color)) +
      (0.11 * GetBValue(Color)));
      result := RGB(B, B, B);

      </pre>

      Damit werden die korrelierten Helligkeitswerte der einzelnen Farbanteile berücksichtigt und es entstehen keine helligkeitsverfälschungen.

      Nun, nach Bearbeitung des Bitmapinhaltes wird einfach ein fenster ohne Rahmen/Caption etc. über das komplette Desktop gelegt. In diesem Form eine Imagekomponente mit Align=alClient und die Bitmap zugewiesen.

      Gruß Hage

      Comment


      • #4
        Salve Hagen,

        Leider geht es nicht um den gesamten Desktopinhalt. Das Programm an dem ich arbeite scrollt ein Auto ueber den Desktop, und nun moechte ich gern den Berreich unter dem Auto schattenmaessig abdunkeln. Der Bereich (eigentlich sind es zwei) ist naturgemaess absolut unfoermig, so dass die von Koschi vorgeschlagenen Regions meiner Meinung nicht in Frage kommen. Die scroll-Performance von Regions ist eh endlos schlecht. Daher hatte ich angefangen, mit einer Schatten-Masken des Autos und verschieden Rops und BitBlt zu arbeiten. Das ganze funktioniert auch sehr gut fuer 16/256 Farben. Allerdings nicht bei hoeerer Farbtiefe, da werden naemlich alle Farben die nicht in der 16/256er Pallete drin sind heller bzw. komplementaer dargesttellt.

        Deine Schattenroutine ist auch eher weniger geeignet, da ich jedes Pixel einzeln setzen muesste, und das frisst unheimlich Zeit. Vielleicht kann man dein Program ja mit Scanline kombinieren, allerdings fehlt mir da die Erfahrung. Dein Hinweis auf die Lochmaske hingegen scheint mir DIE Loesung zu sein. Ich arbeite ja eh schon mit Masken. Allerdings bin ich nie auf die Idee gekommen das ein auf den Bildschirm gelegtes schwarz/grau-Punk-Raster glattweg als Schatten angesehen werden kann. Besten Dank.

        salute
        Hartmu

        Comment


        • #5
          Ave :-

          Comment

          Working...
          X