【问题标题】:GL Maximum Textures Size PolicyGL 最大纹理尺寸政策
【发布时间】:2013-10-15 11:57:25
【问题描述】:

我正在使用 AndEngine 开发游戏。由于我是为 Android 做的,并且我想覆盖尽可能多的设备而不牺牲纹理质量,所以我有 2 种纹理包类型:HD 和 LOW:

  • 高清纹理 = 2048x2048
  • 低纹理= 1024x1024
  • 高清摄像头 = 800x1280
  • 低摄像头 = 400x640

我已经制定了设置 HD 纹理包或 LOW 纹理包的所有逻辑,我现在需要的是在应用启动时选择要使用的女巫的好策略。

使用 AndEngine 的:

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

我遇到了一些价值观:

型号:三星 Note 8、索尼 XPERIA U
GL_MAX_TEXTURE_SIZE:4096
GL_MAX_TEXTURE_IMAGE_UNITS:8
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:8

型号:三星 Galaxy Mini、三星 S3 Mini、HTC One S
GL_MAX_TEXTURE_SIZE:4096
GL_MAX_TEXTURE_IMAGE_UNITS:16
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:20

型号:三星 S4、Nexus4、XPERIA Z1
GL_MAX_TEXTURE_SIZE:4096
GL_MAX_TEXTURE_IMAGE_UNITS:16
GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:32

在这个openGL Docs 中,我可以找到每个常量的含义,但是我在这里有点迷茫,我不知道如何使用这些数据来为我的纹理和相机选择正确的设置。

我需要您的帮助和提示,我是否走在正确的道路上?我接下来应该如何处理这些信息?
感谢您的宝贵时间。

【问题讨论】:

    标签: android opengl-es-2.0 andengine


    【解决方案1】:

    GL_MAX_TEXTURE_SIZE 是您的硬件支持的最大方形纹理尺寸。

    • 任何纹理的 X 和 Y 维度都不能超过这个大小。

    GL_MAX_TEXTURE_IMAGE_UNITS 是指您可以在可编程管道中绑定和使用的纹理的最大数量(例如 unique GLSL 程序中的采样器统一名称)(GL_MAX_TEXTURE_UNITS 是固定功能模拟在 GLES 1.0 中)。

    • 在 GLES 2.0 中,最小值为 2。

    GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 是指您可以在 GLSL 程序中的所有着色器中使用的纹理数量。

    • 片段着色器中的 4 个采样器 + 顶点着色器中的 4 个采样器 = 8 个组合纹理图像单元


    注意:OpenGL ES 2.0 不需要顶点着色器中的纹理查找支持,我怀疑 Samsung Note 8, Sony XPERIA U 的实现不支持这一点,从 COMBINED 和一般 TMU 计数。

    • 查询GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 的值将结束任何猜测。


    不过,要回答您的实际问题……您可以用来确定要使用哪个纹理包的唯一值之一是GL_MAX_TEXTURE_SIZE。没有您可以查询的 OpenGL 参数来确定底层硬件的内存容量/纹理填充率,这是您在选择纹理包时真正想知道的。您将需要通过其他方式收集此信息,可能是小型基准测试或已知硬件的数据库,或者如果您幸运的话,该平台有一个单独的 API 可以让您查询这些信息。

    【讨论】:

    • 你好安东。首先让我感谢您的时间和信息。我有一些紧迫的最后期限,所以现在我不得不搁置这个“选择纹理类型政策”。我会仔细研究你所说的,并尽快继续我的研究。我会一直更新这篇文章。
    【解决方案2】:

    我遇到了另一个可能派上用场的测试用例,检查可用内存:

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

    到目前为止,我的测试用例是:

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

    如上所述,我会一直更新这篇文章,直到找到一个好的可靠解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-21
      • 1970-01-01
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多