GL Maximum Textures Size Policy

2019-05-23 15:32发布

I'm developing a game with AndEngine. Since I'm doing it for Android and I want to cover as many devices as possible without the textures quality trade off I have 2 texture packs types: the HD and the LOW:

  • HD textures = 2048x2048
  • LOW textures= 1024x1024
  • HD camera = 800x1280
  • LOW camera = 400x640

I've have made all the logic of setting up a HD texture pack or a LOW texture pack, what I need now is a good policy for choosing witch to use when the app starts up.

Using AndEngine's:

GLState state = new GLState();
int max = state.getInteger(GLES20.GL_MAX_...);

I came across some values:

Model: Samsung Note 8, Sony XPERIA U
GL_MAX_TEXTURE_SIZE: 4096
GL_MAX_TEXTURE_IMAGE_UNITS: 8
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 8

Model: Samsung Galaxy Mini, Samsung S3 Mini, HTC One S
GL_MAX_TEXTURE_SIZE: 4096
GL_MAX_TEXTURE_IMAGE_UNITS: 16
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 20

Model: Samsung S4, Nexus4, XPERIA Z1
GL_MAX_TEXTURE_SIZE: 4096
GL_MAX_TEXTURE_IMAGE_UNITS: 16
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 32

In this openGL Docs I could find each constant meaning, but I'm a little lost here, I don't know how to use this data in order to choose the right setup for my textures and camera.

I need your help and tips, am I in the right path? What should I do next with this info?
Thanks for your time.

2条回答
淡お忘
2楼-- · 2019-05-23 15:46

GL_MAX_TEXTURE_SIZE is the maximum square texture dimensions your hardware supports.

  • Neither the X nor Y dimensions of any texture can exceed this size.

GL_MAX_TEXTURE_IMAGE_UNITS refers to the maximum number of textures (e.g. unique sampler uniform names in a GLSL program) you can bind and use in the programmable pipeline (GL_MAX_TEXTURE_UNITS is the fixed-function analog in GLES 1.0).

  • In GLES 2.0 this has a minimum value of 2.

GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS refers to the number of textures you can use across all shaders in your GLSL program.

  • 4 samplers in a fragment shader + 4 samplers in a vertex shader = 8 Combined Texture Image Units


NOTE: OpenGL ES 2.0 does not require texture lookup support in vertex shaders, and I suspect Samsung Note 8, Sony XPERIA U has an implementation that does not support this, judging by the parity between COMBINED and general TMU counts.

  • Querying the value of GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS would put an end to any speculation though.


To answer your actual question, though... the only one of these values you can use to determine which texture pack to use is GL_MAX_TEXTURE_SIZE. There is no OpenGL parameter you can query to determine the underlying hardware's memory capacity / texture fillrate, which is what you really want to know when selecting texture packs. You will need to gather this information through other means, perhaps a mini-benchmark or a database of known hardware, or if you are lucky the platform has a separate API that lets you query this.

查看更多
霸刀☆藐视天下
3楼-- · 2019-05-23 16:05

I came across another test case that may come in handy, checking for available memory:

        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        ActivityManager activityManager = (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE);
        activityManager.getMemoryInfo(mi);
        long availableMegs = mi.availMem / 1048576L;

So far my test cases are:

if (IS_TABLET7 || IS_TABLET10) {
    useHIGH &= smallestWidthSize >= TABLET_MAX_SMALLEST_WIDTH;
} else {
    useHIGH &= smallestWidthSize >= SMARTPHONE_MAX_SMALLEST_WIDTH;
}

Log.i(C.TAG, "=========SCREEN DIMENSIONS=========");
Log.i(C.TAG, "Screen Size Info: smallestWidthSize = " + smallestWidthSize);
Log.i(C.TAG, "Screen Size Info: smallestWidthSize >= MAX_SMALLEST_WIDTH (" + (IS_TABLET ? TABLET_MAX_SMALLEST_WIDTH : SMARTPHONE_MAX_SMALLEST_WIDTH) + ")? " + useHIGH);
Log.i(C.TAG, "Screen Size Info: should use Texture Type > " + (useHIGH ? "HIGH" : "LOW"));


useHIGH &= availableMegs > MIN_RAM_LIMIT;
Log.i(C.TAG, "=========AVAILABLE RAM=========");
Log.i(C.TAG, "Memory Info: available RAM = " + availableMegs + "Mb");
Log.i(C.TAG, "Memory Info: available RAM > MIN_RAM_LIMIT(" + MIN_RAM_LIMIT + "Mb)? " + useHIGH);
Log.i(C.TAG, "Memory Info: should use Texture Type > " + (useHIGH ? "HIGH" : "LOW"));

As stated above I'll always keep this post updated until a good solid solution is reached.

查看更多
登录 后发表回答