/* * 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.opengl.fbms; import org.lwjgl.opengl.Display; import org.terasology.assets.ResourceUrn; import org.terasology.config.Config; import org.terasology.config.RenderingConfig; import org.terasology.context.Context; import org.terasology.rendering.opengl.AbstractFBOsManager; import org.terasology.rendering.opengl.DefaultDynamicFBOs; import static org.terasology.rendering.opengl.DefaultDynamicFBOs.FINAL; import static org.terasology.rendering.opengl.DefaultDynamicFBOs.READ_ONLY_GBUFFER; import static org.terasology.rendering.opengl.DefaultDynamicFBOs.WRITE_ONLY_GBUFFER; import org.terasology.rendering.opengl.FBO; import org.terasology.rendering.opengl.FBOConfig; import org.terasology.rendering.opengl.ScreenGrabber; /** * TODO: Add javadocs * TODO: Better naming */ public class DisplayResolutionDependentFBOs extends AbstractFBOsManager { private FBO.Dimensions fullScale; private RenderingConfig renderingConfig; private ScreenGrabber screenGrabber; public DisplayResolutionDependentFBOs(Context context) { renderingConfig = context.get(Config.class).getRendering(); screenGrabber = context.get(ScreenGrabber.class); fullScale = new FBO.Dimensions(Display.getWidth(), Display.getHeight()); generateDefaultFBOs(); } private void generateDefaultFBOs() { generateDefaultFBO(READ_ONLY_GBUFFER); generateDefaultFBO(WRITE_ONLY_GBUFFER); generateDefaultFBO(FINAL); } private void generateDefaultFBO(DefaultDynamicFBOs defaultDynamicFBO) { FBOConfig fboConfig = defaultDynamicFBO.getConfig(); FBO fbo = generateWithDimensions(fboConfig, fullScale.multiplyBy(fboConfig.getScale())); defaultDynamicFBO.setFbo(fbo); defaultDynamicFBO.setFrameBufferManager(this); } @Override public FBO request(FBOConfig fboConfig) { FBO fbo; ResourceUrn fboName = fboConfig.getName(); if (fboConfigs.containsKey(fboName)) { if (!fboConfig.equals(fboConfigs.get(fboName))) { throw new IllegalArgumentException("Requested FBO is already available with different configuration"); } fbo = fboLookup.get(fboConfig.getName()); } else { fbo = generateWithDimensions(fboConfig, fullScale.multiplyBy(fboConfig.getScale())); } retain(fboName); return fbo; } private void updateFullScale() { if (screenGrabber.isNotTakingScreenshot()) { fullScale = new FBO.Dimensions(Display.getWidth(), Display.getHeight()); } else { fullScale = new FBO.Dimensions( renderingConfig.getScreenshotSize().getWidth(Display.getWidth()), renderingConfig.getScreenshotSize().getHeight(Display.getHeight()) ); } fullScale.multiplySelfBy(renderingConfig.getFboScale() / 100f); } /** * Invoked before real-rendering starts * TODO: how about completely removing this, and make Display observable and this FBM as an observer */ public void update() { updateFullScale(); if (READ_ONLY_GBUFFER.getFbo().dimensions().areDifferentFrom(fullScale)) { disposeAllFBOs(); createFBOs(); updateDefaultFBOs(); notifySubscribers(); } } private void disposeAllFBOs() { for (ResourceUrn urn : fboConfigs.keySet()) { fboLookup.get(urn).dispose(); } fboLookup.clear(); } private void createFBOs() { for (FBOConfig fboConfig : fboConfigs.values()) { generateWithDimensions(fboConfig, fullScale.multiplyBy(fboConfig.getScale())); } } private void updateDefaultFBOs() { READ_ONLY_GBUFFER.setFbo(fboLookup.get(READ_ONLY_GBUFFER.getName())); WRITE_ONLY_GBUFFER.setFbo(fboLookup.get(WRITE_ONLY_GBUFFER.getName())); FINAL.setFbo(fboLookup.get(FINAL.getName())); } // TODO: Pairing FBOs for swapping functionality public void swapReadWriteBuffers() { FBO fbo = READ_ONLY_GBUFFER.getFbo(); READ_ONLY_GBUFFER.setFbo(WRITE_ONLY_GBUFFER.getFbo()); WRITE_ONLY_GBUFFER.setFbo(fbo); fboLookup.put(READ_ONLY_GBUFFER.getName(), READ_ONLY_GBUFFER.getFbo()); fboLookup.put(WRITE_ONLY_GBUFFER.getName(), WRITE_ONLY_GBUFFER.getFbo()); notifySubscribers(); } }