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

Android OpenGL入門之GLSurfaceView

 更新時間:2021年04月14日 09:44:23   作者:Scott_S  
這篇文章主要介紹了OpenGL入門知識,如何在Android中使用GLSurfaceView,如果對OpenGL感興趣的同學,可以參考下

GLSurfaceView使用

OpenGL ES是是一個開源圖形庫,那么與之相關的需要一個東西去顯示畫面,在android里,opengl包里提供了一個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.

可見系統(tǒng)已封裝好一個View用于渲染畫面并能進行相應設置。

使用步驟如下:

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

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

GLSurfaceView詳細分析:

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

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

2.setRender會進行一些默認的設置,并生成一個GLThread的線程進行渲染繪制相關操作,繪制的內(nèi)容默認情況下依舊是繪制到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 了一個EglHelper類,并在一段邏輯判斷后調(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);
    }
    ...
}

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

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

5.在guardedRun() start()調(diào)用后會調(diào)用EglHelper.createSurface()方法,最終也會調(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相關知識

EGL用于管理繪圖表面,有如下機制

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

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

EGL有如下一些方法:

EGLDisplay eglGetDisplay(Object native_display);
1.打開與EGL顯示服務器的鏈接打開與EGL顯示服務器的鏈接
2.native_display是一個displayId,指定顯示鏈接,默認鏈接為EGL_DEFAULT_DISPLAY

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

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

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

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

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

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

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

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

以上就是Android OpenGL入門之GLSurfaceView的詳細內(nèi)容,更多關于Android GLSurfaceView的資料請關注腳本之家其它相關文章!

相關文章

最新評論