Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative usage #19

Open
kunterbunt2 opened this issue Jun 19, 2022 · 4 comments
Open

Alternative usage #19

kunterbunt2 opened this issue Jun 19, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@kunterbunt2
Copy link

The vfxManager uses a fbo to capture all activities and then adds all the effects.
This saves one copy operations.
But, currently fbos in libgdx do not support multi sampling.
So, I am forced to give up sampling support if I use vfxManager.
Can we have an alternative method that just copies the current screen without capturing in a fbo?
This way all draw operations can use multi sampling.

@metaphore metaphore added the enhancement New feature or request label Jul 10, 2022
@metaphore
Copy link
Member

Hi, sorry for the late reply and thanks for the input!

I'm not very familiar with any other sampling methods available for cross-platform libGDX shaders (we stack with GLSL v1.20, if I'm not mistaken). Could you please explain your case in a bit more details? What exactly would you prefer to use to supply the initial image to the effect processing pipeline?

@kunterbunt2
Copy link
Author

Hi, originally I thought, why not read from the current screen?
But, I learned that opengl does not support reading from the screen.
So, it looks as if we can close this as not possible.
But, thanks for looking into it.

@Betalord
Copy link

Betalord commented Mar 2, 2023

Actually, OpenGL does support reading from screen.
In my code, I copy backbuffer contents to a texture and use that for gdx-vfx effects. This is how I copy backbuffer:

public static void copyBackBufferToTexture(Texture tex) {
	    tex.bind();
	    Gdx.gl.glCopyTexImage2D(GL20.GL_TEXTURE_2D, 0, Format.toGlFormat(tex.getTextureData().getFormat()), 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 0); // WARNING: getFormat() doesn't always return correct format!
	    Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0); // unbind
}

You better use RGBA_8888 format, or you could run into troubles (libGDX being buggy).
Also, you can simply create a FBO and use its color texture with this method. Here is my little library that does just that and uses Bloom effect (modify it as needed):

package com.betalord.sgx.rendering;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.utils.Disposable;
import com.betalord.sgx.util.SGXFrameBuffer;
import com.crashinvaders.vfx.VfxManager;
import com.crashinvaders.vfx.effects.BloomEffect;

public class PostProcessing implements Disposable {
	private VfxManager vfxManager;
	private boolean enabled = true;
	/** An intermediate FBO we use to copy back buffer contents to it and then pass it to gdx-vfx. */
	private SGXFrameBuffer fbo;
	private int width = 0;
	private int height = 0;

	public void init(int width, int height) {
		this.width = width;
		this.height = height;

		vfxManager = new VfxManager(Pixmap.Format.RGBA8888, width, height);
		BloomEffect bloom = new BloomEffect();
		//bloom.applySettings(new BloomEffect.Settings(10, 0.85f, 1f, 0.85f, 1.1f, 0.85f));
		bloom.applySettings(new BloomEffect.Settings(10, 0.1f, 1f, 0.85f, 1.1f, 1.85f));
		vfxManager.addEffect(bloom);
		fbo = new SGXFrameBuffer(Pixmap.Format.RGBA8888, width, height, false);
	}

	public void process() {
		if (!enabled)
			return;
		
		RenderUtils.copyBackBufferToTexture(fbo.getColorBufferTexture());
		vfxManager.cleanUpBuffers();
		vfxManager.useAsInput(fbo.getColorBufferTexture());
		vfxManager.applyEffects(); // apply the effects chain to the captured frame
		vfxManager.renderToScreen(); // render result to the screen
	}

	public void resize(int width, int height) {
		if (this.width == width && this.height == height)
			return;
		this.width = width;
		this.height = height;

		vfxManager.resize(width, height);
		// resize FBO:
		if (fbo != null) fbo.dispose();
		fbo = new SGXFrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
	}

	public void enable(boolean enable) {
		this.enabled = enable;
	}

	public void enable() {
		enable(true);
	}

	public void disable() {
		enable(false);
	}

	public boolean isEnabled() {
		return enabled;
	}

	@Override
	public void dispose() {
		if (vfxManager != null)
			vfxManager.dispose();
		if (fbo != null)
			fbo.dispose();
	}
}

Note though, that gdx-vfx is possibly quite slow and could probably be greatly optimized. It uses several shader passes that could be reduced to a single pass, and some redundant (I believe) FBOs. But I haven't looked much into the code, just had a glance at it.

@mgsx-dev
Copy link

mgsx-dev commented Mar 2, 2023

@Betalord Sorry to be a bit rude but :

OpenGL does support reading from screen

Yes, but that would be very inefficient in this context, it requires copy from GPU memory to CPU memory and send it back to the GPU memory, that's very bad in term of performances.

You better use RGBA_8888 format, or you could run into troubles (libGDX being buggy)

No. Libgdx works well with some other formats.

Also, you can simply create a FBO and use its color texture with this method

Yes, that's the proper way to do it.

that gdx-vfx is possibly quite slow and could probably be greatly optimized. It uses several shader passes that could be reduced to a single pass, and some redundant (I believe) FBOs

No. The lib is good. It's just that post processing effects are greedy.

But I haven't looked much into the code

Yeah, that's probably why you say that :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants