DrawImageRect, is it meant to work like this?

BlitzMax Forums/BlitzMax Beginners Area/DrawImageRect, is it meant to work like this?

In all previous Blitz this drew a rectangular portion of an image. In Bmax, it simply resizes thw whole image to the dimensions you give.

This strikes me as pretty useless, as a simple bit of math and setscale can do exactly the same thing.

So, is it supposed to work like this? And if so, to what purpose?

I agree - needs changing I reckon.

Maybe an option of both would be a solution

Some people find scaling hard and have little Knowledge of formular to convert from image width to a pixel scale.
Sould leave that one in for the beginners

As for DrawimageRect would be nice to see it back as having to mess with pixmaps is a pain

Just my View :)

Well, you don't have to mess with pixmaps.

You can actually fake B2D Drawimage rects with the use of viewports, though it requires a bit more code. But I do prefer the B2D drawimagerects, and was curious about the change in Bmax.

To be honest the only thing I really miss in Bmax is Setbuffer(Imagebuffer()). I believe that's a hardware limitation of 3D graphics cards though. A real shame, as having to use grabimage pretty much grinds everything to a halt.

This function simulates DrawImageRect from Blitz2D:

Function DrawImagePart(Image:TImage, DrawX#, DrawY#, PartX#, PartY#, PartWidth#, PartHeight#, Frame# = 0)
	Local OldX:Int
	Local OldY:Int
	Local OldWidth:Int
	Local OldHeight:Int
	
	Local ViewportX:Int = DrawX
	Local ViewportY:Int = DrawY
	
	' Save current viewport settings
	GetViewport(OldX, OldY, OldWidth, OldHeight)
	
	' Calculate viewport coordinates based on image's handle	
	If Image.Handle_X Then
		Local PercentX:Float
		PercentX = Float(Image.Handle_X) / Float(Image.Width)
		ViewportX = DrawX - (PercentX * PartWidth)
	EndIf
	If Image.Handle_Y Then
		Local PercentY:Float
		PercentY = Float(Image.Handle_Y) / Float(Image.Height)
		ViewportY = DrawY - (PercentY * PartHeight)
	EndIf
	
	SetViewport(ViewportX, ViewportY, PartWidth, PartHeight)
	DrawImage(Image, DrawX-PartX, DrawY-PartY, Frame)
	
	' Restore old viewport settings
	SetViewport(OldX, OldY, OldWidth, OldHeight)
End Function


http://www.blitzbasic.com/codearcs/codearcs.php?code=1241

Ah, excellent stuff Noel.

I'll do a few speed tests, but I'd be willing to bet the opengl method is a lot faster than viewporting it.

I just ran a simple test using both viewporting and Noel's open gl method:

Graphics(640,480,32,-1)

SetMaskColor(255,0,255)
Local TestImage:TImage = LoadImage("test.bmp")
SetImageHandle(TestImage,ImageWidth(TestImage)/2,ImageHeight(TestImage)/2)

Local StartTime:Int
Local ElapsedTime:Int

SetBlend(SolidBlend)

StartTime = MilliSecs()
For Local I:Int = 1 To 1000000
	DrawImagePart(TestImage,320,240,25,25,80,110)
Next
ElapsedTime = MilliSecs() - StartTime

Print(ElapsedTime)

End


On my machine, I got the following results:
DrawImageBlock: 20947
DrawImagePart: 6654

Debug off, of course.
Athlon 64 3200+, Radeon 9800 Pro 128MB

Here's another simpler one to test for speed if you want.

Function DrawImageRect(img:TImage, x#, y#, rx#, ry#, rw#, rh#)
	SetViewport x, y, rw, rh
	DrawImage img, x - rx, x - ry
	
	SetViewport 0, 0, GFX_WIDTH, GFX_HEIGHT
End Function


Thanks Eikon, the code I posted above was adapted directly from that sample you gave in another thread. I just added a few things to make sure it works exactly the way it should(such as to correctly deal with image handles, the user's viewport settings, and animation frames). I would definitely use the faster method for a release that didn't use any of those things, though.

Oh, I see. Didn't really look at the code well enough to notice. It should be noted that TeaMonkey originally came up with this, so big credit to him