Ich habe da ein kleines Problem. Habe mir eine kleine Routine gebastelt welche 2D Sprites skaliert und gespiegelt auf den Bildschirm bringen kann. Allerdings liegt irgendwo ein kleiner Bug im Programmcode.
Wenn ich zwei Sprites darstelle - eins davon transparent - wird die Transparenz fehlerhaft angezeigt. Jedoch nicht wenn die geblittete Größe der des Orignalsprites entspricht.
Hat vielleicht jemand einen kleinen Tip auf Lager ?
Ich habe die Zeilen mit den fehlerhaften Befehlen mal auskommentiert. So könnt Ihr selber mal probieren.
Code ist PB4.3
Grüße und Danke
Martin
Code: Alles auswählen
#width=640
#height=480
#DDBLT_WAIT = $01000000
#DDBLT_KEYSRC = $8000
Structure PB_Sprite
Sprite.l
Width.w
Height.w
Depth.w
Mode.w
FileName.l
RealWidth.w
RealHeight.w
ClipX.w
ClipY.w
EndStructure
Structure DDCOLORKEY
dwColorSpaceLowValue.l ;// low boundary of color space that is to
dwColorSpaceHighValue.l ;// high boundary of color space that is
EndStructure
Structure RGN
dwSize.l
iType.l
nCount.l
nRgnSize.l
rcBoundLeft.l
rcBoundTop.l
rcBoundRight.l
rcBoundBottom.l
rc1Left.l
rc1Top.l
rc1Right.l
rc1Bottom.l
rc2Left.l
rc2Top.l
rc2Right.l
rc2Bottom.l
EndStructure
Declare _GetBackBufferSurface()
Declare _GetDDrawBase()
Declare DisplaySprite_(Sprite,x,y,dWidth,dHeight,Transparent=0,Color=0)
InitSprite()
InitKeyboard()
UseJPEGImageDecoder()
OpenScreen(#width,#height,16,"test")
; Sprites erstellen
ClearScreen(0)
StartDrawing(ScreenOutput())
For i=1 To 20
Box(Random(300),Random(200),Random(100),Random(100),RGB(Random(255),Random(255),Random(255)))
Circle(Random(300)+320,Random(200),Random(80),RGB(Random(255),Random(255),Random(255)))
Next
StopDrawing()
GrabSprite(1,0,0,320,240)
GrabSprite(2,320,0,320,240)
;Variablen für die Bewegung
ysstep = 1 : yw=2
xpos1 = 120 : xstep1 = 2
ypos1 = 240 : ystep1 = 4
Repeat
ClearScreen(RGB(0,0,200))
;-- Originalgröße von Sprite funktioniert
;DisplaySprite_(1,xpos1,ypos1,320,240,0)
;-- skaliert funktioniert nicht...
;-- Sprite2 übernimmt transparenz von Sprite1
;DisplaySprite_(1,xpos1,ypos1,300,200,0)
DisplaySprite_(2,320-yw/2,240-yw/2,yw,yw,1)
;-- Originalgröße von Sprite funktioniert
;DisplaySprite_(1,xpos1,ypos1,320,240,0)
;-- skaliert funktioniert nicht...
;-- Sprite1 übernimmt transparenz von Sprite2
DisplaySprite_(1,xpos1,ypos1,300,200,0)
yw + ysstep
If yw>300 Or yw<3 : ysstep = -ysstep : EndIf
xpos1 + xstep1 : If xpos1<0 Or xpos1+320>#width : xstep1 = -xstep1 : EndIf
ypos1 + ystep1 : If ypos1<0 Or ypos1+240>#height : ystep1 = -ystep1 : EndIf
FlipBuffers()
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)
End
Procedure _GetBackBufferSurface()
!extrn _PB_Sprite_CurrentBitmap
!MOV Eax,[_PB_Sprite_CurrentBitmap]
ProcedureReturn
EndProcedure
Procedure _GetDDrawBase() ; returns the directdraw interface
!extrn _PB_DDrawBase
!MOV Eax,[_PB_DDrawBase]
ProcedureReturn
EndProcedure
Procedure DisplaySprite_(Sprite,x,y,dWidth,dHeight,Transparent=0,color=0)
Protected rgn.RGN,*DD.IDirectDraw7,*Clipper.IDirectDrawClipper,clipper.b
*Sprite.PB_Sprite=IsSprite(Sprite)
If *Sprite=0:ProcedureReturn 0:EndIf
*DDS.IDirectDrawSurface7=*Sprite\Sprite
If *DDS=0:ProcedureReturn 0:EndIf
*Back.IDirectDrawSurface7=_GetBackBufferSurface()
ck.DDCOLORKEY\dwColorSpaceLowValue = color
ck\dwColorSpaceHighValue = color
*DDS\SetColorKey($8,ck)
rSrc.RECT
rSrc\left = 0
rSrc\top = 0
rSrc\right = *Sprite\RealWidth
rSrc\bottom = *Sprite\RealHeight
rDst.RECT
rDst\left = X
rDst\top = Y
rDst\right = X + dWidth ;Stretch
rDst\bottom = Y + dHeight
If (rDst\right > rDst\left) And (rDst\bottom>rDst\top)
clipper = #False
If x<0 Or y<0 Or rDst\right > #width Or rDst\bottom > #height
rgn\dwSize=SizeOf(RGNDATAHEADER)
rgn\iType=#RDH_RECTANGLES
rgn\nCount=1
rgn\nRgnSize=16
rgn\rcBoundLeft=0
rgn\rcBoundTop=0
rgn\rcBoundRight=#width
rgn\rcBoundBottom=#height
rgn\rc1Left=0
rgn\rc1Top=0
rgn\rc1Right=#width
rgn\rc1Bottom=#height
*DD=_GetDDrawBase()
If *DD=0:ProcedureReturn #False:EndIf
*DD\CreateClipper(0,@*Clipper,0)
If *Clipper=0:ProcedureReturn #False:EndIf
If *Clipper\SetClipList(rgn,0)<>#S_OK
*Clipper\Release()
ProcedureReturn #False
EndIf
If *Back\SetClipper(*Clipper)<>#S_OK
*Clipper\Release()
ProcedureReturn #False
EndIf
clipper = #True
EndIf
If Transparent=1
*Back\Blt(rDst,*DDS ,rSrc,#DDBLT_WAIT | #DDBLT_KEYSRC ,0)
Else
*Back\Blt(rDst,*DDS ,rSrc,#DDBLT_WAIT ,0)
EndIf
If clipper=#True
*Back\SetClipper(0)
*Clipper\Release()
EndIf
EndIf
EndProcedure