Sprite used as mask

BlitzMax Forums/BlitzMax Beginners Area/Sprite used as mask

Is there some way to use a sprite as a mask for
another sprite?. So for example if a sprite inside
this mask sprite goes out of the mask sprite shape
then its not drawn, or viceversa, something like viewport
but instead of beign a box it can be a custom shape.
Posbile or not posible?.

Oh, I'd love to find out, too! :}

there are no native bmax commands but you can do it low level through stencil buffers.


or, depending on what you are doing you could fake it by depth, but I can't think of a way to fake it without masking a whole rectangle.

-cls
-setviewport to the imagerect
-draw the items to be masked
-draw the mask


shadeblend can be used to create/draw the mask of a positive graphic

I believe you can do it at GL/DX level using either single-pass or multi-pass multitexturing.

You mean for cookie cutter effects?

I'm pretty sure with DX multitexture you can take the texture from one and the 'shape' of another.
Having said that, I re-read the original post and don't think I understand what is being asked.
My guess is there might be an easy answer if the question was understood.
e.g. Non-rectangle viewport can be a rectangular viewport + overlay image Would that be enough?

One way to do it would be to draw the image you want masked onto a newly cleared screen, draw the mask over it, then use GrabImage() to grab the masked portion. Then you draw that image over whatever background you want. Like this:
Move the masked smiley face with the mouse, move the portion which is masked with the cursor keys.
SuperStrict

Graphics 800,600

AutoMidHandle True

'create the smiley face image
Cls
SetColor 255,255,0
DrawOval 0,0,100,100
SetColor 0,0,0
DrawOval 23,23,20,20
DrawOval 56,23,20,20
DrawRect 33,66,33,20
Local Smiley:TImage = CreateImage(100,100)
GrabImage(Smiley,0,0)

'create the sprite mask
Local mask:TImage = CreateImage(200,200)
Cls

Local Pixmap:TPixmap = LockImage(mask)
For Local x:Int = -100 To 99
	For Local y:Int = -100 To 99
		If (x*x+y*y) > 900
			WritePixel(Pixmap,x+100,y+100,$FF000000) 'black pixel with alpha = 1.0
		Else
			WritePixel(Pixmap,x+100,y+100,$00000000) 'black pixel with alpha = 0.0
		End If
	Next
Next

SetMaskColor 0,0,0 'mask color is black by default
Local MaskedSmiley:TImage = CreateImage(100,100,1,DYNAMICIMAGE|MASKEDIMAGE) 'MASKEIMAGE flag will set alpha to 0 for any black pixels

Local MaskOffsetX:Int = 0 'the mask offset from the smileyface
Local MaskOffsetY:Int = 0

SetBlend AlphaBlend 'using alpha blend mode
While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
	Cls
	DrawImage Smiley,50,50 'draw the smileyface
	DrawImage mask,MaskOffsetX+50,MaskOffsetY+50 'draw the mask over the smileyface
	GrabImage (MaskedSmiley,0,0) 'grab the now masked smileyface
	SeedRnd(1) 'Make sure random background is drawn same every frame
	
	Cls
	For Local i:Int = 1 To 20 'drawing some random shapes
		SetColor Rand(0,255),Rand(0,255),Rand(0,255) 'random color
		DrawOval Rand(0,800),Rand(0,600),Rand(10,100),Rand(10,100) 'random ovals
	Next
	SetColor 255,255,255 'set the color back to white
	
	Local MX:Int = MouseX()
	Local MY:Int = MouseY() 'get the mouse coordinates
	
	DrawImage maskedSmiley,MX,MY 'draw the image on the screen
	Flip
	
	If KeyDown(KEY_LEFT) Then MaskOffsetX :- 1 'move mask left
	If KeyDown(KEY_RIGHT) Then MaskOffsetX :+ 1 'move mask right
	If KeyDown(KEY_UP) Then MaskOffsetY :- 1 'Move mask up
	If KeyDown(KEY_DOWN) Then MaskOffsetY :+ 1 'Move mask down
	If MaskOffsetX > 50 Then MaskOffsetX = 50 'Limit the movement of the mask
	If MaskOffsetX < -50 Then MaskOffsetX = -50
	If MaskOffsetY > 50 Then MaskOffsetY = 50
	If MaskOffsetY < -50 Then MaskOffsetY = -50
	
	

Wend



Thanks a lot for that piece of code TomToad, and
thanks everyone else for the help also, your code
gave me a different idea.

First do a pixmapwindow() on the image i want
masked, this will result in an effect like viewport,
it will be masked just with a rectangle.

Then i do like you did on your code but just inside
a small portion of the screen, because otherwise
i would need to alter my sprite management code
wich is not posible.
So, before i draw my masked image i take picture
of the area i want to draw to, lets say a 50x50 pixels
rectangle, then i fill that same area with black, then
i draw my pixmap on that area, and then i draw my
static mask on there, then i call grabimage, and then
i redraw the picture i took before, and at last i draw
my sprite with custom mask shape :D

I fear that it will mess with the alpha thought, i didnt test
this yet but i will tomorrow, thanks again.