|
02-05-2015, 05:23 PM
|
#1
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
IPlug link to cairo (2D vector library)
I finally ends up my investigation with a fully working link between IPlug/LICE and cairo, a 2D vector library.
You can found a full tutorial here:
https://simplapi.wordpress.com/2015/...ics-in-wdl-ol/
You can have such rendering:
And with original LICE:
IMPORTANT:
This is still a beta test *as it's only 2 days old try*, I have tested it only on Windows (no AAX test, no iOs test...), standalone app, or inside DAW, both works.
As cairo is available almost on any platform you may dream of, it should works also without so much difficulties on linux/mac environment.
SSSooo, if some people got the AAX SDK/works on Mac, please take a moment to try it, I will update the tutorial with your recommandations for having cairo running the AAX/PT framework
Feel free to comment!
|
|
|
02-05-2015, 05:24 PM
|
#2
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
reserved.
|
|
|
02-05-2015, 06:58 PM
|
#3
|
Human being with feelings
Join Date: May 2012
Location: PA, USA
Posts: 356
|
Very nice. I am going to have to take a look at this.
Do you have any idea what the speed of Cairo would be for tasks such as continually drawing waveforms, spectrum analyzers, etc.?
|
|
|
02-06-2015, 01:30 AM
|
#4
|
Human being with feelings
Join Date: Jan 2012
Posts: 104
|
how you manage the mouse picking?
for example intercept when is on the point or on the line?
|
|
|
02-06-2015, 02:11 AM
|
#5
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Cool!
Note that LICE already includes libpng and zlib, so I would expect that you can also just compile the pixman and cairo bits (assuming the LICE and cairo compiler settings are comatible).
And quickly looking at your example... Wouldn't it be possible to call cairo_image_surface_create() and cairo_create() in the control's constructor, and reuse them in each Draw() call? I guess this should be slightly more efficient, unless cairo somehow cashes its memory allocations, then it probably doesn't matter.
|
|
|
02-06-2015, 04:13 AM
|
#6
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by random_id
Very nice. I am going to have to take a look at this.
Do you have any idea what the speed of Cairo would be for tasks such as continually drawing waveforms, spectrum analyzers, etc.?
|
That's the next question I need to answer, within 3/4 days (I need to do other things a little), but I have reasonable chance to get something working with low CPU usage, as you can play some games in the firefox canvas (which rely on cairo).
Quote:
Originally Posted by Tronic
how you manage the mouse picking?
for example intercept when is on the point or on the line?
|
Like you see in the example, I keep cairo to the bare minimum inside the plugin only the draw function is affected, letting IPlug handling the maximum, so the mouse stay on IPlug side, use OnMouseDown or others as usual, only change the render
I may wrote down another article for that, but for using cairo in an existing code, the easy way consist of getting the x/y coordinate from IPlug OnMouseDown, remove the left or top of your IControl from it (as cairo is center to 0/0 and IPlug to left/top), and those x/y are directly usable inside cairo now!
EDIT: sorry I didn't fully reply. For bezier stuff (it's one of the two things I need to do in my project), I didn't have other choice than having a bezier algorithm next to my render: http://devmag.org.za/2011/04/05/bzie...es-a-tutorial/
I personnaly choose to render the graphic in %, so the max point is internally 1:1 coordinate, and I simply use the width/height of control when rendering to find the graphic relationship.
So, when user submit a mouse click/drag, I catch this, convert it to %, ask my internal code if there is a point there or not, apply modification if there is.
So basically personnaly I'm outside both IPlug and cairo while doing this operation. But yes, basically (even with Lice), you have no choice than storing somewhere at least the points you are using to render, to be able to do that!
Quote:
Originally Posted by Tale
Cool!
Note that LICE already includes libpng and zlib, so I would expect that you can also just compile the pixman and cairo bits (assuming the LICE and cairo compiler settings are comatible).
And quickly looking at your example... Wouldn't it be possible to call cairo_image_surface_create() and cairo_create() in the control's constructor, and reuse them in each Draw() call? I guess this should be slightly more efficient, unless cairo somehow cashes its memory allocations, then it probably doesn't matter.
|
It's somehow a strange situation, as I compiled it to minimum, I should not need libpng or zlib, but for a reason I don't know, the compiler still ask me to include them (even if according to doc, I should be able to skip them, keeping only pixman)...
Regarding the *clear* the documentation says to redraw all the surface, there is a case how to clear while keeping all alpha channels:
http://cairographics.org/FAQ/#clear_a_surface
The second code is the one!
I don't recommand it, but there is also another way (i guess):
The cairo surface creation has an import function http://cairographics.org/manual/cair...reate-for-data
Where you submit the data pointer to it.
If I check the code the cairo surface rely on _pixman_bits_image_init (from pixman) which rely on create_bits, and inside you will see a nice malloc
By keep an internal pointer to data with height*width pixel size, and following how to create stride variable (see doc), you may succeed to do that, because *i guess*, clearing the pointer will simply consist into setting everything to 0 in this array...
So you probably want to do that, at least you will avoid the malloc everytime you redraw, but you will not avoid all the compute with this. The advantage will of course to keep the alpha channel in this situation compare to the official way to clear
But the clear solution provided in code is probably WAY better
|
|
|
02-06-2015, 06:02 AM
|
#7
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by Tale
Cool!
Note that LICE already includes libpng and zlib, so I would expect that you can also just compile the pixman and cairo bits (assuming the LICE and cairo compiler settings are comatible).
And quickly looking at your example... Wouldn't it be possible to call cairo_image_surface_create() and cairo_create() in the control's constructor, and reuse them in each Draw() call? I guess this should be slightly more efficient, unless cairo somehow cashes its memory allocations, then it probably doesn't matter.
|
I update the code to avoid using create on every Draw, so now the system is contructing the surface/context on constructor, and only clear on Draw!
Note that, as I said, it may be a bad idea in some cases, keeping the ratio of 1:1 between all elements (cairo, IControl, LICE Wrapper), is the key to avoid many graphic bugs, so, as we construct the surface on constructor, you must take care of any resize happenning to the control, by destroying the surface/context and re-create a new one with updated widht/height.
EDIT: I didn't put it in big red mark, but there is a github ready if you want to test it: https://github.com/Deisss/IPlug-cairo-example
The *-app is configured for Debug-x64/x86 and Release-x64-x86, it should works out of the box if you include it in IPlugExamples folder like usual!
|
|
|
02-06-2015, 12:45 PM
|
#8
|
Human being with feelings
Join Date: Jan 2012
Posts: 104
|
Last edited by Tronic; 02-06-2015 at 12:59 PM.
|
|
|
02-06-2015, 01:59 PM
|
#9
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by Tronic
|
Hum, two things (not to be arrogant to you, just to be sure we talk the same thing):
- You do know there is already everything to handle mouse click in your IControl ?
- You also do know by not setting a proxy between your rendering and your data, may lead to strange situation (like you resize the control between two VST version, oupsy the point is not at the good place anymore...) ?
Actually I don't understand so much why you want have cairo handling points for you, it's not his purpose, and your IControl already has this feature...
|
|
|
02-06-2015, 02:31 PM
|
#10
|
Human being with feelings
Join Date: Jan 2012
Posts: 104
|
do not worry you're not rude, I'm here to discuss ideas,
I do not think I explained myself, I try to explain better:
since the mouse and key event, we have already, my question was:
<< How to know when I am with the mouse on a path or a point of it? >>
and not when I am on the rectangle of IControl.
so I think the only way is to know the points of the path from cairo,
and compare them with the current relative position of the mouse, so the functions posted above, they offer these possibilities.
|
|
|
02-06-2015, 03:07 PM
|
#11
|
Human being with feelings
Join Date: Apr 2009
Location: Berlin, Germany
Posts: 1,248
|
nice!
here's a PR to improve the specifying of include/lib folder across different builds
https://github.com/Deisss/IPlug-cairo-example/pull/1
will also see about the mac version in a bit
oli
|
|
|
02-06-2015, 04:12 PM
|
#12
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by olilarkin
|
I merge it But I don't have time to update article, will do during this week (for now I wrote a more general article about mouse and graphics for Tronic ).
Actually for a reason I don't know I didn't see the *.props file until now, really cool indeed
Also, Tronic makes a really good points, The Martin Finke blog does not cover at all graphics ( http://www.martin-finke.de/blog/tags...o_plugins.html ), so I'm writing a little tutorial for graphics and mouse relation (not cairo related).
Btw, WDL-OL can grow up a lot in community if there is some usefull tutorials to dive into, so I try to help my best
|
|
|
02-06-2015, 04:57 PM
|
#13
|
Human being with feelings
Join Date: Jan 2012
Posts: 104
|
and it work
Edit: you have to place this before the render stroke or fill part
Code:
...
// mX,mY var is populated with OnMouseOver function
if (cairo_in_stroke(cr, mX, mY))
{
wsprintf(tmp, "MOUSE OVER STROKE: X=%d Y=%d\n", mX, mY);
OutputDebugString(tmp);
}
// Render
cairo_stroke(cr);
...
Last edited by Tronic; 02-06-2015 at 05:07 PM.
|
|
|
02-06-2015, 05:57 PM
|
#14
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by Tronic
and it work
Edit: you have to place this before the render stroke or fill part
Code:
...
// mX,mY var is populated with OnMouseOver function
if (cairo_in_stroke(cr, mX, mY))
{
wsprintf(tmp, "MOUSE OVER STROKE: X=%d Y=%d\n", mX, mY);
OutputDebugString(tmp);
}
// Render
cairo_stroke(cr);
...
|
As I said I understand too late your request, but from what you wanted to do, indeed the cairo functions where the good idea
Nice one btw, can make some nice living things now
On my side, as I misunderstand your request, I did a tutorial on handling mouse and graphic in a IControl:
https://simplapi.wordpress.com/2015/...by-user-input/
Like Martin's tutorials series does not cover this part, it's a good addition to tutorial list for WDL-OL even if it's not related to your problem ^^
Last edited by Deisss; 02-06-2015 at 06:05 PM.
|
|
|
02-06-2015, 06:12 PM
|
#15
|
Human being with feelings
Join Date: Jan 2012
Posts: 104
|
I really appreciate the tutorial well made like yours, I expect others
and I think that the community really does have people like you who still want to share.
Anyway I want to report this other library, still young but promising,
I was experimenting with it and the performance is not bad.
https://github.com/memononen/nanovg
|
|
|
02-07-2015, 02:31 AM
|
#16
|
Human being with feelings
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,653
|
Quote:
Originally Posted by Deisss
I update the code to avoid using create on every Draw, so now the system is contructing the surface/context on constructor, and only clear on Draw!
|
Looking good, thanks for figuring this out.
Quote:
Originally Posted by Deisss
Note that, as I said, it may be a bad idea in some cases, keeping the ratio of 1:1 between all elements (cairo, IControl, LICE Wrapper), is the key to avoid many graphic bugs, so, as we construct the surface on constructor, you must take care of any resize happenning to the control, by destroying the surface/context and re-create a new one with updated widht/height.
|
Understood.
|
|
|
02-07-2015, 08:42 AM
|
#17
|
Human being with feelings
Join Date: Apr 2012
Posts: 279
|
Quote:
Originally Posted by Deisss
Like Martin's tutorials series does not cover this part, it's a good addition to tutorial list for WDL-OL even if it's not related to your problem ^^
|
Thanks for this!! Will come in handy sooner or later...
|
|
|
02-10-2015, 03:28 PM
|
#18
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by stw
Thanks for this!! Will come in handy sooner or later...
|
You're welcome
|
|
|
02-14-2015, 07:39 PM
|
#19
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Quote:
Originally Posted by random_id
Very nice. I am going to have to take a look at this.
Do you have any idea what the speed of Cairo would be for tasks such as continually drawing waveforms, spectrum analyzers, etc.?
|
Just finish a first try, seems fine here (on a 3y old I5 ULV, so if it does not hit the CPU, it will probably never hit the CPU on any current computer )
|
|
|
08-26-2015, 11:47 AM
|
#20
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Did anyone succeed to run cairo on mac?
|
|
|
09-17-2015, 07:32 AM
|
#21
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
I succeed.
The problem is more on building cairo on mac, on X64 no problem, but for x86 homebrew is uncool with me...
I can check if I still got the project/code somewhere...
PS: sorry for delay I got busy recently on many other projects...
|
|
|
09-17-2015, 08:06 AM
|
#22
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Hey, thanks for the reply. I have manage to build cairo using macports with command in terminal "sudo port install cairo +universal" this successfuly built cairo for x86 and x64 and for 10.5 SDK and newer using 10.9 os x and xcode 6.2...
I am having problems building cairo for windows tho. I tried to follow instructions on cairo webite but I could not build it... How did you build it for windows?
|
|
|
09-19-2015, 06:05 PM
|
#23
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Thanks for the tips...
To be honest on windows that was a pain in the ass, took me like a full evening to succeed, getting a lot of random/undocumented bugs...
The worst part is like when I succeed to build on x64, there is a whole new bug list when I switch on x86 ^^ But thats because they dont really care about windows, and thats uncool if you cant find a prebuild version somewhere.
You should take directly compiled versions ive builded on the article above, its for windows, there is x86 and x64, will save you so much time (and it provide 4 different build if I remember)
|
|
|
09-26-2015, 02:00 AM
|
#24
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by Deisss
You should take directly compiled versions ive builded on the article above, its for windows, there is x86 and x64, will save you so much time (and it provide 4 different build if I remember)
|
I know, but these libraries don't work in VS2015, so in the future I will need to compile myself... I was surprised how easy was building cairo for Mac..
|
|
|
09-26-2015, 07:06 AM
|
#25
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Here is very efficient drawing function for mac and windows. This is much faster method for drawing than drawing each pixel separately on mac like in this thread:
http://forum.cockos.com/showthread.php?t=166215
Code:
inline void Cairo_Draw_To_Lice(IGraphics *cpGraphics, cairo_surface_t *surf, int x, int y, int width, int height)
{
cairo_surface_flush(surf);
unsigned int *data = (unsigned int*)cairo_image_surface_get_data(surf);
IRECT rect = IRECT(x,y,width,height);
#ifdef _WIN32
LICE_WrapperBitmap WrapperBitmap = LICE_WrapperBitmap(data, width, height, width, false);
IBitmap result(&WrapperBitmap, width, height);
pGraphics->DrawBitmap(&result, &rect);
#elif defined(__APPLE__)
for(int i = 0; i < (width * height); ++i)
{
// argb to bgra aaaaaaaa rrrrrrrr gggggggg bbbbbbbb to bbbbbbbb gggggggg rrrrrrrr aaaaaaaa
*data = (*data >> 24) | (*data << 24) | ((*data &0xFF0000) >> 8) | ((*data &0xFF00) << 8);
// ___a b__a b_ra bgra
data = data + 1;
}
data = data - (width * height);
LICE_WrapperBitmap WrapperBitmap = LICE_WrapperBitmap(data, width, height, width, false);
IBitmap result(&WrapperBitmap, width, height);
cpGraphics->DrawBitmap(&result, &rect);
#endif
}
|
|
|
10-02-2015, 05:49 AM
|
#26
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
Here is the sidenote i've got prepared in case of a new build, may help you in this case, I output the raw version of it (I wrote time to time to remember few key points):
Except for pixman and cairo, which is good but incomplete, please use this link to build:
http://cairographics.org/end_to_end_build_for_win32/
EDIT: as far as I remember, I didn't install MSYS or Dev or cUrl as I don't need it (gitbash >>>> MSYS, and I already got VS installed)
======
PIXMAN
======
You need to have access to default linux build tools, so gitbash is a good start ( https://git-scm.com/downloads ), and a ready to user VS compiler.
First of all, register cl compiler (visual studio c compiler) into the main windows path:
C:\<your path to VS>\Microsoft Visual Studio 12.0\VC\bin
NOTE: here of course, as you are on VS 2015, it's probably not 12.0 version...
Second, instead of
make -f Makefile.win32 "CFG=release"
You need to manually include everything:
CFLAGS="-I'/C/<your path to VS>/Microsoft Visual Studio 12.0/VC/include'" make -f Makefile.win32 CFG=release MMX=off SSE2=on SSE3=on
Note: on x86 you can activate MMX, on x64, you can't (bug)
Note2: on x86, at the end you may need to add a "ARCH=x86" to have the right linker
Note3: careful with /C/ not /C:/...
Will compile as expected, as you manually register the lib and include needed for cl compiler before compilation time.
=====
CAIRO
=====
You need -again- to use a gitbash with this time much more commands (all on a single line):
Create a folder (I named it C:\piou36), with the following elements in it:
Everything from this folder:
C:/<your path to VS>/Microsoft Visual Studio 12.0/VC/lib
And everything from this folder:
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64
And:
And the libs zlib, libpng and pixman
Should be quite big (almost 1gb if I remember). I've try a lot to multiple include instead of creating this kind of tmp folder, it was quite a failure But maybe it was too late
The command to run after that:
LDFLAGS="/LIBPATH:'C:/piou36'" CFLAGS="-I'/C/<your path to VS>/Microsoft Visual Studio 12.0/VC/include' -I'/C/Program Files (x86)/Windows Kits/8.1/Include/um' -I'/C/Program Files (x86)/Windows Kits/8.1/Include/shared' -I'/C/build_cairo/output/include'" make -f Makefile.win32 "CFG=release"
The c:\build_cairo is where I've stored everything, but it's not so revelant except it needs to exists of course...
Note: on x86 you may need to add a "ARCH=x86" to have the right x86 linker
Hope this helps But I could succeed to build all with this helper ^^
Last edited by Deisss; 10-02-2015 at 06:00 AM.
|
|
|
10-04-2015, 08:39 AM
|
#27
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Thanks a lot, this will definitely come in handy!
|
|
|
01-17-2016, 06:15 PM
|
#28
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Hey, I successfully built cairo 1.14.6 for MSVC2015! What a pain in the a...
Anyway, I finally got it using their end to end build guide. 32bit was easy, but figuring 64bit was tough... I will post soon detailed guide how to build it, for now here are just the binaries...
Download here
|
|
|
01-18-2016, 02:08 PM
|
#29
|
Human being with feelings
Join Date: Apr 2012
Posts: 279
|
cool!
Looking forward to the detailed guide!
|
|
|
02-06-2016, 01:38 PM
|
#30
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Ok, guys, I made cmd script to simplify Cairo build. Please try it and tell me if it works for you.
Read description before build!
If build fales for some reason, upload here Build_Log.txt file...
Good luck building cairo...
Download from Github: https://github.com/Youlean/Win32-Cairo-Build.git
|
|
|
02-06-2016, 03:30 PM
|
#31
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
It seams that there is problem building in VS 2013, but I am working on it. Building in VS2015 Community was tested and it is OK...
|
|
|
02-07-2016, 08:51 AM
|
#32
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Building in VS2013 should work now...
|
|
|
02-22-2016, 08:01 AM
|
#33
|
Human being with feelings
Join Date: Feb 2015
Posts: 36
|
After building it for the first time I was so tired I could not have enough power to make a script for it, well done
|
|
|
02-23-2016, 09:03 AM
|
#34
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Thanks Deisss! Cairo is really nice, and performance is awesome compared to Lice!
|
|
|
12-13-2016, 04:18 AM
|
#35
|
Human being with feelings
Join Date: Mar 2016
Posts: 234
|
Thanks Deisss & Youlean for the brillant work/support, and for compile Cairo for us (very damn task, Youlean).
Now, is it normal that once I've added Cairo, Visual Studio (2015) warn me with this linker message?
Code:
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
Should I disable/enable some settings?
Thanks!
|
|
|
12-14-2016, 04:56 AM
|
#36
|
Human being with feelings
Join Date: May 2015
Location: Serbia
Posts: 654
|
Quote:
Originally Posted by Nowhk
Thanks Deisss & Youlean for the brillant work/support, and for compile Cairo for us (very damn task, Youlean).
Now, is it normal that once I've added Cairo, Visual Studio (2015) warn me with this linker message?
Code:
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
Should I disable/enable some settings?
Thanks!
|
I never saw this warning.. Well if it works, than it is OK.
|
|
|
12-20-2016, 02:53 AM
|
#37
|
Human being with feelings
Join Date: Mar 2016
Posts: 234
|
Quote:
Originally Posted by Youlean
I never saw this warning.. Well if it works, than it is OK.
|
I think thats related to this: https://msdn.microsoft.com/en-us/lib...(v=vs.60).aspx
I guess you compiled Cairo with different Run Time settings, rather the ones of IPlug (such as one of MD, /ML, /MT, /LD).
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 10:13 PM.
|