Image alpha masking / clipping composting?

Monkey Forums/Monkey Programming/Image alpha masking / clipping composting?

Soap(Posted 2012) [#1]
We really need something like this for a project. The alternative is to greatly increase the file size.

This image illustrates what I need to be able to do:

Take two images. Draw one image so that its own alpha is composited with another image in the region of where it is being drawn compared to the second image (the clipmap) to make the first image less visible depending on what the alpha is where it is being clipped.


CopperCircle(Posted 2012) [#2]
Have a look at this post, shows how to do it:

http://www.monkeycoder.co.nz/Community/posts.php?topic=3495#37194


NoOdle(Posted 2012) [#3]
CopperCircle beat me to it. The worms code I posted can be used to do this. Additionally you could store the images as data and load them, saving the need to render to screen and grab using readpixels.


Soap(Posted 2012) [#4]
What about real time? We are making some tests and seeing what can be usable.

What we really need for mojo is something like this: http://www.opengl.org/wiki/Stencil_Mask


Soap(Posted 2012) [#5]
[monkeycode]
Strict
Import mojo

Function Main : Int()
New MyApp()
Return 0
End Function

Class MyApp Extends App


Method OnCreate : int()
SetUpdateRate( 60 )
Return 0
End Method



Method OnUpdate:Int()

Return 0
End Method

Method OnRender : Int()

Return 0
End Method

End Class


Function CreateCustomImages : Void()

'// Create space for tool
Local w : Int = tool.Width()
Local h : Int = tool.Height()
Local pixels : Int[ w * h ]
Local img : Image

Cls 128, 0, 255

'// Grab tool sprite and mask background colour
DrawImage tool, 0, 0
ReadPixels( pixels, 0, 0, w, h )
PixelArrayMask( pixels, 128, 0, 255 )
img = CreateImage( w, h, 1, Image.MidHandle )
img.WritePixels( pixels, 0, 0, w, h )
tool = img
toolPixels = pixels

'// Create space for ground
w = Min( ground.Width(), DeviceWidth() )
h = Min( ground.Height(), DeviceHeight() )
pixels = New Int[ w * h ]

Cls 128, 0, 255

'// Grab ground sprite and mask background colour
DrawImage ground, 0, 0
ReadPixels( pixels, 0, 0, w, h )
PixelArrayMask( pixels, 128, 0, 255 )
img = CreateImage( w, h )
img.WritePixels( pixels, 0, 0, w, h )
ground = img
groundPixels = pixels

End Function




Global CurrentMask:Image 'Reference to the last mask used, useful for preventing
Global Mask:Int[] 'Mask's pixels
Global MaskX:Float, MaskY:Float 'Mask's location
Global MaskActive:Bool = True


'// Converts Mask Pixel Color to Transparent Pixel
Function PixelArrayMask:Void(pixels:Int[], mask_r:Int = 0, mask_g:Int = 0, mask_b:Int = 0 )
For Local i : Int = 0 Until pixels.Length
Local argb : Int = pixels[ i ]
Local a : Int = ( argb Shr 24 ) & $ff
Local r : Int = ( argb Shr 16 ) & $ff
Local g : Int = ( argb Shr 8 ) & $ff
Local b : Int = argb & $ff
If a = 255 And r = mask_r And g = mask_g And b = mask_b
a = 0
argb = ( a Shl 24 ) | ( r Shl 16 ) | ( g Shl 8 ) | b
pixels[ i ] = argb
Endif
Next
End Function


'Sets the global mask location
Function SetMask:Void(img:Image, x:Float, y:Float)
CurrentMask = img ; MaskX = x; MaskY = y
End Function

Function SetMask:Void(OnOff:Bool)
MaskActive = OnOff
End Function

Function DrawImageMasked:Void(image:Image, x:Float, y:Float)
If MaskActive
'First, determine the rect area we need to blit. It's the intersection of the mask and the image.

'Now, pull the pixels from the source image.

'Run the source pixels through the alpha mask function to mask them.

'Finally, blit the result pixels to the screen.

End If
End Function

[/monkeycode]

What we have so far but can't get it to work. Help?

A mojo polygon scissor would be a good enough compromise for our needs.


zoqfotpik(Posted 2013) [#6]
Bumping this.

I would like to have copper effects running inside of defined areas on a bitmap. For my purposes there are a number of ways I could fake it including just drawing a rectangular copper field and then rendering a bitmap in front of that with a transparent area cut out of a black rectangle that fully covers the copper field. But I'd really like to see image scissoring.

There are probably oodles of other things more important than this. Which is probably why it hasn't been added.

One other thing I may do is set up my own low-res pixmap and write color cycling and masking functions for that, then upres it-- this is just for a title screen and doesn't even need to run that fast though the copper cycling should be smooth.

For those who do not know (ie those born in the last 30 years) copper was a color cycling effect used on Atari STs, Amigas, Commodore 64s and other machines of that vintage to deliver snazzy color effects on extremely substandard hardware.

http://www.youtube.com/watch?v=5CUUOlYxlZ8

http://en.wikipedia.org/wiki/Raster_bar

This is a very cool sort of effect and since I am writing retro games it would be nice to include-- but it really requires bitmap masking to work and it's looking like that will require some sort of custom routine. It should be possible to write a pixelwise search and replace in 320x200 to upscale...