RE: [fltk.general] transparent polygon [General Use]

182 views
Skip to first unread message

MacArthur, Ian (Leonardo, UK)

unread,
Aug 2, 2016, 4:46:15 AM8/2/16
to fltkg...@googlegroups.com
> Any plans for implementing transparent polygons ?
> Or is it this possible now ??


Can you describe what you want to do here?

It is possible the render images with alpha, for example, which might do what you want, or to draw shaped windows.

I don’t think there's an easy way to draw a transparent line or fill a transparent poly though.

If you can outline what you want to do, maybe someone will know how to get there.




Selex ES Ltd
Registered Office: Sigma House, Christopher Martin Road, Basildon, Essex SS14 3EL
A company registered in England & Wales. Company no. 02426132
********************************************************************
This email and any attachments are confidential to the intended
recipient and may also be privileged. If you are not the intended
recipient please delete it from your system and notify the sender.
You should not copy it or use it for any purpose nor disclose or
distribute its contents to any other person.
********************************************************************

holm.h...@gmail.com

unread,
Aug 2, 2016, 5:16:31 AM8/2/16
to fltk.general, ian.ma...@leonardocompany.com

What I try to achieve :
 I have a map/chart  and want to draw a polygon around a certain region. I want the region to be highligthed so that the user are aware that this region is special, but the user should still be able to see whats on the map under the polygon.

I was thinking of transparent polygons to do this, but there may be alternatives ?

Best regards
Håvard

MacArthur, Ian (Leonardo, UK)

unread,
Aug 2, 2016, 5:47:18 AM8/2/16
to fltkg...@googlegroups.com
If you just want to draw an outline then you can just use fl_line() segments, or a more complex loop with fl_begin_line(), fl_end_line() etc.


However, it sounds to me like you want to change the appearance of the filled region within the outline, whilst not obscuring the underlying map image.

For that, I would render the requisite poly into a separate surface and then alpha-blend it on top of the map top get the desired effect.

There's no direct way to do this in fltk, but it's not that hard to do; indeed ISTR that Greg posted an example recently that did something very like that...

Or maybe I made that up? Dunno... Anyway, worth a fish about over here...

http://www.seriss.com/people/erco/fltk

See if you see anything handy...


I'm intrigued by this - might take a stab at it over lunch to see what happens. But don't wait for me if you find something better obviously!

holm.h...@gmail.com

unread,
Aug 2, 2016, 6:03:08 AM8/2/16
to fltk.general, ian.ma...@leonardocompany.com

Thanks again for your answer Ian,

You are thinking of rendering to a png-image or something? I guess your are right - that should work, but I work in fullscreen mode, and to make this general I may end up with a full-screen-size image - to draw a polygon here and there. Sound like a solution, but not the ideal solution.

My program is required to run fast.

Håvard

Albrecht Schlosser

unread,
Aug 2, 2016, 6:53:09 AM8/2/16
to fltkg...@googlegroups.com
On 02.08.2016 12:03 holm.h...@gmail.com wrote:
>
> Thanks again for your answer Ian,
>
> You are thinking of rendering to a png-image or something? I guess your
> are right - that should work, but I work in fullscreen mode, and to make
> this general I may end up with a full-screen-size image - to draw a
> polygon here and there. Sound like a solution, but not the ideal solution.

I think that you can use smaller images that are just as large of the
bounding box of the part of the polygon you want to cover. But let's see
what Ian finds out...

> My program is required to run fast.

Another idea would be to draw the filled polygon _before_ your real
data. You could do that in your draw() method if you have the
information which area(s) should be highlighted in your widget's data.
There are all sorts of clipping and redrawing only an area of you widget
to avoid flicker, i.e. you can damage() a region you want to redraw with
the filled (background/highlight) polygon in place and/or when you
(re)move the highlight polygon. This might be faster, but you need to
adjust your draw() method.

holm.h...@gmail.com

unread,
Aug 2, 2016, 7:35:58 AM8/2/16
to fltk.general, Albrech...@online.de

That sounds interesting ! I have not damaged a region like you mention, so I may follow-up up with questions.. I quess "checkers" in the test-directory is a starting point to learn.

MacArthur, Ian (Leonardo, UK)

unread,
Aug 2, 2016, 9:07:00 AM8/2/16
to fltkg...@googlegroups.com

> I'm intrigued by this - might take a stab at it over lunch to see what
> happens. But don't wait for me if you find something better obviously!

OK, kinda ran out of time, so this is what I have. It's not pretty but seems to work fine, and the resource load doesn't seem to heinous.

This is a reasonably decent PC and I assume the GPU is doing at least some of the heavy lifting for blitting the 2D surfaces about...

That said; Brian is right, if you really want to do this quickly, you probably want to do it via GL, which will allow the GPU to be leveraged to do all the nasty alpha mess I'm doing by hand in this code!

<code follows as attachment>
overlay_img.cxx

holm.h...@gmail.com

unread,
Aug 2, 2016, 5:16:42 PM8/2/16
to fltk.general, ian.ma...@leonardocompany.com

Thank you, I will consider using it. I think the result would look nice.

I guess it is out of the scope to look for a function :
        void fl_color (uchar r, uchar g, uchar b, uchar a);
so than you could spesify transparency along with the color. To be available for all drawing functions...
would be a nice feature tough.. I do not know the internal code of fltk, but that may be a big job ??

Best regards
Håvard

MacArthur, Ian (Leonardo, UK)

unread,
Aug 3, 2016, 5:17:26 AM8/3/16
to fltkg...@googlegroups.com
> Thank you, I will consider using it. I think the result would look nice.

Your most welcome; the code is probably not optimal - as I was writing it I was bugged by a sense that I was missing some sensible optimization, just couldn't see what.

That said, in testing, the code ran with very little CPU load, so I think it may be "Good Enough" as it stands.

Needs a bit of a tidy up, of course, and the means to draw arbitrary poly's rather than just rectangles, and to set the colour and alpha of the poly. I might even add those; though maybe not...

Still, if this approach *does not* work for you, doing it via GL is probably the better bet, since it is probable that will better leverage the abilities of the GPU to do the heavy lifting.

But don't assume any given solution will be slow; always test it!
Modern GPU's are very good at 2D rendering, so often things that look like they would be slow or expensive to do turn out to be much better than expected.


> I guess it is out of the scope to look for a function :
>        void fl_color (uchar r, uchar g, uchar b, uchar a);
> so than you could spesify transparency along with the color.
> To be available for all drawing functions...
> would be a nice feature tough.. I do not know the internal code
> of fltk, but that may be a big job ??

The core 2D rendering API's in fltk are intended to provide the basic functionalities for the GUI controls and such, and largely mirror the underlying API's of the underlying systems that we wrap.

Things like transparency and so forth aren't really part of that API - they are more part of the compositing of the window and such.

Now, toolkits like Cairo or AGG can do this for you, and you can use them from fltk. I don't have much experience with AGG, but I do use Cairo on occasion - it works very well, but I find it to be slow at times.

For fltk, we never felt this was the right way to go though; instead, we try to make it trivial to use GL instead, and that is worth looking at. As others have said, it would be fairly straightforward to load your map into a GL surface and draw blended polys on to it. So if my code isn't going to work for you, that would be a thing to try next, I suggest.

MacArthur, Ian (Leonardo, UK)

unread,
Aug 3, 2016, 10:35:24 AM8/3/16
to fltkg...@googlegroups.com
> Needs a bit of a tidy up, of course, and the means to draw arbitrary
> poly's rather than just rectangles, and to set the colour and alpha of
> the poly. I might even add those; though maybe not...


Didn't tidy the code up; did modify the test harness to change the poly shape, colour and alpha dynamically on the fly as it runs, to try and see how bad the CPU load might be.

With a refresh of 20 FPS, I'm not really seeing any CPU load at all on this machine, so (despite all reasonable expectations) this approach might actually be good enough, particularly if the polygon is changed reasonably infrequently (I think, but can not prove, that most of the work in this code is actually from my nasty hack for randomly generating a polygon on the fly and nothing to do with the whole overlay scheme at all!)



Anyway, if interested, see attached;
overlay_img.cxx

holm.h...@gmail.com

unread,
Aug 4, 2016, 3:18:01 AM8/4/16
to fltk.general, ian.ma...@leonardocompany.com

Thank you all, Now there are several alternatives. Just one more thing as the thread is still warm.. I will now start implementing/testing. I have working code for different methods , but I do not have it clear when it comes to OpenGL. To me it seems like I should do something like :

offscreen_buffer = fl_create_offscreen( w(), h() );
fl_begin_offscreen(offscreen_buffer);
opengl-stuff
fl_end_offscreen();
fl_copy_offscreen(x(), y(), w(), h(), offscreen_buffer, 0,0);

But will the opengl-drawing-pixmap now be transparent ? Any special setting to make this happen ?

Best regards
Håvard

MacArthur, Ian (Leonardo, UK)

unread,
Aug 4, 2016, 5:32:43 AM8/4/16
to fltkg...@googlegroups.com
(CAVEAT: No one should take my advice on GL use, it is not my strong suit!)

No, I don't think that's a sensible approach with GL.
You would be better creating an FL_GL_Window and using that as your base, rather than messing about with fl_offscreens and so forth (GL and fltk's offscreen do not always interact well on all platforms, depends on the underlying GL implementation and GPU hardware too much) whereas GL has lots of mechanisms of its own for handling offscreen frame buffer objects and textures and so forth that are likely to be hardware accelerated and smooth and fast...


So, when I was doing something similar, what I did was derive a window from Fl_GL_Window, and then use that to create a number of GL framebuffer objects, one of these the background was drawn into (IIRC, this object was much bigger than the window so I could scroll it about easily...) and then the various overlays were rendered into another FBO.

When my derived widget's draw() method was called, it basically grabbed the appropriate chunk of the "background" FBO then blended the "overlay" FBO on top of it.

And... I'm pretty sure I turned on multisample anti-aliasing before the blend, to make the lines all come out nice.

Anyway, it looked nice, and was pretty quick (even on a PC with a rubbish GPU card fitted - blindingly quick on my Mac with a decent GPU!)

I can't post the code, but the ideas should work.

It's a pain to set up though; to use any even moderately sophisticated GL features, you will need to use some sort of GL extension manager (at least on WinXX and X11, OSX may not need to these days) and there is a world of boilerplate code you need to set up to get it all working. I used libglew for my extension manager and it worked out really well, but it is an added dependency (and complexity) that you may not need or want.


So; GL is the "right" way to go, it is very powerful and can do amazing stuff, but it's worth trying the basic 2D tricks shown here too. They may well be Fast Enough, and they will be simpler to get going in most cases!

holm.h...@gmail.com

unread,
Aug 4, 2016, 9:30:01 AM8/4/16
to fltk.general, ian.ma...@leonardocompany.com

You are probably right, but 02.02.15 in the thread "fl_copy_offscreen", Albert mentioned that he should show code which transforms offscreen buffer to transparent image : "My next post (in a few minutes) will show code to draw into an Fl_Offscreen buffer, convert that buffer to an Fl_RGB_Image with alpha channel, and then draw that image on the window with transparency".

Albert, do you still have this code ? It would be interesting to see how this approach would perform.

Best regards
Håvard

MacArthur, Ian (Leonardo, UK)

unread,
Aug 4, 2016, 10:58:49 AM8/4/16
to fltkg...@googlegroups.com
> You are probably right, but 02.02.15 in the thread "fl_copy_offscreen",
> Albert mentioned that he should show code which transforms offscreen
> buffer to transparent image : "My next post (in a few minutes) will show
> code to draw into an Fl_Offscreen buffer, convert that buffer to an
> Fl_RGB_Image with alpha channel, and then draw that image on the window
> with transparency".


OK... um, by "probably right" are you referring to my comments on using GL, or...?

The technique Albrecht was referring to is, I think, pretty much the technique I showed in my example, except that I used an Fl_Image_Surface rather than an Fl_Offscreen. In this case they are pretty much analogous.


(It is possible that an Fl_Image_Surface would play nicer with GL, actually, but I don't think that's pertinent here since the technique proposed is a "non-GL" solution to the problem.)

Greg Ercolano

unread,
Aug 4, 2016, 2:09:16 PM8/4/16
to fltkg...@googlegroups.com
What's the intention of the offscreen stuff?
You shouldn't need any of that to handle the transparency.

If you draw the map image with glDrawPixels() (or make it a texturemap
and assign it to a simple rectangular polygon), then draw the
polygons over that using an RGBA color for the polygon that has
a transparent value for the A value in the color (alpha).
There is some openGL prep work you have to do to enable alpha
blending.. see:

"How to draw a transparent polygon in openGL":
http://stackoverflow.com/questions/3125017/how-to-draw-transparent-polygon-in-opengl

And:
https://www.opengl.org/archives/resources/faq/technical/transparency.htm

And an example/tutorial here:
http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-10-transparency/

..then refer to the more specific openGL docs for glEnable() and glBlendFunc()

I don't have an FLTK example on my cheat page that shows transparent rendering,
but you can at least use one of the opengl examples there as a starting point,
and then weave in your code to enable transparency and rendering the map image.
Just go onto this page and repeatedly search for "opengl" to find all the
opengl examples.. with those you can at least familiarize yourself with how
opengl and FLTK are mixed, and how to do some operations you might need,
like assigning texture maps (if you go that route over using glDrawPixels()):
http://seriss.com/people/erco/fltk/#OpenGLTextureMappedImage

..and rendering simple filled polygons:
http://seriss.com/people/erco/fltk/#OpenGlTextOn3D

I would suggest working with perspective turned off, so that you end up
with orthographic projections, so that your polygons draw directly over
the map image, without distortion due to perspective/parallax/etc.

Jumping into openGL is a little non-trivial, but once you learn it,
you can do all kinds of high speed 3D and 2D rendering on all platforms
with and without FLTK. So I'd suggest doing a little bit of reading up
on openGL first; look at the simple FLTK opengl examples on the above
cheat page, and look at the opengl docs for each opengl function
(function names that start with glXXX) to figure out exactly how
they work, then start experimenting with the example code.

Albrecht Schlosser

unread,
Aug 5, 2016, 3:53:24 AM8/5/16
to fltkg...@googlegroups.com
On 04.08.2016 15:30 holm.h...@gmail.com wrote:

> Albert mentioned that he should show code which transforms offscreen
> buffer to transparent image : "My next post (in a few minutes) will show
> code to draw into an Fl_Offscreen buffer, convert that buffer to an
> Fl_RGB_Image with alpha channel, and then draw that image on the window
> with transparency".
>
> Albert, do you still have this code ?

No, sorry. BTW: my name is Albrecht.

> It would be interesting to see how this approach would perform.

You may want to take a look at the code in this post:
https://groups.google.com/d/msg/fltkgeneral/lqjMyks77fM/b174F9_aAgAJ

that shows how to draw a transparent image, but only for rectangles.

Combine this with drawing your poly into an Fl_Offscreen (see example
test/offscreen) [1], read the image bits with fl_read_image(),

<http://www.fltk.org/doc-1.3/group__fl__drawings.html#ga0cdc05d3f7689e1c6b8a26fd0bd97233>

set the transparency according to the pixel colors for each pixel
(background color: 100%, your filled polygon color: your alpha), then do
the same as shown in that post.

[1] If you want to follow that route, I suggest to create an
fl_offscreen that is large enough to hold your poly, fill it with a
white background (fl_rectf()), then draw your poly into it with the
color you want to draw. After reading the image back with
fl_read_image() with your desired alpha value you can loop over all
image pixels and set alpha to 100% (255) for all pixels that have the
background color (r=g=b=255).


Albrecht Schlosser

unread,
Aug 5, 2016, 4:08:02 AM8/5/16
to fltkg...@googlegroups.com
On 05.08.2016 09:53 Albrecht Schlosser wrote:

> Combine this with drawing your poly into an Fl_Offscreen (see example
> test/offscreen) [1], read the image bits with fl_read_image(),
>
> <http://www.fltk.org/doc-1.3/group__fl__drawings.html#ga0cdc05d3f7689e1c6b8a26fd0bd97233>
>
> set the transparency according to the pixel colors for each pixel
> (background color: 100%, your filled polygon color: your alpha), then do
> the same as shown in that post.
>
> [1] If you want to follow that route, I suggest to create an
> fl_offscreen that is large enough to hold your poly, fill it with a
> white background (fl_rectf()), then draw your poly into it with the
> color you want to draw. After reading the image back with
> fl_read_image() with your desired alpha value you can loop over all
> image pixels and set alpha to 100% (255) for all pixels that have the
> background color (r=g=b=255).

Another IMHO interesting way to draw the transparent image with your
filled poly after creating the image as described above would be to use
an Fl_Box that has the size of the image created above, set
box->image(your_image), and add this box to your window/group _after_
your widget so that it will show above your widget. Since the box has a
transparent image (label) it will be drawn above your widget.

You can resize and move the image box around over your widget like
another layer on top of your widget, fill it with another transparent,
filled polygon (image), etc.. You wouldn't need to change your widget's
draw method, and you could hide() and show() the transparent box as
needed. You don't need to draw() your image explicitly because the
Fl_Box widget will do this for you.

The only drawback I see with this approach is that fl_read_image() is
known to be slow, at least if you read back pixels from a window. It
might be faster if you read pixels from an Fl_Offscreen, as it would be
the case here.

holm.h...@gmail.com

unread,
Aug 5, 2016, 5:53:30 AM8/5/16
to fltk.general, Albrech...@online.de

Hi,

Thank you Albrecht,

I will try out this method, I think it sounds like a good solution.

Regarding Fl_Offscreen, I have tested out the code posted by mpercy in the thread "Writing a Window to a File without Displaying It". mpercy uses OpenGL to draw the graphics. Using OpenGL would increase possibilities for this method even further, but to me it seems like whats between
fl_begin_offscreen( offscreen_buffer ); and fl_end_offscreen();
is not captured when OpenGL is used. Fltk drawings are however captured. Is it correct that Fl_Offscreen do not work well with OpenGL ?

Best regards
Håvard

Albrecht Schlosser

unread,
Aug 5, 2016, 6:00:45 AM8/5/16
to fltkg...@googlegroups.com
On 05.08.2016 11:53 holm.h...@gmail.com wrote:

> Is it correct that Fl_Offscreen do not work well with OpenGL ?

Yes, I think so. OpenGL uses its own drawing context so I think that
this can't work with Fl_Offscreen. But I don't know much about OpenGL
with FLTK, so others may give you better answers.

MacArthur, Ian (Leonardo, UK)

unread,
Aug 5, 2016, 6:02:06 AM8/5/16
to fltkg...@googlegroups.com
> Regarding Fl_Offscreen, I have tested out the code posted by mpercy in
> the thread "Writing a Window to a File without Displaying It". mpercy
> uses OpenGL to draw the graphics. Using OpenGL would increase
> possibilities for this method even further, but to me it seems like
> whats between
> fl_begin_offscreen( offscreen_buffer ); and fl_end_offscreen();
> is not captured when OpenGL is used. Fltk drawings are however captured.
> Is it correct that Fl_Offscreen do not work well with OpenGL ?

That depends very much on the underlying implementation of GL, and the way in which fl_offscreen operates on any given platform.

That is why I was suggesting you try to use Fl_Image_Surface rather than fl_offscreen for this purpose; they are broadly analogous, but Fl_Image_Surface is much more likely to work correctly with a GL context.

Note that my example used Fl_Image_Surface rather than fl_offscreen, although I did not use GL for the rendering.

So it may still work as a basis if you want to try using GL instead; see how that works out.
Reply all
Reply to author
Forward
0 new messages