提供的机制
- 与设别的原生窗口系统通信
- 查询绘图表面的可用类型和配置
- 创建绘图表面
- 在OpenGL ES3.0和其他图形渲染API之间同步渲染
- 管理纹理贴图等渲染资源
EGLint esCreateWindow(EGLNativeWindowType *eglNativeWindow)
{
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};
EGLint surface_attribList[] = {EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE};
EGLint attribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; // OpenGL 2.0
EGLint w, h, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;
//获得默认的显示窗口
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
//初始化display
eglInitialize(display, 0, 0);
// eglChooseConfig(display, attribs, nullptr, 0, &numConfigs);
const EGLint MaxConfigs = 10;
EGLConfig configs[MaxConfigs];
//让EGL选择配置,maxconfigs返回最大配置数量,numConfigs指返回的实际配置数量
eglChooseConfig(display, attribs, configs, MaxConfigs, &numConfigs);
auto i = 0;
for (; i < numConfigs; i++) {
auto &cfg = configs[i];
EGLint r, g, b, d;
//获取配置属性与预设相同
if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) &&
eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) &&
eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) &&
eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) &&
r == 8 && g == 8 && b == 8 && d == 0) {
config = configs[i];
break;
}
}
//如果没有获取到,则默认第一个配置
if (i == numConfigs) {
config = configs[0];
}
//EGL_NATIVE_VISUAL_ID:关于应原生窗口系统可视ID句柄
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
//创建渲染表面
surface = eglCreateWindowSurface(display, config, window, surface_attribList/*为NULL,则都为默认值*/);
//可能返回错误
if (surface == EGL_NO_SURFACE) {
switch(eglGetError()){
case EGL_BAD_MATCH:
break;
case EGL_BAD_CONFIG:
break;
case EGL_BAD_NATIVE_WINDOW:
break;
case EGL_BAD_ALLOC:
break;
default:
break;
}
return -1;
}
//创建渲染上下文(如果想创建屏幕外渲染区域EGL Pbuffer代码大同小异,但如果想要做的是渲染到一个纹理,则使用帧缓冲区对象更高效)
context = eglCreateContext(display, config, NULL, attribList);
if (context == EGL_NO_CONTEXT) {
return -1;
}
//指定创建的渲染上下文为当前上下文。EGL规范要求makeCurrent实现进行一次刷新,所以这调用对于基于图块的架构代价很高
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
return -1;
}
//可以查询渲染表面的宽高
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
return 0;
}