欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android OpenGL入門(mén)之GLSurfaceView

 更新時(shí)間:2021年04月14日 09:44:23   作者:Scott_S  
這篇文章主要介紹了OpenGL入門(mén)知識(shí),如何在A(yíng)ndroid中使用GLSurfaceView,如果對(duì)OpenGL感興趣的同學(xué),可以參考下

GLSurfaceView使用

OpenGL ES是是一個(gè)開(kāi)源圖形庫(kù),那么與之相關(guān)的需要一個(gè)東西去顯示畫(huà)面,在android里,opengl包里提供了一個(gè)View叫GLSurfaceView,它的定義如下:

An implementation of SurfaceView that uses the dedicated surface for
displaying OpenGL rendering.

它的特性如下:

  • Manages a surface, which is a special piece of memory that can be
  • composited into the Android view system.
  • Manages an EGL display, which enables OpenGL to render into a surface.
  • Accepts a user-provided Renderer object that does the actual rendering.
  • Renders on a dedicated thread to decouple rendering performance from the UI thread.
  • Supports both on-demand and continuous rendering.
  • Optionally wraps, traces, and/or error-checks the renderer's OpenGL calls.

可見(jiàn)系統(tǒng)已封裝好一個(gè)View用于渲染畫(huà)面并能進(jìn)行相應(yīng)設(shè)置。

使用步驟如下:

1.創(chuàng)建定義一個(gè)GLSurfaceView
2.調(diào)用GLSurfaceView的setEGLContextClientVersion設(shè)置版本號(hào),可設(shè)為2
3.onResume 和 onPause分別調(diào)用GLSurfaceView相應(yīng)的生命周期方法
4.調(diào)用GLSurfaceView的setRender設(shè)置自己實(shí)現(xiàn)GLSurfaceView.Render接口的類(lèi)
5.Render接口有3個(gè)方法,分別是SurfaceCreated時(shí)候進(jìn)行相應(yīng)的初始化工作,SurfaceChange時(shí)候高寬的適配以及具體的DrawFrame方法

  • onSurfaceCreated(GL10 gl, EGLConfig config);
  • onSurfaceChanged(GL10 gl, int width, int height);
  • onDrawFrame(GL10 gl);

GLSurfaceView詳細(xì)分析:

1.GLSurfaceView在構(gòu)造函數(shù)中調(diào)用init()設(shè)置如上3個(gè)回掉函數(shù)

private void init() {
      SurfaceHolder holder = getHolder();
      holder.addCallback(this);
  }

2.setRender會(huì)進(jìn)行一些默認(rèn)的設(shè)置,并生成一個(gè)GLThread的線(xiàn)程進(jìn)行渲染繪制相關(guān)操作,繪制的內(nèi)容默認(rèn)情況下依舊是繪制到SurfaceView所提供的Surface上

  public void setRenderer(Renderer renderer) {
      checkRenderThreadState();
      if (mEGLConfigChooser == null) {
          mEGLConfigChooser = new SimpleEGLConfigChooser(true);
      }
      if (mEGLContextFactory == null) {
          mEGLContextFactory = new DefaultContextFactory();
      }
      if (mEGLWindowSurfaceFactory == null) {
          mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory();
      }
      mRenderer = renderer;
      mGLThread = new GLThread(mThisWeakRef);
      mGLThread.start();
  }

3.GLThread的run()方法里調(diào)用了guardedRun()方法,在guardedRun方法里new 了一個(gè)EglHelper類(lèi),并在一段邏輯判斷后調(diào)用了EglHelper的start方法。

4.EglHelper.start()方法里

 public void start() {
    mEgl = (EGL10) EGLContext.getEGL();
    mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

    if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
       throw new RuntimeException("eglGetDisplay failed");
    }
    int[] version = new int[2];
    if(!mEgl.eglInitialize(mEglDisplay, version)) {
      throw new RuntimeException("eglInitialize failed");
    }
    GLSurfaceView view = mGLSurfaceViewWeakRef.get();
    if (view == null) {
        mEglConfig = null;
        mEglContext = null;
    } else {
        mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay);
        mEglContext = view.mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
    }
    ...
}

這里有如下幾個(gè)重要方法,最終會(huì)調(diào)用到C++層去初始化相關(guān)的渲染界面

  • EGLContext.getEGL()
  • eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
  • eglInitialize(mEglDisplay, version)
  • createContext()

5.在guardedRun() start()調(diào)用后會(huì)調(diào)用EglHelper.createSurface()方法,最終也會(huì)調(diào)用到C++層。

public boolean createSurface() {
//Check preconditions.
//window size has changed, create a new surface.
	destroySurfaceImp();
//Create an EGL surface we can render into.
    GLSurfaceView view = mGLSurfaceViewWeakRef.get();
    if (view != null) {
       	mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface(mEgl,
                        mEglDisplay, mEglConfig, view.getHolder());
    } else {mEglSurface = null;}
    ...
    int error = mEgl.eglGetError();
	...
    if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
     	logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
     	return false;
   	}
    return true;
}
  • createWindowSurface
  • eglGetError
  • eglMakeCurrent

EGL相關(guān)知識(shí)

EGL用于管理繪圖表面,有如下機(jī)制

  • 與設(shè)備的原生窗口系統(tǒng)通信
  • 查詢(xún)繪圖表面的可用類(lèi)型和配置
  • 創(chuàng)建繪圖表面
  • 在OpenGL ES 3.0和其他圖形渲染API之間同步渲染
  • 管理紋理貼圖等渲染資源

EGLDisplay:由于每個(gè)窗口系統(tǒng)都有不同的語(yǔ)義,所以EGL提供基本的不透明類(lèi)型EGLDisplay,封裝了所有系統(tǒng)相關(guān)性,用于和原生窗口系統(tǒng)接口

EGL有如下一些方法:

EGLDisplay eglGetDisplay(Object native_display);
1.打開(kāi)與EGL顯示服務(wù)器的鏈接打開(kāi)與EGL顯示服務(wù)器的鏈接
2.native_display是一個(gè)displayId,指定顯示鏈接,默認(rèn)鏈接為EGL_DEFAULT_DISPLAY

boolean eglInitialize(EGLDisplay display, int[] major_minor)
1.打開(kāi)鏈接后,需要初始化EGL
2.display:getDisplay返回的值
3.主次版本號(hào)

boolean eglChooseConfig(EGLDisplay display, int[] attrib_list, EGLConfig[] configs, int config_size, int[] num_config);
1.讓EGL選擇匹配的EGLConfig
2.具體就是調(diào)用選擇配置,配置細(xì)節(jié)暫不敘述

EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);
1.創(chuàng)建渲染上下文
2.display:指定的顯示鏈接
3.config:指定的配置
4.share_context:允許多個(gè)EGL上下文共享特定類(lèi)型的數(shù)據(jù);使用EGL_NO_CONTEXT表示沒(méi)有共享
5.attrib_list:指定創(chuàng)建上下文使用的屬性列表;只有一個(gè)可接受的屬性:EGL_CONTEXT_CLIENT_VERSION表示指定與你所使用的OpenGL ES版本

6.eglCreateContext成功時(shí),它返回一個(gè)指向新創(chuàng)建上下文的句柄。

EGLSurface eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);
1.有了符合渲染要求的EGLConfig,就可調(diào)用此函數(shù)創(chuàng)建一個(gè)窗口
2.屬性同上

int eglGetError();
1.EGL函數(shù)成功時(shí)返回EGL_TRUE,否則返回EGL_FALSE。如果需要查詢(xún)故障原因,調(diào)用eglGetError()得到返回錯(cuò)誤碼。

boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
1.因一個(gè)應(yīng)用程序可能創(chuàng)建多個(gè)EGLContext用于不同的用途,所以需要關(guān)聯(lián)特定的EGLContext和渲染表面即:指定當(dāng)前上下文

整個(gè)大概流程就如上所述調(diào)用下來(lái)。

以上就是Android OpenGL入門(mén)之GLSurfaceView的詳細(xì)內(nèi)容,更多關(guān)于A(yíng)ndroid GLSurfaceView的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論