## Integrating Effekseer's efk files

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Integrating Effekseer's efk files

Hi all!

I'm new to LÖVE -- I'm curious if anyone has tried to use Effekseer's .efk files directly in LÖVE projects (using the Effekseer runtime library, maybe?). If so, how did you go about doing it?

I've been able to export effects to PNG spritesheets, but they take up a huge amount of space compared to .efk files, and aren't as dynamic (eg: varying in the paths that particles take each time the effect is triggered).

Thanks!
MrFariator
Party member
Posts: 297
Joined: Wed Oct 05, 2016 11:53 am

### Re: Integrating Effekseer's efk files

As far as I can tell, there isn't any easy solution to your conundrum. To me it seems you'd have to grab the code for Effekseer's OpenGL branch, and write some wrapper around it to include it in your project (the help page for Cocos2d may be useful here). Even then, you'd have to make it play ball with LÖVE's draw functions, kind of asking you to add Effekseer to LÖVE source and build your own version of LÖVE, if not as an external library to load at runtime. Otherwise you'd have to reverse engineer the efk file format, and make it work with the systems LÖVE provides, which is likely not a trivial task in its own right either.

Effekseer seems to have bindings for Cocos2d, so perhaps it could be possible to ask the developers to add support for Love2d as well. They might not play ball, but hey, might be worth asking?
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

Ahh, thanks for the suggestions! I'll see if it's straightforward to get it integrated in with the draw functions and report back.
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

I had some initial success by adding an Effekseer runtime and building it in the love repo, though there's still a lot of things to fix and improve. Basically I took Examples/OpenGL/main.cpp and put the Manager class as an object inside graphics/opengl/Graphics.cpp in love. In lua, you can do:

Code: Select all

function love.load(args)
manager = love.graphics.getEffectManager()
effect = love.graphics.newEffect("efk/Laser01.efk")
end

function love.keypressed(key, unicode)
if key == 'space' then
effect:play(0, 0, 0)
end
end

function love.update(dt)
manager:update(dt)
end

function love.draw()
-- Effects are drawn automatically by love
end
My WIP is available in the effekseer branch here: https://github.com/gittup/love/tree/effekseer

Here's an example image from the attached effekseer.love file:
Example image
effekseer.png (225.69 KiB) Viewed 10148 times
The two red things are regular pngs drawn with love.graphics.draw(), and the green things are drawn with Effekseer.

Note that I don't think this is the right approach overall, but it was the first way that I tried that actually successfully showed an effect on screen. I'd love to get some help properly integrating it into love. A few issues I ran into:

1) I haven't been able to fully integrate Effekseer's rendering with love's. I first tried making the manager object something that you create from love.load() or somewhere, rather than building it into Graphics.cpp. However, when I called draw() on the manager, it was making direct OpenGL calls that then got overwritten by Graphics::draw(). I was hoping to do something like this in order to draw the effects at a layer of my choosing:

Code: Select all

function love.draw()
love.graphics.draw(img1)
love.graphics.draw(manager)
love.graphics.draw(img2)
end
But unfortunately the image draws don't actually get drawn until later, while the effekseer manager gets rendered immediately. This meant the effects were always drawn behind everything. The hack of putting the manager code inside Graphics.cpp was intended to work around this, so the effects are basically drawn after everything else.

I think the right approach probably involves writing a custom renderer to replace EffekseerRendererGL.Renderer.cpp so that it can render things in a way love understands. I don't understand this well enough to know for sure, though.

2) Possibly related to 1), but when rendering shaders, effekseer calls glUseProgram(some number), and then when it closes out the shaders, it calls glUseProgram(0). This ended up causing everything rendered by love to not show up. I put a hack in to find out which program love was expecting it to be (it was number 3), and set it back to that after rendering the effekseer manager.

3) Also maybe related to rendering, I left in hard-coded values for setting the projection/camera matrices (these come from the effekseer example code). Obviously that needs to hook into love's matrices, or something.

Those are the main issues I'm aware of. Even after that there's a bunch of (easier) work adding extra wrappers to manipulate effects and such, but I wanted to share this initial success and see if anyone else can help with the hard parts

Some other notes:

- I think I was able to successfully get Effekseer's image loading working with love's filesystem code (this is what LoveTextureLoader / LoveEffectLoader are for). That enables the newEffect('file.efk') to find the efk file, and the .png files that the .efk file refers to internally.

- I left in main.lua calling manager:update(dt), since I assume the manager code would need to go back there and not be attached to Graphics.cpp. If the manager is truly internal in love, then presumably the update call could be done internally as well.
Attachments
effekseer.love
.love file to test effekseer
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

I made a little progress, in that I figured out where the draw() calls were getting buffered. Calling gfx->flushStreamDraws() in the draw routine for the EffekseerManager makes things layer as expected. So this draw function now shows img1 behind the Effekseer effects, and img2 in front of them:

Code: Select all

function love.draw()
love.graphics.draw(img1)
love.graphics.draw(manager)
love.graphics.draw(img2)
end
It also means I don't need the ugly hack of adding an EffectManager in Graphics.cpp, so in Lua you can just do:

Code: Select all

function love.load(args)
manager = love.graphics.newEffectManager()
effect = love.graphics.newEffect(manager, "efk/Laser01.efk")
end

function love.update(dt)
manager:update(dt)
if [some condition] then
handle = manager:play(effect, 0, 0, 0)
end
end

function love.draw()
love.graphics.draw(manager)
end
You could also create multiple managers to draw different sets of effects in different layers, if desired.

I'm still having trouble sorting out how to set the Projection & Camera matrices in Effekseer's renderer to match coordinates with love. Or, if that should be avoided entirely and instead change the Effekseer renderer to render with love's StreamDrawCommand stuff. Can anyone recommend an approach here?

Here's my current test branch: https://github.com/gittup/love/tree/effekseer2

And a simple .love project that loads a .efk file (press spacebar to spawn an effect):
effekseer2.love
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

I've updated my test branch (https://github.com/gittup/love/tree/effekseer2) to try an orthographic projection with x,y coordinates matching the love window. I also added support to call draw() on the individual effect handles, rather than just on the manager. This makes it easier for the effects to be translated into the right position via love.graphics.translate() or the additional arguments in draw(), similar to other graphics primitives.

Here's what it looks like if I spawn a lightning bolt at the x,y coordinates in love.mousepressed(). You can see that the effect can be drawn ahead of or behind other graphics elements depending on the order of the love.graphics.draw() calls (like you'd expect).
love-effekseer-lightning.gif (861.36 KiB) Viewed 9281 times
Feedback or suggestions for improvement are welcome!
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

I've updated it to also work with love.js, so web love games can use Effekseer effects as well.

I think the remaining work is to figure out how to get EffekseerRendererGL.Shader.cpp to integrate better with Love's OpenGL.cpp. This would help the glUseProgram() issue mentioned earlier, as well as a new issue in love.js with things not rendering because glEnableVertexAttribArray() calls happen in those two files. If the Effekseer code made use of Love's functions to handle this, I think it would be more cleanly integrated.

I'm also still not sure the way the matrices are handled is at all correct, but it seems to display 2d effects fine.
Prole
Posts: 10
Joined: Sat Mar 20, 2021 2:05 am

### Re: Integrating Effekseer's efk files

I filed an issue (https://github.com/love2d/love/issues/1691) to see if Effekseer support could get upstreamed, but it was suggested that I turn it into a plugin instead. So now it's a plugin instead of a love2d fork, and is available here: https://github.com/gittup/EffekseerForLove

Hope someone else finds it useful!
ReFreezed
Party member
Posts: 323
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

### Re: Integrating Effekseer's efk files

I just want to say, nice work! This thread fits more in the Libraries and Tools forum at this point.
Tools: Hot Particles, LuaPreprocess, (more) Games: Momento Temporis: Light from the Deep, Energize!
"If each mistake being made is a new one, then progress is being made."