/******************************************************************************* * Copyright 2011 See AUTHORS file. * * 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 com.badlogic.gdx.tests.g3d.shadows.utils; import com.badlogic.gdx.graphics.g3d.environment.BaseLight; import com.badlogic.gdx.utils.GdxRuntimeException; /** FixedShadowMapAllocator behavior is naive. It separates the texture in several parts and for each light increments the region. * The larger the size, the better the quality or quantity. * <p> * Examples: <br /> * If you set size to QUALITY_MAX and mapQuantity to NB_MAP_MIN, each depth map would be 2048*2048 (it's huge!).<br /> * If you set size to QUALITY_MIN and mapQuantity to NB_MAP_MAX, each depth map would be 64*64. * </p> * @author realitix */ public class FixedShadowMapAllocator implements ShadowMapAllocator { /** Helpers to choose shadow map quality */ public static final int QUALITY_MIN = 1024; public static final int QUALITY_MED = 2048; public static final int QUALITY_MAX = 4096; /** Helpers to choose number of supported shadows */ public static final int QUANTITY_MAP_MIN = 4; public static final int QUANTITY_MAP_MED = 16; public static final int QUANTITY_MAP_MAX = 32; /** Shadow map size (Width = Height) */ protected final int size; /** Quantity of renderable parts */ protected final int mapQuantity; /** Current rendered part */ protected int currentMap; /** Result region */ protected ShadowMapRegion result = new ShadowMapRegion(); /** Is in allocation state */ protected boolean allocating = false; /** Create new FixedShadowMapAllocator * @param size Size of shadow map * @param nbMap Quantity of supported regions */ public FixedShadowMapAllocator (int size, int nbMap) { this.size = size; this.mapQuantity = nbMap; } @Override public int getWidth () { return size; } @Override public int getHeight () { return size; } /** @return Quantity of supported regions. */ public int getMapQuantity () { return mapQuantity; } @Override public void begin () { if (allocating) { throw new GdxRuntimeException("Allocator must end before begin"); } allocating = true; currentMap = 0; } @Override public void end () { if (!allocating) { throw new GdxRuntimeException("Allocator must begin before end"); } allocating = false; } @Override public ShadowMapRegion nextResult (BaseLight light) { if (!allocating) { throw new GdxRuntimeException("Allocator must begin before call"); } int nbOnLine = (int)Math.round(Math.sqrt(mapQuantity)); int i = currentMap % nbOnLine; int j = currentMap / nbOnLine; int sizeMap = size / nbOnLine; result.x = i * sizeMap; result.y = j * sizeMap; result.width = sizeMap; result.height = sizeMap; if (result.x >= size || result.y >= size) return null; currentMap += 1; return result; } }