Fill an area with an image
BlitzMax Forums/BlitzMax Programming/Fill an area with an image
| ||
I want to fill an area of any position, width and height, with a repeated, tiled image. How is this possible? I've been told to avoid SetViewport because it doesn't work on some cards. Is this true? |
| ||
Yes it's true I've seen it with my own eyes.' ----------------------------------------------------------------------------- ' ccDrawImageArea: Draws part of an image. ' (by Ian Duff) ' ----------------------------------------------------------------------------- Function ccDrawImageArea(image:TImage, x#, y#, rx#, ry#, rw#, rh#, theframe=0) 'Note that this code works fine in DirectX or OpenGL on PCs - it autodetects (Grey Alien). 'Warning: make sure that none of your images have pixels right on the edge otherwise 'when drawing clipped, they may leave smear in the clipped area! (Grey Alien). Local origin_x#, origin_y# ; GetOrigin (origin_x, origin_y) Local tw = ccDrawImageAreaPow2Size(image.width) Local th = ccDrawImageAreaPow2Size(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)) 'Protect against frameA being null due to alt+tab. (Grey Alien) If frameA<>Null Then 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) EndIf ?Win32 EndIf ? Function ccDrawImageAreaPow2Size%(n) Local ry = 1 While ry < n ry :* 2 Wend Return ry End Function End Function Calc how many whole tiles you can fit and draw them, then use the above code for the partial rects. The above code doesn't work with rotated textures. |
| ||
...Or... Enable texture repeat and draw a textured poly with its UVs set accordingly. |
| ||
Enable texture repeat and draw a textured poly with its UVs set accordingly. ...how do I do that, then? |
| ||
You'll need DX and OpenGL API calls for that (probably). I've no idea how, never delved into it that far. The expert techies round here seem to always deliver the goods ;-) |
| ||
|
| ||
Hotness! Looks like this works with rotated textures too yes? Now GfK, you better say thanks. ;-) |
| ||
You can rotate the poly using Max2D's normal transformation commands. If you wanted to rotate the 'tiles', you'd need to manually rotate the poly's UVs. |
| ||
I tried something like that before with the code I posted at the top but it just wasn't working how I expected. I wanted to rotate the original texture, capture a small part of it in a vertical rectangle (so effectively the rotation was clipped to a rectangle) and then draw it on-screen. It was turdish. |
| ||
Hey not sure when this was posted, but does Yan's example still work for everyone? The SetTextureRepeat function kicks up a fuss on this line glBindTexture GL_TEXTURE_2D, TGLImageFrame(image.Frame(0)).name Unhandled Exception: Attempt to access field or method of Null object |
| ||
The OpenGL driver used to be the default on Windows. Now you must explicitly enable it. That's the commented out line at the start of the code. |
| ||
Got ya, thanks :) |