OpenGL texture size limits. Providing alternative resources for specific Android devices

In my Android app which is an OpenGL ES 2.0 game, I have included 4 sets of graphical assets like

  • ldpi
  • MDPI
  • HDI
  • xhdpi

Now, in my xhdpi folder , the biggest asset I have is 2560 x 1838, since I'm targeting the big screens here (like a Google Nexus 10 tablet that gets its assets from the XHDPI folder). So far, everything has worked on the devices I've tested on (Google Nexus 10, Samsung Galaxy S3, S4 and S5, Nexus 4 and 5, etc., etc.).

I recently heard from a user who ran into problems with their HTC One X + phone (I believe there are other reasons for this besides the one I'm talking about, so I have a separate question open to other questions ).

The point is that this , the maximum texture size for this phone is 2048x2048, but then according to this this phone gets its resources from the XHDPI folder.

So it will not render textures from this atlas (this is a backgrounds atlas containing 6 separate backgrounds 1280 * 612.

I now have two options that I know of to fix this:

  • Reduce the size of the background. Excluded as it would degrade quality on larger devices (e.g. Nexus 10)

  • Splitting into 2 atlases would rather not do this as I would like to keep all backgrounds in 1 atlas to optimize loading speed (and just keep things in order)

Are there any other options? Can I provide another folder in the xhdpi subfolder that meets the 1X + limits? And if so, how do I get the device to grab resources from there?

I'm doing this blindly as I don't have a 1X + to test this against, but from what I've read, I believe assets larger than 2048 x 2048 will 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];
}

      

+3


source to share


1 answer


If you don't know if a texture will be loaded, you can do all the same operations, except using GL_PROXY_TEXTURE_2D (or 1D, 3D, etc.) instead of GL_TEXTURE_2D to check if loading will work for a given texture size and parameters. OpenGL tries to load and it will set the entire texture state to 0 if it doesn't work or there is another problem with the texture parameter. Then, if the texture load fails (in your case, due to the image being too large), your program loads the smaller scaled texture.

EDIT: I am using iOS and my gl.h does not include GL_PROXY_TEXTURE_ * and I cannot find a reference to the OpenGL ES3 spec , so I am not sure if this will work for you with OpenGL.

Alternatively, get the maximum size of the texture (by size, like width, height, or depth) and load the appropriate image with:



glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );

      

Then check the image to make sure it works.

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!");
}

      

+2


source







All Articles