/* * 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.RenderingDebugConfig; import org.terasology.monitoring.PerformanceMonitor; import org.terasology.registry.In; import org.terasology.rendering.dag.AbstractNode; import static org.terasology.rendering.opengl.DefaultDynamicFBOs.FINAL; 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.ScreenGrabber; import org.terasology.rendering.opengl.fbms.DisplayResolutionDependentFBOs; import org.terasology.rendering.world.WorldRenderer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad; /** * An instance of this class adds depth of field blur, motion blur and film grain to the rendering * of the scene obtained so far. Furthermore, depending if a screenshot has been requested, * it instructs the ScreenGrabber to save it to a file. * * If RederingDebugConfig.isEnabled() returns true, this node is instead responsible for displaying * the content of a number of technical buffers rather than the final, post-processed rendering * of the scene. */ public class FinalPostProcessingNode extends AbstractNode implements PropertyChangeListener { private static final ResourceUrn POST_MATERIAL = new ResourceUrn("engine:prog.post"); private static final ResourceUrn DEBUG_MATERIAL = new ResourceUrn("engine:prog.debug"); @In private Config config; @In private WorldRenderer worldRenderer; @In private ScreenGrabber screenGrabber; @In private DisplayResolutionDependentFBOs displayResolutionDependentFBOs; private RenderingDebugConfig renderingDebugConfig; private EnableMaterial enablePostMaterial; private EnableMaterial enableDebugMaterial; /** * This method must be called once shortly after instantiation to fully initialize the node * and make it ready for rendering. */ @Override public void initialise() { renderingDebugConfig = config.getRendering().getDebug(); renderingDebugConfig.subscribe(RenderingDebugConfig.ENABLED, this); enablePostMaterial = new EnableMaterial(POST_MATERIAL.toString()); enableDebugMaterial = new EnableMaterial(DEBUG_MATERIAL.toString()); if (!renderingDebugConfig.isEnabled()) { addDesiredStateChange(enablePostMaterial); } else { addDesiredStateChange(enableDebugMaterial); } addDesiredStateChange(new BindFBO(FINAL.getName(), displayResolutionDependentFBOs)); addDesiredStateChange(new SetViewportToSizeOf(FINAL.getName(), displayResolutionDependentFBOs)); } /** * Execute the final post processing on the rendering of the scene obtained so far. * * It uses the GBUFFER as input and the FINAL FBO to store its output, rendering * everything to a quad. */ @Override public void process() { PerformanceMonitor.startActivity("rendering/finalPostProcessing"); renderFullscreenQuad(); if (!screenGrabber.isNotTakingScreenshot()) { screenGrabber.saveScreenshot(); } PerformanceMonitor.endActivity(); } @Override public void propertyChange(PropertyChangeEvent evt) { // we assume here that this property change event is fired only if there has been a change if (!renderingDebugConfig.isEnabled()) { removeDesiredStateChange(enableDebugMaterial); addDesiredStateChange(enablePostMaterial); } else { removeDesiredStateChange(enablePostMaterial); addDesiredStateChange(enableDebugMaterial); } worldRenderer.requestTaskListRefresh(); } }