1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tests.g3d.shadows.utils; 18 19 import com.badlogic.gdx.graphics.g3d.environment.BaseLight; 20 import com.badlogic.gdx.utils.GdxRuntimeException; 21 22 /** FixedShadowMapAllocator behavior is naive. It separates the texture in several parts and for each light increments the region. 23 * The larger the size, the better the quality or quantity. 24 * <p> 25 * Examples: <br /> 26 * If you set size to QUALITY_MAX and mapQuantity to NB_MAP_MIN, each depth map would be 2048*2048 (it's huge!).<br /> 27 * If you set size to QUALITY_MIN and mapQuantity to NB_MAP_MAX, each depth map would be 64*64. 28 * </p> 29 * @author realitix */ 30 public class FixedShadowMapAllocator implements ShadowMapAllocator { 31 /** Helpers to choose shadow map quality */ 32 public static final int QUALITY_MIN = 1024; 33 public static final int QUALITY_MED = 2048; 34 public static final int QUALITY_MAX = 4096; 35 36 /** Helpers to choose number of supported shadows */ 37 public static final int QUANTITY_MAP_MIN = 4; 38 public static final int QUANTITY_MAP_MED = 16; 39 public static final int QUANTITY_MAP_MAX = 32; 40 41 /** Shadow map size (Width = Height) */ 42 protected final int size; 43 /** Quantity of renderable parts */ 44 protected final int mapQuantity; 45 /** Current rendered part */ 46 protected int currentMap; 47 /** Result region */ 48 protected ShadowMapRegion result = new ShadowMapRegion(); 49 /** Is in allocation state */ 50 protected boolean allocating = false; 51 52 /** Create new FixedShadowMapAllocator 53 * @param size Size of shadow map 54 * @param nbMap Quantity of supported regions */ 55 public FixedShadowMapAllocator (int size, int nbMap) { 56 this.size = size; 57 this.mapQuantity = nbMap; 58 } 59 60 @Override 61 public int getWidth () { 62 return size; 63 } 64 65 @Override 66 public int getHeight () { 67 return size; 68 } 69 70 /** @return Quantity of supported regions. */ 71 public int getMapQuantity () { 72 return mapQuantity; 73 } 74 75 @Override 76 public void begin () { 77 if (allocating) { 78 throw new GdxRuntimeException("Allocator must end before begin"); 79 } 80 allocating = true; 81 currentMap = 0; 82 } 83 84 @Override 85 public void end () { 86 if (!allocating) { 87 throw new GdxRuntimeException("Allocator must begin before end"); 88 } 89 allocating = false; 90 } 91 92 @Override 93 public ShadowMapRegion nextResult (BaseLight light) { 94 if (!allocating) { 95 throw new GdxRuntimeException("Allocator must begin before call"); 96 } 97 98 int nbOnLine = (int)Math.round(Math.sqrt(mapQuantity)); 99 int i = currentMap % nbOnLine; 100 int j = currentMap / nbOnLine; 101 int sizeMap = size / nbOnLine; 102 103 result.x = i * sizeMap; 104 result.y = j * sizeMap; 105 result.width = sizeMap; 106 result.height = sizeMap; 107 108 if (result.x >= size || result.y >= size) return null; 109 110 currentMap += 1; 111 112 return result; 113 } 114 } 115