/**
* Creates an EGL rendering context and all associated elements
*/
void (*CreateEGL) (EGLNativeWindowType window, EGLDisplay* outDisplay, EGLContext* outContext, EGLSurface* outSurface, EGLConfig* outConfig);
/**
* Destroy EGL context and all associated elements
*/
void (*DestroyEGL) (EGLDisplay* display, EGLContext* context, EGLSurface* surface);
/**
* When native window resized, we need reset surface
* the surface will destroyed and create new one and make current
*/
void (*ResetSurface) (EGLNativeWindowType window, EGLDisplay display, EGLContext context, EGLConfig config, EGLSurface* surface);
out前缀的参数是出参数。ResetSurface 在系统OnResize的时候调用。因为在OnResize的时候,window的with和height会改变,这个只会影响surface,所以只需摧毁surface重建新的surface,然后重新调用eglMakeCurrent即可。ResetSurface需要的config,就是CreateEGL最后返回的config参数。
/**
* Creates an EGL rendering context and all associated elements
*/
void CreateEGL(EGLNativeWindowType window, EGLDisplay* outDisplay, EGLContext* outContext, EGLSurface* outSurface, EGLConfig* outConfig)
{
*outDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (*outDisplay == EGL_NO_DISPLAY)
{
ALog_A(0, "CreateEGL failed EGL unable to eglGetDisplay");
}
if (!eglInitialize(*outDisplay, NULL/*major*/, NULL/*minor*/))
{
ALog_A(0, "CreateEGL failed EGL unable to eglInitialize");
}
EGLint numConfigs;
// Here specify the attributes of the desired configuration.
// Below, we select an EGLConfig with at least 8 bits per color
// component compatible with on-screen windows
const EGLint configAttribs[] =
{
EGL_DEPTH_SIZE, 16,
EGL_RED_SIZE, 8, // 5,
EGL_GREEN_SIZE, 8, // 6,
EGL_BLUE_SIZE, 8, // 5,
EGL_ALPHA_SIZE, 8, // 0,
EGL_STENCIL_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
/* Here, the application chooses the configuration it desires. In this
* sample, we have a very simplified selection process, where we pick
* the first EGLConfig that matches our criteria
*/
eglChooseConfig(*outDisplay, configAttribs, outConfig, 1, &numConfigs);
if (numConfigs < 1)
{
ALog_A(0, "CreateEGL failed no config match eglChooseConfig");
}
const EGLint surfaceAttrs[] =
{
EGL_RENDER_BUFFER,
EGL_BACK_BUFFER,
EGL_NONE
};
*outSurface = eglCreateWindowSurface(*outDisplay, *outConfig, window, surfaceAttrs);
if (*outSurface == EGL_NO_SURFACE)
{
ALog_A(0, "CreateEGL failed EGL unable to eglCreateWindowSurface");
}
const EGLint contextAttribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
*outContext = eglCreateContext(*outDisplay, *outConfig, EGL_NO_CONTEXT, contextAttribs);
if (*outContext == EGL_NO_CONTEXT)
{
ALog_A(0, "CreateEGL failed EGL unable to eglCreateContext");
}
if (!eglMakeCurrent(*outDisplay, *outSurface, *outSurface, *outContext))
{
ALog_A(0, "CreateEGL failed EGL unable to eglMakeCurrent");
}
// eglSwapInterval(*outDisplay, 0);
}
/**
* Destroy EGL context and all associated elements
*/
void DestroyEGL(EGLDisplay* display, EGLContext* context, EGLSurface* surface)
{
if (*display != EGL_NO_DISPLAY)
{
eglMakeCurrent(*display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (*context != EGL_NO_CONTEXT)
{
eglDestroyContext(*display, *context);
}
if (*surface != EGL_NO_SURFACE)
{
eglDestroySurface(*display, *surface);
}
eglTerminate(*display);
}
*display = EGL_NO_DISPLAY;
*context = EGL_NO_CONTEXT;
*surface = EGL_NO_SURFACE;
}
static void ResetSurface(EGLNativeWindowType window, EGLDisplay display, EGLContext context, EGLConfig config, EGLSurface* surface)
{
if (*surface != EGL_NO_SURFACE)
{
eglDestroySurface(display, *surface);
}
const EGLint surfaceAttrs[] =
{
EGL_RENDER_BUFFER,
EGL_BACK_BUFFER,
EGL_NONE
};
*surface = eglCreateWindowSurface(display, config, window, surfaceAttrs);
if (!eglMakeCurrent(display, *surface, *surface, context))
{
ALog_A(0, "ResetSurface failed EGL unable to eglMakeCurrent");
}
}