Integrating Cairo with UE?

I was looking for ways to add vector graphics function to UE, when I stumbled upon Cairo. Cairo has all the functions I want and seems to be designed for real time use. So I wondered, if it is realistic to link Cairo with UE. I know enough C++ to do it, but I don’t know how UE will react to it. Has anyone experience with linking to external C++ libraries and knows where the pitfalls are?

I would imagine the pitfalls are getting it integrated with UE4’s rendering code. If you have a solid knowledge of DX11 and UE4’s rendering system then it wouldn’t be too terrible.

Cairo has the ability to render to a memory buffer. So my idea is, to push the resulting buffer into a dynamic texture. It doesn’t sound too hard. But I suspect I’m missing something.
If I manage to pull this off, I’ll make the result available as open source. So if anyone has any helpful suggestions, I would appreciate it.

So I went ahead and tried to link to the Cairo library. I used the Win64 libraries from GTK+ and followed the instructions from here. I wrote a short Blueprint function, that created a Cairo surface and deleted it again as a test. Everything compiled fine. I copied the Cairo DLLs and dependencies into the “Binaries/Win64” folder. But when I restarted, UE4 immediately exited with a rather unhelpful message:


LogModuleManager:Warning: ModuleManager: Unable to load module 'Z:/Unreal Projects/CairoTest/Binaries/Win64/UE4Editor-CairoTest.dll' because the file couldn't be loaded by the OS.

That’s all the log file has to say about it :(.

I had missing dependencies. GTK+ is a mess. I just threw every DLL in and now it doesn’t crash anymore.

a4bbc61338d51624dc5143f875b169f0fce62e64.jpeg

I did it! :slight_smile: And it was much easier than I expected.

This is a rectangle and a 360° arc drawn by Cairo and then copied to a dynamic Texture2D.

Here’s the code, if someone is curious:



	cairo_t *cr;
	cairo_surface_t *surface;
	UTexture2D * Texture;
	int stride;

	int img_size = 256;

	stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, img_size);
	unsigned char* data = (unsigned char *)FMemory::Malloc(img_size * stride);
	
	surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, img_size, img_size, stride);
	cr = cairo_create(surface);
	cairo_set_source_rgb(cr, 1.0, 0, 0);
	cairo_fill(cr);
	cairo_set_line_width(cr, 5.0);
	cairo_rectangle(cr, 10, 10, 200, 200);
	cairo_arc(cr, 100, 100, 50, 0, 359);
	cairo_stroke(cr);

	Texture = UTexture2D::CreateTransient(img_size, img_size);
	Texture->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
	Texture->SRGB = 0;
	FTexture2DMipMap& Mip = Texture->PlatformData->Mips[0];
	void* Data = Mip.BulkData.Lock(LOCK_READ_WRITE);
	FMemory::Memcpy(Data, data, img_size * stride);
	Mip.BulkData.Unlock();
	Texture->UpdateResource();

	cairo_destroy(cr);
	FMemory::Free(data);


I’d love to be able to do this but my C++ voodoo is not strong enough :confused:

I couldn’t even tell after reading the linking static libraries page if you had to build UE4 from source to be able to do this or if you could just put a bunch of DLL’s in a certain folder and tweak some config files.

Is there any chance you could maybe do a tute explaining some of the details of getting this going?

Hi,
you’re the first one to be interested in this. :slight_smile:
The completed sample project is here: GitHub - Banbury/UE4Cairo: Integrates the Cairo graphics library into Unreal Engine 4.
Just clone the project and open it with UE4. You will need to install Visual Studio 2013. But you won’t need to compile UE4. Just the sources in the project. There’s a sample level, that shows all the functions.
Currently there’s no easy way to move the code to a different project. I mean to convert this into a plugin (now that I know how it’s done). But I have no idea, when I have the time to do it. Just watch the Github repo and hope for the best :).
If you’re just interested in the mechanics of writing plugins in C++, have a look at this project: GitHub - Banbury/UE4Elias: An Unreal Engine 4 plugin for ELIAS.
I have learned a lot between those two projects and UE4Elias is the more advanced.
If you have questions, I’ll try to answer them. But right now I have no time to write tutorials.

Greetings

Banbury

Nice! Does this require an Engine change to make it happen or is it possible to integrate as a Plugin?

Just read the post above yours. :wink:

Hi Banbury,

Thanks for replying so quickly!

Unfortunately when I try to open your example project (either from VS2013 or UE4.8.3) I get an error message saying:

“The game module ‘CairoTest’ could not be loaded. There may be an operating system error or the module may not be properly set up.”

I’ll play around for a while and see what I can figure out…

I have no idea, what the problem is. I can open the project with UE 4.8.3. Does the log file say something?

Hi Banbury,

Ok, home from work again, back into it…

Even though they’re basic, for the sake of being comprehensive here are the steps I took to try and open the project on my machine:

29c3dbf74cf7479706a9d0014986bb0c5c1c2690.jpeg
4c5b31ded4eb0bd3ea5df47feb498f03d95edf7d.jpeg
f88def574fe7a8ebaa2e721ac902a9c28d226d92.jpeg
8c764ef3126491a5e45eed163cc0cdc7f4781478.jpeg

And here are the contents of the two log files in saved/logs/

CairoTest-backup-2015.08.03-20.25.48.log

CairoTest.log

The only line in there that says error is something about experimental character AI but the error message up top is specifically about Cairo so… well, I don’t know :slight_smile:

Does any of this suggest a possible cause for the crash to you?

Sorry, I haven’t the slightest idea, what’s causing it. Try cleaning the project before compiling it. If that doesn’t work, try creating a new project and copy the C++ files there. Make sure it has the same name, or you’ll have to change the build files.

No worries, I’ll have a go at that tonight and let you know how I go.

Nice work! What you’ve done is very interesting, so I’ll be following your progress closely.

ioFlow: do you need to get the cairo DLLs and put them into your binaries folder? From http://cairographics.org/download/:

Those files don’t seem to be in the repo after a cursory glance, so you’ll probably have to get them yourself. As mentioned above you also want to grab everything GTK+ and throw it in there with it.

VERY VERY HAPPY!!!

(got it going)

Basically:

  • open the sample project provided by Banbury above
  • rebuild the plugin when requested
  • plugin does build but project crashes when it trys to open in UE4
  • BUT a binaries folder has now been created in the project folder
  • Go to http://www.gtk.org/download/win64.php and download the “all-in-one bundle” for GTK+ 3.x
  • Uncompress this and get ALL the dll files from the bin folder in it and put them in the binaries folder in the UE4 project
  • The project should now open in UE4!

I’ll do some testing tonight and figure out exactly which DLLs you do and don’t need and post the results.

Thanks of course to Banbury for all of this, I can’t tell you how awesome it is to be able to procedurally generate textures in UE4 :slight_smile:

Okay, I’ll write down some installation instructions on the Github page. I forgot, that the DLLs have to be copied manually into the Binaries folder.

Hi, I Trying Build Project and OK, The sample level when i Start is OK…

Now, When a trying draw a Retangle 100 x 10 the editor kill… exists a minimal resolution for draw objects ?

Not that I know of. Did you connect the ‘context’ pin?
Otherwise I’ll need more information. A screenshot of your Blueprint and a copy of the log file would be helpful. If the editor crashed, there should have been a crash report. Copy the contents of that, too.