I have written a little test app, and it seems to work fine. Only one small mistake. If the Viewport starts at (100,100) and I draw the image at (120,120) the lase pixel row and colum (above and left from the image) will be repeated.
Here's the code. You can hold down "Q" to swap between BlitzMax SetViewport and the overwritten SetViewport-Command
SuperStrict
Graphics 640,480,0
'Viewport coords
Global vx:Float, vy:Float, vw:Float, vh:Float
Local t:TImage = LoadImage ("gfx/mainmenu.png")
Local a:Int = 0
While(Not KeyDown(KEY_ESCAPE))
a:+1
Cls
If KeyDown(KEY_Q)
SetViewportC 200+(Sin(a)*100),200+(Cos(a)*100),100,100
DrawImageC t,210,210
Else
SetViewport 200+(Sin(a)*100),200+(Cos(a)*100),100,100
DrawImage t,210,210
SetViewport 0,0,640,480
End If
Flip
Wend
Function SetViewportC( x:Float, y:Float, width:Float, height:Float )
vx = x
vy = y
vw = width
vh = height
End Function
Function DrawImageC(image:TImage, x:Float, y:Float, frame:Int=0)
'Calculate new coords, I don't know how to calculate them
Local rx:Float = vx
Local ry:Float = vy
Local rw:Float = vw
Local rh:Float = vh
rx:-x
ry:-y
x = vx
y = vy
ccDrawImageArea(image,x,y,rx,ry,rw,rh,frame)
End Function
Function ccDrawImageArea(image:TImage, x#, y#, rx#, ry#, rw#, rh#, frame:Int=0)
Local origin_x#, origin_y# ; GetOrigin (origin_x, origin_y)
Local tw:Int = Pow2Size(image.width)
Local th:Int = Pow2Size(image.height)
Local rw1# = rx + rw
Local rh1# = ry + rh
Local x0# = -image.handle_x, x1# = x0 + rw
Local y0# = -image.handle_y, y1# = y0 + rh
If rw1 > image.width
x1 = x0 + rw + image.width - rw1
rw1 = image.width
EndIf
If rh1 > image.height
y1 = y0 + rh + image.height - rh1
rh1 = image.height
EndIf
?Win32
If TD3D7ImageFrame(image.frame(frame))
Local frame:TD3D7ImageFrame = TD3D7ImageFrame(image.frame(frame))
frame.setUV(rx / tw, ry / th, rw1 / tw, rh1 / th)
frame.Draw x0, y0, x1, y1, x + origin_x, y + origin_y
frame.setUV(0, 0, image.width / Float(tw), image.height / Float(th))
Else
?
Local frame:TGLImageFrame = TGLImageFrame (image.frame(frame))
frame.u0 = rx / tw
frame.v0 = ry / th
frame.u1 = rw1 / tw
frame.v1 = rh1 / th
frame.Draw x0, y0, x1, y1, x + origin_x, y + origin_y
frame.u0 = 0
frame.v0 = 0
frame.u1 = image.width / Float(tw)
frame.v1 = image.height / Float(th)
?Win32
EndIf
?
Function Pow2Size:Int(n:Int)
Local ry:Int = 1
While ry:Int < n
ry :* 2
Wend
Return ry
End Function
End Function