/* * Copyright 2017 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.monitoring.PerformanceMonitor; import org.terasology.rendering.assets.material.Material; 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.SetInputTextureFromFBO; import org.terasology.rendering.dag.stateChanges.SetViewportToSizeOf; import org.terasology.rendering.opengl.BaseFBOsManager; import org.terasology.rendering.opengl.FBO; import org.terasology.rendering.opengl.FBOConfig; import org.terasology.rendering.opengl.FBOManagerSubscriber; import static org.terasology.rendering.dag.stateChanges.SetInputTextureFromFBO.FboTexturesTypes.ColorTexture; import static org.terasology.rendering.opengl.OpenGLUtils.renderFullscreenQuad; /** * Instances of this class take the content of the color attachment of an input FBO * and downsamples it into the color attachment of a smaller output FBO. */ public class DownSamplerNode extends ConditionDependentNode implements FBOManagerSubscriber { private static final String TEXTURE_NAME = "tex"; private static final int SLOT_0 = 0; private static final ResourceUrn DOWN_SAMPLER_MATERIAL = new ResourceUrn("engine:prog.downSampler"); private String performanceMonitorLabel; private BaseFBOsManager outputFBOmanager; private FBOConfig outputFBOconfig; private FBO outputFBO; private Material downSampler; /** * Throws a RuntimeException if invoked. Use initialise(...) instead. */ @Override public void initialise() { throw new RuntimeException("Please do not use initialise(). For this class use initialise(...) instead."); } /** * Initializes the DownSamplerNode instance. This method is meant to be called once, shortly after instantiation. * * @param inputConfig an FBOConfig instance describing the input FBO, to be retrieved from the FBO manager * @param inputManager the FBO manager from which to retrieve the input FBO * @param outputConfig an FBOConfig instance describing the output FBO, to be retrieved from the FBO manager * @param outputManager the FBO manager from which to retrieve the output FBO * @param aLabel a String to label the instance's entry in output generated by the PerformanceMonitor */ public void initialise(FBOConfig inputConfig, BaseFBOsManager inputManager, FBOConfig outputConfig, BaseFBOsManager outputManager, String aLabel) { this.outputFBOconfig = outputConfig; this.outputFBOmanager = outputManager; requiresFBO(inputConfig, inputManager); requiresFBO(outputConfig, outputManager); outputFBO = outputManager.get(this.outputFBOconfig.getName()); outputManager.subscribe(this); addDesiredStateChange(new BindFBO(outputConfig.getName(), outputManager)); addDesiredStateChange(new SetViewportToSizeOf(outputConfig.getName(), outputManager)); addDesiredStateChange(new SetInputTextureFromFBO(SLOT_0, inputConfig.getName(), ColorTexture, inputManager, DOWN_SAMPLER_MATERIAL, TEXTURE_NAME)); setupConditions(); addDesiredStateChange(new EnableMaterial(DOWN_SAMPLER_MATERIAL.toString())); downSampler = getMaterial(DOWN_SAMPLER_MATERIAL); this.performanceMonitorLabel = aLabel; } /** * This method does nothing. It is meant to be overridden by inheriting classes if needed. * On the other hand, there might be situations in which downsampling should always occur, * in which case this DownSamplerNode class is good as it is. */ protected void setupConditions() { } /** * Processes the input FBO downsampling its color attachment into the color attachment of the output FBO. */ @Override public void process() { PerformanceMonitor.startActivity(performanceMonitorLabel); downSampler.setFloat("size", outputFBO.width(), true); renderFullscreenQuad(); PerformanceMonitor.endActivity(); } @Override public void update() { // Note: we don't need to update the inputFBO because only SetInputTextureFromFBO // needs to keep it up to date and takes care of that internally. outputFBO = outputFBOmanager.get(outputFBOconfig.getName()); } }