Timing Problem oder DirectX Fehler ?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Stickdevil
Beiträge: 1
Registriert: 08.04.2010 13:20

Timing Problem oder DirectX Fehler ?

Beitrag von Stickdevil »

Hallo zusammen !
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
Benutzeravatar
Schlumpf
Beiträge: 19
Registriert: 21.03.2010 00:52
Wohnort: Der Puff von Schlumpfhausen

Re: Timing Problem oder DirectX Fehler ?

Beitrag von Schlumpf »

Das ist ja sehr speziell, wird wahrscheinlich an den internen Routinen liegen die du aufrufst.

Je nach einstellungen der Treiber und der Grafikkarte wird vielleicht beim Zoomen die Farbe weichgerechnet, und das funktioniert natürlich nicht mit einer Transparenzfarbe.

Das Zoomen eines 2D-Objektes zur Laufzeit ist immer problematisch. Die Klassische Lösung wäre da verschiedene Zoomstufen vorab zu rendern.
PB 4.41 - Win XP pro
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Re: Timing Problem oder DirectX Fehler ?

Beitrag von Fluid Byte »

Ich würd' gern helfen aber ich sehe nicht ein mich mit einer veralteten Version herumzuschlagen.
Windows 10 Pro, 64-Bit / Outtakes | Derek
Antworten