• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.graphics;
18 
19 import com.badlogic.gdx.Gdx;
20 import com.badlogic.gdx.graphics.Pixmap.Blending;
21 import com.badlogic.gdx.graphics.Texture.TextureFilter;
22 import com.badlogic.gdx.graphics.Texture.TextureWrap;
23 import com.badlogic.gdx.graphics.TextureData.TextureDataType;
24 import com.badlogic.gdx.graphics.glutils.MipMapGenerator;
25 import com.badlogic.gdx.utils.Disposable;
26 
27 /** Class representing an OpenGL texture by its target and handle. Keeps track of its state like the TextureFilter and TextureWrap.
28  * Also provides some (protected) static methods to create TextureData and upload image data.
29  * @author badlogic, Xoppa */
30 public abstract class GLTexture implements Disposable {
31 	/** The target of this texture, used when binding the texture, e.g. GL_TEXTURE_2D */
32 	public final int glTarget;
33 	protected int glHandle;
34 	protected TextureFilter minFilter = TextureFilter.Nearest;
35 	protected TextureFilter magFilter = TextureFilter.Nearest;
36 	protected TextureWrap uWrap = TextureWrap.ClampToEdge;
37 	protected TextureWrap vWrap = TextureWrap.ClampToEdge;
38 
39 	/** @return the width of the texture in pixels */
getWidth()40 	public abstract int getWidth ();
41 
42 	/** @return the height of the texture in pixels */
getHeight()43 	public abstract int getHeight ();
44 
45 	/** @return the depth of the texture in pixels */
getDepth()46 	public abstract int getDepth ();
47 
48 	/** Generates a new OpenGL texture with the specified target. */
GLTexture(int glTarget)49 	public GLTexture (int glTarget) {
50 		this(glTarget, Gdx.gl.glGenTexture ());
51 	}
52 
GLTexture(int glTarget, int glHandle)53 	public GLTexture (int glTarget, int glHandle) {
54 		this.glTarget = glTarget;
55 		this.glHandle = glHandle;
56 	}
57 
58 	/** @return whether this texture is managed or not. */
isManaged()59 	public abstract boolean isManaged ();
60 
reload()61 	protected abstract void reload ();
62 
63 	/** Binds this texture. The texture will be bound to the currently active texture unit specified via
64 	 * {@link GL20#glActiveTexture(int)}. */
bind()65 	public void bind () {
66 		Gdx.gl.glBindTexture(glTarget, glHandle);
67 	}
68 
69 	/** Binds the texture to the given texture unit. Sets the currently active texture unit via {@link GL20#glActiveTexture(int)}.
70 	 * @param unit the unit (0 to MAX_TEXTURE_UNITS). */
bind(int unit)71 	public void bind (int unit) {
72 		Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0 + unit);
73 		Gdx.gl.glBindTexture(glTarget, glHandle);
74 	}
75 
76 	/** @return The {@link Texture.TextureFilter} used for minification. */
getMinFilter()77 	public TextureFilter getMinFilter () {
78 		return minFilter;
79 	}
80 
81 	/** @return The {@link Texture.TextureFilter} used for magnification. */
getMagFilter()82 	public TextureFilter getMagFilter () {
83 		return magFilter;
84 	}
85 
86 	/** @return The {@link Texture.TextureWrap} used for horizontal (U) texture coordinates. */
getUWrap()87 	public TextureWrap getUWrap () {
88 		return uWrap;
89 	}
90 
91 	/** @return The {@link Texture.TextureWrap} used for vertical (V) texture coordinates. */
getVWrap()92 	public TextureWrap getVWrap () {
93 		return vWrap;
94 	}
95 
96 	/** @return The OpenGL handle for this texture. */
getTextureObjectHandle()97 	public int getTextureObjectHandle () {
98 		return glHandle;
99 	}
100 
101 	/** Sets the {@link TextureWrap} for this texture on the u and v axis. Assumes the texture is bound and active!
102 	 * @param u the u wrap
103 	 * @param v the v wrap */
unsafeSetWrap(TextureWrap u, TextureWrap v)104 	public void unsafeSetWrap (TextureWrap u, TextureWrap v) {
105 		unsafeSetWrap(u, v, false);
106 	}
107 
108 	/** Sets the {@link TextureWrap} for this texture on the u and v axis. Assumes the texture is bound and active!
109 	 * @param u the u wrap
110 	 * @param v the v wrap
111 	 * @param force True to always set the values, even if they are the same as the current values. */
unsafeSetWrap(TextureWrap u, TextureWrap v, boolean force)112 	public void unsafeSetWrap (TextureWrap u, TextureWrap v, boolean force) {
113 		if (u != null && (force || uWrap != u)) {
114 			Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_WRAP_S, u.getGLEnum());
115 			uWrap = u;
116 		}
117 		if (v != null && (force || vWrap != v)) {
118 			Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_WRAP_T, v.getGLEnum());
119 			vWrap = v;
120 		}
121 	}
122 
123 	/** Sets the {@link TextureWrap} for this texture on the u and v axis. This will bind this texture!
124 	 * @param u the u wrap
125 	 * @param v the v wrap */
setWrap(TextureWrap u, TextureWrap v)126 	public void setWrap (TextureWrap u, TextureWrap v) {
127 		this.uWrap = u;
128 		this.vWrap = v;
129 		bind();
130 		Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_WRAP_S, u.getGLEnum());
131 		Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_WRAP_T, v.getGLEnum());
132 	}
133 
134 	/** Sets the {@link TextureFilter} for this texture for minification and magnification. Assumes the texture is bound and active!
135 	 * @param minFilter the minification filter
136 	 * @param magFilter the magnification filter */
unsafeSetFilter(TextureFilter minFilter, TextureFilter magFilter)137 	public void unsafeSetFilter (TextureFilter minFilter, TextureFilter magFilter) {
138 		unsafeSetFilter(minFilter, magFilter, false);
139 	}
140 
141 	/** Sets the {@link TextureFilter} for this texture for minification and magnification. Assumes the texture is bound and active!
142 	 * @param minFilter the minification filter
143 	 * @param magFilter the magnification filter
144 	 * @param force True to always set the values, even if they are the same as the current values. */
unsafeSetFilter(TextureFilter minFilter, TextureFilter magFilter, boolean force)145 	public void unsafeSetFilter (TextureFilter minFilter, TextureFilter magFilter, boolean force) {
146 		if (minFilter != null && (force || this.minFilter != minFilter)) {
147 			Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_MIN_FILTER, minFilter.getGLEnum());
148 			this.minFilter = minFilter;
149 		}
150 		if (magFilter != null && (force || this.magFilter != magFilter)) {
151 			Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_MAG_FILTER, magFilter.getGLEnum());
152 			this.magFilter = magFilter;
153 		}
154 	}
155 
156 	/** Sets the {@link TextureFilter} for this texture for minification and magnification. This will bind this texture!
157 	 * @param minFilter the minification filter
158 	 * @param magFilter the magnification filter */
setFilter(TextureFilter minFilter, TextureFilter magFilter)159 	public void setFilter (TextureFilter minFilter, TextureFilter magFilter) {
160 		this.minFilter = minFilter;
161 		this.magFilter = magFilter;
162 		bind();
163 		Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_MIN_FILTER, minFilter.getGLEnum());
164 		Gdx.gl.glTexParameterf(glTarget, GL20.GL_TEXTURE_MAG_FILTER, magFilter.getGLEnum());
165 	}
166 
167 	/** Destroys the OpenGL Texture as specified by the glHandle. */
delete()168 	protected void delete () {
169 		if (glHandle != 0) {
170 			Gdx.gl.glDeleteTexture (glHandle);
171 			glHandle = 0;
172 		}
173 	}
174 
175 	@Override
dispose()176 	public void dispose () {
177 		delete();
178 	}
179 
uploadImageData(int target, TextureData data)180 	protected static void uploadImageData (int target, TextureData data) {
181 		uploadImageData(target, data, 0);
182 	}
183 
uploadImageData(int target, TextureData data, int miplevel)184 	public static void uploadImageData (int target, TextureData data, int miplevel) {
185 		if (data == null) {
186 			// FIXME: remove texture on target?
187 			return;
188 		}
189 
190 		if (!data.isPrepared()) data.prepare();
191 
192 		final TextureDataType type = data.getType();
193 		if (type == TextureDataType.Custom) {
194 			data.consumeCustomData(target);
195 			return;
196 		}
197 
198 		Pixmap pixmap = data.consumePixmap();
199 		boolean disposePixmap = data.disposePixmap();
200 		if (data.getFormat() != pixmap.getFormat()) {
201 			Pixmap tmp = new Pixmap(pixmap.getWidth(), pixmap.getHeight(), data.getFormat());
202 			Blending blend = Pixmap.getBlending();
203 			Pixmap.setBlending(Blending.None);
204 			tmp.drawPixmap(pixmap, 0, 0, 0, 0, pixmap.getWidth(), pixmap.getHeight());
205 			Pixmap.setBlending(blend);
206 			if (data.disposePixmap()) {
207 				pixmap.dispose();
208 			}
209 			pixmap = tmp;
210 			disposePixmap = true;
211 		}
212 
213 		Gdx.gl.glPixelStorei(GL20.GL_UNPACK_ALIGNMENT, 1);
214 		if (data.useMipMaps()) {
215 			MipMapGenerator.generateMipMap(target, pixmap, pixmap.getWidth(), pixmap.getHeight());
216 		} else {
217 			Gdx.gl.glTexImage2D(target, miplevel, pixmap.getGLInternalFormat(), pixmap.getWidth(), pixmap.getHeight(), 0,
218 				pixmap.getGLFormat(), pixmap.getGLType(), pixmap.getPixels());
219 		}
220 		if (disposePixmap) pixmap.dispose();
221 	}
222 }
223