apply shadow mask to sprite ?

BlitzMax Forums/BlitzMax Beginners Area/apply shadow mask to sprite ?

Dax Trajero(Posted 2007) [#1]
What's the best way in blitz mask to apply a shadow mask to a spite ?

eg.
draw background
draw sprite
overlay shadow mask over sprite (and not background)


Dreamora(Posted 2007) [#2]
What is a shadow mask.

Just make it darker?

Draw the sprite with solid or masked blend mode and draw the shadow mask with shadeblend

if you mean a shadow: alphablend and correct color information in the image

Both needs TImage and won't work with pixmaps


ImaginaryHuman(Posted 2007) [#3]
Probably asking to draw a shadow beneath the sprite using the sprite's mask as the shape of it, but drawing it with something like ShadeBlend.

You could simply try drawing the sprite in shadeblend at an offset from the real sprite position then draw the real sprite normally on top of it. To use the sprite's mask is a whole other ball game for which you'll need to know how to write your own OpenGL/DX code.


Dax Trajero(Posted 2007) [#4]
sorry - to elaborate...

Think Speedball (late 80's game on the Amiga) - the background image shows an arena with walls on each side. Some of the walls project shadows, which I've drawn on the background image.

Whenever a sprite moves around the arena surface and passes close to a wall, it moves into this shadowed area.

I want to darken the sprite as it moves into this area.

Incidentally, when I had Blitz3D, I used drawImageRect when I want to draw a 32x32 area of a say an 800x600 image. What replaces this in BlitzMax ? I tried drawImageRect in BMax, but it doesn't seem to work the same?


tonyg(Posted 2007) [#5]
I want to darken the sprite as it moves into this area.


Draw the sprite, then draw the shadow with alphablend?
Incidentally, when I had Blitz3D, I used drawImageRect when I want to draw a 32x32 area of a say an 800x600 image. What replaces this in BlitzMax ? I tried drawImageRect in BMax, but it doesn't seem to work the same?


Do a search as there has been lots of discussion. There are about 4 implementations in the Code Archives, some easier than others, some quicker.


Dax Trajero(Posted 2007) [#6]
tonyg

when you say draw the sprite, then draw the shadow with alphablend - this is my current solution but here's why I don't like it...

when I do the last part of what you said - draw the shadow with alphablend, its also darkening the transparent area of the sprite

how do I draw the shadow onto the sprite so it doesn't darken the transparent area of the sprite ?


tonyg(Posted 2007) [#7]
Then you need to show some example code as that is wrong.
Graphics 800 , 600
Local image1:timage = LoadImage("max.png")
SetClsColor 0,0,255
While Not KeyHit(KEY_ESCAPE)
	Cls
	SetColor 255 , 255 , 255
	SetAlpha 1.0
	SetBlend maskblend
	DrawImage image1 , MouseX() , MouseY() 
        setcolor 255,0,0
	SetBlend alphablend
	SetAlpha 0.6
	DrawRect 100 , 100 , 100 , 100
	Flip
Wend



Dax Trajero(Posted 2007) [#8]
tonyg,

Thanks for the code, I'll test it and try and incorporate it.


Dax Trajero(Posted 2007) [#9]
tonyg

here's the code I was using (posted on this website by someone)

Function DrawImagePart(Image:TImage, DrawX#, DrawY#, PartX#, PartY#, PartWidth#, PartHeight#, Frame# = 0)

Local OldX:Int
Local OldY:Int
Local OldWidth:Int
Local OldHeight:Int

Local ViewportX:Int = DrawX
Local ViewportY:Int = DrawY

' Save current viewport settings
GetViewport(OldX, OldY, OldWidth, OldHeight)

' Calculate viewport coordinates based on image's handle
If Image.Handle_X Then
Local PercentX:Float
PercentX = Float(Image.Handle_X) / Float(Image.Width)
ViewportX = DrawX - (PercentX * PartWidth)
EndIf
If Image.Handle_Y Then
Local PercentY:Float
PercentY = Float(Image.Handle_Y) / Float(Image.Height)
ViewportY = DrawY - (PercentY * PartHeight)
EndIf

SetViewport(ViewportX, ViewportY, PartWidth, PartHeight)
DrawImage(Image, DrawX-PartX, DrawY-PartY, Frame)

' Restore old viewport settings
SetViewport(OldX, OldY, OldWidth, OldHeight)

End Function


tonyg(Posted 2007) [#10]
I don 't understand.
Is that code not working or something?
Is it related to the shadow question or a seperate topic on your drawimagerect query?
I did a search and there's a large number of results which might help plus this one which you opened.
Have a browse through those results and you should have as good an understanding of Bmax DrawImageRect possibilities as many of the people here.


Dax Trajero(Posted 2007) [#11]
Sorry, here's what i'm doing...

1) I'm using the above to draw my 32x32 sprite (from an 800x600 image)

2) I'm then using the same code to draw the 32x32 shadow (from an 800x600 image) "on top" of the sprite, alphablended to 0.75

The problem is , I only want the shadow to cover the sprite - not the transparent areas around the sprite as it currently is doing.

Imagine the sprite was 32x32 frame and was a ball shape. I only want the shadow to cover the ball and not transparent areas around the ball in the same 32x32 sprite frame.

I need some way to mask off the unused (eg. transparent) area of the 32x32 sprite frame so only the actual sprite is shaded.


Dreamora(Posted 2007) [#12]
If you only want to cover the sprite create a seperate shadow texture that does not have anything in the "transparent" area.

you can not selective disable stuff with blending unless you modify the texture information itself.


Dax Trajero(Posted 2007) [#13]
Ok, so you can't do some kind of logic operation, combining the sprite 32x32 and the shadow image 32x32 and only darken the sprite - leaving the sprites transparent area untouched ?

in theory all I need do is take the non-transparent pixels from the 32x32 sprite and use this to mask off the shadow texture

so this can't be done ?

"If you only want to cover the sprite create a seperate shadow texture that does not have anything in the "transparent" area." - I'd need to do this dynamically each frame


Dreamora(Posted 2007) [#14]
Yes and no

Not with max2d blend modes

Yes because I think there might be a combination in opengl src,dst settings for the blend that might work.

That or you have to make the shadow alpha 0 where it shall not have an effect.

Texture blending is no boolean filter nor can you normally do that operations, like you can do in graphic apps


Dax Trajero(Posted 2007) [#15]
ok

for now then, it leaves me with the only solution of drawing the 800x800 background, drawing the 4 32x32 sprites, then drawing the 800x600 shadow image over the top of everything.

It works perfectly, but I was worried about the performance hit of needlessly drawing the whole 800x600 shadow image.

Oh well, I'll come back to it when my game is finished and see if I can optimise it somehow.

Thanks all


Dax Trajero(Posted 2007) [#16]
Incidentally, why did BlitzMax neglect / change the drawImageRect command ?

Surely its a commonly used command to draw individual sprites from a larger strip of sprite frames ?! I can't understand why they'd change it ?


Dreamora(Posted 2007) [#17]
no idea, thats why there are drawimagearea commands and the like to get the old functionality back