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
17package com.badlogic.gdx.graphics;
18
19import com.badlogic.gdx.Application;
20import com.badlogic.gdx.Gdx;
21import com.badlogic.gdx.assets.AssetManager;
22import com.badlogic.gdx.assets.loaders.AssetLoader;
23import com.badlogic.gdx.files.FileHandle;
24import com.badlogic.gdx.graphics.profiling.GLProfiler;
25import com.badlogic.gdx.utils.Array;
26import com.badlogic.gdx.utils.GdxRuntimeException;
27
28import java.util.HashMap;
29import java.util.Map;
30
31/**
32 * Open GLES wrapper for TextureArray
33 * @author Tomski */
34public class TextureArray extends GLTexture {
35
36	final static Map<Application, Array<TextureArray>> managedTextureArrays = new HashMap<Application, Array<TextureArray>>();
37
38	private TextureArrayData data;
39
40	public TextureArray (String... internalPaths) {
41		this(getInternalHandles(internalPaths));
42	}
43
44	public TextureArray (FileHandle... files) {
45		this(false, files);
46	}
47
48	public TextureArray (boolean useMipMaps, FileHandle... files) {
49		this(useMipMaps, Pixmap.Format.RGBA8888, files);
50	}
51
52	public TextureArray (boolean useMipMaps, Pixmap.Format format, FileHandle... files) {
53		this(TextureArrayData.Factory.loadFromFiles(format, useMipMaps, files));
54	}
55
56	public TextureArray (TextureArrayData data) {
57		super(GL30.GL_TEXTURE_2D_ARRAY, Gdx.gl.glGenTexture());
58
59		if (Gdx.gl30 == null) {
60			throw new GdxRuntimeException("TextureArray requires a device running with GLES 3.0 compatibilty");
61		}
62
63		load(data);
64
65		if (data.isManaged()) addManagedTexture(Gdx.app, this);
66	}
67
68	private static FileHandle[] getInternalHandles (String... internalPaths) {
69		FileHandle[] handles = new FileHandle[internalPaths.length];
70		for (int i = 0; i < internalPaths.length; i++) {
71			handles[i] = Gdx.files.internal(internalPaths[i]);
72		}
73		return handles;
74	}
75
76	private void load (TextureArrayData data) {
77		if (this.data != null && data.isManaged() != this.data.isManaged())
78			throw new GdxRuntimeException("New data must have the same managed status as the old data");
79		this.data = data;
80
81		bind();
82		Gdx.gl30.glTexImage3D(GL30.GL_TEXTURE_2D_ARRAY, 0, data.getInternalFormat(), data.getWidth(), data.getHeight(), data.getDepth(), 0, data.getInternalFormat(), data.getGLType(), null);
83
84		if (!data.isPrepared()) data.prepare();
85
86		data.consumeTextureArrayData();
87
88		setFilter(minFilter, magFilter);
89		setWrap(uWrap, vWrap);
90		Gdx.gl.glBindTexture(glTarget, 0);
91	}
92
93	@Override
94	public int getWidth () {
95		return data.getWidth();
96	}
97
98	@Override
99	public int getHeight () {
100		return data.getHeight();
101	}
102
103	@Override
104	public int getDepth () {
105		return data.getDepth();
106	}
107
108	@Override
109	public boolean isManaged () {
110		return data.isManaged();
111	}
112
113	@Override
114	protected void reload () {
115		if (!isManaged()) throw new GdxRuntimeException("Tried to reload an unmanaged TextureArray");
116		glHandle = Gdx.gl.glGenTexture();
117		load(data);
118	}
119
120	private static void addManagedTexture (Application app, TextureArray texture) {
121		Array<TextureArray> managedTextureArray = managedTextureArrays.get(app);
122		if (managedTextureArray == null) managedTextureArray = new Array<TextureArray>();
123		managedTextureArray.add(texture);
124		managedTextureArrays.put(app, managedTextureArray);
125	}
126
127
128	/** Clears all managed TextureArrays. This is an internal method. Do not use it! */
129	public static void clearAllTextureArrays (Application app) {
130		managedTextureArrays.remove(app);
131	}
132
133	/** Invalidate all managed TextureArrays. This is an internal method. Do not use it! */
134	public static void invalidateAllTextureArrays (Application app) {
135		Array<TextureArray> managedTextureArray = managedTextureArrays.get(app);
136		if (managedTextureArray == null) return;
137
138		for (int i = 0; i < managedTextureArray.size; i++) {
139			TextureArray textureArray = managedTextureArray.get(i);
140			textureArray.reload();
141		}
142	}
143
144	public static String getManagedStatus () {
145		StringBuilder builder = new StringBuilder();
146		builder.append("Managed TextureArrays/app: { ");
147		for (Application app : managedTextureArrays.keySet()) {
148			builder.append(managedTextureArrays.get(app).size);
149			builder.append(" ");
150		}
151		builder.append("}");
152		return builder.toString();
153	}
154
155	/** @return the number of managed TextureArrays currently loaded */
156	public static int getNumManagedTextureArrays () {
157		return managedTextureArrays.get(Gdx.app).size;
158	}
159
160}
161