一:OpenGL_ES怎么和操作系统原生窗口联系的?
OpenGL_ES应用程序运行linux,windows,MacOS或其他操作系统上的,这些操作系统都有自己的窗口系统,这些窗口都有一些配置参数,比如当前画刷颜色,窗口尺寸,状态信息等,这叫做窗口环境,Windows上又叫设备环境,同样OpenGL_ES要向窗口绘制内容,也需要有一个和应用程序窗口环境相匹配的渲染环境,叫OpenGL_ES渲染环境。所以有一个中间层API,来为OpenGL_ES和应用程序窗口建立联系,建立OpenGL_ES渲染环境,这样OpenGL_ES就可以把内容渲染到应用程序窗口上了,这样的中间层API就是EGL,EGL是一种接口,让OpenGL_ES和Windows,Linux, Brew, Symbian, Android, MacOS操作系统下的原生窗口之间建立联系。
二:OpenGL_ES渲染环境建立的过程:
0:总体过程:OpenGL_ES先把内容画到自己渲染表面上面,然后通过swapbuffers交换到本地窗口上
1:获取默认显示器:eglGetDisplay;
2:初始化EGL,以便使用EGL接口,eglInitialize;
3:获取最佳像素格式配置,eglChooseConfig;
4:创建渲染表面,相当于显示器上的一个窗口,eglCreateWindowSurface;
5:创建渲染环境,保存OpenGL渲染状态,eglCreateContext;
6:切换渲染表面和渲染环境给某一个线程使用,eglMakeCurrent;
7:呈现到窗口上,eglSwapBuffers;
三: 相关代码:
///
// CreateEGLContext()
//
// Creates an EGL rendering context and all associated elements
//
EGLBoolean CreateEGLContext ( EGLNativeWindowType hWnd, EGLDisplay* eglDisplay,
EGLContext* eglContext, EGLSurface* eglSurface,
EGLint attribList[])
{
EGLint numConfigs;
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
EGLContext context;
EGLSurface surface;
EGLConfig config;
EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
// Get Display
display = eglGetDisplay((EGLNativeDisplayType)x_display);
if ( display == EGL_NO_DISPLAY )
{
return EGL_FALSE;
}
// Initialize EGL
if ( !eglInitialize(display, &majorVersion, &minorVersion) )
{
return EGL_FALSE;
}
// Get configs
if ( !eglGetConfigs(display, NULL, 0, &numConfigs) )
{
return EGL_FALSE;
}
// Choose config
if ( !eglChooseConfig(display, attribList, &config, 1, &numConfigs) )
{
return EGL_FALSE;
}
// Create a surface
surface = eglCreateWindowSurface(display, config, (EGLNativeWindowType)hWnd, NULL);
if ( surface == EGL_NO_SURFACE )
{
return EGL_FALSE;
}
// Create a GL context
context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs );
if ( context == EGL_NO_CONTEXT )
{
return EGL_FALSE;
}
// Make the context current
if ( !eglMakeCurrent(display, surface, surface, context) )
{
return EGL_FALSE;
}
*eglDisplay = display;
*eglSurface = surface;
*eglContext = context;
return EGL_TRUE;
}