Da er nicht mit 3DSprites arbeiten wollte würde PlgBlt schon etwas bringen. Ich habe mal ein kleines Beispiel dazu geschrieben, bei gleichen Winkeln für x und y geht auch drehen ohne Probleme.
Code: Alles auswählen
EnableExplicit
UseJPEGImageDecoder()
;- Prozedur Zerren, verformt ein Bild in ImgSource zu hdcDest. Bezugspunkt ist die untere linke Ecke
; -> Source: ImageNr, falls *imgRect = 0 - Devicecontext des Sourceimage ansonsten
; *imgRect: Ausschnitt aus hdcSource, falls Source hdc, ansonsten 0, falls ImageNr. übergeben wird
; xAngle, yAngle: Winkel, um den verzerrt werden soll
; xZoom, yZoom: Faktor, um den skaliert werden soll
; Maske: Maske, die bestimmt, welche Bits berücksichtigt werden sollen (ImageID bzw. Bitmaphandle)
; mx, my: Startpunkt, ab der die Maske benutzt werden soll
Procedure Zerren(Source, hdcDest, *imgRect.RECT, xAngle.d, yAngle.d, xZoom.d = 1, yZoom.d = 1, Maske = 0, mx = 0, my = 0)
Protected x, y, w, h, hz, wz, hdcSrc
Dim Plg.POINT(2) ; Array für Paralelogramm
If *imgRect = 0
; Source ist ein Image, Abmessungen von Image holen
x = 0
y = 0
w = ImageWidth(Source)
h = ImageHeight(Source)
Else
; Source ist ein Devicekontext, Abmessungen aus *imgRect
x = *imgRect\left
y = *imgRect\top
w = (*imgRect\right - *imgRect\left)
h = (*imgRect\bottom - *imgRect\top)
EndIf
; Gezoomte Breite und Höhe bestimmen um damit das Parallelogramm zu berechnen
wz = w * xZoom
hz = h * yZoom
;Parallelogramm berechnen
Plg(0)\x = hz * Tan(xAngle)
Plg(0)\y = 0
Plg(1)\x = wz + hz * Tan(xAngle)
Plg(1)\y = wz * Tan(yAngle)
Plg(2)\x = 0
Plg(2)\y = hz
If Plg(0)\x < 0
;Falls gezerrtes Image nach links gestaucht wird so weit nach rechts verschieben bis kein negatives x vorhanden
Plg(1)\x + Plg(0)\x
Plg(2)\x + Plg(0)\x
Plg(0)\x = 0
EndIf
If Plg(1)\y < 0
;Falls gezerrtes Image nach oben gestaucht wird so weit nach unten verschieben bis kein negatives y vorhanden
Plg(0)\y + Plg(1)\y
Plg(2)\y + Plg(1)\y
Plg(1)\y = 0
EndIf
If *imgRect = 0
; hdcSrc muß erstellt werden, der einfachheit halber mit Hilfe des DestHDC
hdcSrc = CreateCompatibleDC_(hdcDest)
SelectObject_(hdcSrc, ImageID(Source))
Else
hdcSrc = Source
EndIf
PlgBlt_(hdcDest, @Plg(0), hdcSrc, x, y, w, h, Maske, mx, my)
EndProcedure
#WND_MAIN = 0
#ima_Picture = 0
#ima_Mask = 1
#ima_Dest = 2
; Gadgetkonstanten
Enumeration
#img_Picture
#btn_Load
#str_Picture
#btn_LoadMask
#str_Mask
#str_AngleX
#str_AngleY
#str_ZoomX
#str_ZoomY
#str_SrcLeft
#str_SrcTop
#str_SrcRight
#str_SrcBottom
#str_MaskLeft
#str_MaskTop
#btn_Start
EndEnumeration
;Konstanten für funktionslose Gadgets
Enumeration #PB_Compiler_EnumerationValue
#txt_AngleX
#txt_AngleY
#txt_ZoomX
#txt_ZoomY
#txt_SrcLeft
#txt_SrcTop
#txt_SrcRight
#txt_SrcBottom
#txt_MaskLeft
#txt_MaskTop
EndEnumeration
Define.l Event, hwnd, AngleX.d, AngleY.d, ZoomX.d, ZoomY.d, x, y, w, h
Define.l imaDest, hdcDest, hdcSrc, SrcRect.RECT
Define.s File, Mask
hwnd = OpenWindow(#WND_MAIN, 0, 0, 800, 600, "PlgBlt", #PB_Window_SystemMenu)
CreateGadgetList(hwnd)
ImageGadget(#img_Picture, 0, 0, 700, 600, 0, #PB_Image_Border)
ButtonGadget(#btn_Load, 710, 10, 80, 30, "Laden")
StringGadget(#str_Picture, 700, 45, 100, 20, "", #PB_String_ReadOnly)
ButtonGadget(#btn_LoadMask, 710, 75, 80, 30, "Maske")
StringGadget(#str_Mask, 700, 110, 100, 20, "", #PB_String_ReadOnly)
TextGadget(#txt_AngleX, 710, 140, 80, 15, "X Winkel")
StringGadget(#str_AngleX, 710, 160, 80, 20, "0")
TextGadget(#txt_AngleY, 710, 185, 80, 15, "Y Winkel")
StringGadget(#str_AngleY, 710, 205, 80, 20, "0")
TextGadget(#txt_ZoomX, 710, 235, 80, 15, "Zoom X")
StringGadget(#str_ZoomX, 710, 255, 80, 20, "1")
TextGadget(#txt_ZoomY, 710, 280, 80, 15, "Zoom Y")
StringGadget(#str_ZoomY, 710, 300, 80, 20, "1")
TextGadget(#txt_SrcLeft, 710, 330, 20, 20, "SL")
StringGadget(#str_SrcLeft, 735, 330, 55,20, "-1")
TextGadget(#txt_SrcTop, 710, 355, 20, 20, "ST")
StringGadget(#str_SrcTop, 735, 355, 55,20, "0")
TextGadget(#txt_SrcRight, 710, 380, 20, 20, "SR")
StringGadget(#str_SrcRight, 735, 380, 55,20, "0")
TextGadget(#txt_SrcBottom, 710, 405, 20, 20, "SB")
StringGadget(#str_SrcBottom, 735, 405, 55,20, "0")
TextGadget(#txt_MaskLeft, 710, 435, 20, 20, "ML")
StringGadget(#str_MaskLeft, 735, 435, 55,20, "0")
TextGadget(#txt_MaskTop, 710, 460, 20, 20, "SB")
StringGadget(#str_MaskTop, 735, 460, 55,20, "0")
ButtonGadget(#btn_Start, 710, 560, 80, 30, "Start")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #btn_Load
File = OpenFileRequester("Bild wählen", "", "Bilddateien (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp|JPG Dateien (*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap Dateien (*.bmp)|*.bmp|Alle Dateien (*.*)|*.*", 0)
If File <> ""
LoadImage(#ima_Picture, File)
If ImageWidth(#ima_Picture) > 700
ResizeImage(#ima_Picture, 700, ImageHeight(#ima_Picture) * 700 / ImageWidth(#ima_Picture))
EndIf
SetGadgetState(#img_Picture, ImageID(#ima_Picture))
SetGadgetText(#str_Picture, GetFilePart(File))
SetGadgetText(#str_SrcLeft, "0")
SetGadgetText(#str_SrcTop, "0")
SetGadgetText(#str_SrcRight, Str(ImageWidth(#img_Picture)))
SetGadgetText(#str_SrcBottom, Str(ImageHeight(#img_Picture)))
EndIf
Case #btn_LoadMask
File = OpenFileRequester("Bild wählen", "", "Bilddateien (*.jpg;*.jpeg;*.bmp)|*.jpg;*.jpeg;*.bmp|JPG Dateien (*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap Dateien (*.bmp)|*.bmp|Alle Dateien (*.*)|*.*", 0)
If File <> ""
LoadImage(#ima_Mask, File)
SetGadgetText(#str_Mask, GetFilePart(File))
Else
FreeImage(#ima_Mask)
SetGadgetText(#str_Mask, "")
EndIf
Case #btn_Start
AngleX = ValD(GetGadgetText(#str_AngleX)) * 3.14159 / 180
AngleY = ValD(GetGadgetText(#str_AngleY)) * 3.14159 / 180
ZoomX = ValD(GetGadgetText(#str_ZoomX))
ZoomY = ValD(GetGadgetText(#str_ZoomY))
CreateImage(#ima_Dest, 700, 600)
hdcDest = StartDrawing(ImageOutput(#ima_Dest))
hdcSrc = CreateCompatibleDC_(hdcDest)
SelectObject_(hdcSrc, ImageID(#ima_Picture))
SrcRect\left = Val(GetGadgetText(#str_SrcLeft))
SrcRect\top = Val(GetGadgetText(#str_SrcTop))
SrcRect\right = Val(GetGadgetText(#str_SrcRight))
SrcRect\bottom = Val(GetGadgetText(#str_SrcBottom))
If IsImage(#ima_Mask)
Zerren(hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY, ImageID(#ima_Mask), Val(GetGadgetText(#str_MaskLeft)), Val(GetGadgetText(#str_MaskTop)))
Else
Zerren(hdcSrc, hdcDest, @SrcRect, AngleX, AngleY, ZoomX, ZoomY)
EndIf
DeleteDC_(hdcSrc)
StopDrawing()
SetGadgetState(#img_Picture, ImageID(#ima_Dest))
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
Sollen Drehwinkel über 90° zulässig sein muß der Teil wo die Koordinaten für das Parallelogramm berechnet werden entsprechend angepasst werden.