Sign up

Pages: 1 2

Alpha madness

I'm simply trying to draw some lines on in a Drawing Area but for some reason the lines always have some transparency even with Alpha set to 1(it seems about 50% ish).

I was using setLineWidth at 0.75 trying to get a "finer" line. I just set it to 1 and it seemed to reduce the transparency.. and if I set it to 2 then there is no transparency but is this because they are overlapping? I don't understand why the line with would modify the alpha in any way(except for > 1 which would be overlap).

cr.setLineWidth(2.0);
								cr.setSourceRgba(0.0, 1.0, 0.0, 1.0);
								//cr.setSourceRgb(0.0, 1.0, 0.0);
								cr.moveTo(30, 100); 
								cr.lineTo(0, 0); 
								cr.stroke();

[There also seems to be something wrong with the code formatter... in the text all the above is aligned, in the display it is not.]

Any ideas? It's as if there is some global setting that set's the alpha then everything else is with respect to it. If I draw the same line over itself it gets darker(which is a solution but then requires me drawing everything more than once and doesn't explain what is going on).

Re: Alpha madness

On 04-06-2019 04:17, Alex X wrote:

I'm simply trying to draw some lines on in a Drawing Area but for some reason the lines always have some transparency even with Alpha set to 1(it seems about 50% ish).

I was using setLineWidth at 0.75 trying to get a "finer" line. I just set it to 1 and it seemed to reduce the transparency.. and if I set it to 2 then there is no transparency but is this because they are overlapping? I don't understand why the line with would modify the alpha in any way(except for > 1 which would be overlap).

...

Any ideas? It's as if there is some global setting that set's the alpha then everything else is with respect to it. If I draw the same line over itself it gets darker(which is a solution but then requires me drawing everything more than once and doesn't explain what is going on).

Cairo uses the OVER operator by default, which will blend the
background and what your drawing together. So for your case you will
want to change it to SOURCE.

cr.setOperator(CairoOperator.SOURCE);

More information about the operators: https://cairographics.org/operators/

Re: Alpha madness

On Tue, 4 Jun 2019 19:46:39 +0200, Mike Wey wrote:

On 04-06-2019 04:17, Alex X wrote:

I'm simply trying to draw some lines on in a Drawing Area but for some reason the lines always have some transparency even with Alpha set to 1(it seems about 50% ish).

I was using setLineWidth at 0.75 trying to get a "finer" line. I just set it to 1 and it seemed to reduce the transparency.. and if I set it to 2 then there is no transparency but is this because they are overlapping? I don't understand why the line with would modify the alpha in any way(except for > 1 which would be overlap).

...

Any ideas? It's as if there is some global setting that set's the alpha then everything else is with respect to it. If I draw the same line over itself it gets darker(which is a solution but then requires me drawing everything more than once and doesn't explain what is going on).

Cairo uses the OVER operator by default, which will blend the
background and what your drawing together. So for your case you will
want to change it to SOURCE.

cr.setOperator(CairoOperator.SOURCE);

More information about the operators: https://cairographics.org/operators/

Unfortunately it didn't work. Well, I have a drawing underneath that seems to get darker suggesting it is working for that but the lines I'm drawing on top did not change ;/

It looks like it is one of the blending modes but the above simply does not work, In fact, it produces some weird ghosting effects when the drawing area moves. If I use IN things are worse, nothing is drawn at first then everything is very glitchy.

It seems that with SOURCE, what happens is that the drawing area is not cleared and so moving it around will produce overlapping images that blend per frame... which doesn't make sense for SOURCE... but maybe it suggests I need to clear the drawing area per frame?

I might need to take a look at some cario drawing code because I might not be setting stuff up correctly.

Re: Alpha madness

On Tue, 04 Jun 2019 02:17:03 GMT, Alex X wrote:

I was using setLineWidth at 0.75 trying to get a "finer" line. I just set it to 1 and it seemed to reduce the transparency.. and if I set it to 2 then there is no transparency but is this because they are overlapping? I don't understand why the line with would modify the alpha in any way(except for > 1 which would be overlap).

It's not the transparency, it's antialiasing.

Re: Alpha madness

On 05-06-2019 00:08, Alex X wrote:

Unfortunately it didn't work. Well, I have a drawing underneath that seems to get darker suggesting it is working for that but the lines I'm drawing on top did not change ;/

It looks like it is one of the blending modes but the above simply does not work, In fact, it produces some weird ghosting effects when the drawing area moves. If I use IN things are worse, nothing is drawn at first then everything is very glitchy.

It seems that with SOURCE, what happens is that the drawing area is not cleared and so moving it around will produce overlapping images that blend per frame... which doesn't make sense for SOURCE... but maybe it suggests I need to clear the drawing area per frame?

I might need to take a look at some cario drawing code because I might not be setting stuff up correctly.

I had some more time to test, But when there is no transparency involved
OVER and SOURCE behave the same.

For a Drawing Area you usually have to redraw it completely when it's
repainted.

But is does appear to anti aliasing like Ron suggests, the default seems
to use some transparency. You can turn anti aliasing of with:

context.setAntialias(CairoAntialias.NONE);

Some of the other option might produce a better result.

Re: Alpha madness

On Wed, 5 Jun 2019 22:28:30 +0200, Mike Wey wrote:

On 05-06-2019 00:08, Alex X wrote:

Unfortunately it didn't work. Well, I have a drawing underneath that seems to get darker suggesting it is working for that but the lines I'm drawing on top did not change ;/

It looks like it is one of the blending modes but the above simply does not work, In fact, it produces some weird ghosting effects when the drawing area moves. If I use IN things are worse, nothing is drawn at first then everything is very glitchy.

It seems that with SOURCE, what happens is that the drawing area is not cleared and so moving it around will produce overlapping images that blend per frame... which doesn't make sense for SOURCE... but maybe it suggests I need to clear the drawing area per frame?

I might need to take a look at some cario drawing code because I might not be setting stuff up correctly.

I had some more time to test, But when there is no transparency involved
OVER and SOURCE behave the same.

For a Drawing Area you usually have to redraw it completely when it's
repainted.

But is does appear to anti aliasing like Ron suggests, the default seems
to use some transparency. You can turn anti aliasing of with:

context.setAntialias(CairoAntialias.NONE);

Some of the other option might produce a better result.

hmm... I replied but it didn't go through I guess.

It did work. Strange that AA would screw up the line. It shouldn't mess with the original like it does. Maybe there is a setting that modifies it's behavior?

Another question: Is there any way to draw over a widget easily? e.g., get a context of a widget and just draw on it over all the children widgets for a container and it not mess with anything(just purely visual).

Re: Alpha madness

Another question: Is there any way to draw over a widget easily? e.g., get a context of a widget and just draw on it over all the children widgets for a container and it not mess with anything(just purely visual).

I have overridden the addOnDraw, the problem is I need to sync two addOnDraws...

It would be better to be able to get the context for the widget I want then draw to it in a single addOnDraw so they will always be in sync.

Re: Alpha madness

On 06-06-2019 06:08, Alex X wrote:

Another question: Is there any way to draw over a widget easily? e.g., get a context of a widget and just draw on it over all the children widgets for a container and it not mess with anything(just purely visual).

I have overridden the addOnDraw, the problem is I need to sync two addOnDraws...

It would be better to be able to get the context for the widget I want then draw to it in a single addOnDraw so they will always be in sync.

This should work for drawing on top of widgets:

addOnDraw(&draw);

bool draw(Scoped!Context cr, Widget widget)
{
     widget.getWidgetClass().draw(widget.getWidgetStruct(), 
cr.getContextStruct());

     cr.moveTo(0,0);
     cr.lineTo(100,100);
     cr.stroke();

     return true;
}

Re: Alpha madness

On Thu, 6 Jun 2019 23:00:05 +0200, Mike Wey wrote:

On 06-06-2019 06:08, Alex X wrote:

Another question: Is there any way to draw over a widget easily? e.g., get a context of a widget and just draw on it over all the children widgets for a container and it not mess with anything(just purely visual).

I have overridden the addOnDraw, the problem is I need to sync two addOnDraws...

It would be better to be able to get the context for the widget I want then draw to it in a single addOnDraw so they will always be in sync.

This should work for drawing on top of widgets:

addOnDraw(&draw);

bool draw(Scoped!Context cr, Widget widget)
{
     widget.getWidgetClass().draw(widget.getWidgetStruct(), 
cr.getContextStruct());

     cr.moveTo(0,0);
     cr.lineTo(100,100);
     cr.stroke();

     return true;
}

I'm either misunderstanding your code or didn't explain what I want well enough or you misunderstood me ;)

I have two widgets where I am drawing stuff to

w1.addOnDraw(&a)
w2.addOnDraw(&b)

Both a and b need to be synchronized though.

addOnDraw may call a and b at drastically different times. I queue them up together but the internal scheduling does not call them together(stuff happens in between).

I could up the frame rate and this might fix things at the cost of unnecessary processing.

What I'd like to do is

just have one draw routine:

w1.addOnDraw(&a)

bool a(Scoped!Context cr, Widget widget)
{
     widget.getWidgetClass().draw(widget.getWidgetStruct(), 
cr.getContextStruct());

// Get the context for the the 2nd widget
     cr2 = getContext(w2);

     cr.moveTo(0,0);
     cr.lineTo(100,100);
     cr.stroke();

     cr2.moveTo(0,0);
     cr2.lineTo(100,100);
     cr2.stroke();

     cr2.destroy(); // or whatever it is

     return true;
}

I realize it might not be valid to get the context for another widget outside the draw(it might not exist or whatever) but the idea is to show that above they should be synced together. since the draw routines happen together.

What is happening is that I have two widgets that are suppose to draw something in sync. I queue the routines but they are not called together and one lags the other and it is clearly obvious they are not in sync by the design.

If I upped the frame rate it would make it less obvious I imagine but I'd rather not have it an issue at all.

I'm thinking I might have to rethink my design and it might solve some problems though. I'm drawing in a child drawing area and I might just need to draw in the parent widget and take try to position things properly and it might work. That way everything will definitely be synced. It might work for my application since it is relatively basic.

Re: Alpha madness

On 07-06-2019 04:38, Alex X wrote:

I'm either misunderstanding your code or didn't explain what I want well enough or you misunderstood me ;)

I have two widgets where I am drawing stuff to

w1.addOnDraw(&a)
w2.addOnDraw(&b)

Both a and b need to be synchronized though.

addOnDraw may call a and b at drastically different times. I queue them up together but the internal scheduling does not call them together(stuff happens in between).

I could up the frame rate and this might fix things at the cost of unnecessary processing.

What I'd like to do is

just have one draw routine:

w1.addOnDraw(&a)

bool a(Scoped!Context cr, Widget widget)
{
      widget.getWidgetClass().draw(widget.getWidgetStruct(),
cr.getContextStruct());

// Get the context for the the 2nd widget
      cr2 = getContext(w2);

      cr.moveTo(0,0);
      cr.lineTo(100,100);
      cr.stroke();

      cr2.moveTo(0,0);
      cr2.lineTo(100,100);
      cr2.stroke();

      cr2.destroy(); // or whatever it is

      return true;
}

I realize it might not be valid to get the context for another widget outside the draw(it might not exist or whatever) but the idea is to show that above they should be synced together. since the draw routines happen together.

What is happening is that I have two widgets that are suppose to draw something in sync. I queue the routines but they are not called together and one lags the other and it is clearly obvious they are not in sync by the design.

If I upped the frame rate it would make it less obvious I imagine but I'd rather not have it an issue at all.

I'm thinking I might have to rethink my design and it might solve some problems though. I'm drawing in a child drawing area and I might just need to draw in the parent widget and take try to position things properly and it might work. That way everything will definitely be synced. It might work for my application since it is relatively basic.

I misunderstood you.

To draw on a other widget you can use this:

auto gdkWin = otherWidget.getWindow();
auto gdkCx  = gdkWin.beginDrawFrame(gdkWin.getVisibleRegion());
auto cairoCx = gdkCx.getCairoContext();

// Draw to cairoCx.

gdkWin.endDrawFrame();

Pages: 1 2