Home | History | Annotate | Download | only in glutils
      1 
      2 package com.badlogic.gdx.graphics.glutils;
      3 
      4 import com.badlogic.gdx.Gdx;
      5 import com.badlogic.gdx.files.FileHandle;
      6 import com.badlogic.gdx.graphics.Cubemap;
      7 import com.badlogic.gdx.graphics.Cubemap.CubemapSide;
      8 import com.badlogic.gdx.graphics.CubemapData;
      9 import com.badlogic.gdx.graphics.GL20;
     10 import com.badlogic.gdx.graphics.GLTexture;
     11 import com.badlogic.gdx.graphics.Pixmap;
     12 import com.badlogic.gdx.graphics.Pixmap.Blending;
     13 import com.badlogic.gdx.graphics.Pixmap.Format;
     14 import com.badlogic.gdx.graphics.Texture;
     15 import com.badlogic.gdx.graphics.TextureData;
     16 import com.badlogic.gdx.utils.GdxRuntimeException;
     17 
     18 /** A FacedCubemapData holds a cubemap data definition based on a {@link TextureData} per face.
     19  *
     20  * @author Vincent Nousquet */
     21 public class FacedCubemapData implements CubemapData {
     22 
     23 	protected final TextureData[] data = new TextureData[6];
     24 
     25 	/** Construct an empty Cubemap. Use the load(...) methods to set the texture of each side. Every side of the cubemap must be set
     26 	 * before it can be used. */
     27 	public FacedCubemapData () {
     28 		this((TextureData)null, (TextureData)null, (TextureData)null, (TextureData)null, (TextureData)null, (TextureData)null);
     29 	}
     30 
     31 	/** Construct a Cubemap with the specified texture files for the sides, optionally generating mipmaps. */
     32 	public FacedCubemapData (FileHandle positiveX, FileHandle negativeX, FileHandle positiveY, FileHandle negativeY,
     33 		FileHandle positiveZ, FileHandle negativeZ) {
     34 		this(TextureData.Factory.loadFromFile(positiveX, false), TextureData.Factory.loadFromFile(negativeX,
     35 			false), TextureData.Factory.loadFromFile(positiveY, false), TextureData.Factory.loadFromFile(
     36 			negativeY, false), TextureData.Factory.loadFromFile(positiveZ, false), TextureData.Factory
     37 			.loadFromFile(negativeZ, false));
     38 	}
     39 
     40 	/** Construct a Cubemap with the specified texture files for the sides, optionally generating mipmaps. */
     41 	public FacedCubemapData (FileHandle positiveX, FileHandle negativeX, FileHandle positiveY, FileHandle negativeY,
     42 		FileHandle positiveZ, FileHandle negativeZ, boolean useMipMaps) {
     43 		this(TextureData.Factory.loadFromFile(positiveX, useMipMaps), TextureData.Factory.loadFromFile(
     44 			negativeX, useMipMaps), TextureData.Factory.loadFromFile(positiveY, useMipMaps), TextureData.Factory
     45 			.loadFromFile(negativeY, useMipMaps), TextureData.Factory.loadFromFile(positiveZ, useMipMaps),
     46 			TextureData.Factory.loadFromFile(negativeZ, useMipMaps));
     47 	}
     48 
     49 	/** Construct a Cubemap with the specified {@link Pixmap}s for the sides, does not generate mipmaps. */
     50 	public FacedCubemapData (Pixmap positiveX, Pixmap negativeX, Pixmap positiveY, Pixmap negativeY, Pixmap positiveZ,
     51 		Pixmap negativeZ) {
     52 		this(positiveX, negativeX, positiveY, negativeY, positiveZ, negativeZ, false);
     53 	}
     54 
     55 	/** Construct a Cubemap with the specified {@link Pixmap}s for the sides, optionally generating mipmaps. */
     56 	public FacedCubemapData (Pixmap positiveX, Pixmap negativeX, Pixmap positiveY, Pixmap negativeY, Pixmap positiveZ,
     57 		Pixmap negativeZ, boolean useMipMaps) {
     58 		this(positiveX == null ? null : new PixmapTextureData(positiveX, null, useMipMaps, false), negativeX == null ? null
     59 			: new PixmapTextureData(negativeX, null, useMipMaps, false), positiveY == null ? null : new PixmapTextureData(positiveY,
     60 			null, useMipMaps, false), negativeY == null ? null : new PixmapTextureData(negativeY, null, useMipMaps, false),
     61 			positiveZ == null ? null : new PixmapTextureData(positiveZ, null, useMipMaps, false), negativeZ == null ? null
     62 				: new PixmapTextureData(negativeZ, null, useMipMaps, false));
     63 	}
     64 
     65 	/** Construct a Cubemap with {@link Pixmap}s for each side of the specified size. */
     66 	public FacedCubemapData (int width, int height, int depth, Format format) {
     67 		this(new PixmapTextureData(new Pixmap(depth, height, format), null, false, true), new PixmapTextureData(new Pixmap(depth,
     68 			height, format), null, false, true), new PixmapTextureData(new Pixmap(width, depth, format), null, false, true),
     69 			new PixmapTextureData(new Pixmap(width, depth, format), null, false, true), new PixmapTextureData(new Pixmap(width,
     70 				height, format), null, false, true), new PixmapTextureData(new Pixmap(width, height, format), null, false, true));
     71 	}
     72 
     73 	/** Construct a Cubemap with the specified {@link TextureData}'s for the sides */
     74 	public FacedCubemapData (TextureData positiveX, TextureData negativeX, TextureData positiveY, TextureData negativeY,
     75 		TextureData positiveZ, TextureData negativeZ) {
     76 		data[0] = positiveX;
     77 		data[1] = negativeX;
     78 		data[2] = positiveY;
     79 		data[3] = negativeY;
     80 		data[4] = positiveZ;
     81 		data[5] = negativeZ;
     82 	}
     83 
     84 	@Override
     85 	public boolean isManaged () {
     86 		for (TextureData data : this.data)
     87 			if (!data.isManaged()) return false;
     88 		return true;
     89 	}
     90 
     91 	/** Loads the texture specified using the {@link FileHandle} and sets it to specified side, overwriting any previous data set to
     92 	 * that side. Note that you need to reload through {@link Cubemap#load(CubemapData)} any cubemap using this data for the change
     93 	 * to be taken in account.
     94 	 * @param side The {@link CubemapSide}
     95 	 * @param file The texture {@link FileHandle} */
     96 	public void load (CubemapSide side, FileHandle file) {
     97 		data[side.index] = TextureData.Factory.loadFromFile(file, false);
     98 	}
     99 
    100 	/** Sets the specified side of this cubemap to the specified {@link Pixmap}, overwriting any previous data set to that side.
    101 	 * Note that you need to reload through {@link Cubemap#load(CubemapData)} any cubemap using this data for the change to be
    102 	 * taken in account.
    103 	 * @param side The {@link CubemapSide}
    104 	 * @param pixmap The {@link Pixmap} */
    105 	public void load (CubemapSide side, Pixmap pixmap) {
    106 		data[side.index] = pixmap == null ? null : new PixmapTextureData(pixmap, null, false, false);
    107 	}
    108 
    109 	/** @return True if all sides of this cubemap are set, false otherwise. */
    110 	public boolean isComplete () {
    111 		for (int i = 0; i < data.length; i++)
    112 			if (data[i] == null) return false;
    113 		return true;
    114 	}
    115 
    116 	/** @return The {@link TextureData} for the specified side, can be null if the cubemap is incomplete. */
    117 	public TextureData getTextureData (CubemapSide side) {
    118 		return data[side.index];
    119 	}
    120 
    121 	@Override
    122 	public int getWidth () {
    123 		int tmp, width = 0;
    124 		if (data[CubemapSide.PositiveZ.index] != null && (tmp = data[CubemapSide.PositiveZ.index].getWidth()) > width) width = tmp;
    125 		if (data[CubemapSide.NegativeZ.index] != null && (tmp = data[CubemapSide.NegativeZ.index].getWidth()) > width) width = tmp;
    126 		if (data[CubemapSide.PositiveY.index] != null && (tmp = data[CubemapSide.PositiveY.index].getWidth()) > width) width = tmp;
    127 		if (data[CubemapSide.NegativeY.index] != null && (tmp = data[CubemapSide.NegativeY.index].getWidth()) > width) width = tmp;
    128 		return width;
    129 	}
    130 
    131 	@Override
    132 	public int getHeight () {
    133 		int tmp, height = 0;
    134 		if (data[CubemapSide.PositiveZ.index] != null && (tmp = data[CubemapSide.PositiveZ.index].getHeight()) > height)
    135 			height = tmp;
    136 		if (data[CubemapSide.NegativeZ.index] != null && (tmp = data[CubemapSide.NegativeZ.index].getHeight()) > height)
    137 			height = tmp;
    138 		if (data[CubemapSide.PositiveX.index] != null && (tmp = data[CubemapSide.PositiveX.index].getHeight()) > height)
    139 			height = tmp;
    140 		if (data[CubemapSide.NegativeX.index] != null && (tmp = data[CubemapSide.NegativeX.index].getHeight()) > height)
    141 			height = tmp;
    142 		return height;
    143 	}
    144 
    145 	@Override
    146 	public boolean isPrepared () {
    147 		return false;
    148 	}
    149 
    150 	@Override
    151 	public void prepare () {
    152 		if (!isComplete()) throw new GdxRuntimeException("You need to complete your cubemap data before using it");
    153 		for (int i = 0; i < data.length; i++)
    154 			if (!data[i].isPrepared()) data[i].prepare();
    155 	}
    156 
    157 	@Override
    158 	public void consumeCubemapData () {
    159 		for (int i = 0; i < data.length; i++) {
    160 			if (data[i].getType() == TextureData.TextureDataType.Custom) {
    161 				data[i].consumeCustomData(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i);
    162 			} else {
    163 				Pixmap pixmap = data[i].consumePixmap();
    164 				boolean disposePixmap = data[i].disposePixmap();
    165 				if (data[i].getFormat() != pixmap.getFormat()) {
    166 					Pixmap tmp = new Pixmap(pixmap.getWidth(), pixmap.getHeight(), data[i].getFormat());
    167 					Blending blend = Pixmap.getBlending();
    168 					Pixmap.setBlending(Blending.None);
    169 					tmp.drawPixmap(pixmap, 0, 0, 0, 0, pixmap.getWidth(), pixmap.getHeight());
    170 					Pixmap.setBlending(blend);
    171 					if (data[i].disposePixmap()) pixmap.dispose();
    172 					pixmap = tmp;
    173 					disposePixmap = true;
    174 				}
    175 				Gdx.gl.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 1);
    176 				Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, pixmap.getGLInternalFormat(), pixmap.getWidth(),
    177 					pixmap.getHeight(), 0, pixmap.getGLFormat(), pixmap.getGLType(), pixmap.getPixels());
    178 			}
    179 		}
    180 	}
    181 
    182 }
    183