OpenGL纹理大小限制。为特定Android设备提供备用资源

时间:2014-09-11 20:32:28

标签: android opengl-es resources textures texture2d

在我的Android应用程序中,这是一个OpenGL ES 2.0游戏,我已经包含了4组图形资源,如此

  • LDPI
  • MDPI
  • HDPI
  • xhdpi

现在,在我的 xhdpi 文件夹中,我拥有的最大资产是2560 x 1838,因为我在这里定位大屏幕(例如Google Nexus 10平板电脑从中获取资源XHDPI文件夹)。到目前为止,一切都在我测试过的设备上运行(谷歌Nexus 10,三星Galaxy S3,S4& S5,Nexus 4& 5等等)。

我最近听到一位用户在HTC One X +手机上遇到问题时遇到了问题(我相信还有其他原因,除了我在这里谈论的那个,所以我有一个单独的对其他问题持开放态度。)

根据:this,这款手机的最大纹理尺寸是2048x2048,但根据this,这款手机可以从XHDPI文件夹中获取资源。

因此,它不会显示此地图集的纹理(它是背景图集,包含6个独立背景,分别为1280 * 612。

现在我有两个选项可以解决这个问题:

  • 缩小背景的大小。 排除因为这会影响大屏幕设备(如nexus 10)的质量

  • 拆分为2张地图宁可不这样做,因为希望将所有背景保留在1张图册中以优化加载速度(并且只是为了保持整洁)

还有其他选择吗?我是否能够在 xhdpi 的子文件夹中提供符合1X +限制的另一个文件夹?如果是这样,我如何让设备从那里获取资源?

我这样做是盲目的,因为我没有1X +来测试这个,但是根据我的阅读,我认为资产大于2048 x 2048会导致这个设备上的问题。

这是我应用纹理的代码:

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];
}

1 个答案:

答案 0 :(得分:2)

如果你不知道纹理加载是否有效,你可以做所有相同的操作,除了使用GL_PROXY_TEXTURE_2D(或1D,3D等)而不是GL_TEXTURE_2D来检查是否负载将适用于给定的纹理大小和参数。 OpenGL尝试执行加载,并且如果它不起作用或者纹理参数中存在另一个问题,它将把所有纹理状态设置为0。然后,如果纹理加载失败(在你的情况下由于图像太大),让你的程序加载一个较小的缩放纹理。

编辑:我使用的是iOS,我的gl.h没有包含GL_PROXY_TEXTURE_ *而我在OpenGL ES3 specification找不到任何引用,所以我不确定这是否有效适用于OpenGL。

或者,获取最大纹理尺寸(每个尺寸,例如宽度,高度或深度)并使用以下方法加载合适的图像尺寸:

glGetIntegerv( GL_MAX_TEXTURE_SIZE, &size );

然后,检查您的图像以确保其有效。

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