Android OpenGL 입문 GLSurfaceView

GLSurfaceView 사용
OpenGL ES 는 오픈 소스 그래 픽 라 이브 러 리 입 니 다.이와 관련 된 것 은 화면 을 표시 하 는 것 이 필요 합 니 다.안 드 로 이 드 에서 opengl 가방 에 View 를 GLSurface View 라 고 제공 합 니 다.그 정 의 는 다음 과 같 습 니 다.
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.
  • 이 를 통 해 시스템 이 화면 을 렌 더 링 하고 해당 하 는 설정 을 할 수 있 도록 View 를 봉 인 했 음 을 알 수 있다.
    사용 절 차 는 다음 과 같다.
    1.GLSurfaceView 정의 만 들 기
    2.GLSurface View 의 setEGLContextClient Version 을 호출 하여 버 전 번 호 를 2 로 설정 할 수 있 습 니 다.
    3.onResume 과 onPause 는 각각 GLSurface View 에 해당 하 는 수명 주기 방법 을 호출 합 니 다.
    4.GLSurfaceView 의 setRender 설정 을 사용 하여 GLSurfaceView 를 실현 합 니 다.Render 인터페이스의 클래스
    5.Render 인 터 페 이 스 는 세 가지 방법 이 있 는데 그것 이 바로 Surface Created 일 때 해당 하 는 초기 화 작업 을 하고 Surface Change 일 때 높 고 넓 은 어댑터 와 구체 적 인 DrawFrame 방법 이다.
  • onSurfaceCreated(GL10 gl, EGLConfig config);
  • onSurfaceChanged(GL10 gl, int width, int height);
  • onDrawFrame(GL10 gl);
  • GLSurfaceView 상세 분석:
    1.GLSurfaceView 는 구조 함수 에서 init()를 호출 하여 이전 3 개의 리 턴 함 수 를 설정 합 니 다.
    
    private void init() {
          SurfaceHolder holder = getHolder();
          holder.addCallback(this);
      }
    2.setRender 는 기본 설정 을 하고 GLThread 스 레 드 를 생 성하 여 렌 더 링 작업 을 합 니 다.그 리 는 내용 은 기본적으로 Surface View 가 제공 하 는 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()방법 에 서 는 guarded Run()방법 을 호출 했 고,guarded Run 방법 에 서 는 new 가 EglHelper 류 를 사용 하 였 으 며,논리 적 판단 후 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);
        }
        ...
    }
    여기 에는 다음 과 같은 몇 가지 중요 한 방법 이 있 습 니 다.최종 적 으로 C++층 으로 호출 하여 관련 렌 더 링 인터페이스 를 초기 화 할 것 입 니 다.
  • EGLContext.getEGL()
  • eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
  • eglInitialize(mEglDisplay, version)
  • createContext()
  • 5.guardedRun()start()호출 후 EglHelper.createSurface()방법 을 호출 하고 최종 적 으로 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 은 그림 표면 을 관리 하 는 데 사용 되 며 다음 과 같은 메커니즘 이 있 습 니 다.
    4.567917.설비 의 네 이 티 브 창 시스템 과 통신그림 표면의 사용 가능 한 유형 과 설정 을 조회 합 니 다그림 표면 만 들 기
  • OpenGL ES 3.0 과 다른 그래 픽 렌 더 링 API 사이 에서 동기 화 렌 더 링
  • 무늬 스티커 등 렌 더 링 자원 관리
  • EGLDisplay:모든 창 시스템 에 서로 다른 의미 가 있 기 때문에 EGL 은 기본 적 인 불투명 형식 EGLDisplay 를 제공 합 니 다.모든 시스템 의 상관 성 을 패키지 하여 네 이 티 브 창 시스템 인터페이스 에 사용 합 니 다.
    EGL 은 다음 과 같은 방법 이 있 습 니 다.
    EGLDisplay eglGetDisplay(Object native_display);
    1.EGL 디 스 플레이 서버 와 의 링크 열기 EGL 디 스 플레이 서버 와 의 링크 열기
    2.native_display 는 display Id 로 디 스 플레이 링크 를 지정 합 니 다.기본 링크 는 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.구체 적 인 것 은 선택 설정 을 호출 하 는 것 입 니 다.설정 세부 사항 은 설명 하지 않 습 니 다.
    EGLContext eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);
    1.렌 더 링 컨 텍스트 만 들 기
    2.display:지정 한 디 스 플레이 링크
    3.config:지정 한 설정
    4.share_context:여러 EGL 컨 텍스트 가 특정 형식의 데 이 터 를 공유 할 수 있 도록 합 니 다.EGL 사용NO_CONTEXT 는 공유 하지 않 았 다 고 합 니 다.
    5.attrib_list:컨 텍스트 를 만 드 는 데 사용 할 속성 목록 을 지정 합 니 다.하나만 받 아들 일 수 있 는 속성:EGLCONTEXT_CLIENT_VERSION 은 당신 이 사용 하 는 OpenGL ES 버 전 을 지정 합 니 다.
    6.eglCreate Context 가 성공 하면 새로 만 든 컨 텍스트 를 가리 키 는 핸들 을 되 돌려 줍 니 다.
    EGLSurface eglCreateWindowSurface(EGLDisplay display, EGLConfig config, Object native_window, int[] attrib_list);
    1.렌 더 링 요구 에 맞 는 EGLConfig 가 있 으 면 이 함수 로 창 을 만 들 수 있 습 니 다.
    2.속성 동상
    int eglGetError();
    1.EGL 함수 성공 시 EGL 반환TRUE,그렇지 않 으 면 EGL 로 돌아 갑 니 다.FALSE。고장 원인 을 조회 하려 면 eglGetError()를 호출 하여 오류 코드 를 되 돌려 받 습 니 다.
    boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context);
    1.한 프로그램 이 여러 개의 EGLContext 를 만 들 수 있 기 때문에 특정한 EGLContext 와 렌 더 링 표면 을 연결 해 야 합 니 다.즉,현재 컨 텍스트 를 지정 합 니 다.
    전체 대략적인 절 차 는 상술 한 바 와 같이 호출 된다.
    이상 은 안 드 로 이 드 OpenGL 입문 GLSurface View 의 상세 한 내용 입 니 다.안 드 로 이 드 GLSurface View 에 관 한 더 많은 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기