need to rotate a pixmap with smooth filtering

BlitzMax Forums/BlitzMax Programming/need to rotate a pixmap with smooth filtering

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Here is the BlitzMax version of the rotozoomer demo. However, it is not working right. I get what seems to be different colors in X but in Y the same color is repeated down the screen. I cannot figure out where the bug is. Can anyone help?

OEJ: Should be easy enough to adapt this to what you want, once it's working, it handles alphablending, rotation, zoom, a background image, and the rotation angle can be a Float.

Anyone see the bug? (My images are just 640x480 images) I am quite certain it has nothing to do with the alphablending. Even with bare minimum of two lines - WritePixel(ReadPixel()) it is still wrong.

'Software rotation demo

Strict
SetGraphicsDriver(GLMax2DDriver())
Graphics 640,480,0

'Prepare pixmaps
Local BackgroundPixmap:TPixmap=LoadPixmap("Background.jpg")
If PixmapFormat(BackgroundPixmap)<>PF_RGBA8888 Then BackgroundPixmap=ConvertPixmap(BackgroundPixmap,PF_RGBA8888)
Local SourcePixmap:TPixmap=LoadPixmap("RotoZoom.jpg")
If PixmapFormat(SourcePixmap)<>PF_RGBA8888 Then SourcePixmap=ConvertPixmap(SourcePixmap,PF_RGBA8888)
Local DestPixmap:TPixmap=CreatePixmap(640,480,PF_RGBA8888,4)
Local SourcePixelsPerRow=PixmapWidth(SourcePixmap)
Local DestPixelsPerRow=PixmapWidth(DestPixmap)
Local OpWidth:Int=128'PixmapWidth(SourcePixmap) 'Width of operation
Local OpHeight:Int=128'PixmapHeight(SourcePixmap) 'Height of operation
Local OpWidth2:Int=OpWidth/2
Local OpHeight2:Int=OpHeight/2
Local XCenter:Int'=OpWidth/2
Local YCenter:Int'=OpHeight/2

'Dummy alpha values
For Local aa:Int=0 To OpHeight-1
	For Local bb:Int=0 To OpWidth-1
		WritePixel(SourcePixmap,bb,aa,ReadPixel(SourcePixmap,bb,aa)+Max(aa+bb,256)) 'Make alpha to see effect if image doesn't have one
	Next
Next

'Set up variables
Local Angle:Float=0
Local Magnification:Float=1.0
Local Y_UAdd,Y_VAdd,X_UAdd,X_VAdd:Float
Local Y_U,Y_V,X_U,X_V:Float
Local SourceBase:Int Ptr=Int Ptr(PixmapPixelPtr(SourcePixmap,0,0))
Local DestBase:Int Ptr=Int Ptr(PixmapPixelPtr(DestPixmap,0,0))
Local SourcePixel,DestPixel:Int
Local Red,Green,Blue:Int
Local Alpha:Float

'Demo
Repeat
	'Interaction/autorotate
	If MouseDown(1) Then Magnification:+0.01
	If MouseDown(2) Then Magnification:-0.01
	Angle:+1
	If Angle>=360 Then Angle:-360
	If Angle<0 Then Angle:+360

	'Setup
	Y_UAdd=Cos(Angle+90)*Magnification
	Y_VAdd=Sin(Angle+90)*Magnification
	X_UAdd=Cos(Angle)*Magnification
	X_VAdd=Sin(Angle)*Magnification
	XCenter=MouseX()
	YCenter=MouseY()
	Y_U=-(Y_UAdd*OpHeight2)-(X_UAdd*OpWidth2)
	Y_V=-(Y_VAdd*OpHeight2)-(X_VAdd*OpWidth2)
	
	'Draw it
	DestPixmap.Paste(BackgroundPixmap,0,0) 'Draw background
	For Local Y:Int=0 To OpHeight-1
		X_U=Y_U
		X_V=Y_V
		For Local X:Int=0 To OpWidth-1
			SourcePixel=Int Ptr(SourceBase + Min(Max(0,XCenter+X_U),OpWidth) + ((Min(Max(0,YCenter+X_V),OpHeight) * SourcePixelsPerRow)))[0] 'Read full pixel, clipped
			'SourcePixel=ReadPixel(SourcePixmap,XCenter+X_U,YCenter+X_V)
			Alpha=(SourcePixel Shr 24)/256.0
			Red=((SourcePixel Shl 8) Shr 24) * Alpha
			Green=((SourcePixel Shl 16) Shr 24) * Alpha
			Blue=(SourcePixel & $FF) * Alpha
			Alpha=1.0-Alpha
			DestPixel=(DestBase+X+(Y*OpWidth))[0] 'Read full pixel, clipped
			'DestPixel=ReadPixel(DestPixmap,X,Y)
			Red:+(((DestPixel Shl 8) Shr 24) * Alpha)
			Green:+(((DestPixel Shl 16) Shr 24) * Alpha)
			Blue:+((DestPixel & $FF) * Alpha)
			(DestBase+X+(Y*DestPixelsPerRow))[0]=(Red Shl 24) | (Green Shl 16) | (Blue Shl 8) 'Plot RGBA
			'WritePixel(DestPixmap,X,Y,(Red Shl 24)|(Green Shl 16)|(Blue Shl 8)) 'Write RGBA
			'WritePixel DestPixmap,X,Y,SourcePixel
			X_U:+X_UAdd
			X_V:+X_VAdd
		Next
		Y_U:+Y_UAdd
		Y_V:+Y_VAdd
	Next
	DrawPixmap DestPixmap,0,0
	Flip 1
Until KeyHit(KEY_ESCAPE)