47

我正在尝试在 Honeycomb 中启用硬件加速,并在 Canvas 上显示一些位图。一切正常,但对于大型位图(一维>2048),我在日志中收到错误:

OpenGLRenderer:位图太大而无法上传到纹理中

我知道这是因为硬件限制,如果启用硬件加速(通过 View.isHardwareAccelerated() 检查),可以通过减小要显示的最大位图大小来解决这个问题。

我的问题是:如何通过硬件轻松确定可用于位图绘制的最大纹理大小。2048 似乎是我设备的限制,但在不同的设备上可能会有所不同。

编辑:我不是在创建 OpenGL 应用程序,只是普通应用程序,它可以利用硬件加速。因此我对OpenGL一点也不熟悉,我只是在日志中看到与OpenGL相关的错误,并寻求解决它。

4

4 回答 4

67

目前最小限制为 2048 像素(即硬件必须支持至少 2048x2048 的纹理。)在 ICS 中,我们将在 Canvas 类上引入一个新的 API,它将为您提供以下信息:
Canvas.getMaximumBitmapWidth()Canvas.getMaximumBitmapHeight().

于 2011-09-23T01:07:38.840 回答
18

获得最大允许大小的另一种方法是遍历所有 EGL10 配置并跟踪最大大小。

public static int getMaxTextureSize() {
    // Safe minimum default size
    final int IMAGE_MAX_BITMAP_DIMENSION = 2048;

    // Get EGL Display
    EGL10 egl = (EGL10) EGLContext.getEGL();
    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

    // Initialise
    int[] version = new int[2];
    egl.eglInitialize(display, version);

    // Query total number of configurations
    int[] totalConfigurations = new int[1];
    egl.eglGetConfigs(display, null, 0, totalConfigurations);

    // Query actual list configurations
    EGLConfig[] configurationsList = new EGLConfig[totalConfigurations[0]];
    egl.eglGetConfigs(display, configurationsList, totalConfigurations[0], totalConfigurations);

    int[] textureSize = new int[1];
    int maximumTextureSize = 0;

    // Iterate through all the configurations to located the maximum texture size
    for (int i = 0; i < totalConfigurations[0]; i++) {
        // Only need to check for width since opengl textures are always squared
        egl.eglGetConfigAttrib(display, configurationsList[i], EGL10.EGL_MAX_PBUFFER_WIDTH, textureSize);

        // Keep track of the maximum texture size
        if (maximumTextureSize < textureSize[0])
            maximumTextureSize = textureSize[0];
    }

    // Release
    egl.eglTerminate(display);

    // Return largest texture size found, or default
    return Math.max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION);
}

根据我的测试,这非常可靠,不需要您创建实例。性能方面,在我的 Note 2 上执行需要 18 毫秒,而在我的 G3 上只需要 4 毫秒。

于 2014-11-08T23:36:34.700 回答
8

如果您想动态了解设备的纹理大小限制(因为它会根据设备而变化),您必须调用此方法:

int[] maxTextureSize = new int[1];
gl.glGetIntegerv(GL10.GL_MAX_TEXTURE_SIZE, maxTextureSize, 0);

并且不要忘记对于某些设备(例如 Nexus One),纹理大小必须是 2 的幂!

我知道我的答案是在上次更新该主题后很长时间......对不起

于 2012-07-26T08:43:04.850 回答
4

根据规范,调用glGetIntegerv.GL_MAX_TEXTURE_SIZE

GL_MAX_TEXTURE_SIZE 参数返回一个值。该值给出了 GL 可以处理的最大纹理的粗略估计。该值必须至少为 64。

http://www.khronos.org/opengles/sdk/docs/man/xhtml/glGet.xml

于 2011-09-18T08:00:39.067 回答