blob: dcd894d19cfcb4d8ab06572590feee07030b4c3f [file] [log] [blame]
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.opengl;
import java.io.InputStream;
import java.io.IOException;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.microedition.khronos.opengles.GL10;
import android.content.res.AssetManager;
/**
* {@hide}
*/
public class Texture {
private int width, height, bpp;
private ByteBuffer data;
private int name = -1;
// Texture maps have the following format. All integers
// are 16 bits, high byte first. Pixels are in 5/6/5
// RGB format, low byte first.
//
// width
// height
// pixel (0, 0)
// pixel (1, 0)
// ...
// pixel (width - 1, height - 1)
private int readInt16(InputStream is) throws IOException {
return is.read() | (is.read() << 8);
}
public Texture(InputStream is) throws IOException {
this.width = readInt16(is);
this.height = readInt16(is);
this.bpp = 2;
int npixels = width*height;
int nbytes = npixels*bpp;
byte[] arr = new byte[nbytes];
int idx = 0;
while (idx < nbytes) {
int nread = is.read(arr, idx, nbytes - idx);
idx += nread;
}
if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
// Swap pairs of bytes on big-endian platforms
for (int i = 0; i < npixels; i++) {
int j = i*2;
int k = j + 1;
byte tmp = arr[j];
arr[j] = arr[k];
arr[k] = tmp;
}
}
this.data = ByteBuffer.allocateDirect(arr.length);
this.data.order(ByteOrder.nativeOrder());
data.put(arr);
data.position(0);
}
private int loadTexture(GL10 gl,
int textureUnit,
int minFilter, int magFilter,
int wrapS, int wrapT,
int mode,
int width, int height,
int dataType,
Buffer data) {
int[] texture = new int[1];
gl.glGenTextures(1, texture, 0);
gl.glEnable(gl.GL_TEXTURE_2D);
gl.glClientActiveTexture(textureUnit);
gl.glBindTexture(gl.GL_TEXTURE_2D, texture[0]);
gl.glTexParameterf(gl.GL_TEXTURE_2D,
gl.GL_TEXTURE_MIN_FILTER,
minFilter);
gl.glTexParameterf(gl.GL_TEXTURE_2D,
gl.GL_TEXTURE_MAG_FILTER,
magFilter);
gl.glTexParameterf(gl.GL_TEXTURE_2D,
gl.GL_TEXTURE_WRAP_S,
wrapS);
gl.glTexParameterf(gl.GL_TEXTURE_2D,
gl.GL_TEXTURE_WRAP_T,
wrapT);
gl.glTexEnvf(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, mode);
gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB,
width, height,
0, gl.GL_RGB, dataType,
data);
return texture[0];
}
public void setTextureParameters(GL10 gl) {
if (name < 0) {
name = loadTexture(gl,
gl.GL_TEXTURE0,
gl.GL_NEAREST, gl.GL_NEAREST,
gl.GL_REPEAT, gl.GL_REPEAT,
gl.GL_MODULATE,
width, height,
gl.GL_UNSIGNED_SHORT_5_6_5,
data);
}
gl.glBindTexture(gl.GL_TEXTURE_2D, name);
}
}