Opengl学习二-EGL的搭建

1,134 阅读2分钟

EGL

是OpenGLES的本地窗口系统的接口,不同平台上EGL配置是不一样的, 而OpenGL的调用方式是一致的,就是说:OpenGL跨平台就是依赖于EGL接口

为什么要自己创建EGL环境

当我们需要把同一个场景渲染到不同的Surface上时,此时系统GLSurfaceView 就不能满足需求了,所以我们需要自己创建EGL环境来实现渲染操作

注意

OpenGL整体是一个状态机,通过改变状态就能改变后续的渲染方式,而EGLContext(EGL上下文)就 保存有所有状态,因此可以通过共享EGLContext来实现统一场景渲染到不同的Surface上

创建自己的EglHelper

1.得到Egl实例: 2.得到默认的显示设备(就是窗口) 3.初始化默认显示设备 4.设置显示设备的属性 5.从系统中获取对应属性的配置 6.创建EglContext 7.创建渲染的Surface 8.绑定EglContext和Surface到显示设备中 9.刷新数据,显示渲染场景 `

private EGL10 mEgl;
private EGLDisplay mEglDisplay;
private EGLContext mEglContext;
private EGLSurface mEglSurface;

public void initEgl(Surface surface, EGLContext eglContext)
{

    //1、
    mEgl = (EGL10) EGLContext.getEGL();

    //2、
    mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
        throw new RuntimeException("eglGetDisplay failed");
    }

    //3、
    int[] version = new int[2];
    if(!mEgl.eglInitialize(mEglDisplay, version)) {
        throw new RuntimeException("eglInitialize failed");
    }

    //4、
    int [] attrbutes = new int[]{
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_ALPHA_SIZE, 8,
            EGL10.EGL_DEPTH_SIZE, 8,
            EGL10.EGL_STENCIL_SIZE, 8,
            EGL10.EGL_RENDERABLE_TYPE, 4,
            EGL10.EGL_NONE};

    int[] num_config = new int[1];
    if(!mEgl.eglChooseConfig(mEglDisplay, attrbutes, null, 1, num_config))
    {
        throw new IllegalArgumentException("eglChooseConfig failed");
    }

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

    //5、
    EGLConfig[] configs = new EGLConfig[numConfigs];
    if (!mEgl.eglChooseConfig(mEglDisplay, attrbutes, configs, numConfigs,
            num_config)) {
        throw new IllegalArgumentException("eglChooseConfig#2 failed");
    }

    //6、

    int[] attrib_list = {
            EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
            EGL10.EGL_NONE
    };

    if(eglContext != null)
    {
        mEglContext = mEgl.eglCreateContext(mEglDisplay, configs[0], eglContext, attrib_list);
    }
    else
    {
        mEglContext = mEgl.eglCreateContext(mEglDisplay, configs[0], EGL10.EGL_NO_CONTEXT, attrib_list);
    }

    //7、
    mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, configs[0], surface, null);

    //8、
    if(!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext))
    {
        throw new RuntimeException("eglMakeCurrent fail");
    }
}
public boolean swapBuffers()
{
    if(mEgl != null)
    {
        return mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
    }
    else
    {
        throw new RuntimeException("egl is null");
    }
}

public EGLContext getmEglContext() {
     return mEglContext;
}

public void destoryEgl()
{
    if(mEgl != null)
    {
        mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                EGL10.EGL_NO_SURFACE,
                EGL10.EGL_NO_CONTEXT);

        mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
        mEglSurface = null;

        mEgl.eglDestroyContext(mEglDisplay, mEglContext);
        mEglContext = null;

        mEgl.eglTerminate(mEglDisplay);
        mEglDisplay = null;
        mEgl = null;
    }
}





`