copy x,y,w,h of an image to the backbuffer ?

BlitzMax Forums/BlitzMax Beginners Area/copy x,y,w,h of an image to the backbuffer ?

Dax Trajero(Posted 2006) [#1]
can someone tell me which command to use that will copy a selected area x,y,w,h of a loaded image to x,y of the screen ?

When I briefly used Blitz3D, I used DrawIMageRect, but when I use it in BMax, its not working correctly (its copying the WHOLE image instead of x,y,w,h of the image) and scaling it down


Grey Alien(Posted 2006) [#2]
' -----------------------------------------------------------------------------
' ccDrawImageArea by Ian Duff (faster?)
' -----------------------------------------------------------------------------
' Note that this code works fine in DirectX or OpenGL on PCs - it autodetects (JB).
Function ccDrawImageArea(image:TImage, x#, y#, rx#, ry#, rw#, rh#, theframe=0)
Local origin_x#, origin_y# ; GetOrigin (origin_x, origin_y)
Local tw = Pow2Size(image.width)
Local th = 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(theframe))
Local frame:TD3D7ImageFrame = TD3D7ImageFrame(image.frame(theframe))

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 frameA:TGLImageFrame = TGLImageFrame (image.frame(theframe))

frameA.u0 = rx / tw
frameA.v0 = ry / th
frameA.u1 = rw1 / tw
frameA.v1 = rh1 / th

frameA.Draw x0, y0, x1, y1, x + origin_x, y + origin_y

frameA.u0 = 0
frameA.v0 = 0
frameA.u1 = image.width / Float(tw)
frameA.v1 = image.height / Float(th)
?Win32
EndIf
?

Function Pow2Size(n)
Local ry = 1

While ry < n
ry :* 2
Wend

Return ry
End Function
End Function




Dax Trajero(Posted 2006) [#3]
cheers

I see DrawImageRect isn't the same command as it was in B3D, s o I couldn't use that.

I'm wondering now, whether to use your function above for each of my 32x32 sprites, or do just a single drawimage, which will overlay all my sprites in one go

do you think I'd pay a big performance hit on a 800x600 screen if I did the latter ?


Grey Alien(Posted 2006) [#4]
Soryry, I'm not sure what you mean by "overlay all my sprites in one go".


Dax Trajero(Posted 2006) [#5]
sorry, here's an explanation

1. I draw a background image, 800x600
2. I draw 4no. sprites, each 32x32 incl alpha
3. I draw a foreground image, 800x600 incl alpha

or

3. I use your code, DrawImageArea on each of the sprites to draw a 32x32 section of the foreground image on each of the sprites

so, to recap, I'm just wondering if there's much of a saving using your code to draw 4no, 32x32 blocks, instead of just using DrawImage to draw a single 800x600 foreground image instead?


bregors(Posted 2006) [#6]
.


Grey Alien(Posted 2006) [#7]
I would have said there will be a saving using the image rect code becasue you are only drawing 4096 pixels instead o 480,000! However, as the 3D card is handling the drawing the saving isn't as much as it would have been in the old days when the CPU was doing the work.


Dax Trajero(Posted 2006) [#8]
Grey, can you explain your code, above...

?Win32

also there seems to be a function inside a function, which I've never seen before ?


JazzieB(Posted 2006) [#9]
The code between the ?win32 and the next ? is only compiled on a PC, as only a PC will have DirectX, but could also be using OpenGL. If the above were compiled on a Mac or under Linux then all the DirectX code would be ignored.

The above code uses some low level API calls/accessing to achieve it's rect copying, so needs to know which graphics API is in use (on a PC).

I can't help you with an explanation of the rest of the code, but maybe Grey can, although I don't think the code is his (could be wrong though).

The ? commands are known as compiler directives and instruct the compiler whether to compile certain chunks of code or not. This can be done on platform (Windows, Mac or Linux), processor (PowerPC, x86) or whether the program is being compiled in debug or not. They can be quite useful, especially when you want your games to work across mulitple platforms.


Grey Alien(Posted 2006) [#10]
Yeah the code isn't mine, someone posted it for me once and I kept a copy for use. JazzieB is correct about ?win32

Functions within functions are very useful in certain circumstances. You can't call it from anywhere else except from within the function it's declared in.