/*******************************************************************************
* Copyright 2012 bmanuel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.bitfire.postprocessing.effects;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.math.Vector2;
import com.bitfire.postprocessing.PostProcessor;
import com.bitfire.postprocessing.PostProcessorEffect;
import com.bitfire.postprocessing.filters.Blur;
import com.bitfire.postprocessing.filters.Blur.BlurType;
import com.bitfire.postprocessing.filters.Combine;
import com.bitfire.postprocessing.filters.CrtScreen;
import com.bitfire.postprocessing.filters.CrtScreen.RgbMode;
import com.bitfire.postprocessing.utils.PingPongBuffer;
public final class CrtMonitor extends PostProcessorEffect {
private PingPongBuffer pingPongBuffer = null;
private FrameBuffer buffer = null;
private CrtScreen crt;
private Blur blur;
private Combine combine;
private boolean doblur;
private boolean blending = false;
private int sfactor, dfactor;
// the effect is designed to work on the whole screen area, no small/mid size tricks!
public CrtMonitor (int fboWidth, int fboHeight, boolean barrelDistortion, boolean performBlur, RgbMode mode, int effectsSupport) {
doblur = performBlur;
if (doblur) {
pingPongBuffer = PostProcessor.newPingPongBuffer(fboWidth, fboHeight, PostProcessor.getFramebufferFormat(), false);
blur = new Blur(fboWidth, fboHeight);
blur.setPasses(1);
blur.setAmount(1f);
// blur.setType( BlurType.Gaussian3x3b ); // high defocus
blur.setType(BlurType.Gaussian3x3); // modern machines defocus
} else {
buffer = new FrameBuffer(PostProcessor.getFramebufferFormat(), fboWidth, fboHeight, false);
}
combine = new Combine();
crt = new CrtScreen(barrelDistortion, mode, effectsSupport);
}
@Override
public void dispose () {
crt.dispose();
combine.dispose();
if (doblur) {
blur.dispose();
}
if (buffer != null) {
buffer.dispose();
}
if (pingPongBuffer != null) {
pingPongBuffer.dispose();
}
}
public void enableBlending (int sfactor, int dfactor) {
this.blending = true;
this.sfactor = sfactor;
this.dfactor = dfactor;
}
public void disableBlending () {
this.blending = false;
}
// setters
public void setTime (float elapsedSecs) {
crt.setTime(elapsedSecs);
}
public void setColorOffset (float offset) {
crt.setColorOffset(offset);
}
public void setChromaticDispersion (float redCyan, float blueYellow) {
crt.setChromaticDispersion(redCyan, blueYellow);
}
public void setChromaticDispersionRC (float redCyan) {
crt.setChromaticDispersionRC(redCyan);
}
public void setChromaticDispersionBY (float blueYellow) {
crt.setChromaticDispersionBY(blueYellow);
}
public void setTint (Color tint) {
crt.setTint(tint);
}
public void setTint (float r, float g, float b) {
crt.setTint(r, g, b);
}
public void setDistortion (float distortion) {
crt.setDistortion(distortion);
}
public void setZoom (float zoom) {
crt.setZoom(zoom);
}
public void setRgbMode (RgbMode mode) {
crt.setRgbMode(mode);
}
// getters
public Combine getCombinePass () {
return combine;
}
public float getOffset () {
return crt.getOffset();
}
public Vector2 getChromaticDispersion () {
return crt.getChromaticDispersion();
}
public float getZoom () {
return crt.getZoom();
}
public Color getTint () {
return crt.getTint();
}
public RgbMode getRgbMode () {
return crt.getRgbMode();
}
@Override
public void rebind () {
crt.rebind();
}
@Override
public void render (FrameBuffer src, FrameBuffer dest) {
// the original scene
Texture in = src.getColorBufferTexture();
boolean blendingWasEnabled = PostProcessor.isStateEnabled(GL20.GL_BLEND);
Gdx.gl.glDisable(GL20.GL_BLEND);
Texture out = null;
if (doblur) {
pingPongBuffer.begin();
{
// crt pass
crt.setInput(in).setOutput(pingPongBuffer.getSourceBuffer()).render();
// blur pass
blur.render(pingPongBuffer);
}
pingPongBuffer.end();
out = pingPongBuffer.getResultTexture();
} else {
// crt pass
crt.setInput(in).setOutput(buffer).render();
out = buffer.getColorBufferTexture();
}
if (blending || blendingWasEnabled) {
Gdx.gl.glEnable(GL20.GL_BLEND);
}
if (blending) {
Gdx.gl.glBlendFunc(sfactor, dfactor);
}
restoreViewport(dest);
// do combine pass
combine.setOutput(dest).setInput(in, out).render();
};
}