Reputation: 3887
Within my Android App, which is an OpenGL ES 2.0 game, I've included 4 sets of graphic resources like so
Now, within my xhdpi folder, the largest asset I have is 2560 x 1838 as I'm targeting large screens here (for example the Google Nexus 10 tablet which gets its resources from the XHDPI folder). Up until now, everything has worked on the devices on which I've tested (Google Nexus 10, Samsung Galaxy S3, S4 & S5, Nexus 4 & 5 etc etc....)
I've recently heard from a user who has encountered problems running this on an HTC One X+ handset (I believe there are other reasons for this besides the one I'm talking about here so I have a separate question open for the other issues).
The thing is, according to: this, the maximum texture size for the this phone is 2048x2048, but then according to this this phone gets its resources from the XHDPI folder.
So, it won't display the textures from this atlas (it's an atlas of backgrounds containing 6 separate backgrounds of 1280*612.
Now I have two options that I am aware of to fix this:
Reduce the size of the backgrounds. Ruled out as this would compromise quality on larger-screen devices (like the nexus 10)
Split into 2 atlases would rather not do this as would like to keep all backgrounds in 1 atlas to optimise loading speed (and just to keep things tidy)
Are there any other options? Am I able to provide, within a sub folder of xhdpi another folder that fits within the 1X+'s limits? And if so, how do I get the device to grab resources from there?
I'm doing this blind as I don't have an 1X+ on which to test this, but from what I've read, I believe having assets larger than 2048 x 2048 is going to cause problems on this device.
This is my code for applying textures:
public static int LoadTexture(GLSurfaceView view, Bitmap imgTex){
//Array for texture
int textures[] = new int[1];
try {
//texture name
GLES20.glGenTextures(1, textures, 0);
//Bind textures
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
//Set parameters for texture
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
//Apply texture
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgTex, 0);
//clamp texture
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
} catch (Exception e){
}
//Increase texture count
textureCount++;
//Return texture
return textures[0];
}
Upvotes: 3
Views: 1974
Reputation: 1499
If you don't know if a texture load will work, you can do all the same operations, except use GL_PROXY_TEXTURE_2D (or 1D, 3D, etc.) instead of GL_TEXTURE_2D to check to see if the load will work for a given texture size and parameters. OpenGL attempts to perform the load, and and it will set all texture state to 0 if it doesn't work or there is another problem in a texture parameter. Then if the texture load fails (in your case due to the image being too big), have your program load a smaller scaled texture.
EDIT: I use iOS and my gl.h doesn't include GL_PROXY_TEXTURE_* and I can't find any reference in the OpenGL ES3 specification, so I'm not sure this will work for you with OpenGL.
Alternatively, get your max texture size (per dimension, e.g. width, height or depth) and load a suitable image sized using:
glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );
Afterward, check your image to ensure it worked.
GLuint name;
int width = 10000; // really bad width
int height = 512;
GLint size;
glGenTextures( 1, &name );
glBindTexture( GL_TEXTURE_2D, name );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0);
GLenum error = glGetError();
if( error ) {
printf("Failed!");
}
else {
printf("Succeeded!");
}
Upvotes: 2