/*
* Copyright 2016 MovingBlocks
*
* 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 org.terasology.rendering.dag.nodes;
import org.terasology.assets.ResourceUrn;
import org.terasology.config.Config;
import org.terasology.config.RenderingConfig;
import org.terasology.monitoring.PerformanceMonitor;
import org.terasology.registry.In;
import org.terasology.rendering.dag.ConditionDependentNode;
import org.terasology.rendering.dag.stateChanges.BindFBO;
import org.terasology.rendering.dag.stateChanges.EnableMaterial;
import org.terasology.rendering.dag.stateChanges.SetViewportToSizeOf;
import org.terasology.rendering.opengl.FBO;
import org.terasology.rendering.opengl.FBOConfig;
import static org.terasology.rendering.opengl.ScalingFactors.HALF_SCALE;
import org.terasology.rendering.opengl.fbms.DisplayResolutionDependentFBOs;
import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad;
/**
* An instance of this class takes advantage of the color and depth buffers attached to the read-only gbuffer
* and produces light shafts from the main light (sun/moon). It is therefore a relatively inexpensive
* 2D effect rendered on a full screen quad - no 3D geometry involved.
*
* Trivia: the more correct term would be Crepuscular Rays [1], an atmospheric effect. One day we might
* be able to provide indoor light shafts through other means and it might be appropriate to rename
* this node accordingly.
*
* [1] https://en.wikipedia.org/wiki/Crepuscular_rays
*/
public class LightShaftsNode extends ConditionDependentNode {
public static final ResourceUrn LIGHT_SHAFTS_FBO = new ResourceUrn("engine:fbo.lightShafts");
@In
private Config config;
@In
private DisplayResolutionDependentFBOs displayResolutionDependentFBOs;
/**
* This method must be called once shortly after instantiation to fully initialize the node
* and make it ready for rendering.
*/
@Override
public void initialise() {
RenderingConfig renderingConfig = config.getRendering();
renderingConfig.subscribe(RenderingConfig.LIGHT_SHAFTS, this);
requiresCondition(renderingConfig::isLightShafts);
requiresFBO(new FBOConfig(LIGHT_SHAFTS_FBO, HALF_SCALE, FBO.Type.DEFAULT), displayResolutionDependentFBOs);
addDesiredStateChange(new BindFBO(LIGHT_SHAFTS_FBO, displayResolutionDependentFBOs));
addDesiredStateChange(new SetViewportToSizeOf(LIGHT_SHAFTS_FBO, displayResolutionDependentFBOs));
addDesiredStateChange(new EnableMaterial("engine:prog.lightShafts"));
// TODO: move content of ShaderParametersLightShafts to this class
}
/**
* Renders light shafts, taking advantage of the information provided
* by the color buffer and especially the depth buffer attached to the FBO
* currently set as read-only.
*/
@Override
public void process() {
PerformanceMonitor.startActivity("rendering/lightShafts");
// The source code for this method is quite short because everything happens in the shader and its setup.
// In particular see the class ShaderParametersLightShafts and resource lightShafts_frag.glsl
renderFullscreenQuad();
PerformanceMonitor.endActivity();
}
}