Transparent app's background

Find quick help here to get you started with Hollywood
Ferin
Posts: 18
Joined: Fri May 26, 2017 12:41 am

Transparent app's background

Post by Ferin »

Hi chaps and dames,
Is it possible to make window of an app's fully transparent? Lets say i want to make clock app that shape isn't rectangular,
if i make my clock's dial circular i'll get nastily looking corners. Any chance there is a proper Hollywood's way of doing it,
i even don't mind using some dirty tricks, if there are any ;p.
Thanks.
User avatar
airsoftsoftwair
Posts: 5425
Joined: Fri Feb 12, 2010 2:33 pm
Location: Germany
Contact:

Re: Transparent app's background

Post by airsoftsoftwair »

Not sure I understand this question but why do you say you get "nastily looking corners" when using circular-shaped window? Using alpha channel transparency your windows can have any shape you like and there should be no nastily looking corners or there's something wrong. Have you checked out the AlphaApple example that is shipped with Hollywood?
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Transparent app's background

Post by jPV »

Ferin wrote:Is it possible to make window of an app's fully transparent? Lets say i want to make clock app that shape isn't rectangular,
if i make my clock's dial circular i'll get nastily looking corners. Any chance there is a proper Hollywood's way of doing it,
i even don't mind using some dirty tricks, if there are any ;p.
If you mean by "nastily looking corners" the OS window borders, those can be hidden by using "Borderless" window.

Or if you get black background instead of transparent area on "corners" around the circular clock image, then you are running the program on a screen which doesn't support alpha transparency. For example, on Amiga compatible systems you need to have 32bit screen with compositing mode turned on. I have no idea about other platforms though... but if this is your problem, you can do some kind of dirty software hack to get it look transparent.

Here's one example for the latter case:

Code: Select all

@DISPLAY {Hidden = True, Borderless = True}
@BRUSH 1, "ram:analogclockbg.png", {LoadAlpha=True}

EscapeQuit(True)

; The display should be transparent and drawn by hardware, if you have alpha transparent bgimage
; and run it on a suitable screen mode (32bit and hw accelerated).
; If you move the window or other windows beneath it, everything should update automatically.
BrushToBGPic(1,1)
DisplayBGPic(1, {X = #KEEPPOSITION, Y = #KEEPPOSITION})
OpenDisplay(1)

WaitLeftMouse

; Let's do the transparency with a software rendering hack instead:

; Let's grab the underlying area of the screen by hiding our window first.
HideDisplay()
Wait(10)
GrabDesktop(2,{X=GetAttribute(#DISPLAY,0,#ATTRXPOS) ,Y=GetAttribute(#DISPLAY,0,#ATTRYPOS) ,Width=GetAttribute(#DISPLAY,0,#ATTRWIDTH) ,Height=GetAttribute(#DISPLAY,0,#ATTRHEIGHT)})
; ...and draw our own graphics over it
SelectBrush(2, #SELMODE_COMBO, 2)
DisplayBrush(1,0,0)
EndSelect()
; ...and then use the resulting image as a new bgpic
BrushToBGPic(2,1)
DisplayBGPic(1, {X = #KEEPPOSITION, Y = #KEEPPOSITION})
; Now we can bring the window visible again. Note that transparent areas in this bgpic won't update automatically,
; and you might want to check if window has moved/resized and draw it again then etc.
ShowDisplay()

WaitLeftMouse
Ferin
Posts: 18
Joined: Fri May 26, 2017 12:41 am

Re: Transparent app's background

Post by Ferin »

My apologies for long delay and not being more specific in asking questions.

Generally speaking, I was wondering if i can make background of my app 100% transparent when running it on WB's screen.
jPV answered already, and it works well, thanks a lot, but i have more questions.

Here we go:
Example with brush with transparent regions works when we load bg picture,what in case i want to display just some text,
lets say with TextOut(), is there anyway to make background 100% transparent and dipslay text only without any bg picture?
For example i want to make digital clock, window size will be 200x200 pixels, i want to make it fully transparent, so
it looks like digits of the clock sit on WB backdrop or menu top bar. As i understand to get that effect user gonna need to
switch composition on. But how it's going to look in Morphos and AROS, or even windows, macosx?

Next case, i want to make some kind of glow effect around object, text or/and brush, that blends nicely in WB's screen.
How to achieve that, is it possible at all?
Apart from that setting bg picture determines the dimensions of our app's window, even if i set width and height attributes
of DISPLAY function, is there anyway of overriding that 'feature' without resizing background picture and still have transparent
area beyond pictures bondaries? To be precise, i have 100X100 background and want my window to be 200x200. Background's
picture has an irregular shape with transparent pixels around it and i need 50 pixels transparent 'frame' around it.
I hope i've expressed my needs more precise ths time.

Regarding software hack version. Would it work on AOS3.x with Planamarama plugin?
And how to make it 'flush' background every set amount of time in most efficient way?
I mean how often should i clear background and what functions/loops use for it.

Thank you very much for you help so far and ask for more ; ).
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Transparent app's background

Post by jPV »

Ferin wrote:Example with brush with transparent regions works when we load bg picture,what in case i want to display just some text,
lets say with TextOut(), is there anyway to make background 100% transparent and dipslay text only without any bg picture?
I haven't found a way to render something directly over transparent bgpic, but you can first create an alpha transparent brush and then draw the text into the brush (SelectBrush with a suitable combo mode), and then use that brush as a new bgpic (BrushToBGPic). Then you can have your text or other graphics over a transparent display.

For example i want to make digital clock, window size will be 200x200 pixels, i want to make it fully transparent, so
it looks like digits of the clock sit on WB backdrop or menu top bar. As i understand to get that effect user gonna need to
switch composition on. But how it's going to look in Morphos and AROS, or even windows, macosx?
Actually, I think that constantly updating program (clock) is harder to make with hardware compositing mode, because if you do it like I said above (BrushToBGPic), you are likely to see glitches when the bgpic gets changed. So it doesn't look good when updated once per second or not even once per minute.

But if you use software rendering hack mentioned in previous posts, then you can have screengrab as the bgpic and draw other things over it normally. I think that would work well, but the downside is of course if you want to move the window, it will need manual re-drawing then.

Next case, i want to make some kind of glow effect around object, text or/and brush, that blends nicely in WB's screen.
How to achieve that, is it possible at all?
Apart from that setting bg picture determines the dimensions of our app's window, even if i set width and height attributes
of DISPLAY function, is there anyway of overriding that 'feature' without resizing background picture and still have transparent
area beyond pictures bondaries? To be precise, i have 100X100 background and want my window to be 200x200. Background's
picture has an irregular shape with transparent pixels around it and i need 50 pixels transparent 'frame' around it.
That's easy with the previously mentioned ways. Create a brush with size 200x200 (make it transparent or use screengrab depending if doing hw or sw rendering), render your own 100x100 background with glow effects you want in the middle of it, and use the result as a new bgpic.

I've used this method in my RNOWidgets program when creating automatic drop shadows for widgets. If you have access to a MorphOS machine, have a test run with it. You can enable/disable compositing mode and enable/disable dropshadows from the settings etc. Here is one image where you can see the shadows in action.

Regarding software hack version. Would it work on AOS3.x with Planamarama plugin?
I still haven't had time to check the plugin and have no idea how it works, but why not?

And how to make it 'flush' background every set amount of time in most efficient way?
I mean how often should i clear background and what functions/loops use for it.
I wouldn't like to do it time based, because most of the updates would be unnecessary, and when you have moved the window, updating wouldn't probably hit in the right time either.

I made it (in RNOWidgets) so that background is refreshed only when window gets deactivated and it has been moved (user has moved the window and then clicks somewhere else and our window gets deactivated). I do it by installing InactiveWindow and MoveWindow event handlers, and in move window function I only set a variable which tells if the window has been moved, if it hasn't it's useless to re-draw the background. Then the inactive window function re-draws the background only if the move variable is set.
Ferin
Posts: 18
Joined: Fri May 26, 2017 12:41 am

Re: Transparent app's background

Post by Ferin »

Firstly i want to express my admiration for your RNOWidgets, wow, looks amazing :shock: .
Secondly thanks for your help, it's nice to get advice from someone experienced, you answers are simple and easy to understand.
But there we go again, more questions ; ).

I was wondering if there is a function (didn't find one myself) that makes possible to mask object with transparent brush (100% or less transparency, depending on needs), so everyting covered with it becomes invisible or partialy translucent? If not, that would be nice feature to have in Hollywood, little request to Andreas; ).

Another unrelated question. We can rotate objects around Z axis, is there a way to rotate things round the X and Y to add some kind of depth and 3D transformation?
jPV wrote:I haven't found a way to render something directly over transparent bgpic, but you can first create an alpha transparent brush and then draw the text into the brush (SelectBrush with a suitable combo mode), and then use that brush as a new bgpic (BrushToBGPic). Then you can have your text or other graphics over a transparent display.
I thought as well about using 99% transparent brush. But most likely your way is better.
Actually, I think that constantly updating program (clock) is harder to make with hardware compositing mode, because if you do it like I said above (BrushToBGPic), you are likely to see glitches when the bgpic gets changed. So it doesn't look good when updated once per second or not even once per minute.
But in hardware compositing mode i do not need to update it every so often, even at all, since it displays properly all the time? I just try to understand all principles
of Hollywood, to make sure i don't make silly mistakes later on.
But if you use software rendering hack mentioned in previous posts, then you can have screengrab as the bgpic and draw other things over it normally. I think that would work well, but the downside is of course if you want to move the window, it will need manual re-drawing then.
Is there any reason why i should want to use software rendering rather than hardware? Is H/W method much more demanding for cpu/gpu?
Or it's better because some people do not enable h/w compositing in their system, thus app is more universal?
I made it (in RNOWidgets) so that background is refreshed only when window gets deactivated and it has been moved (user has moved the window and then clicks somewhere else and our window gets deactivated). I do it by installing InactiveWindow and MoveWindow event handlers, and in move window function I only set a variable which tells if the window has been moved, if it hasn't it's useless to re-draw the background. Then the inactive window function re-draws the background only if the move variable is set.
But what in case user does not activate window and moves something over it and then clicks on depth gadget to send it to the back?
Grabbed part of the window gonna be visible over it? Is there any event handler that checks for such eventuality?
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Transparent app's background

Post by jPV »

Ferin wrote:Firstly i want to express my admiration for your RNOWidgets, wow, looks amazing :shock: .
Thanks :) I'm pretty satisfied to it too ;)

I was wondering if there is a function (didn't find one myself) that makes possible to mask object with transparent brush (100% or less transparency, depending on needs), so everyting covered with it becomes invisible or partialy translucent? If not, that would be nice feature to have in Hollywood, little request to Andreas; ).
I think SelectAlphaChannel or SelectBrush do all you need?

Another unrelated question. We can rotate objects around Z axis, is there a way to rotate things round the X and Y to add some kind of depth and 3D transformation?
Hmm.. not that I remember. That could be really nice and useful actually. If there isn't, this should be a feature request then! :)

Actually, I think that constantly updating program (clock) is harder to make with hardware compositing mode, because if you do it like I said above (BrushToBGPic), you are likely to see glitches when the bgpic gets changed. So it doesn't look good when updated once per second or not even once per minute.
But in hardware compositing mode i do not need to update it every so often, even at all, since it displays properly all the time? I just try to understand all principles
of Hollywood, to make sure i don't make silly mistakes later on.
If we are still talking about a clock program where everything else would be transparent except the numbers, you need to update the transparent background image with new numbers at least every minute. And changing the bgpic makes the window reinitialize and that makes a visible "glitch". Dragging the window around etc is of course pretty and you don't have to do anything for it, but if you still have to update the transparent content of your program, that causes a problem. That's why I don't have fully transparent (transparency under the numbers/hands) clock in RNOWidgets, but I have fully transparent calendar, because it doesn't have to update itself periodically :) I just have static (but still transparent on edges) bgpics with clocks. But if anyone figures out a solution for this, please tell me too!

But if you use software rendering hack mentioned in previous posts, then you can have screengrab as the bgpic and draw other things over it normally. I think that would work well, but the downside is of course if you want to move the window, it will need manual re-drawing then.
Is there any reason why i should want to use software rendering rather than hardware? Is H/W method much more demanding for cpu/gpu?
Or it's better because some people do not enable h/w compositing in their system, thus app is more universal?
With the software hack you don't have to update the bgpic constantly, there aren't any graphical issues when updating numbers to it. So that's a plus for it... but otherwise h/w compositing would be better. And universality is a valid point too, h/w compositing requires a 32bit screen with compositing (hw accelerated layers) enabled, and that's not the case on all systems for reason or another. I made it configurable for my program, and it also autodetects if the sceen is in compatible mode on MorphOS, but I didn't find a way to autodetect it on OS4, so it defaults to sw rendering. Of course you could decide to go hw compositing only if you want, but tell it in the requirements :)

I made it (in RNOWidgets) so that background is refreshed only when window gets deactivated and it has been moved (user has moved the window and then clicks somewhere else and our window gets deactivated). I do it by installing InactiveWindow and MoveWindow event handlers, and in move window function I only set a variable which tells if the window has been moved, if it hasn't it's useless to re-draw the background. Then the inactive window function re-draws the background only if the move variable is set.
But what in case user does not activate window and moves something over it and then clicks on depth gadget to send it to the back?
Grabbed part of the window gonna be visible over it? Is there any event handler that checks for such eventuality?
Yeah, it's always a compromise. I don't think you can check for that kind of situation...
Ferin
Posts: 18
Joined: Fri May 26, 2017 12:41 am

Re: Transparent app's background

Post by Ferin »

jPV wrote: I think SelectAlphaChannel or SelectBrush do all you need?
Thanks jPV, i have to try if they would do the job.
Ferin
Posts: 18
Joined: Fri May 26, 2017 12:41 am

Re: Transparent app's background

Post by Ferin »

Unfortunately i failed to achieve my goals with SelectAlphaChannel and SelectBrush functions. To illustrate what i try to get i've prepared an image:
Image
Basicaly i want to make green brush called "MASK" to make orange brush with ID=1 invisible everywhere it is covered. Of course MASK brush is not visible (it's only here to illustrate the principle). Ideally would be nice to be able to assign as many IDs as required, so green MASK brush "covers" all of them with invisibility (full or partial) leaving everything else in tact.

I don't think it's possible at the moment but i may be wrong.

Another thing I'm struggling with is drawing single straight line with LineTo() function.
Whatever i try it says "Can't draw an empty path!"

If i add more LineTo()s it does not say anything but does not draw anything either.
Adding AddBoxToPath makes draw box but not lines?!

Image

Image

And last thing, when i use PathToBrush it says it needs at least one argument in the table?
I wanted to turn a single path into a brush and then rasterize it, but it seems that i have to pass two path IDs to this function or am i doing something wrong?

Generally i want to create vector text with AddTextToPath() => turn it to brush => modify brush with PerspectiveDistortBrush() => display both - original and distorted at the same time. I know there is simple solution to that, but i can not find it.
User avatar
jPV
Posts: 600
Joined: Sat Mar 26, 2016 10:44 am
Location: RNO
Contact:

Re: Transparent app's background

Post by jPV »

Ferin wrote:Unfortunately i failed to achieve my goals with SelectAlphaChannel and SelectBrush functions. To illustrate what i try to get i've prepared an image:
Image
Basicaly i want to make green brush called "MASK" to make orange brush with ID=1 invisible everywhere it is covered. Of course MASK brush is not visible (it's only here to illustrate the principle). Ideally would be nice to be able to assign as many IDs as required, so green MASK brush "covers" all of them with invisibility (full or partial) leaving everything else in tact.

I don't think it's possible at the moment but i may be wrong.
Hmm.. not completely sure how you would like to have it, but here are some examples what I quickly came up with. There are always other ways to do things too, but let's see where this goes with these :)

Code: Select all

@DISPLAY 1,{Color=$00A4FF}

; Let's create our main brush
original_brush = CreateBrush(Nil,200,100,$FF6400)
; Get text into it by selecting it as the output device
SelectBrush(original_brush)
SetFont(#SANS, 40)
TextOut(#CENTER,#CENTER,"Brush ID=1")
EndSelect()

; And display it in its whole glory
DisplayBrush(original_brush,50,10)

; Let's do all modifications to brush 1 now on and keep our original brush as a backup
CopyBrush(original_brush,1)

; Let's then create couple "mask" brushes, but let's use alpha channel instead of actual "on/off" masks (which would also be possible, and faster too)
fully_transparent_mask_brush = CreateBrush(Nil,200,100,#GREEN,{AlphaChannel=True,Clear=True})

semi_transparent_mask_brush = CreateBrush(Nil,200,100,#GREEN,{AlphaChannel=True})
ReduceAlphaChannel(semi_transparent_mask_brush,"50%")

; Vanilla copy copies mask brush alpha values as they are
SetAlphaIntensity(#VANILLACOPY)

; Let's select alpha channel of our brush as an output device and render our mask brush's alpha channel on it
SelectAlphaChannel(1)
DisplayBrush(fully_transparent_mask_brush,-100,50)
EndSelect()

; And show the result
DisplayBrush(1,50,120)

; Let's revert to our original brush. Of course other brushes could be used too.
CopyBrush(original_brush,1)

; And then do the same with our semi transparent mask brush
SelectAlphaChannel(1)
DisplayBrush(semi_transparent_mask_brush,-100,50)
EndSelect()

DisplayBrush(1,50,230)


; You could also draw directly to alpha channel without making a mask brush
CopyBrush(original_brush,1)

SelectAlphaChannel(1)
SetAlphaIntensity("50%")
SetFillStyle(#FILLCOLOR)
Box(0,50,100,100)
EndSelect()

DisplayBrush(1,350,10)


WaitLeftMouse
And that looks like this:
Image

But that only works if you render the "mask" to each brush individially, and maybe do some calculations for positions if they have to be somehow connected.

If you want to have the mask to mask all underlying gfx, maybe you could render everything into one big brush or so.. or maybe use layers somehow like this:

Code: Select all

; Let's enable layers
@DISPLAY 1,{Color=$00A4FF, Layers=True}

; Let's create our main brush again
original_brush = CreateBrush(Nil,200,100,$FF6400)
SelectBrush(original_brush)
SetFont(#SANS, 40)
TextOut(#CENTER,#CENTER,"Brush ID=1")
EndSelect()

; And some kind of "mask" brush
fully_transparent_mask_brush = CreateBrush(Nil,200,100,#GREEN,{AlphaChannel=True,Clear=True})

; Let's create a single big layer where we do all our drawing operations
CreateLayer(0,0,GetAttribute(#DISPLAY,0,#ATTRWIDTH),GetAttribute(#DISPLAY,0,#ATTRHEIGHT),{AlphaChannel=True, Clear=True})

; Draw some graphics into it
SelectLayer(1,#SELMODE_COMBO)
DisplayBrush(original_brush,50,10)
DisplayBrush(original_brush,260,10)
DisplayBrush(original_brush,50,120)
DisplayBrush(original_brush,260,120)
EndSelect()

; And then modify alpha channel with our mask brush
SetAlphaIntensity(#VANILLACOPY)
SelectAlphaChannel(1,#LAYER)
DisplayBrush(fully_transparent_mask_brush,80,40)
EndSelect()

WaitLeftMouse
This looks like this:
Image

But then, if you want it to be moving quickly around and not being static render, maybe something else should be figured out... there really are several ways to approach the issue and what's the best depends your exact goal :)

I don't know now if there's one single easy way to make everything under it transparent...

Or maybe with clipregion... although you can't do semi transparent areas, but fully transparent somehow like this:

Code: Select all

@DISPLAY 1,{Color=$00A4FF}

; Let's create our main brush again
original_brush = CreateBrush(Nil,200,100,$FF6400)
SelectBrush(original_brush)
SetFont(#SANS, 40)
TextOut(#CENTER,#CENTER,"Brush ID=1")
EndSelect()

; Let's create kind of a inverse clipregion, whole screen, but then small area where you can't draw
clipregion_brush = CreateBrush(Nil,GetAttribute(#DISPLAY,0,#ATTRWIDTH),GetAttribute(#DISPLAY,0,#ATTRHEIGHT),Nil,{Mask=True})
SetMaskMode(#MASKINVISIBLE)
SetFillStyle(#FILLCOLOR)
SelectMask(clipregion_brush)
Box(80,40,200,100)
EndSelect()

CreateClipRegion(1, #SHAPE, clipregion_brush, 0, 0)
SetClipRegion(1)

DisplayBrush(original_brush,50,10)
DisplayBrush(original_brush,260,10)
DisplayBrush(original_brush,50,120)
DisplayBrush(original_brush,260,120)

WaitLeftMouse
Which looks exactly the same as the previous example.

Another thing I'm struggling with is drawing single straight line with LineTo() function.
Whatever i try it says "Can't draw an empty path!"
I don't have any expericene with vector graphics yet, so no time to start learning and guessing now. Maybe someone else could help :)
Post Reply