Results 1 to 9 of 9

Thread: Seeing graphics outside of screen area? (DDraw)

  1. #1

    Thread Starter
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134

    Seeing graphics outside of screen area? (DDraw)

    What I mean is, I want to know how to make DDraw 'clip' the graphics that overlap outside of the screen, not just destroy them.

    This is very important as it is for a tile engine!!
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  2. #2
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    Yup, nasty little problem

    Assuming you're using Fullscreen Exclusive mode (otherwise you can just use the built-in DirectDraw Clipper object). Clip the graphics yourself, it's the only way:

    (msBack = BackBuffer surface, msTile = Graphics surface, mrScreen = Screen sized rectangle)


    Code:
    Dim rSource As RECT
    Dim lX As Long
    Dim lY As Long
    
    ' Calculate the X And Y coordinates of the tile / sprite / graphic here
    lX = -5
    lY = -5
    
    ' Set up the source rectangle As normal
    With rSource
        .Left = 0
        .Top = 0
        .Right = 32
        .Height = 32
    
        ' Now, perform the manual clipping
        ' Left side
        If lX < 0 Then
            .Left = Abs(lX)
            lX = 0
        End If
    
        ' Right side
        If lX + 32 > mrScreen.Right Then
            .Right = mrScreen.Right - lX
        End If
    
        ' Top side
        If lY < 0 Then
            .Top = Abs(lY)
            lY = 0
        End If
    
        ' Bottom side
        If lY + 32 > mrScreen.Bottom Then
            .Bottom = mrScreen.Bottom - lY
        End If
    End With
    
    ' That's it, now just Blt the tile / sprite / graphic
    msBack.BltFast lX, lY, msTile, rSouce, DDBLTFAST_WAIT
    It's not that hard, just draw it out on a piece of paper, that's how I got it. It's not tested though, so there might be some small errors in it...

    Hope this helps!
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  3. #3
    Frenzied Member HarryW's Avatar
    Join Date
    Jan 2000
    Location
    Heiho no michi
    Posts
    1,827
    Err... can't you use hardware clipping? Maybe it's a VB thing, cos I'm pretty sure this doesn't pose a problem in C.
    Harry.

    "From one thing, know ten thousand things."

  4. #4
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    "Hardware Clipping", guess that relies on the hardware, or is it widely supported? Anyways, I never heard of hardware clipping in VB (actually, never even heard of hardware clipping in general ), but if that's possible, be sure to let me know too
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  5. #5
    Frenzied Member HarryW's Avatar
    Join Date
    Jan 2000
    Location
    Heiho no michi
    Posts
    1,827
    Well yeah, I just call it hardware clipping because if the card supports it then it will be done in the HAL (most cards do I think), but it's in the HEL too so you don't have to worry about it being available. In C at least, you have to define a list of clipping regions which is a bit of a pain in the arse data structure to work with, involving alittle dynamic memory allocation... actually it is an incredibly bizarre data structure and I have no idea why they chose it... well anyway I don't know how you'd do it in VB but I'm pretty sure it's possible. Probably a lot simpler too. You define a clip list and then make a call to DDraw->CreateClipper and DDSurface->AttachClipper if my memory serves me correctly.

    Hardware clipping is probably the main reason to use Blt instead of BltFast, since BltFast doesn't take any notice of any DirectDraw clippers you have setup.
    Harry.

    "From one thing, know ten thousand things."

  6. #6
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    I don't think it's really possible in VB, the only clippers I know of only work in Windowed mode, so I'm just going to convert my code into a function which handles the clipping...
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  7. #7
    Frenzied Member Jotaf98's Avatar
    Join Date
    Jun 2000
    Location
    I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
    Posts
    1,457
    Hey, PsychoMark, I'm not sure that function will work if the Top/Left is greater than 0. Most DX engines have this problem because they don't need to blt from different parts of one source image, I had to find a really good one that supported it: go to http://www.planet-source-code.com and look for the Grenade Launcher in the VB section.
    Code:
    Temp = Me.GetIQ()
    'Error 9: Overflow
    'DON'T PANIC! :eek:

    To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systems here.


    Jotaf's Theories!
    "Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."

  8. #8
    Fanatic Member PsychoMark's Avatar
    Join Date
    Feb 2001
    Location
    Netherlands
    Posts
    540
    Oops, yeah, that's right, I got that same problem when programming MouseAttack DX (you can find it at my website, including source code)... here's the clipping code used in that game:

    Code:
    Public Sub Draw(Viewport As RECT)
        Dim rSrc As RECT
        Dim lY As Long
        Dim lX As Long
        
        ' Draw mouse
        With Settings
            rSrc = FillRect(.State * .Width, .AniFrame * .Height, .Width, .Height)
            
            ' Clip!
            lX = .X
            lY = .Y
            
            If .Y < Viewport.Top Then
                rSrc.Top = rSrc.Top + Abs(.Y - Viewport.Top)
                lY = Viewport.Top
            End If
            
            If .X < Viewport.Left Then
                rSrc.Left = rSrc.Left + Abs(.X - Viewport.Left)
                lX = Viewport.Left
            End If
            
            If .Y + .Height > Viewport.Bottom Then
                rSrc.Bottom = rSrc.Bottom - (.Height - (Viewport.Bottom - .Y))
            End If
            
            If .X + .Width > Viewport.Right Then
                rSrc.Right = rSrc.Right - (.Width - (Viewport.Right - .X))
            End If
            
            msBack.BltFast lX, lY, msMouse, rSrc, DDBLTFAST_SRCCOLORKEY
        End With
    End Sub
    The FillRect is just a simple function which fill a RECT structure (but using Width and Height, so Right becomes Left + Width etc...)
    Teaudirenopossum.Musasapientumfixaestinaure.
    (I can't hear you. There's a banana in my ear)

  9. #9
    Member Stef's Avatar
    Join Date
    May 2001
    Posts
    41
    Here's the tile-blitting code from a tile engine I wrote some time ago....
    Code:
    Private Sub BlitTile(X As Integer, Y As Integer, TileNum As Integer, XOffset As Integer, YOffset As Integer)
     Dim rSrc As RECT, rDest As RECT
     If X = 0 Then
      rSrc.Left = TileDesc(TileNum).X + XOffset
      rSrc.Right = TileDesc(TileNum).X + TileSize
      rDest.Left = 0
      rDest.Right = TileSize - XOffset
     ElseIf X >= frmScreen.ScaleWidth Then
      rSrc.Left = TileDesc(TileNum).X
      rSrc.Right = rSrc.Left + XOffset
      rDest.Left = X - XOffset
      rDest.Right = frmScreen.ScaleWidth
     Else
      rSrc.Left = TileDesc(TileNum).X
      rSrc.Right = rSrc.Left + TileSize
      rDest.Left = X - XOffset
      rDest.Right = rDest.Left + TileSize
     End If
     If Y = 0 Then
      rSrc.Top = TileDesc(TileNum).Y + YOffset
      rSrc.Bottom = TileDesc(TileNum).Y + TileSize
      rDest.Top = 0: rDest.Bottom = TileSize - YOffset
     ElseIf Y >= frmScreen.ScaleHeight Then
      rSrc.Top = TileDesc(TileNum).Y
      rSrc.Bottom = TileDesc(TileNum).Y + YOffset
      rDest.Top = Y - YOffset
      rDest.Bottom = frmScreen.ScaleHeight
     Else
      rSrc.Top = TileDesc(TileNum).Y
      rSrc.Bottom = TileDesc(TileNum).Y + TileSize
      rDest.Top = Y - YOffset
      rDest.Bottom = rDest.Top + TileSize
     End If
     srfBackBuf.Blt rDest, srfTiles, rSrc, DDBLT_WAIT
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width