ClipSprite3D for DirectX7 / DirectX9 (x86/x64)

Share your advanced PureBasic knowledge/code with the community.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

ClipSprite3D for DirectX7 / DirectX9 (x86/x64)

Post by Fluid Byte »

It seems my tenacity paid off since I finally found all needed information to update the famous ClipSprite3D code from S.M. The original code for DX7 has been cleaned, updated and extended. The dependency for the DirectDraw interface to retrieve the real width and height has been removed. That means a lot of the overhead is gone (DDPIXELFORMAT, DDCOLORKEY, etc.).

Though the best thing still is that it finally works correctly with the DirectX9 subsystem. It's now a compact piece of code which will automatically call the correct version depending on the selected subsystem.

* Updated the code to support DirectX 9 as the default subsystem (PB 4.40 and later) *

Code: Select all

; ==========================================
; #  ClipSprite3D for DirectX7 / DirectX9  #
; ==========================================

; Original by: S.M. (Stefan Moebius)
; Modfied by: Fluid Byte
; Platform: Windows
; E-Mail: fluidbyte@web.de

EnableExplicit

CompilerIf Subsystem("DirectX7")
	Structure D3DTLVERTEX
		x.f
		y.f
		z.f
		rhw.f
		Color.i
		Specular.i
		tu.f
		tv.f
	EndStructure
	
	Structure PB_DX7Sprite3D
		Texture.IDirectDrawSurface7 ; DirectDrawSurface7
		Vertice.D3DTLVERTEX[4]      ; The 4 vertices for the rectangle sprite
		Width.w                     ; width set with ZoomSprite3D()
		Height.w                    ; height set with ZoomSprite3D()	
		unknown.i
	EndStructure

	Procedure ClipSprite3D(Sprite3D,ClipX,ClipY,ClipWidth,ClipHeight)
		Protected *ptr.PB_DX7Sprite3D = IsSprite3D(Sprite3D)
		
		If *ptr = 0 : ProcedureReturn 0 : EndIf
		
		Protected RealWidth = SpriteWidth(Sprite3D)
		Protected RealHeight = SpriteHeight(Sprite3D)
			
		If ClipX < 0 : ClipX = 0 : EndIf
		If ClipY < 0 : ClipY = 0 : EndIf
		
		If ClipWidth < 0 : ClipWidth = 0 : EndIf
		If ClipHeight < 0 : ClipHeight = 0 : EndIf		

		If ClipX > RealWidth : ClipX =  RealWidth : EndIf
		If ClipY > RealHeight : ClipY = RealHeight : EndIf
		
		If ClipX + ClipWidth > RealWidth : ClipWidth = RealWidth - ClipX : EndIf
		If ClipY + ClipHeight > RealHeight : ClipHeight = RealHeight - ClipY : EndIf
		
		*ptr\Vertice[0]\tu = ClipX / RealWidth
		*ptr\Vertice[0]\tv = ClipY / RealHeight
		
		*ptr\Vertice[1]\tu = (ClipX + ClipWidth) / RealWidth
		*ptr\Vertice[1]\tv = ClipY / RealHeight
		
		*ptr\Vertice[2]\tu = ClipX / RealWidth
		*ptr\Vertice[2]\tv = (ClipY + ClipHeight) / RealHeight
		
		*ptr\Vertice[3]\tu = (ClipX + ClipWidth) / RealWidth
		*ptr\Vertice[3]\tv = (ClipY + ClipHeight) / RealHeight
		
		ProcedureReturn 1
	EndProcedure
CompilerElse
	Structure D3DTLVERTEX
	  x.f
	  y.f
	  z.f
	  rhw.f
	  Color.l
	  tu.f
	  tv.f
	EndStructure

	Structure PB_DX9Sprite3D
	  TexRes.i                  ; TexRes
	  Vertice.D3DTLVERTEX[4]    ; The 4 vertices for the rectangle sprite
	  TmpVertice.D3DTLVERTEX[4] ; The 4 vertices for the rectangle sprite
	  Width.l                   ; width set with ZoomSprite3D()
	  Height.l                  ; height set with ZoomSprite3D()
	  RealWidth.l
	  RealHeight.l
	  Angle.f
	  Transformed.l
	EndStructure

	Procedure ClipSprite3D(Sprite3D,ClipX,ClipY,ClipWidth,ClipHeight)
		Protected *ptr.PB_DX9Sprite3D = IsSprite3D(Sprite3D)
		
		If *ptr = 0 : ProcedureReturn #False : EndIf
		
		If ClipX < 0 : ClipX = 0 : EndIf
		If ClipY < 0 : ClipY = 0 : EndIf
		
		If ClipWidth < 0 : ClipWidth = 0 : EndIf
		If ClipHeight < 0 : ClipHeight = 0 : EndIf
		
		If ClipX > *ptr\RealWidth : ClipX = *ptr\RealWidth : EndIf
		If ClipY > *ptr\RealHeight : ClipY = *ptr\RealHeight : EndIf
		
		If ClipX + ClipWidth > *ptr\RealWidth : ClipWidth = *ptr\RealWidth - ClipX : EndIf
		If ClipY + ClipHeight > *ptr\RealHeight : ClipHeight = *ptr\RealHeight - ClipY : EndIf
		
		*ptr\Vertice[0]\tu = ClipX / *ptr\RealWidth
		*ptr\Vertice[0]\tv = ClipY / *ptr\RealHeight 
		
		*ptr\Vertice[1]\tu = (ClipX + ClipWidth) / *ptr\RealWidth 
		*ptr\Vertice[1]\tv = ClipY / *ptr\RealHeight
		
		*ptr\Vertice[2]\tu = ClipX / *ptr\RealWidth 
		*ptr\Vertice[2]\tv = (ClipY + ClipHeight) / *ptr\RealHeight 
		
		*ptr\Vertice[3]\tu = (ClipX + ClipWidth) / *ptr\RealWidth 
		*ptr\Vertice[3]\tv = (ClipY + ClipHeight) / *ptr\RealHeight 

		ProcedureReturn #True
	EndProcedure
CompilerEndIf
Last edited by Fluid Byte on Sun Jan 22, 2017 2:08 pm, edited 9 times in total.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

* This demo doesn't work any more since a lot of images have been removed from the "examples" folder since 4.50 *

Enhanced demo version:

Code: Select all

InitSprite() : InitSprite3D() : InitKeyboard()

OpenWindow(0,0,0,640,480,"ClipSprite3D for DX7/DX9",#WS_SYSMENU | #WS_CAPTION | 1)
OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0)

Define i, EventID, AnimFrame, AnimDelay, CVL

; * Background
CreateSprite(0,640,480)
StartDrawing(SpriteOutput(0))
For i=0 To 479 : CVL = i * 125 / 479 : Box(0,i,640,1,RGB(70 + CVL,90 + CVL,110 + CVL)) : Next
StopDrawing()

; * Checkerboard
CreateSprite(1,128,128,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
Box(0,0,256,256,RGB(35,70,255))
Box(0,0,50,50,RGB(100,230,0))
Box(50,50,50,50,RGB(230,60,20))
StopDrawing()

CreateSprite3D(1,1)
ZoomSprite3D(1,192,192)
ClipSprite3D(1,0,0,100,100)

; * ImageStrip
CreateImage(0,512,512)
StartDrawing(ImageOutput(0))
For i=1 To 8
	LoadImage(i,#PB_Compiler_Home + "Examples\Sources - Advanced\Waponez II\Data\Explosion_" + Str(i) + ".bmp")
	DrawImage(ImageID(i),(i - 1) * 64,0) : FreeImage(i)
Next
StopDrawing()

SaveImage(0,GetTemporaryDirectory() + "tmp4f8s5.bmp") : FreeImage(0)
LoadSprite(2,GetTemporaryDirectory() + "tmp4f8s5.bmp",#PB_Sprite_Texture)

CreateSprite3D(2,2)
ZoomSprite3D(2,128,128)
ClipSprite3D(2,0,0,64,64)

Sprite3DQuality(1)

Repeat
	EventID = WindowEvent()
	
	ExamineKeyboard()
		
	ClearScreen(0)
	
	DisplaySprite(0,0,0)

	AnimDelay + 1
	
	If AnimDelay = 8
		AnimDelay = 0
		AnimFrame + 1
		If AnimFrame = 8 : AnimFrame = 0 : EndIf		
		ClipSprite3D(2,64 * AnimFrame,0,64,64)
	EndIf
	
	Start3D()
	Sprite3DBlendingMode(5,13)
	RotateSprite3D(1,1,1)
	DisplaySprite3D(1,70,140)	
	DisplaySprite3D(2,370,40)
	Sprite3DBlendingMode(5,2)
	DisplaySprite3D(2,440,180)
	Sprite3DBlendingMode(8,4)
	DisplaySprite3D(2,370,320)
	Stop3D()
		
	FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or EventID = #PB_Event_CloseWindow
Last edited by Fluid Byte on Wed Jul 21, 2010 9:36 pm, edited 1 time in total.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Very nice work!

And is it just my eyes or does using the DirectX9 subsystem have better alpha-blending? I noticed on the edges of an animated sprite in DX7 there is slight pixel shifting or something. Either way using the DirectX9 subsystem looks cleaner to my eyes. Thanks for posting this. ;)

EDIT: Oh, I noticed the edge difference with my example combined with your DirectX9 code. http://www.purebasic.fr/english/viewtopic.php?t=36285
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

And is it just my eyes or does using the DirectX9 subsystem have better alpha-blending?
Alpha-blending is the same but the texture-filtering is better. :wink:
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
IceSoft
Addict
Addict
Posts: 1616
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

Should be a nativ function of the Sprite3D PureBasic library.
Belive!
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

as I already said: if native, then setting of u/v coordinates.
you can do clip with u/v setting, but you cannot do u/v setting with clip.
oh... and have a nice day.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Post by djes »

IceSoft wrote:Should be a nativ function of the Sprite3D PureBasic library.
+1
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Does anyone know why the third pic which is sprite #2 doesn't load but instead is a duplicate of sprite #1? All three images are located with the source. So it's not a path problem.

Code: Select all

Code Removed
Last edited by J. Baker on Wed Mar 25, 2009 8:14 pm, edited 1 time in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Could you provide the images please?

[edit]
you need to put IncludeBinary into DataSection/EndDataSection
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Fluid Byte wrote:Could you provide the images please?

[edit]
you need to put IncludeBinary into DataSection/EndDataSection
It seems to be a DisplaySprite3D error/bug. If I just use DisplaySprite it loads the correct image and it duplicates the first 3d sprite when DisplaySprite3D is used.

I would have to create another image. The third image is for something I'm working on.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

Fluid Byte wrote:Could you provide the images please?
EDIT: Images Removed
Last edited by J. Baker on Wed Mar 25, 2009 8:15 pm, edited 1 time in total.
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

Change

Code: Select all

CreateSprite3D(0, 0)
CreateSprite3D(1, 0)
CreateSprite3D(2, 0)
to

Code: Select all

CreateSprite3D(0, 0)
CreateSprite3D(2, 2)
PS: Could you remove your above code? I want to keep the thread clean.
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

thanks, I should have caught that. ;)
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Post by J. Baker »

It seems that Sprite3DQuality doesn't work with DirectX9. Does this have to do with DirectDraw?
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

J. Baker wrote:It seems that Sprite3DQuality doesn't work with DirectX9. Does this have to do with DirectDraw?
That has nothing to do with this code. Besides, it works perfectly. Could you please post in "Coding Questions" and not here?
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
Post Reply