GLSurfaceView.Renderer
界面包含方法onSurfaceCreated(GL10 gl, EGLConfig config)
。我知道GL10
参数在很大程度上已经过时,但EGLConfig
参数用于什么?鉴于it declares no public properties or methods,有什么意义呢?这是其他事情的争论吗?
答案 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
这取自书籍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
一书。