CopyRect via SetScale?

BlitzMax Forums/BlitzMax Programming/CopyRect via SetScale?

DivineDominion(Posted 2004) [#1]
Hello there

I found out that a few things are missing of which I didn't know that I would ever notice. CopyRect is one of these things.
I want to play around witht eh OOP thing in BMax and so I'm trying to create a small game, a horizontal shooter thingie like the arcade games from nippon ;)
so I would prefer a resolution of 320x240, scaled up to 640x480. SetScale or SetTransform do their job very good, but its a nice pain in the neck to think about multiplying all my 'object.x = x' with 2 to set the proper position while drawing things in their doubled size.

I haven't found out yet what a Pixmap is for, so I don't know whether grabbing a Pixmap from Backbuffer and resizing it to 640x480 would fix my problem.

If you tried a few things like that I'd be happy to get information about speed and results!

Thanks in advance
DivineDominion (GER :))


ImaginaryHuman(Posted 2004) [#2]
There are some OpenGL commands that can read and write pixels and scale them.


Damien Sturdy(Posted 2004) [#3]
wow. theres no CopyRect? holy crap!? errr.... i was just about to need that!


DivineDominion(Posted 2004) [#4]
Seems to be fast when you create a new image, grab everything and then use setscale 2,2, draw it and setscale 1,1 again. I need it to "zoom" into my game - but beware, windowed mode doenst work properly, especially not with grabimage, see bugreports


ImaginaryHuman(Posted 2004) [#5]
Umm.. another option you have is to draw everything to your backbuffer with normal coordinates - no need to multiple it all by 2, and then use some kind of OpenGL scale thing to resize the whole frame to 640x480 - which could be output to the front buffer as a replacement for `flip`, or to itself, or something.


ImaginaryHuman(Posted 2004) [#6]
But if you have 640x480 and you plan to render the same number of pixels, why not just use regular sized graphics? Why 320?


Tom(Posted 2004) [#7]
Try this, it uses memcopy.

I'm not sure if my clipping code is correct, please correct it if you know better :)

tidbits:
Images draw about 3 times quicker than pixmaps, but locking/unlocking images can KILL the framerate, that's why I'm doing 100 in a loop.

Images, or was it pixmaps?, undergo a conversion if their format isn't the same as the default context which is usualy PF_RGBA8888, so it's worthwhile converting loaded images/pixmaps to the same as the screen format. John Devoy tested this and said it was at least twice as fast in a drawing loop after converting. (I think it was pixmaps now :)


Graphics 1024,768,32,0
Global FPS, RFPS,LastSEcs	' Frame Counter Stuff

SeedRnd MilliSecs()

Local imga:TImage=LoadImage("d:\t.jpg",DYNAMICIMAGE)
Local imgb:TImage=CreateImage(imga.width,imga.height,1,imga.flags)

bglSetSwapInterval(0)	' Disable vsync


Local t:Int=0
While Not KeyHit(KEY_ESCAPE)
	CheckFPS()
	If Keyhit(KEY_SPACE)
		Local a:TPixmap=LockImage(imga)
		Local b:TPixmap=LockImage(imgb)
		
		For i=0 To 99
			CopyRect(Rand(0,200),Rand(0,300),64,64,Rand(0,300),Rand(0,300),a,b)
		Next
		UnlockImage(imga)
		UnlockImage(imgb)
	End If

	t:+1	
	Cls

	DrawImage imga,MouseX(),MouseY()
	DrawImage imgb,600,MouseY()
	
	
	Local mem_alloced=MemAlloced(),mem_usage=MemUsage()
	DrawText "MemAlloced="+mem_alloced+" MemUsage="+mem_usage,0,0
	DrawText "FPS: "+RFPS,0,24
	DrawText "Hit SPACE to do 100 CopyRects()",0,48
	
	Flip
	FlushMem
Wend


Function CopyRect(srcX:Int, srcY:Int, srcW:Int, srcH:Int, dstX:Int, dstY:Int, s:TPixmap, d:TPixmap)
	If srcX > s.width Or srcY > s.height Return	' Source x,y within width/height?
	If dstX > d.width Or dstY > d.height Return	' Dest..........

	Local sBytes:Int
	Local dBytes:Int
	
	Select s.format
		Case PF_RGBA8888
			sBytes=4
		Case PF_BGRA8888
			sBytes=4
		Default
			sBytes=3
	End Select

	Select d.format
		Case PF_RGBA8888
			dBytes=4
		Case PF_BGRA8888
			dBytes=4
		Default
			dBytes=3
	End Select
		
	If sBytes<>dBytes Return	' don't even go there! :)

	Local srcP:Byte Ptr = s.pixels
	Local dstP:Byte Ptr = d.pixels

	' Clip?
	If (srcX + srcW) > s.width Then srcW = s.width - srcX
	If (srcY + srcH) > s.height Then srcY = s.height - srcY
	
	' Will source rect fit in dest image?
	If srcW > (d.width - dstX) Then srcW = d.width - dstX
	If srcH > (d.height - dstY) Then srcH = d.height - dstY

	For y=0 To srcH-1
		MemCopy(dstP + ((dstY+y) * d.pitch) + (dstX * dBytes), srcP + ((srcY+y) * s.pitch) + (srcX * sBytes),srcW * sBytes)
	Next
End Function



Function CheckFPS()
	If (MilliSecs()-lastsecs) <1000 Then 
		fps = fps +1
	Else
		lastsecs = MilliSecs()
		rfps = fps
		fps = 0
	EndIf
End Function



Tom