Scrolling Image ...Slow...
BlitzMax Forums/BlitzMax Programming/Scrolling Image ...Slow...
| ||
| Hi guys, I'm trying to write a function that will wrap an image (scroll it in one direction and wrap it around to the other side). I've got this: Function WrapImage(img:TImage, frame = 0, stepsize = 20, dir = 1) Local w:Int = img.Width Local h:Int = img.Height Local tStep:TImage Local tOther:Timage Cls DrawImage img,0,0,0 Select dir Case 1 'Left to Right tStep = CreateImage(stepsize,h) tOther = CreateImage(w - stepsize,h) GrabImage(tStep,w - stepsize,0) GrabImage(tOther,0,0) Cls DrawImage tStep,0,0 DrawImage tOther,stepsize,0 GrabImage(img,0,0) End Select End Function But it's slow as molasses in January. Is there a way to speed this code up? |
| ||
| That's because GrabImage is very slow and you even use it three times. I think you should try to modify the texture's u and v-coords. |
| ||
| why you just dont draw it offscreen? ie. drawimage img, -10, 0 drawimage img, -10+imagewidth, 0 of course it's not the same as in your example, but if you scroll full screen width it should no matter :) |
| ||
| I suppose there's no equivalent to the "CopyRect" command in BMax is there. Modify the texture's u/v coords you say? I'll check into that. Thanks! |
| ||
| There's some code which will emulate the old drawimagerect function (either using UV or setviewport). You might be able to display the image twice, once from point 0,0 in the image and the other 0+xchange,0+ychange but it's fiddly. |
| ||
| I would draw the image twice, side by side and scroll both in the direction you want, then once the first image has completely left the screen simply move it back the full width of the screen. This is a variation of the coarse scroll used in Atari's days. IPete2. |
| ||
| Yeah, sounds better than modifying u/v-coords *g* You should take a look at SetViewport as tonyg said. |
| ||
| I like your idea IPete2. However, I just wrote this little ditty. Kind of like the early stages of a tile mapping object or something:
Strict
Type TTiledImage
Field StepSize = 10
Field ColumnCount:Int
Field RowCount:Int
Field Tiles:TImage[]
Field Direction:Int
Field WinWidth:Int
Field WinHeight:Int
Field GetImageCallback(tw:TTiledImage)
'Create from image
Method FromFIle:Int(url:Object,StepSize = 10)
Local temp:TImage = LoadImage(url)
If ImageWidth(temp) Mod StepSize = 0 and ImageHeight(temp) Mod StepSize = 0 Then
RowCount = ImageHeight(temp) / StepSize
ColumnCount = ImageWidth(temp) / StepSize
WinWidth = ColumnCount
WinHeight = RowCount
Tiles = New TImage[ColumnCount * RowCount]
Cls
DrawImage temp,0,0
For Local r:Int = 0 To RowCount - 1
For Local c:Int = 0 To ColumnCount - 1
Local tt:TImage = CreateImage(StepSize,StepSize)
GrabImage(tt,c * StepSize,r * StepSize)
Tiles[c + r * ColumnCount] = tt
If GetImageCallback <> Null Then GetImageCallback(Self)
Next
Next
Cls
Return True
Else
RuntimeError ("Step size must divide evenly into image width and height.")
End If
End Method
Method Render(posX:Int, posY:Int,oX:Int, oY:Int, w:Int = -1, h:Int = -1)
Local c:Int = ColumnCount - oX
Local r:Int = RowCount - oY
If w <> -1 Then WinWidth = w
If h <> -1 Then WinHeight = h
For Local ir:Int = 0 To WinHeight - 1
For Local ic:Int = 0 To WinWidth - 1
If c = ColumnCount Then c = 0
If r = RowCount Then r = 0
DrawImage Tiles[c + r * ColumnCount],posX + ic * StepSize, posY + ir * StepSize
c:+ 1
Next
c = ColumnCount - oX
r:+ 1
Next
End Method
End Type
'Test Code
Graphics 640,480,0
Local map:TTiledImage = New TTiledImage
map.FromFIle("Panda-Kiss.jpg")
Local ox:Int = 0
Local oy:Int = 0
While not KeyHit(KEY_ESCAPE)
Cls
map.Render(10,10,ox,oy)
'ox:+ 1; oy:+ 1
If KeyDown(KEY_UP) Then oy:-1
If KeyDown(KEY_DOWN) Then oy:+1
If KeyDown(KEY_LEFT) Then ox:-1
If KeyDown(KEY_RIGHT) Then ox:+1
If ox = map.ColumnCount Then ox = 0
If ox < 0 Then ox = map.ColumnCount - 1
If oy = map.RowCount Then oy = 0
If oy < 0 Then oy = map.RowCount - 1
Flip
'Delay 1000
Wend
Try it with this photo: |