/* * 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; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import org.terasology.assets.ResourceUrn; /** * Builder class to simplify the syntax creating an FBO. * <p> * Once the desired characteristics of the FBO are set via the Builder's constructor and its * use*Buffer() methods, the build() method can be called for the actual FBO to be generated, * alongside the underlying FrameBuffer and its attachments on the GPU. * <p> * The new FBO is automatically registered with the LwjglRenderingProcess, overwriting any * existing FBO with the same title. */ public class FBOConfig { private ResourceUrn fboName; private FBO.Dimensions dimensions; private FBO.Type type; private boolean useDepthBuffer; private boolean useNormalBuffer; private boolean useLightBuffer; private boolean useStencilBuffer; private float scale; /** * Constructs an FBO builder capable of building the two most basic FBOs: * an FBO with no attachments or one with a single color buffer attached to it. * <p> * To attach additional buffers, see the use*Buffer() methods. * <p> * Example: FBO basicFBO = new FBObuilder("basic", new Dimensions(1920, 1080), Type.DEFAULT).build(); * * @param fboName A string identifier, the title is used to later manipulate the FBO through * methods such as LwjglRenderingProcess.getFBO(title) and LwjglRenderingProcess.bindFBO(title). * @param dimensions A Dimensions object providing width and height information. * @param type Type.DEFAULT will result in a 32 bit color buffer attached to the FBO. (GL_RGBA, GL11.GL_UNSIGNED_BYTE, GL_LINEAR) * Type.HDR will result in a 64 bit color buffer attached to the FBO. (GL_RGBA, GL_HALF_FLOAT_ARB, GL_LINEAR) * Type.NO_COLOR will result in -no- color buffer attached to the FBO * (WARNING: this could result in an FBO with Status.DISPOSED - see FBO.getStatus()). */ public FBOConfig(ResourceUrn fboName, FBO.Dimensions dimensions, FBO.Type type) { this.fboName = fboName; this.dimensions = dimensions; this.type = type; } /** * Same as the previous FBObuilder constructor, but taking in input * explicit, integer width and height instead of a Dimensions object. */ public FBOConfig(ResourceUrn fboName, int width, int height, FBO.Type type) { this(fboName, new FBO.Dimensions(width, height), type); } public FBOConfig(ResourceUrn fboName, ScalingFactors factors, FBO.Type type) { this.fboName = fboName; this.type = type; this.scale = factors.getScale(); } public FBOConfig(ResourceUrn fboName, float scale, FBO.Type type) { Preconditions.checkArgument(scale != 0, "scale can not be zero."); this.fboName = fboName; this.type = type; this.scale = scale; } public FBOConfig(ResourceUrn fboName, FBO.Type type) { this.fboName = fboName; this.type = type; } /** * Sets the builder to generate, allocate and attach a 24 bit depth buffer to the FrameBuffer to be built. * If useStencilBuffer() is also used, an 8 bit stencil buffer will also be associated with the depth buffer. * For details on the specific characteristics of the buffers, see the FBO.create() method. * * @return The calling instance, to chain calls, i.e.: new FBObuilder(...).useDepthBuffer().build(); */ public FBOConfig useDepthBuffer() { useDepthBuffer = true; return this; } /** * Sets the builder to generate, allocate and attach a normals buffer to the FrameBuffer to be built. * For details on the specific characteristics of the buffer, see the FBO.create() method. * * @return The calling instance, to chain calls, i.e.: new FBObuilder(...).useNormalsBuffer().build(); */ public FBOConfig useNormalBuffer() { useNormalBuffer = true; return this; } /** * Sets the builder to generate, allocate and attach a light buffer to the FrameBuffer to be built. * Be aware that the number of bits per channel for this buffer changes with the set FBO.Type. * For details see the FBO.create() method. * * @return The calling instance, to chain calls, i.e.: new FBObuilder(...).useLightBuffer().build(); */ public FBOConfig useLightBuffer() { useLightBuffer = true; return this; } /** * -IF- the builder has been set to generate a depth buffer, using this method sets the builder to * generate a depth buffer inclusive of stencil buffer, with the following characteristics: * internal format GL_DEPTH24_STENCIL8_EXT, data type GL_UNSIGNED_INT_24_8_EXT and filtering GL_NEAREST. * * @return The calling instance of FBObuilder, to chain calls, * i.e.: new FBObuilder(...).useDepthBuffer().useStencilBuffer().build(); */ public FBOConfig useStencilBuffer() { useStencilBuffer = true; return this; } // TODO: add javadocs public boolean hasDepthBuffer() { return useDepthBuffer; } public boolean hasNormalBuffer() { return useNormalBuffer; } public boolean hasLightBuffer() { return useLightBuffer; } public boolean hasStencilBuffer() { return useStencilBuffer; } public FBO.Type getType() { return type; } public float getScale() { return scale; } public FBO.Dimensions getDimensions() { return dimensions; } public ResourceUrn getName() { return fboName; } public void setDimensions(FBO.Dimensions dimensions) { this.dimensions = dimensions; } @Override public int hashCode() { // TODO: add scale and dimension return Objects.hashCode(fboName, type, useDepthBuffer, useNormalBuffer, useLightBuffer, useStencilBuffer); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof FBOConfig) { // TODO: add scale and dimension check here FBOConfig config = (FBOConfig) obj; return this.fboName.equals(config.getName()) && this.type == config.getType() && this.useDepthBuffer == config.useDepthBuffer && this.useNormalBuffer == config.useNormalBuffer && this.useLightBuffer == config.useLightBuffer && this.useStencilBuffer == config.useStencilBuffer; } return false; } }