免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
學(xué)習(xí)OpenGL

1, 前言

在前文(學(xué)習(xí)OpenGL-ES: 1 - 像素、顏色、顯存、環(huán)境初始化和EGL)中提到EGL是本地平臺和OpenGL ES之間的抽象層,其完成了本地相關(guān)的環(huán)境初始化和上下文控制工作,以保證OpenGL ES的平臺無關(guān)性。主要包含如下工作:

a,選擇顯示設(shè)備

b, 選擇像素格式。

c, 選擇某些特性,比如如果你打算畫中國水墨畫,你需要額外指定宣紙和毛筆。 

d, 申請顯存。 

e, 創(chuàng)建上下文(Context),上下文本質(zhì)上是一組狀態(tài)的集合,描述了在某個特定時刻系統(tǒng)的狀態(tài), 用于處理暫停、恢復(fù)、銷毀、重建等情況;

f, 指定當(dāng)前的環(huán)境為繪制環(huán)境 。

總體流程上,EGL按順序分為若干步驟:

1, 選擇顯示設(shè)備display,即上述的a.

2,指定特性,包括上述的像素格式(b)和特定特性(c),根據(jù)指定的特性來獲取多個滿足這些特性的config(比如你指定RGB中的R為5bits,那么可能會有RGB_565和RGB_555兩種像素格式均滿足此特性),用戶從這些可用的configs中選擇一個,根據(jù)display和config獲取繪制用的buffer(一般為顯存),即上述的d。

3,使用display、config、buffer來創(chuàng)建context,及即上述的e.

4, 使用display、buffer、context 設(shè)置當(dāng)前的渲染環(huán)境,即上述的f.

本文將以Android下EGL的使用為例逐一進(jìn)行講解。

2,選擇顯示設(shè)備及確認(rèn)EGL版本

EGL有1.0、1.1、1.2、1.3、1.4這幾個版本,Android中使用的是1.4,EGL提供了查詢版本的API,以下為Android中例子:

    EGL10 egl = (EGL10) EGLContext.getEGL();    EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); //獲取顯示設(shè)備       // Init    int[] version = new int[2];    egl.eglInitialize(display, version); //version中存放EGL 版本號,int[0]為主版本號,int[1]為子版本號    String vendor = egl.eglQueryString(display, EGL10.EGL_VENDOR);    WLog.d("egl vendor: " + vendor); // 打印此版本EGL的實(shí)現(xiàn)廠商    String version = egl.eglQueryString(display, EGL10.EGL_VERSION);    WLog.d("egl version: " + version);// 打印EGL版本號    String extension = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);    WLog.d("egl extension: " + extension); //打印支持的EGL擴(kuò)展

 

說明:

1,雖然Android使用(實(shí)現(xiàn))的是EGL 1.4(從打印的版本號中可見), 但在Android 4.2(API 17)以前的版本沒有EGL14,只有EGL10和EGL11,而這兩個版本是不支持OpengGL ES 2.x的,因此在老版本中某些ES 2.x相關(guān)的常量參數(shù)只能用手寫的硬編碼代替,典型的如設(shè)定EGL渲染類型API的參數(shù)EGL10.EGL_RENDERABLE_TYPE,這個屬性用不同的賦值指定的不同的渲染API,包括OpenGL,OpenGL ES 1.x, OpenGL ES 2.x,OpenVG等,如果采用ES 2.0,應(yīng)該設(shè)置此值為: EGL14.EGL_OPENGL_ES2_BIT,但是在Android 4.2之前,沒有EGL14接口,只能采取手寫的硬編碼來指定,類似: EGL_RENDERABLE_TYPE = 4;

2,egl.eglQueryString()用來查詢EGL的相關(guān)信息,詳見這里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

3,EGL10.EGL_DEFAULT_DISPLAY 默認(rèn)對應(yīng)手機(jī)主屏幕。

3,指定(buffer)特性,獲取config

1,構(gòu)造需要的特性列表

int[] attributes = new int[] {         EGL10.EGL_RED_SIZE, 8,  //指定RGB中的R大?。╞its)        EGL10.EGL_GREEN_SIZE, 8, //指定G大小        EGL10.EGL_BLUE_SIZE, 8,  //指定B大小        EGL10.EGL_ALPHA_SIZE, 8, //指定Alpha大小,以上四項實(shí)際上指定了像素格式        EGL10.EGL_DEPTH_SIZE, 16, //指定深度緩存(Z Buffer)大小        EGL10.EGL_RENDERABLE_TYPE, 4, //指定渲染api類別, 如上一小節(jié)描述,這里或者是硬編碼的4,或者是EGL14.EGL_OPENGL_ES2_BIT         EGL10.EGL_NONE };  //總是以EGL10.EGL_NONE結(jié)尾

 2, 獲取所有可用的configs,每個config都是EGL系統(tǒng)根據(jù)特定規(guī)則選擇出來的最符合特性列表要求的一組特性。

 

    EGLConfig config = null;
int[] configNum = new int[1];    //獲取滿足attributes的config個數(shù)。    egl.eglChooseConfig(display, attributes, null, 0, configNum);    int num = configNum[0];    if(num != 0){        EGLConfig[] configs = new EGLConfig[num];        //獲取所有滿足attributes的configs        egl.eglChooseConfig(display, attributes, configs, num, configNum);        config = configs[0]; //以某種規(guī)則選擇一個config,這里使用了最簡單的規(guī)則。          }

說明:

1,display和attributes都來自之前的步驟。

2,eglChooseConfig(display, attributes, configs, num, configNum); 用于獲取滿足attributes的所有config,參數(shù)1、2其意明顯,參數(shù)3用于存放輸出的configs,參數(shù)4指定最多輸出多少個config,參數(shù)5由EGL系統(tǒng)寫入,表明滿足attributes的config一共有多少個。如果使用eglChooseConfig(display, attributes, null, 0, configNum)這種形式調(diào)用,則會在configNum中輸出所有滿足條件的config個數(shù)。

3,一般習(xí)慣是獲取所有滿足attributes的config個數(shù),再據(jù)此分配存放config的數(shù)組,獲取所有config,根據(jù)某種特定規(guī)則,從中選擇其一。

4,API詳細(xì)說明和所有可指定的attributes見這里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

5,打印config中的常用attributes:

  /**   * 打印EGLConfig信息   *    * @param egl   * @param display   * @param config   *          : 指定的EGLConfig   */  public static void printEGLConfigAttribs(EGL10 egl, EGLDisplay display, EGLConfig config) {    int value = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, -1);    WLog.d("eglconfig: EGL_RED_SIZE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, -1);    WLog.d("eglconfig: EGL_GREEN_SIZE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, -1);    WLog.d("eglconfig: EGL_BLUE_SIZE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, -1);    WLog.d("eglconfig: EGL_ALPHA_SIZE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, -1);    WLog.d("eglconfig: EGL_DEPTH_SIZE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, -1);    WLog.d("eglconfig: EGL_RENDERABL_TYPE: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_SAMPLE_BUFFERS, -1);    WLog.d("eglconfig: EGL_SAMPLE_BUFFERS: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_SAMPLES, -1);    WLog.d("eglconfig: EGL_SAMPLES: " + value);    value = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, -1);    WLog.d("eglconfig: EGL_STENCIL_SIZE: " + value);  } /**   * 在指定EGLConfig中查找指定attrib的值,如果沒有此屬性,返回指定的默認(rèn)值   *    * @param egl   * @param display   * @param config   *          : 指定的EGLConfig   * @param attribute   *          : 指定的attrib   * @param defaultValue   *          : 查找失敗時返回的默認(rèn)值   * @return: 查找成功,返回查找值;查找失敗,返回參數(shù)中指定的默認(rèn)值   */  static public int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config,      int attribute, int defaultValue) {    int[] val = new int[1];    if (egl.eglGetConfigAttrib(display, config, attribute, val)) {      return val[0];    }    return defaultValue;  }

 

4, 獲取顯存

EGLSurface surface = egl.eglCreateWindowSurface(display, config, surfaceHolder, null);

 說明:

 1,詳細(xì)的參數(shù)說明見這里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

 2,參數(shù)surfaceHolder是android.view.SurfaceHolder類型,負(fù)責(zé)對Android Surface的管理,后續(xù)將對此進(jìn)行較詳細(xì)說明,參看第8小節(jié)。

3,參數(shù)4用于描述WindowSurface類型,初始化方式如同前面小節(jié)的egl attributes, 其中一個attribute是EGL_RENDER_BUFFER, 用于描述渲染buffer(所有的繪制在此buffer中進(jìn)行)類別,取值為EGL_SINGLE_BUFFER以及默認(rèn)的EGL_BACK_BUFFER,前者屬于單緩沖,繪制的同時用戶即可見;后者屬于雙緩沖,前端緩沖用于顯示,OpenGL ES 在后端緩沖中進(jìn)行繪制,繪制完畢后使用eglSwapBuffers()交換前后緩沖,用戶即看到在后緩沖中的內(nèi)容,如此反復(fù)。其他attributes見官方文檔。

5, 創(chuàng)建context

 int attrs[] = {         EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,         EGL10.EGL_NONE, }; EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, attrs);

說明:

函數(shù)原型     EGLContext  eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);

share_context: 是否有context共享,共享的contxt之間亦共享所有數(shù)據(jù)。EGL_NO_CONTEXT代表不共享。

attrib_list: 目前可用屬性只有EGL_CONTEXT_CLIENT_VERSION, 1代表OpenGL ES 1.x, 2代表2.0。同樣在Android4.2之前,沒有EGL_CONTEXT_CLIENT_VERSION這個屬性,只能使用硬編碼0x3098代替。

函數(shù)詳細(xì)描述:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

6, 設(shè)置為當(dāng)前的渲染環(huán)境

egl.eglMakeCurrent(display, surface, surface, contxt);

比較簡單,不做贅述,詳細(xì)描述:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

7,環(huán)境初始化完畢,開始使用OpenGL ES 2.0 API 進(jìn)行繪制。

// 開始使用OpenGL ES 2.0 API 進(jìn)行繪制。GLES20.glClearColor(0, 0, 0, 1);GLES20.clear(GL_COLOR_BUFFER_BIT);

8,關(guān)于SurfaceHolder

一般在Android中使用OpenGL ES,總是會從GLSurfaceView和Renderer開始,但是由上面描述的過程可知,只需要提供一個合適的SurfaceHolder,就可以完成整個環(huán)境初始化,并進(jìn)行繪制。GLSurfaceView和Renderer事實(shí)上只是在本文描述的基礎(chǔ)上封裝了一些便利的功能,便于開發(fā)者開發(fā),比如渲染同步、狀態(tài)控制、主(渲染)循環(huán)等。那么,如何提供一個SurfaceHolder,具體的Surface分配過程又是怎樣的呢,這涉及到Android窗口機(jī)制,屬于比較大的話題,將在下一節(jié)進(jìn)行描述。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Android OpenGL 開發(fā)---EGL 的使用
初始化 GLES
EGL 作用及其使用
【新提醒】Android OpenGL ES 總結(jié)
EGL接口介紹(轉(zhuǎn))
【轉(zhuǎn)】android.opengl.GLSurfaceView 介紹
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服