/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* 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.badlogic.gdx.tests.g3d.shadows.system.classical;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.badlogic.gdx.tests.g3d.shadows.system.FirstPassBaseShadowSystem;
import com.badlogic.gdx.tests.g3d.shadows.utils.DirectionalAnalyzer;
import com.badlogic.gdx.tests.g3d.shadows.utils.LightFilter;
import com.badlogic.gdx.tests.g3d.shadows.utils.NearFarAnalyzer;
import com.badlogic.gdx.tests.g3d.shadows.utils.ShadowMapAllocator;
/** Classical shadow system uses shadow accumulation method. For each light, a depth map is generated and a second pass accumulate
* the shadows. Obviously, the second pass must use the same lighting system as the main rendering pass. Compared to Realistic
* shadow system, it's heavier but has some advantages:
*
* <pre>
* 1 - It supports point light shadowing.
* 2 - It's easy to use in custom shader.
* 3 - There is no constraint about shader varying.
* </pre>
* @author realitix */
public class ClassicalShadowSystem extends FirstPassBaseShadowSystem {
public static final int PASS_QUANTITY = 2;
public static final int SECOND_PASS = 1;
/** true if it's the first light during second pass */
protected boolean firstCallPass2;
protected int nbCall = 0;
public ClassicalShadowSystem () {
super();
}
public ClassicalShadowSystem (NearFarAnalyzer nearFarAnalyzer, ShadowMapAllocator allocator,
DirectionalAnalyzer directionalAnalyzer, LightFilter lightFilter) {
super(nearFarAnalyzer, allocator, directionalAnalyzer, lightFilter);
}
@Override
public int getPassQuantity () {
return PASS_QUANTITY;
}
@Override
public void init (int n) {
super.init(n);
mainShaderProvider = new MainShaderProvider(new MainShader.Config(this));
if (n == SECOND_PASS) init2();
}
@Override
protected void init1 () {
super.init1();
passShaderProviders[FIRST_PASS] = new Pass1ShaderProvider();
}
protected void init2 () {
frameBuffers[SECOND_PASS] = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getBackBufferWidth(), Gdx.graphics.getBackBufferHeight(), true);
passShaderProviders[SECOND_PASS] = new Pass2ShaderProvider(new Pass2Shader.Config(this));
}
@Override
protected void beginPass (int n) {
super.beginPass(n);
if (n == SECOND_PASS) beginPass2();
};
protected void beginPass2 () {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
firstCallPass2 = true;
nbCall = 0;
}
@Override
public Camera next () {
if (currentPass == SECOND_PASS && nbCall > 0) firstCallPass2 = false;
nbCall++;
return super.next();
}
@Override
protected Camera interceptCamera (LightProperties lp) {
if (currentPass == SECOND_PASS) return this.camera;
return lp.camera;
}
@Override
protected void processViewport (LightProperties lp, boolean cameraViewport) {
if (this.currentPass != SECOND_PASS) super.processViewport(lp, cameraViewport);
}
public Texture getMainTexture () {
return getTexture(SECOND_PASS);
}
public boolean isFirstCallPass2 () {
return firstCallPass2;
}
@Override
public String toString () {
return "ClassicalShadowSystem";
}
}