1 /* 2 * Copyright (c) 2009-2010 jMonkeyEngine 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 package jme3tools.converters; 34 35 import com.jme3.math.FastMath; 36 import com.jme3.texture.Image; 37 import com.jme3.texture.Image.Format; 38 import com.jme3.texture.plugins.AWTLoader; 39 import com.jme3.util.BufferUtils; 40 import java.awt.Graphics2D; 41 import java.awt.RenderingHints; 42 import java.awt.image.BufferedImage; 43 import java.nio.ByteBuffer; 44 import java.util.ArrayList; 45 46 public class MipMapGenerator { 47 scaleDown(BufferedImage sourceImage, int targetWidth, int targetHeight)48 private static BufferedImage scaleDown(BufferedImage sourceImage, int targetWidth, int targetHeight) { 49 int sourceWidth = sourceImage.getWidth(); 50 int sourceHeight = sourceImage.getHeight(); 51 52 BufferedImage targetImage = new BufferedImage(targetWidth, targetHeight, sourceImage.getType()); 53 54 Graphics2D g = targetImage.createGraphics(); 55 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); 56 g.drawImage(sourceImage, 0, 0, targetWidth, targetHeight, 0, 0, sourceWidth, sourceHeight, null); 57 g.dispose(); 58 59 return targetImage; 60 } 61 resizeToPowerOf2(Image image)62 public static void resizeToPowerOf2(Image image){ 63 BufferedImage original = ImageToAwt.convert(image, false, true, 0); 64 int potWidth = FastMath.nearestPowerOfTwo(image.getWidth()); 65 int potHeight = FastMath.nearestPowerOfTwo(image.getHeight()); 66 int potSize = Math.max(potWidth, potHeight); 67 68 BufferedImage scaled = scaleDown(original, potSize, potSize); 69 70 AWTLoader loader = new AWTLoader(); 71 Image output = loader.load(scaled, false); 72 73 image.setWidth(potSize); 74 image.setHeight(potSize); 75 image.setDepth(0); 76 image.setData(output.getData(0)); 77 image.setFormat(output.getFormat()); 78 image.setMipMapSizes(null); 79 } 80 generateMipMaps(Image image)81 public static void generateMipMaps(Image image){ 82 BufferedImage original = ImageToAwt.convert(image, false, true, 0); 83 int width = original.getWidth(); 84 int height = original.getHeight(); 85 int level = 0; 86 87 BufferedImage current = original; 88 AWTLoader loader = new AWTLoader(); 89 ArrayList<ByteBuffer> output = new ArrayList<ByteBuffer>(); 90 int totalSize = 0; 91 Format format = null; 92 93 while (height >= 1 || width >= 1){ 94 Image converted = loader.load(current, false); 95 format = converted.getFormat(); 96 output.add(converted.getData(0)); 97 totalSize += converted.getData(0).capacity(); 98 99 if(height == 1 || width == 1) { 100 break; 101 } 102 103 level++; 104 105 height /= 2; 106 width /= 2; 107 108 current = scaleDown(current, width, height); 109 } 110 111 ByteBuffer combinedData = BufferUtils.createByteBuffer(totalSize); 112 int[] mipSizes = new int[output.size()]; 113 for (int i = 0; i < output.size(); i++){ 114 ByteBuffer data = output.get(i); 115 data.clear(); 116 combinedData.put(data); 117 mipSizes[i] = data.capacity(); 118 } 119 combinedData.flip(); 120 121 // insert mip data into image 122 image.setData(0, combinedData); 123 image.setMipMapSizes(mipSizes); 124 image.setFormat(format); 125 } 126 127 } 128