EGSonfig在onSurfaceCreated中的用途?

时间:2015-12-31 19:35:36

标签: android opengl-es

GLSurfaceView.Renderer界面包含方法onSurfaceCreated(GL10 gl, EGLConfig config)。我知道GL10参数在很大程度上已经过时,但EGLConfig参数用于什么?鉴于it declares no public properties or methods,有什么意义呢?这是其他事情的争​​论吗?

2 个答案:

答案 0 :(得分:2)

虽然EGLConfig类没有有用的方法,但您仍然可以使用该对象来获取配置的属性。这是通过EGL10 class完成的,this具有将EGLConfig个实例作为参数的方法。

现在,接下来的问题是如何获得EGL10实例。为此,您在getEgl()上使用静态EGLContext方法。该方法返回EGL实例,您可以将其转换为EGL10

总而言之,整件事情看起来像这样:

EGL10 egl = (EGL10)EGLContext.getEGL();
EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

int[] val = new int[1];
egl.eglGetConfigAttrib(dpy, config, EGL10.EGL_DEPTH_SIZE, val);
int depthBits = val[0];

此代码检索深度缓冲区中的位数。对于此特定示例,您当然也可以使用glGetIntegerv()获得相同的值,但代码片段显示了如何使用config进行EGL调用。

如果要控制使用哪个配置,请在setEGLConfigChooser()上调用GLSurfaceView覆盖之一。更简单的允许您指定颜色,深度和模板缓冲区所需的位数。更灵活的版本允许您传递EGLConfigChooser接口的实现,您可以在其中实现自己的代码以选择首选配置。

答案 1 :(得分:0)

对来源的研究:

您从developers.android.com的文档中获得了很多,但我挖掘了源代码并找到了以下信息:

  

给定的Android设备可能支持多种EGLConfig渲染配置。可用配置可能在数据通道如何存在方面不同,以及为每个通道分配了多少位。因此,GLSurfaceView在开始渲染时必须做的第一件事就是选择要使用的EGLConfig。

     

默认情况下,GLSurfaceView选择具有RGB_888像素格式的EGLConfig,    至少有一个16位深度缓冲区,没有模板。

     

如果您更喜欢不同的EGLConfig,可以通过调用setEGLConfigChooser方法之一覆盖默认行为。

查看GLSurfaceView.Renderer的特定界面和onSurfaceCreated(...)的方法调用。源代码定义了以下内容:

    /**
     * Called when the surface is created or recreated.
     * <p>
     * Called when the rendering thread
     * starts and whenever the EGL context is lost. The EGL context will typically
     * be lost when the Android device awakes after going to sleep.
     * <p>
     * Since this method is called at the beginning of rendering, as well as
     * every time the EGL context is lost, this method is a convenient place to put
     * code to create resources that need to be created when the rendering
     * starts, and that need to be recreated when the EGL context is lost.
     * Textures are an example of a resource that you might want to create
     * here.
     * <p>
     * Note that when the EGL context is lost, all OpenGL resources associated
     * with that context will be automatically deleted. You do not need to call
     * the corresponding "glDelete" methods such as glDeleteTextures to
     * manually delete these lost resources.
     * <p>
     * @param gl the GL interface. Use <code>instanceof</code> to
     * test if the interface supports GL11 or higher interfaces.
     * @param config the EGLConfig of the created surface. Can be used
     * to create matching pbuffers.
     */
    void onSurfaceCreated(GL10 gl, EGLConfig config);

GLSurfaceView的源代码中,我们看到以下界面:

/**
 * An interface for choosing an EGLConfig configuration from a list of
 * potential configurations.
 * <p>
 * This interface must be implemented by clients wishing to call
 * {@link GLSurfaceView#setEGLConfigChooser(EGLConfigChooser)}
 */
public interface EGLConfigChooser {
    /**
     * Choose a configuration from the list. Implementors typically
     * implement this method by calling
     * {@link EGL10#eglChooseConfig} and iterating through the results. Please consult the
     * EGL specification available from The Khronos Group to learn how to call eglChooseConfig.
     * @param egl the EGL10 for the current display.
     * @param display the current display.
     * @return the chosen configuration.
     */
    EGLConfig chooseConfig(EGL10 egl, EGLDisplay display);
}

然后抽象类定义以下内容:

/**
 * Choose a configuration with exactly the specified r,g,b,a sizes,
 * and at least the specified depth and stencil sizes.
 */
private abstract class BaseConfigChooser
        implements EGLConfigChooser {

    public BaseConfigChooser(int[] configSpec) {
        mConfigSpec = filterConfigSpec(configSpec);
    }

    public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        int[] num_config = new int[1];

        if (!egl.eglChooseConfig(display, mConfigSpec, null, 0,
                num_config)) {
            throw new IllegalArgumentException("eglChooseConfig failed");
        }

        int numConfigs = num_config[0];

        if (numConfigs <= 0) {
            throw new IllegalArgumentException(
                    "No configs match configSpec");
        }

        EGLConfig[] configs = new EGLConfig[numConfigs];

        if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs,
                num_config)) {
            throw new IllegalArgumentException("eglChooseConfig#2 failed");
        }
        EGLConfig config = chooseConfig(egl, display, configs);
        if (config == null) {
            throw new IllegalArgumentException("No config chosen");
        }
        return config;
    }

    abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
            EGLConfig[] configs);

    protected int[] mConfigSpec;

    private int[] filterConfigSpec(int[] configSpec) {
        if (mEGLContextClientVersion != 2 && mEGLContextClientVersion != 3) {
            return configSpec;
        }

        /* We know none of the subclasses define EGL_RENDERABLE_TYPE.
         * And we know the configSpec is well formed.
         */
        int len = configSpec.length;
        int[] newConfigSpec = new int[len + 2];
        System.arraycopy(configSpec, 0, newConfigSpec, 0, len-1);
        newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE;

        if (mEGLContextClientVersion == 2) {
            newConfigSpec[len] = EGL14.EGL_OPENGL_ES2_BIT;  /* EGL_OPENGL_ES2_BIT */
        } else {
            newConfigSpec[len] = EGLExt.EGL_OPENGL_ES3_BIT_KHR; /* EGL_OPENGL_ES3_BIT_KHR */
        }

        newConfigSpec[len+1] = EGL10.EGL_NONE;
        return newConfigSpec;

    }
}

您可以在此链接中查看更多源代码:GLSurfaceView.java

EGLConfig的要点:

这取自书籍OpenGL 3.0 ES Programming

  

EGLconfig包含有关EGL提供的曲面的所有信息。这包括有关可用颜色数量,与配置关联的其他缓冲区(如深度和模板缓冲区),曲面类型(Surface Type Translucent等)以及许多其他特征的信息。

     

要查询我们使用以下方法查询的EGLConfig特征的特定列表:

EGLBoolean eglGetConfigAttrib(EGLDisplay display, EGLConfig config, EGLint attribute, EGLint value); 

有关EGLConfig类型的更多信息,请参阅第48页的OpenGL ES 3.0 Programming Guide一书。