真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

OpenGL ES EGL eglMakeCurrent

目錄

創(chuàng)新互聯(lián)公司成立與2013年,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目網(wǎng)站建設、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元天水做網(wǎng)站,已為上家服務,為天水各地企業(yè)和個人服務,聯(lián)系電話:18982081108

  • 一. EGL 前言
  • 二. EGL 繪制流程簡介
  • 三.eglMakeCurrent 函數(shù)簡介
    • 1.eglMakeCurrent 簡介
    • 2.eglMakeCurrent 實現(xiàn)
    • 3.eglMakeCurrent 使用
  • 四.關于多個 EGLContext
  • 五.共享 EGLContext
  • 六.猜你喜歡

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 特效

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 轉(zhuǎn)場

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 函數(shù)

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES GPUImage 使用

零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES GLSL 編程

一. EGL 前言

EGLNativeDisplayType – 系統(tǒng)顯示類型,標識你所開發(fā)設備的物理屏幕,DX/OPenGL ES/Metal/Vulkan….

EGLNativeWindowType – 系統(tǒng)窗口,渲染顯示的窗口句柄

EGLDisplay – 關聯(lián) EGLNativeDisplayType 系統(tǒng)物理屏幕的通用數(shù)據(jù)類型,是平臺上 WGL / GLX / AGL 的等價物

EGLSurface – 渲染區(qū)域,相當于 OpenGL ES 繪圖的畫布 (一塊內(nèi)存空間),用戶想繪制的信息首先都要先繪制到 EGLSurface 上,然后通過 EGLDisplay 顯示

EGLConfig – 對 EGLSurface 的 EGL 配置,可以理解為繪制目標 framebuffer 的配置屬性

EGLContext – OpenGL ES 圖形上下文

二. EGL 繪制流程簡介

  1. 獲取 EGL Display 對象:eglGetDisplay
  2. 初始化與 EGLDisplay 之間的連接:eglInitialize
  3. 獲取 EGLConfig 對象:eglChooseConfig / eglGetConfigs
  4. 創(chuàng)建 EGLContext 實例:eglCreateContext
  5. 創(chuàng)建 EGLSurface 實例:eglCreateWindowSurface / eglCreatePbufferSurface
  6. 連接 EGLContext 和 EGLSurface 上下文 eglMakeCurrent
  7. 使用 OpenGL ES API 繪制圖形:gl_*
  8. 切換 front buffer 和 back buffer 顯示:eglSwapBuffer
  9. 斷開并釋放與 EGLSurface 關聯(lián)的 EGLContext 對象:eglRelease
  10. 刪除 EGLSurface 對象
  11. 刪除 EGLContext 對象
  12. 終止與 EGLDisplay 之間的連接

三.eglMakeCurrent 函數(shù)簡介

EGLContext 上下文包含了操作所需的所有狀態(tài)信息,OpenGL ES 必須有一個可用的上下文才能進行繪圖。

1.eglMakeCurrent 簡介

創(chuàng)建了 EGLSurface 和 EGLContext 之后,因為可能有多個 EGLSurface 和 EGLContext ,所以需要通過 eglMakeCurrent 綁定 EGLSurface 來指定當前上下文

/*描述:創(chuàng)建 OpenGL ES EGLSurface
 *參數(shù):
 *    display:指定顯示的連接
 *    draw:EGL 繪圖表面
 *    read:EGL 繪圖表面
 *    context:通過 eglCreateContext 創(chuàng)建的上下文
 *
 *返回值:成功是返回 EGL_TRUE,失敗時返回 EGL_FALSE
 */

EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(
        	EGLDisplay display,
                EGLSurface draw,
              	EGLSurface read,
                EGLContext context);

相關錯誤碼:

EGL_BAD_MATCH :提供了與窗口屬性不匹配的 EGLConfig,或該 EGLConfig 不支持渲染EGL_BAD_DISPLAY
EGL_NOT_INITIALIZED
EGL_BAD_SURFACE
EGL_BAD_CONTEXT
EGL_BAD_MATCH
EGL_BAD_ACCESS
EGL_BAD_NATIVE_PIXMAP
EGL_BAD_NATIVE_WINDOW
EGL_BAD_CURRENT_SURFACE
EGL_BAD_ALLOC
EGL_CONTEXT_LOST

2.eglMakeCurrent 實現(xiàn)

/******************************************************************************************/
//@Author:猿說編程
//@Blog(個人博客地址): www.codersrc.com
//@File:OpenGL ES EGL eglMakeCurrent
//@Time:2022/08/04 07:30
//@Motto:不積跬步無以至千里,不積小流無以成江海,程序人生的精彩需要堅持不懈地積累!
/******************************************************************************************/


EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,

                            EGLSurface read, EGLContext ctx)

{

    if (egl_display_t::is_valid(dpy) == EGL_FALSE)

        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    if (draw) {

        egl_surface_t* s = (egl_surface_t*)draw;

        if (!s->isValid())

            return setError(EGL_BAD_SURFACE, EGL_FALSE);

        if (s->dpy != dpy)

            return setError(EGL_BAD_DISPLAY, EGL_FALSE);

        // TODO: check that draw is compatible with the context

    }

    if (read && read!=draw) {

        egl_surface_t* s = (egl_surface_t*)read;

        if (!s->isValid())

            return setError(EGL_BAD_SURFACE, EGL_FALSE);

        if (s->dpy != dpy)

            return setError(EGL_BAD_DISPLAY, EGL_FALSE);

        // TODO: check that read is compatible with the context

    }



    EGLContext current_ctx = EGL_NO_CONTEXT;



    if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))

        return setError(EGL_BAD_MATCH, EGL_FALSE);



    if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))

        return setError(EGL_BAD_MATCH, EGL_FALSE);



    if (ctx == EGL_NO_CONTEXT) {

        // if we're detaching, we need the current context

        current_ctx = (EGLContext)getGlThreadSpecific();

    } else {

        egl_context_t* c = egl_context_t::context(ctx);

        egl_surface_t* d = (egl_surface_t*)draw;

        egl_surface_t* r = (egl_surface_t*)read;

        if ((d && d->ctx && d->ctx != ctx) ||

            (r && r->ctx && r->ctx != ctx)) {

            // one of the surface is bound to a context in another thread

            return setError(EGL_BAD_ACCESS, EGL_FALSE);

        }

    }

// 調(diào)用makeCurrent,將gl和當前的進程進行綁定。

    ogles_context_t* gl = (ogles_context_t*)ctx;

    if (makeCurrent(gl) == 0) {

        if (ctx) {

            egl_context_t* c = egl_context_t::context(ctx);

            egl_surface_t* d = (egl_surface_t*)draw;

            egl_surface_t* r = (egl_surface_t*)read;



            if (c->draw) {// 斷開當前draw surface的綁定

                egl_surface_t* s = reinterpret_cast(c->draw);

                s->disconnect();

                s->ctx = EGL_NO_CONTEXT;

                if (s->zombie)

                    delete s;

            }

            if (c->read) {

                // FIXME: unlock/disconnect the read surface too

            }

            // 將draw & read 綁定到當前的上下文。

            c->draw = draw;

            c->read = read;



            if (c->flags & egl_context_t::NEVER_CURRENT) {

                c->flags &= ~egl_context_t::NEVER_CURRENT;

                GLint w = 0;

                GLint h = 0;

                if (draw) {

                    w = d->getWidth();

                    h = d->getHeight();

                }

                ogles_surfaceport(gl, 0, 0);

                ogles_viewport(gl, 0, 0, w, h);

                ogles_scissor(gl, 0, 0, w, h);

            }

            if (d) {

                if (d->connect() == EGL_FALSE) {

                    return EGL_FALSE;

                }

                d->ctx = ctx;

                d->bindDrawSurface(gl);

            }

            if (r) {

                // FIXME: lock/connect the read surface too

                r->ctx = ctx;

                r->bindReadSurface(gl);

            }

        } else {//取消綁定

            // if surfaces were bound to the context bound to this thread

            // mark then as unbound.

            if (current_ctx) {

                egl_context_t* c = egl_context_t::context(current_ctx);

                egl_surface_t* d = (egl_surface_t*)c->draw;

                egl_surface_t* r = (egl_surface_t*)c->read;

                if (d) {

                    c->draw = 0;

                    d->disconnect();

                    d->ctx = EGL_NO_CONTEXT;

                    if (d->zombie)

                        delete d;

                }

                if (r) {

                    c->read = 0;

                    r->ctx = EGL_NO_CONTEXT;

                    // FIXME: unlock/disconnect the read surface too

                }

            }

        }

        return EGL_TRUE;

    }

    return setError(EGL_BAD_ACCESS, EGL_FALSE);

}

3.eglMakeCurrent 使用

一個應用程序可能創(chuàng)建多個 EGLContext 用于不同的用途,所以我們需要關聯(lián)特定的 EGLContext 和渲染表面。這一過程被稱作“指定當前上下文”,使用如下調(diào)用,關聯(lián)特定的 EGLContext 和某個 EGLSurface:

/******************************************************************************************/
//@Author:猿說編程
//@Blog(個人博客地址): www.codersrc.com
//@File:OpenGL ES EGL eglMakeCurrent
//@Time:2022/08/04 07:30
//@Motto:不積跬步無以至千里,不積小流無以成江海,程序人生的精彩需要堅持不懈地積累!
/******************************************************************************************/

EGLBoolean initializeWindow(EGLNativeWindow nativeWindow)
{
    const EGLint configAttribs[] = {EGL_RENDER_TYPE, EGL_WINDOW_BIT,
                                    EGL_RED_SIZE,    8,
                                    EGL_GREEN_SIZE,  8,
                                    EGL_BLUE_SIZE,   8,
                                    EGL_DEPTH_SIZE,  24,
                                    EGL_NONE};

    const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};

    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY)
    if (display == EGL_NO_DISPLAY)
    {
        return EGL_FALSE;
    }

    EGLint major, minor;
    if (!eglInitialize(display, &major, &minor))
    {
        return EGL_FALSE;
    }

    EGLConfig config;
    EGLint numConfigs;
    if (!eglChooseConfig(display, configAttribs, &config, 1, &numConfigs))
    {
        return EGL_FALSE;
    }

    EGLSurface window = eglCreateWindowSurface(display, config, nativeWindow, NULL);
    if (window == EGL_NO_SURFACE)
    {
        return EGL_FALSE;
    }

    //創(chuàng)建上下文
    EGLContext context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
    if (context == EGL_NO_CONTEXT)
    {
        return EGL_FALSE;
    }

    //綁定使用當前上下文
    if (!eglMakeCurrent(display, window, window, context))
    {
        return EGL_FALSE;
    }
    return EGL_TRUE;
}

四.關于多個 EGLContext

某些情況下,我們想創(chuàng)建、使用多個 EGLContext ,對于這種情況,需要注意以下幾個情況:

  • 不能在 2 個線程里綁定同一個 EGLContext 。
  • 不能在 2 個不同的線程里,綁定相同的 EGLSurface 到 2 個不同的 EGLContext 上。
  • 在 2 個不同的線程里,綁定 2 個不同 EGLSurface 到 2 個 EGLContext 上,取決于使用的 GPU 的具體實現(xiàn),可能成功,也可能失敗。

五.共享 EGLContext

共享 EGLContext 這種方式在加載階段很有用。由于上傳數(shù)據(jù)到 GPU(尤其是紋理數(shù)據(jù)(textures))這類操作很重,如果想要維持幀率穩(wěn)定,應該在另一個線程進行上傳。

然而,對于上面多個 EGLContext 的 3 種情況的限制,必須在第一個 EGLContext 之外,創(chuàng)建第二個 EGLContext ,這個 EGLContext 將使用第一個 EGLContext 使用的內(nèi)部狀態(tài)信息。這兩個 Context 即共享 Context 上下文。

需要注意的是:這****兩個 EGLContext 共享的只是內(nèi)部狀態(tài)信息,它們兩個并不共享調(diào)用緩存(每個 EGLContext 各自擁有一個調(diào)用緩存)。

創(chuàng)建第二個 EGLContext 的方法:

/*描述:創(chuàng)建 OpenGL ES 上下文 EGLContext
 *參數(shù):
 *    display:指定顯示的連接
 *    config:配置 EGLConfig
 *    share_context:允許其它 EGLContext 共享數(shù)據(jù),使用 EGL_NO_CONTEXT 表示不共享
 *    attribList:指定操作的屬性列表,只能接受一個屬性 EGL_CONTEXT_CLIENT_VERSION(設置 OpenGL ES 版本)
 *
 *返回值:成功時返回新創(chuàng)建的 EGLContext,失敗時返回 EGL_NO_CONTEXT
 */

EGLContext eglCreateContext(
    EGLDisplay display,
    EGLConfig config,
    EGLContext share_context,
    EGLint const * attrib_list);

注意:第三個參數(shù) share_context 是最重要的,它就是第一個 Context ,表示共享上下文

在第二個線程,不進行任何的繪制,只進行上傳數(shù)據(jù)到 GPU 的操作。所以,給第二個 Context 的 Surface 應該是一個像素緩沖 (pixel buffer) Surface。

EGLSurface eglCreatePbufferSurface(
    EGLDisplay display,
    EGLConfig config,
    EGLint const * attrib_list);

六.猜你喜歡

  1. OpenGL ES 簡介
  2. OpenGL ES 版本介紹
  3. OpenGL ES 2.0 和 3.0 區(qū)別
  4. OpenGL ES 名詞解釋(一)
  5. OpenGL ES 名詞解釋(二)
  6. OpenGL ES GLSL 著色器使用過程
  7. OpenGL ES EGL 簡介
  8. OpenGL ES EGL 名詞解釋
  9. OpenGL ES EGL eglGetDisplay
  10. OpenGL ES EGL eglInitialize
  11. OpenGL ES EGL eglGetConfigs
  12. OpenGL ES EGL eglChooseConfig
  13. OpenGL ES EGL eglGetError
  14. OpenGL ES EGL eglCreateContext
  15. OpenGL ES EGL eglCreateWindowSurface
  16. OpenGL ES EGL eglCreatePbufferSurface
  17. OpenGL ES EGL eglMakeCurrent

本文由博客 - 猿說編程 猿說編程 發(fā)布!


文章名稱:OpenGL ES EGL eglMakeCurrent
轉(zhuǎn)載來源:http://weahome.cn/article/dsoieoj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部