|
-
May 11th, 2001, 06:44 PM
#1
Thread Starter
Good Ol' Platypus
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)
-
May 14th, 2001, 12:57 AM
#2
Fanatic Member
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)
-
May 14th, 2001, 01:02 AM
#3
Frenzied Member
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."
-
May 14th, 2001, 01:05 AM
#4
Fanatic Member
"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)
-
May 14th, 2001, 02:32 AM
#5
Frenzied Member
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."
-
May 14th, 2001, 04:15 AM
#6
Fanatic Member
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)
-
May 14th, 2001, 09:59 AM
#7
Frenzied Member
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.
-
May 14th, 2001, 10:05 AM
#8
Fanatic Member
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)
-
May 14th, 2001, 10:09 AM
#9
Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|