New function: Single Surface Drawing.

BlitzMax Forums/BlitzMax Programming/New function: Single Surface Drawing.

TartanTangerine (was Indiepath)(Posted 2005) [#1]
It was noted that the LoadAnimImage actually creates a new image for each frame (SHOCK). I developed a new Type that allows you to load and draw animated images without the system creating a shed load of new surfaces - Hence Single Surface Drawing.

Stats :-

DirectX - 40% Less Video Ram 28% speed increase
OpenGL - 42% Less Video Ram 28% speed increase AND 57% faster than DirectX (nVidia Fx5200)

[EDIT]This code no longer has any dependencies.

The New Type:
Type TAnimImage
	
	Field Image		:TImage
	Field width		:Int
	Field height		:Int
	Field u0			:Float[]
	Field v0			:Float[]
	Field u1			:Float[]
	Field v1			:Float[] 

        Function         Load:TAnimImage(url:Object,cell_width:Float,cell_height:Float,start:Int,frames:Int,flags=-1)
		Local t:TAnimImage = New TAnimImage
		Local tx:Float
		Local ty:Float
		Local x_Cells:Int
		t.u0		= New Float[frames]
		t.v0		= New Float[frames]
		t.u1		= New Float[frames]
		t.v1		= New Float[frames]
		t.Image 	= LoadImage(url,flags)
		Local xDelta:Float = t.Image.Width / Pow2Size(t.image.width)		
		Local yDelta:Float = t.Image.Height / Pow2Size(t.image.height)
		x_cells	= t.Image.Width  / cell_width
		For Local f = start To frames - 1
			tx = (f Mod x_cells * cell_width) * xdelta
			ty 	= (f / x_cells * cell_Height) * ydelta
			t.u0[f]	= Float(tx) / Float(t.Image.Width)
			t.v0[f] 	= Float(ty) / Float(t.Image.Height)
			t.u1[f]	= Float(tx + cell_width * xdelta)  / Float(t.Image.Width)
			t.v1[f]	= Float(ty + cell_Height * ydelta) / Float(t.Image.Height)
		Next
		Return t		
	End Function
	
	Function  Pow2Size:Float( n )
		Local t=1
		While t<n
			t:*2
		Wend
		Return t
	End Function

	
	Function Free(t:TAnimImage)
		t.Image = Null
		t = Null
		FlushMem()
	End Function
	
	Method Draw(x:Float,y:Float,width:Float,height:Float,frame:Int=0)
		Local DXFrame:TDX7ImageFrame = TDX7ImageFrame (image.frame(0))
		If DXFrame
                   DXFrame.setUV(u0[frame],v0[frame],u1[frame],v1[frame])
                Else
                    Local GLFrame:TGLImageFrame = TGLImageFrame(image.frame(0))
                    GLFrame.u0 = u0[frame]
                    GLFrame.u1 = u1[frame]
                    GLFrame.v0 = v0[frame]
                    GLFrame.v1 = v1[frame]
                EndIf
		DrawImageRect(Self.Image,x,y,width,height)
	End Method
End Type

Example:
Graphics 640,480,0,NOSYNC

Print "Start Memory " + MemAlloced()

Local now:Int = MilliSecs()

Local blob:TAnimImage = TAnimImage.Load("gfx/stoneset0.png",32,64,0,32,FILTEREDIMAGE)
'Local blob:TImage = LoadAnimImage("gfx/stoneset0.png",32,64,0,32,FILTEREDIMAGE)

For Local a = 1 To 100
	Cls
	For Local b = 1 To 10000
		blob.Draw(Rand(0,640),Rand(0,480),20,40,Rand(0,31))
		'DrawImageRect(blob,Rand(0,640),Rand(0,480),20,40,Rand(0,31))
	Next
	Flip
Next

Print "End Memory " + MemAlloced()
Local time:Int = MilliSecs()-now
Print "Time Taken " + time

WaitKey()


To Set Image Handles Use:
SetImageHandle(MyTAnimImage.Image,x,y)



Who was John Galt?(Posted 2005) [#2]
Wow nice on mate -thanks for sharing that.


Ferminho(Posted 2005) [#3]
That's a great help, I think I'll be using it right away. Thanks a lot!


tonyg(Posted 2005) [#4]
Seems to draw some frames 'offset' from their intended start point.
Image file 32*32*5 shows a problem but 32*32*4 does not.


TartanTangerine (was Indiepath)(Posted 2005) [#5]
sorry tonyg, what do you mean?


tonyg(Posted 2005) [#6]
Should have added some code...
Graphics 640,480,0,NOSYNC
SeedRnd MilliSecs()
Local blob:TAnimImage = TAnimImage.Load("animstrip5.png",32,32,0,5,FILTEREDIMAGE)
Local blob1:TAnimImage = TAnimImage.Load("animstrip4.png",32,32,0,4,FILTEREDIMAGE)
'Local blob:TImage = LoadAnimImage("animstrip.png",32,64,0,10,FILTEREDIMAGE)
While Not KeyHit(key_escape)
	Cls
	blob.Draw(0,0,32,32,Rand(0,4))
	blob1.draw(0,50,32,32,Rand(0,3))
'	DrawImage blob,0,0,Rand(0,9)
	DrawText MouseX() + " " + MouseY(),0,100

	Flip
	FlushMem
	Delay 500
Wend

animstrip5.png is 32*32*5
animstrip4.png is 32*32*4


TartanTangerine (was Indiepath)(Posted 2005) [#7]
Probably my dodgy coding. I've only tested with texture sizes ^2 and not strips.


tonyg(Posted 2005) [#8]
I can't see anything wrong with the UV parms when I outpit them.
May I've put SetUv in the wrong place.
Which driver.bmx file should it be added to?
I have it as a method of TImageFrame.


TartanTangerine (was Indiepath)(Posted 2005) [#9]
If it compiles then you've got it in the right place > it's in the max2d.mod directory.

Is this the Method you added to TImageFrame?
	Method SetUV(u0#,v0#,u1#,v1#)
		xyzuv[3]=u0
		xyzuv[4]=v0
		xyzuv[8]=u1
		xyzuv[9]=v0
		xyzuv[13]=u0
		xyzuv[14]=v1
		xyzuv[18]=u1
		xyzuv[19]=v1
	End Method



tonyg(Posted 2005) [#10]
Errr, no.
I added...
Method SetUV(u0#,v0#,u1#,v1#) Abstract

I can't get that new method to build as
'Identifier xyzvu not found.
<edit> although that's the method I have in d3d7max2d.bmx


TartanTangerine (was Indiepath)(Posted 2005) [#11]
Ignore me..... So what I originally said to do. I got my wires crossed.


Steve Elliott(Posted 2005) [#12]
This sounds fantastic! Thanks! I've wondered exactly how LoadAnimImage works - does it create 1 surface - or a surface for each frame?

One thing preventing me using it though, it requires messing about with the official modules. I don't want to do this for fear of upsetting max and thus causing a debugging nightmare - having forgot a couple of lines in a particular module have been added. Plus the fact official updates would over-write any changes anyway.

Could Mark please integrate this into the next update?


TartanTangerine (was Indiepath)(Posted 2005) [#13]
Could Mark please integrate this into the next update?

Ha HA ha ha ha HA ha ha haaaaa.

There is a way around using my SetUV function : http://www.blitzbasic.com/codearcs/codearcs.php?code=1422


tonyg(Posted 2005) [#14]
LoadAnimImage creates a single TImage but seperate pixmaps for each frame. I believe each pixmap is a seperate surface but I could be wrong.
Huge numbers or animations and/or loading your tileset with loadanimimage (especially if the frames are odd size) might create lots of surfaces.
There's also this...
DrawImageBlock
but it's OGL only.
BTW ; Anybody got DrawImageArea or DrawImageBlock to work? If so, how?


TartanTangerine (was Indiepath)(Posted 2005) [#15]
See this:-
device.SetTexture 0,frame.surface

That is the command that switches the texture according to the frame, I think it is safe to assume that seperate surfaces are used for each frame.

The DrawImageBlock code works the same way as my code does, it sets the UV.


TartanTangerine (was Indiepath)(Posted 2005) [#16]
This code now runs straight outta the box. Get it from the top thread.


Steve Elliott(Posted 2005) [#17]

This code now runs straight outta the box



SetUV?


Suco-X(Posted 2005) [#18]
Hi
Can i use the imagescollide functions with TAnimImage?
Mfg Suco


tonyg(Posted 2005) [#19]
You still need the SetUV from the link you had previously.
I added debug statements for the UV parms which all seem OK but it's still offset for anim frames > 4


TartanTangerine (was Indiepath)(Posted 2005) [#20]
Nope, that SetUV Function is the one already in Blitz, I just did not know how to access it directly. Now I know and so do you.


tonyg(Posted 2005) [#21]
Are we using different systems?
Running the example *without* the changes you suggested to add SetUV produces...
"Identifier setUV not found"


TartanTangerine (was Indiepath)(Posted 2005) [#22]
Hmmn, Okay you win I changed the code again. BUT this is DX7 only now.


Yan(Posted 2005) [#23]
This should work with GL too...
Method Draw(x:Float,y:Float,width:Float,height:Float,frame:Int=0)
  Local DXFrame:TDX7ImageFrame = TDX7ImageFrame(image.frame(0))
  If DXFrame
    DXFrame.setUV(u0[frame],v0[frame],u1[frame],v1[frame])
  Else
    Local GLFrame:TGLImageFrame = TGLImageFrame(image.frame(0))
    GLFrame.u0 = u0[frame]
    GLFrame.u1 = u1[frame]
    GLFrame.v0 = v0[frame]
    GLFrame.v1 = v1[frame]
  EndIf
			
  DrawImageRect(Self.Image,x,y,width,height)
End Method



TartanTangerine (was Indiepath)(Posted 2005) [#24]
Updated.


tonyg(Posted 2005) [#25]
They both 'work' fine now.
However, does anybody else have a problem when the animation file has > 4 frames?
<edit> it seems the problem occurs with odd numbers of frames.


TartanTangerine (was Indiepath)(Posted 2005) [#26]
Tonyg, the files I am using with this at the moment consist of 32 frames. I don't have any issue at all (32x64x32).


Yan(Posted 2005) [#27]
tonyg, does this work for you (you should see 16 coloured blocks)?...
img$ = String(getenv_("BMXPath")) + "\samples\birdie\games\tiledrop\media\blocks.png"
 
Graphics 640,480,0

Local blob:TAnimImage = TAnimImage.Load(img$, 32, 32, 0, 16, FILTEREDIMAGE)

For Local b=0 To 15
	blob.Draw(5 + (b * 40), 200, 30, 30, b)
Next

Flip

WaitKey()
End



tonyg(Posted 2005) [#28]
Yep that works but it's an even number of frames (might have missed my previous edit)
Try this...
Type TAnimImage
	
	Field Image		:TImage
	Field width		:Int
	Field height		:Int
	Field u0			:Float[]
	Field v0			:Float[]
	Field u1			:Float[]
	Field v1			:Float[] 
	
	Function Load:TAnimImage(url:Object,cell_width,cell_height,start:Int,frames:Int,flags=-1)
		Local t:TAnimImage = New TAnimImage
		Local tx:Int
		Local ty:Int
		Local x_Cells:Int
		t.u0		= New Float[frames]
		t.v0		= New Float[frames]
		t.u1		= New Float[frames]
		t.v1		= New Float[frames]
		t.Image 	= LoadImage(url,flags)
		x_cells	= t.Image.Width  / cell_width
		For Local f = start To frames - 1
			tx	= f Mod x_cells * cell_width
			ty 	= (f / x_cells * cell_Height)
			t.u0[f]	= Float(tx) / Float(t.Image.Width)
			t.v0[f] 	= Float(ty) / Float(t.Image.Height)
			t.u1[f]	= Float(tx + cell_width)  / Float(t.Image.Width)
			t.v1[f]	= Float(ty + cell_Height) / Float(t.Image.Height)
		Next
		Return t		
	End Function
	
	Function Free(t:TAnimImage)
		t.Image = Null
		t = Null
		FlushMem()
	End Function
Method Draw(x:Float,y:Float,width:Float,height:Float,frame:Int=0)
  Local DXFrame:TDX7ImageFrame = TDX7ImageFrame(image.frame(0))
  If DXFrame
    DXFrame.setUV(u0[frame],v0[frame],u1[frame],v1[frame])
  Else
    Local GLFrame:TGLImageFrame = TGLImageFrame(image.frame(0))
    GLFrame.u0 = u0[frame]
    GLFrame.u1 = u1[frame]
    GLFrame.v0 = v0[frame]
    GLFrame.v1 = v1[frame]
  EndIf
			
  DrawImageRect(Self.Image,x,y,width,height)
End Method	
End Type

'img$ = String(getenv_("BMXPath")) + "\samples\birdie\games\tiledrop\media\blocks.png"
img$ = String(getenv_("BMXPath")) + "\samples\breakout\media\tiles.png"
Graphics 640,480,0

Local blob:TAnimImage = TAnimImage.Load(img$, 32, 20, 0, 5, FILTEREDIMAGE)

For Local b=0 To 4
	blob.Draw(5 + (b * 40), 200, 30, 30, b)
       DrawText b,5+(b*40),200
Next

Flip

WaitKey()
End



TartanTangerine (was Indiepath)(Posted 2005) [#29]
ohh, thats not good. The problem seems to be with the code for calculating the x and y positions of each image in the strip.


tonyg(Posted 2005) [#30]
I thought so but debuglogging the UV coords used and they look 'ok' to my untrained eye.


TartanTangerine (was Indiepath)(Posted 2005) [#31]
I'm about 50% of the way to sorting it.. Fingers crossed.


TartanTangerine (was Indiepath)(Posted 2005) [#32]
The UV's are coming out correctly?!?!?

So why is it not drawing correctly?!?!

x-cells : 1
y-cells : 5
tx :0
ty :0
u0 :0.000000000
v0 :0.000000000
u1 :1.00000000
v1 :0.200000003
tx :0
ty :20
u0 :0.000000000
v0 :0.200000003
u1 :1.00000000
v1 :0.400000006
tx :0
ty :40
u0 :0.000000000
v0 :0.400000006
u1 :1.00000000
v1 :0.600000024
tx :0
ty :60
u0 :0.000000000
v0 :0.600000024
u1 :1.00000000
v1 :0.800000012
tx :0
ty :80
u0 :0.000000000
v0 :0.800000012
u1 :1.00000000
v1 :1.00000000



tonyg(Posted 2005) [#33]
Yep... it's very weird.
Here's the output for an 'even' number...
0.000000000 0.000000000 0.250000000 0.312500000
0.250000000 0.312500000 0.500000000 0.625000000
0.500000000 0.625000000 0.750000000 0.937500000
0.750000000 0.000000000 1.00000000 0.312500000

Is it at all possible the float inaccuracy has anything to do with it? (notice these are all n.n00000)
If the uvs are limited to 4dec places what happens. I'll try it here but it might take a while.


Warren(Posted 2005) [#34]
Is the texture that you're loading a power of two in each dimension? That can mess with texture coordinates if it isn't.


TartanTangerine (was Indiepath)(Posted 2005) [#35]
Ah Warren hit the nail on the head - I think

Bmax must be resizing the texture by padding it some way.

If you make the image 32x128 and then change the dimensions of each frame accordingly it works.

now to fix it.


TartanTangerine (was Indiepath)(Posted 2005) [#36]
Should work now. Updated First Post.

Someone please break it for me :(


tonyg(Posted 2005) [#37]
Looks good here....


Eikon(Posted 2005) [#38]
I've got 189+ tiles here and the wrong image frames are being drawn. Looks to be one or two tiles off in all instances.

'imgTiles:TImage = LoadAnimImage("gfx/tiles/" + tmpPath$, 16, 16, 0, 189 * tmpFrames, MASKEDIMAGE|FILTEREDIMAGE)
imgTiles:TAnimImage = TAnimImage.Load("gfx/tiles/" + tmpPath$, 16, 16, 0, 189 * tmpFrames, MASKEDIMAGE|FILTEREDIMAGE)

If map(x, y, 1) <> -1 Then imgTiles.Draw Int((a * 24) - scrollX), Int(b * 16), 16, 16, map(x, y, 1)
'DrawImage imgTiles, Int((a * 16) - scrollX), Int(b * 24), map(x, y, 1)
My tile image is 144x336
Edit: You also left off the Type and field info in your first post.


TartanTangerine (was Indiepath)(Posted 2005) [#39]
When you say wrong frames do you mean frames are being drawn in error or not at all?


Eikon(Posted 2005) [#40]
They're being drawn correctly, only it's showing a different frame than it should be.


TartanTangerine (was Indiepath)(Posted 2005) [#41]
Can you see any obvious errors in my code?


tonyg(Posted 2005) [#42]
Hmmm. I think I found the problem...
tx = (f Mod x_cells * cell_width) 

should be
tx = (f Mod x_cells * cell_width) * xdelta

...and, famous last words, haven't broken it yet.


TartanTangerine (was Indiepath)(Posted 2005) [#43]
yeah, i tested for height only... I need to employ some full time bug testers :D


Robert Cummings(Posted 2005) [#44]
Very good work. Please consider adding to the next update Mark.


TartanTangerine (was Indiepath)(Posted 2005) [#45]
Updated first post.


Steve Elliott(Posted 2005) [#46]
A typo there Indiepath - should read...

tx = (f Mod x_cells * cell_width) * xdelta

One Eyed Jack, Indiepath laughed at me for suggesting that - you hold him and I'll hit him. ;-)


TartanTangerine (was Indiepath)(Posted 2005) [#47]
And it can go faster : http://www.blitzbasic.com/Community/posts.php?topic=51795


EOF(Posted 2005) [#48]
And now, for the lazy coders version.

Here, you just load an image specifying how many frames are contained within. Then draw the image using whatever frame you desire. No need to worry about cell sizes.

The include:


Test Program:

The 'runner' animstrip is here

Currently, the above only works with a strip of images layed out in a horizontal fashion.

I'm not sure if the old limitation still exists where trying to handle images larger than the graphics display causes issues(?)
When I tried loading the runner animation strip using an image width of 2280 the anim failed to show under DX and played at odd frame positions under GL.
I'll see if I can track down any bugs in the LoadAnim method.


TartanTangerine (was Indiepath)(Posted 2005) [#49]
I'm not sure if the old limitation still exists where trying to handle images larger than the graphics display causes issues(?)

Follow the rules for textures and you can't go wrong.


Eikon(Posted 2005) [#50]
Works great now except that some tiles have a strange border around them. I'm loading the TAnimImage as MASKEDIMAGE|FILTEREDIMAGE, and also Drawing at Int() positions only.
DrawImageRect(Self.Image, Int(x), Int(y), Int(width), Int(height))
Example:
Tiles are sopposed to be dark gray all around, with no light gray edges.

I really want to use this since it gives my program a nice speed boost. Anyone know what the problem could be?


TartanTangerine (was Indiepath)(Posted 2005) [#51]
The issue may be the small inaccurcies of using UV co-ordinates. If your image conforms to rules for textures ie ^ 2 then there should be no issues.


MGE(Posted 2007) [#52]
Is anyone using this anymore? Is it stable?


tonyg(Posted 2007) [#53]
I tested it quite a bit when Tim posted it and it worked well after a few teething problems. It doesn't use anything non-standard so, effectively, you have all the source.


Grey Alien(Posted 2007) [#54]
I really ought to get round to using this. Now all I need is a way to make a "mesh" by drawing those textures joined properly so I can scroll a tilemap at non-integer coords without seeing the joins between the tiles (which you get if you draw all the tiles separately).


TartanTangerine (was Indiepath)(Posted 2007) [#55]
Old B3D code but the priciples are there

http://blitzbasic.com/codearcs/codearcs.php?code=1178
http://blitzbasic.com/codearcs/codearcs.php?code=1377


MGE(Posted 2007) [#56]
"...so I can scroll a tilemap at non-integer coords without seeing the joins between the tiles (which you get if you draw all the tiles separately)."

Hi GA, do you have an .exe demo showing this? I'm not getting any lines and I'm just drawing tiles next to each other.


Grey Alien(Posted 2007) [#57]
Thanks Tim. Will study (when time) but I'm not an expert on DX regretably.

MGE Dev: http://www.greyaliengames.com/framework.php scroll down and get "make me happy". Depending on the type of tile the issue is worse. It only happens at floating point coords of course because the edge is anti-aliased. If it was drawn at integer coords to a giant texture of many tiles and then the big texture was drawn at floating point coords, you wouldn't get the issue.


MGE(Posted 2007) [#58]
GA - checked out the Make Me Happy demo (nice!), didn't see any lines between tiles. Was I supposed to?


Grey Alien(Posted 2007) [#59]
yeah you can see if you look carefully. Well you can on a CRT; if you have a TFT try it in windowed mode so there is no interpolation by your screen. Also try Speed Run then. there are slight sorta flickery lines between the titles as they slide from one int coord to another via floating point due to the anti-aliasing.

btw make me happy took 8 hours (inc. crappy graphics) with my framework :-) Speed run took less time I think.


MGE(Posted 2007) [#60]
hmm... here's a screen grab from windowed mode on my crt. Where are the lines???? The fact that you see lines on your end, makes me shrug again at the fact that already in 2 days I'm seeing more potential Max2d compatibility issues.




HrdNutz(Posted 2007) [#61]
Guys, the lines you MAY be experiencing are most likely due to texture filtering (if you see discolored lines between tiles). Try disabling filtering, and there should be no lines in between tiles. Also try setting texture wrapping mode to CLAMP and see if that helps. The geometry will always jump from pixel to pixel, even at subpixel accuracy. (no subpixels on monitors) This is specially evident on LCD monitors.


MGE(Posted 2007) [#62]
What lines? (Sorry for repeating...) Perhaps it's gpu related and not a stable 2DMax issue?


tonyg(Posted 2007) [#63]
The fact that you see lines on your end, makes me shrug again at the fact that already in 2 days I'm seeing more potential Max2d compatibility issues


As suggested any issue is likely to be a video card 'oddity' rather than Max2D issue.

Out of interest, what are the other potential Max2d compatbility issues you have seen?


Derron(Posted 2007) [#64]
In my try to convert to Tanimimage I have to say that - I only converted some mainsprites. the memory usage increased from 70 to 80MB, the fps-count stays the same (in ogl and also in dx7, dx9 fuzzles the sprites...garbage like).


bye
MB


Grey Alien(Posted 2007) [#65]
MGE Developer: perhaps I should have been clearer. You can only see it as stuff is moving. Go into that game again and press D for debug mode then L for sLow motion. Now move across and watch the edges of the grey tiles, they all flicker in an unappealing way because each one is having it's edge filtered. You can't really notice it on the earth tiles. The sky is a static image so that doesn't count. If I do as HrdNutz suggests and turn off filtering when I load in the tiles, then they all get drawn at integer coords, which of course removes the problem, but then it doesn't look as smooth when it's scrolling.

If you take a static screenshot, it looks fine. The problem is the edges are different from frame to frame.

It should happen on all PCs because all that's happening is each tile is drawn individually so it's edges are anti-aliased (filtered) to "nothing" whereas if they were all drawn to a texture first and then displayed, the edges would anti-alias to the adjoining tiles and it would look better. That's uh my theory anyway. In fact I tested it by moving a larger tile made up of several smaller ones and the flickery joins were not present.

Sometimes this sort of issue can be improved by adding a 1 pixel blank border round each sprite but it didn't help much with this tile problem.


MGE(Posted 2007) [#66]
I'm actually very familiar with the line issue because my older engine suffered from it and I had to add a 1 pixel border around each tile in the texture. So, with that in mind, your demo has no line artifacting on my Intel 82845G driver. ;) It may happen on other GPU's, but it ain't happening on this one. lol..


Grey Alien(Posted 2007) [#67]
hmm, weird. There should be *some* line weirdness esp. as I'm NOT adding the one pixel border in that demo.


HrdNutz(Posted 2007) [#68]
Grey is right about the rendering scene to texture and then to screen - that would appear much smoother. You can see this line flickering very clearly if you draw a filled rect without a texture - the edge will flicker from 1 pixel to the other instead of smoothly gliding in between a single pixel. Subpixels are achieved through texture filtering - monitors can't really display stuff in between pixels.

There is another possible 'line issue' that could display a slight portion of the neighbouring texture cell due to texture filtering - this is a different issue than subpixel 'inaccuracy'. This is related to some driver/card implementations and texture clamping.


Grey Alien(Posted 2007) [#69]
I didn't know about the second line issue.


TartanTangerine (was Indiepath)(Posted 2007) [#70]
As a fix for Greys stuff the following might help
Function setwrap()
	D3D7GraphicsDriver().Direct3DDevice7().SetTextureStageState( 0, D3DTSS_ADDRESS,	D3DTADDRESS_WRAP);
End Function

Function setnowrap()
	D3D7GraphicsDriver().Direct3DDevice7().SetTextureStageState( 0 , D3DTSS_ADDRESS , 	D3DTADDRESS_CLAMP) ; 
End Function