Home | History | Annotate | Download | only in utils
      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