Library overview - crashinvaders/gdx-vfx GitHub Wiki
The library's goal is to provide a simple yet flexible framework to work with post-processing OpenGL shader effects in a LibGDX application. On top of it, there is a bunch of most common out-of-the-box effects included in the library. So it should be a breeze to pick up the library and start using it straight away.
Library module structure
gdx-vfx-core- Core classes.gdx-vfx-effects- Collection of the out-of-the-box filters and effects. Read more about this module at Built-in Effects page.gdx-vfx-gwt- Platform specific code for GWT backend.
Post-processing workflow
These three stages should happen to any post-processing engine:
- Capture the game's scene into an off-screen buffer for further processing (or just provide a static image).
- Apply a chain of shader effects to the image data provided in the first step.
- Render the result to the screen or another buffer (e.g., to save the result to an image).
Most of all, the library focuses on the second step. But to some extent, it covers them all, as there are tools provided for scene capturing and rendering the result out.
General use case
This is how the library is intended to be used in the code:
- You create and configure required Effects and add them to a Manager.
- Inside render code, this happens:
- The Manager starts capturing into an off-screen buffer.
- You render your scene.
- The Manager stops capturing into an off-screen buffer.
- The Manager applies Effect chain to the captured result.
- The Manager renders the result into the screen or to another frame buffer (if you specify one).
- When no longer needed, the Manager and all the Effects should be disposed manually. Please read the notes about this stage here.
Library architecture
These are the most important elements of the library:
VfxManager aka Manager
The core of the library. The Manager maintains and applies post-processing Effect queue to the scene provided. Also, the Manager provides functionality to capture the scene into an off-screen buffer and to render the result to the screen or to another buffer.
VfxEffect aka Effect
Is the base interface for any visual effect. It's important to note that VfxEffect interface derivatives are not necessary OpenGL shader effects, they can be anything, and it's up to the implementation to decide what to do with the graphics data. Thus these are the most important built-in interfaces/classes that implement VfxEffect interface:
ChainVfxEffectA base interface for any effect that can participate in the Manager's effect chain.ShaderVfxEffectIt's an abstract base class for any OpenGL shader-based effects. It lets you create an interface between GLSL code and Java and expose properties/methods to control the shader from the game code. Most of the built-in effects fromgdx-vfx-effectsextend this class (NOTE: not all theShaderVfxEffects areChainVfxEffects, there are some utility ones that can only be used manually).MultipassEffectWrapperMost of theChainVfxEffects are made to be "single pass" effects, and this a simple wrapper that helps to run the same effect multiple times.CompositeVfxEffectA utility effect implementation that helps easily compose multiple other effects together (e.g.BloomEffectis a mix of three different Effects).
Implementation specifics
These are the things that are important to know about before you start using the library code.
VFX frame buffer
The library imposes to use VfxFrameBuffer class over regular FrameBuffer whenever you need to deal with the off-screen rendering during capturing or applying effects chain stages. Please read about VfxFrameBuffer justification on this page.
Ping-pong rendering
As there is a chain of Effects to be applied to the scene one after another, we use the ping-pong buffer rendering approach. Ping-pong buffer basically stands for two buffers where one is used as an input for an Effect (aka src buffer), and the other one as the buffer where the Effect will render the result to (aka dst buffer). Once any Effect is rendered, the two buffers should be swapped, so now the result will be held in the src buffer and ready to be used as an input for another Effect.
Resource disposal
As we are dealing with OpenGL related stuff, most of the library classes implement Disposable interface and shall be properly disposed when no longer needed.
It's important to note, that although a Manager maintains a chain of Effects, it doesn't manage their life-cycle. Means you have to manually call VfxEffect#dispose() when you no longer need it (e.g., application termination).
You create Effect instances outside of the Manager, add/remove them to the Manager whenever you need them to participate in the effect chain, and you're responsible for disposing them yourself.
Custom OpenGL calls
The library relies on an extended set of OpenGL functions, that are not yet available/implemented for all of the official LibGDX backends. Thus VfxGlExtension interface is introduced. Different implementations help to maintain cross-platform support. However, the same implementation is shared among almost all the backends - DefaultVfxGlExtension, except for GWT backend we use GwtVfxGlExtension due to WebGL specifics.
At the runtime, current VfxGlExtension instance is available through VfxGLUtils#glExtension.