Compressed textures become white in Android
i am new to both android and OpenGL development i try to do just a cube with a texture, but i need to make this texture compressed in ETC1 compression, i make a code like i found in the develop.android website but the code run only on the emulator !
i test on two devices
1) Nexus mobile, in this device the cube is not appeared, i search the internet, i found that the original Android of this device was 2.1, and it was upgraded to 2.3, This is a reason make the device can draw the cub ?
2) Motorola Xoom Tablet, it is an Android 3.1 Device, the cube is appeared here but with white color, not the Uncompressed texture, it is supported CTE1 and there are no OPENGL Error !
the compressed texture is PNG 265 * 265 / and i put the compressed texture in the raw folder
the code is like the following
public class TextureCube {
private String TAG;
private Context context;
private FloatBuffer vertexBuffer; // Buffer for vertex-array
private FloatBuffer texBuffer; // Buffer for texture-coords-array
private float[] vertices = { // Vertices for a face
-1.0f, -1.0f, 0.0f, // 0. left-bottom-front
1.0f, -1.0f, 0.0f, // 1. right-bottom-front
-1.0f, 1.0f, 0.0f, // 2. left-top-front
1.0f, 1.0f, 0.0f // 3. right-top-front
};
float[] texCoords = { // Texture coords for the above face
0.0f, 1.0f, // A. left-bottom
1.0f, 1.0f, // B. right-bottom
0.0f, 0.0f, // C. left-top
1.0f, 0.0f // D. right-top
};
int[] textureIDs = new int[1]; // Array for 1 texture-ID
// Constructor - Set up the buffers
public TextureCube(Context context) {
this.context = context;
TAG = "Sam Messages: " + this.getClass().getName();
// Setup vertex-array buffer. Vertices in float. An float has 4 bytes
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder()); // Use native byte order
vertexBuffer = vbb.asFloatBuffer(); // Convert from byte to float
vertexBuffer.put(vertices); // Copy data into buffer
vertexBuffer.position(0); // Rewind
// Setup texture-coords-array buffer, in float. An float has 4 bytes
ByteBuffer tbb = ByteBuffer.allocateDirect(texCoords.length * 4);
tbb.order(ByteOrder.nativeOrder());
texBuffer = tbb.asFloatBuffer();
texBuffer.put(texCoords);
texBuffer.position(0);
}
// Draw the shape
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glFrontFace(GL10.GL_CCW); // Front face in counter-clockwise orientation
gl.glEnable(GL10.GL_CULL_FACE); // Enable cull face
gl.glCullFace(GL10.GL_BACK); // Cull the back face (don't display)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Enable texture-coords-array
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuffer); // Define texture-coords buffer
// front
gl.glPushMatrix();
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// left
gl.glPushMatrix();
gl.glRotatef(270.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// back
gl.glPushMatrix();
gl.glRotatef(180.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// right
gl.glPushMatrix();
gl.glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// top
gl.glPushMatrix();
gl.glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
// bottom
gl.glPushMatrix();
gl.glRotatef(90.0f, 1.0f, 0.0f, 0.0f);
gl.glTranslatef(0.0f, 0.0f, 1.0f);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
gl.glPopMatrix();
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // Disable
// texture-coords-array
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
}
// Load an image into GL texture
public void loadTexture(GL10 gl) {
Boolean loadCompressed = true;
if (loadCompressed) {
/****************************************************/
/** LOAD A COMPRESSED TEXTURE IMAGE */
/***********************************/
Log.w(TAG, ": ETC1 texture support: " + ETC1Util.isETC1Supported());
try {
ETC1Util.loadTexture(GLES20 .GL_TEXTURE_2D, 0, 0,
GLES20.GL_RGB, GLES20.GL_UNSIGNED_SHORT_5_6_5,
context.getResources().openRawResource(R.raw.pic3));
Log.w(TAG, ": OpenGL Error -After LoadTexture()-:" + gl.glGetError());
Log.w(TAG,"OpenGL Extensions: " + gl.glGetString(GL10.GL_EXTENSIONS));
} catch (IOException e) {
Log.w(TAG, ": Could not load texture: " + e);
} finally {
Log.w(TAG, ": OpenGL Error -In Final()-:" + gl.glGetError());
}
} else {
/*****************************************************/
/** LOAD A TEXTURE IMAGE */
/************************/
gl.glGenTextures(1, textureIDs, 0); // Gene开发者_如何学Crate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); // Bind to texture ID Set up texture filters
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
InputStream istream = context.getResources().openRawResource(R.drawable.pic5);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for the currently-bind texture
// ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
/******************************************************/
}
}
You fail to setup a texture name for the compressed texture loading, the two function calls
gl.glGenTextures(1, textureIDs, 0); // Generate texture-ID array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]); // Bind to texture
do this, so place them at the beginning of the function.
A "white" texture usually indicates, that the texture is incomplete. This usually happens if you enable mipmaping but don't supply all required mipmap levels. In the above code you disable mipmaping for uncompressed textures:
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
but leave things as they are, for compressed – try what happens if you put those two calls after the name generation, i.e. also before the if(compressed)
:
public void loadTexture(GL10 gl) {
gl.glGenTextures(1, textureIDs, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textureIDs[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
Boolean loadCompressed = true;
if (loadCompressed) {
/****************************************************/
/** LOAD A COMPRESSED TEXTURE IMAGE */
/***********************************/
Log.w(TAG, ": ETC1 texture support: " + ETC1Util.isETC1Supported());
try {
ETC1Util.loadTexture(GLES20 .GL_TEXTURE_2D, 0, 0,
GLES20.GL_RGB, GLES20.GL_UNSIGNED_SHORT_5_6_5,
context.getResources().openRawResource(R.raw.pic3));
Log.w(TAG, ": OpenGL Error -After LoadTexture()-:" + gl.glGetError());
Log.w(TAG,"OpenGL Extensions: " + gl.glGetString(GL10.GL_EXTENSIONS));
} catch (IOException e) {
Log.w(TAG, ": Could not load texture: " + e);
} finally {
Log.w(TAG, ": OpenGL Error -In Final()-:" + gl.glGetError());
}
} else {
/*****************************************************/
/** LOAD A TEXTURE IMAGE */
/************************/
InputStream istream = context.getResources().openRawResource(R.drawable.pic5);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(istream);
} finally {
try {
istream.close();
} catch (IOException e) {
}
}
// Build Texture from loaded bitmap for the currently-bind texture
// ID
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
/******************************************************/
}
}
精彩评论