DrawImageRect, is it meant to work like this?

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

Simon S(Posted 2005) [#1]
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?


Who was John Galt?(Posted 2005) [#2]
I agree - needs changing I reckon.


Duckstab[o](Posted 2005) [#3]
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 :)


Simon S(Posted 2005) [#4]
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.


Warfield(Posted 2005) [#5]
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



N(Posted 2005) [#6]
http://www.blitzbasic.com/codearcs/codearcs.php?code=1241


Simon S(Posted 2005) [#7]
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.


Warfield(Posted 2005) [#8]
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


Eikon(Posted 2005) [#9]
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



Warfield(Posted 2005) [#10]
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.


Eikon(Posted 2005) [#11]
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