Lock/Unlock - Get/SetLockedPixel  

Die Verwendung von GetLockedPixel und SetLockedPixel ist sehr einfach. Mit diesen Funktionen kann ein Pixel einer Surface direkt verändert werden. So können Fading, Alpha Blending und andere tolle Effekte erreicht werden. Ein paar werden hier erklärt. Die Verwendung von solchen Effekten wertet ein Spiel ungemein auf, aber die Performance lässt dadurch sehr nach.
 
Die Funktion SetLockedPixel liefert im 16bit Modus einen 16bit Farbwert (siehe DirectDraw und 16bit Farben).
 
Doch bevor auf eine Surface direkt zugegriffen werden kann, muss diese mit Lock gesperrt werden. Nach erfolgter Bearbeitung muss die Surface wieder mit Unlock entsperrt werden. Es darf nur auf Pixel innerhalb des gesperrten Bereiches zugegriffen werden. Ein Zugriff außerhalb dieses Bereiches führt unweigerlich zum Absturz des Programms.

Lock(r As RECT, desc As DDSURFACEDESC2, flags As CONST_DDLOCKFLAGS, hnd As Long)

Mit dieser Funktion wird eine Surface gesperrt. Übergeben wird das zu sperrende Rechteck r (siehe Datentyp RECT unter Grundlagen). Mit desc wird die Surfacebeschreibung übergeben (siehe Datentyp DDSURFACEDESC2 unter Grundlagen). Über flags wird festgelegt, wie die Surface gesperrt werden soll (zB. ReadOnly oder WriteOnly). Das Argument hnd ist nicht aktiv und wird auf 0 gesetzt.

Dim destrect As RECT
Dim BmpDesc As DDSURFACEDESC2
        
BmpDesc.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or _
  DDSD_WIDTH Or DDSD_PIXELFORMAT
BmpDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
    
BmpDesc.lWidth = 436
BmpDesc.lHeight = 72
    
'die Bilder werden für ReadOnly gelockt
bmpBild1.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
  DDLOCK_READONLY, 0
bmpBild2.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
  DDLOCK_READONLY, 0
'das Ergebnis-Bild wird für WriteOnly gelockt
bmpErgebnis.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
  DDLOCK_WRITEONLY, 0

Unlock(r As RECT)

Mit dieser Funktion wird die gesperrte Surface wieder freigegeben. Übergeben wird das gesperrte Rechteck r (siehe Datentyp RECT unter Grundlagen).

'freigeben aller Bilder mit Unlock
bmpBild1.Unlock destrect
bmpBild2.Unlock destrect
bmpErgebnis.Unlock destrect

GetLockedPixel(x As Long, y As Long) As Long

Diese Funktion liefert den Farbwert eines Pixel auf x, y. Im 16bit Modus liefert die Funktion einen 16bit Farbwert (siehe DirectDraw und 16bit Farben).
 

SetLockedPixel(x As Long, y As Long, col As Long)

Mit dieser Funktion wird ein Pixel auf x, y auf den Farbwert col gesetzt.

Farbwert = bmpBild2.GetLockedPixel(x, y)
bmpErgebnis.SetLockedPixel x, y, Farbwert
 
  Einfaches Fading [ Top ]

Es können schon einige Effekte erzielt werden, auch wenn man die Farbwerte noch nicht verändert. Ob nun per Zufall die Pixel des einen Bitmaps statt dem anderen gezeichnet werden, bis das zweite Bitmap zur Gänze angezeigt wird, oder ob man nur die Pixel eines bestimmten Farbwertes nimmt, der Fantasie sind keine Grenzen gesetzt.

Zwei Beispiele für einfaches Fading mit DirectDraw können Sie hier downloaden, und die ausführlichen Tipp finden Sie in unserer Tipp-Rubrik.

Download
tip0137.zip
 (32,3 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN (2041) Download
tip0138.zip
 (32,4 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN (1651)

 

  Komplexes Fading [ Top ]

Es lassen sich tolle Effekte erzielen, wenn die Farbwerte der Pixels verändert werden. Das Ein- und Ausblenden eines Bitmaps ist auf diese Art sehr einfach zu realisieren. Genauso kann ein Bitmap in eines der 3 Farbanteile (Rot, Grün oder Blau) gefadet werden, in dem bei allen Pixel nur ein Farbanteil zum Maximum verändert wird.

Sub Fade()
  Dim destrect As RECT
  Dim BmpDesc As DDSURFACEDESC2
  Dim Pixel As Long
  Dim x As Integer
  Dim y As Integer
  Dim PixelRGB As cRGB
  Dim einbyte As Single

  On Error GoTo ErrEnd

  BmpDesc.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or _
     DDSD_WIDTH Or DDSD_PIXELFORMAT
  BmpDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN

  BmpDesc.lWidth = 73
  BmpDesc.lHeight = 85

   'das erste Bild wird für ReadOnly gelockt
  bmpBild1.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
    DDLOCK_READONLY, 0
   'das zweite Bild wird für WriteOnly gelockt
  bmpBild2.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
    DDLOCK_WRITEONLY, 0
   'alle Pixels werden der Reihe nach vom Bild1 eingelesen und in
   'die Farbanteile aufgeteilt. Jeder Farbanteil wird reduziert
   'bzw. erhöht. Der neue Farbwert wird dann in das Bild2
   'geschrieben.

  For y = 0 To 84
     For x = 0 To 72
        Pixel = bmpBild1.GetLockedPixel(x, y)
        PixelRGB = GetRGB16(Pixel)
        einbyte = PixelRGB.r
        If einbyte > 0 Then einbyte = einbyte - counter
        If einbyte < 0 Then einbyte = 0
        If einbyte > 31 Then einbyte = 31
        PixelRGB.r = einbyte
        einbyte = PixelRGB.g

        If Mode16 = Mode565 Then
          If einbyte > 0 Then einbyte = einbyte - (counter * 2)
        Else
          If einbyte > 0 Then einbyte = einbyte - counter
        End If
          If einbyte < 0 Then einbyte = 0
          If einbyte > GruenMax Then einbyte = GruenMax
          PixelRGB.g = einbyte
          einbyte = PixelRGB.b
          If einbyte > 0 Then einbyte = einbyte - counter
          If einbyte < 0 Then einbyte = 0
          If einbyte > 31 Then einbyte = 31
          PixelRGB.b = einbyte
          bmpBild2.SetLockedPixel x, y, Get16BitColor(PixelRGB)
      Next x
  Next y
   'freigeben beider Bilder mit Unlock
  bmpBild1.Unlock destrect
  bmpBild2.Unlock destrect
  Exit Sub

ErrEnd:
  running = False
End Sub

Ein Beispiel zu Bitmap-Fading in 16bit mit DirectDraw können Sie hier downloaden, und den ausführlichen Tipp finden Sie in unserer Tipp-Rubrik.

  Download
tip0136.zip
 (20 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN Downloads bisher: [ 2100 ]

 

  AlphaBlending 16-bit [ Top ]  

Nimmt man die Farbwerte von zwei Pixel und errechnet einen Durchschnitt, so entsteht ein AlphaBlending. Je nach dem um wie viel der Farbwert des einen Pixels verringert und der des anderen erhöht wird, so steht das eine Bild mehr im Hintergrund und das andere mehr im Vordergrund.

AlphaBlending geht sehr an die Performance des Programms. Es sollte daher nur bei kleineren Bildern angewendet werden. Oder man schreibt sich eine C++ DLL die diese Berechnung übernimmt.

Sub AlphaBlending()
  Dim destrect As RECT
  Dim BmpDesc As DDSURFACEDESC2
  Dim Pixel1 As Long
  Dim Pixel2 As Long
  Dim ZielRGB As cRGB
  Dim x As Integer
  Dim y As Integer

  On Error GoTo ErrEnd

  BmpDesc.lFlags = DDSD_CAPS Or DDSD_HEIGHT Or _
    DDSD_WIDTH Or DDSD_PIXELFORMAT
  BmpDesc.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN

  BmpDesc.lWidth = 436
  BmpDesc.lHeight = 72

   'die Bilder werden für ReadOnly gelockt
  bmpBild1.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
    DDLOCK_READONLY, 0
  bmpBild2.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
    DDLOCK_READONLY, 0
   'das Ergebnis-Bild wird für WriteOnly gelockt
  bmpErgebnis.Lock destrect, BmpDesc, DDLOCK_WAIT Or _
    DDLOCK_WRITEONLY, 0

   'alle Pixel werden der Reihe nach vom Bild1 und Bild2 eingelesen
   'und in die Farbanteile aufgeteilt. Jeder Farbanteil wird neu
   'berechnet und dann wieder zu einem Farbwert kombiniert.
   'Der neue Farbwert wird dann in das Bild2 geschrieben.
  For y = 0 To 72
    For x = 0 To 436
      Pixel1 = bmpBild1.GetLockedPixel(x, y)
      Pixel2 = bmpBild2.GetLockedPixel(x, y)
      RGBBild1 = GetRGB16(Pixel1)
      RGBBild2 = GetRGB16(Pixel2)

       'Berechnen der Ziel-RGB-Farbe
      ZielRGB.r = (RGBBild1.r * BlendStatus + RGBBild2.r * _
         (100 - BlendStatus)) \ 100
      ZielRGB.g = (RGBBild1.g * BlendStatus + RGBBild2.g * _
         (100 - BlendStatus)) \ 100
      ZielRGB.b = (RGBBild1.b * BlendStatus + RGBBild2.b * _
         (100 - BlendStatus)) \ 100

      bmpErgebnis.SetLockedPixel x, y, Get16BitColor(ZielRGB)
    Next x
  Next y
   'freigeben aller Bilder mit Unlock
  bmpBild1.Unlock destrect
  bmpBild2.Unlock destrect
  bmpErgebnis.Unlock destrect
  Exit Sub

ErrEnd:
  running = False
End Sub

Ein Beispiel zu AlphaBlending in 16-bit mit DirectDraw können Sie hier downloaden, und den ausführlichen Tipp finden Sie in unserer Tipp-Rubrik.

  Download
tip0135.zip
 (34,8 kB)
Downloadzeit: <1 Min. - 28.8k / <1 Min. - ISDN Downloads bisher: [ 2356 ]

Startseite | VB-/VBA-Tipps | Projekte | Tutorials | API-Referenz | Komponenten | Bücherecke | Gewinnspiele | VB-/VBA-Forum | DirectX-Forum | VB.Net | .Net-Forum | Foren-Archiv | Chat | Spielplatz | Links | Suchen | Stichwortverzeichnis | Feedback | Impressum

Seite empfehlen Bug-Report

Letzte Aktualisierung, Samstag, 06.Oktober 2001