[OpenGL ES] EGL 사용하기

Park Sejin·2022년 8월 28일
0
post-thumbnail

EGL이 어떤 것인지 알아보았으므로 이번에는 EGL을 사용하여 OpenGL ES을 실행해 보겠습니다.

  1. eglGetDisplay 를 호출합니다.

    EGLDisplay eglGetDisplay(NativeDisplayType native_display);
    • 대부분의 EGL 함수들을 사용하기 위해서는 EGL display connection 이 필요합니다.
    • eglGetPlatformDisplay 또는 eglGetDisplayEGL display connection 을 반환합니다.
  2. eglInitialize 를 호출합니다.

    EGLBoolean eglInitialize(EGLDisplay display,
    						  EGLint *major,
                              EGLint *minor);
    • eglInitializeEGL display connection 을 초기화하고 지원하는 EGL의 버전을 반환합니다.
  3. eglBindAPI 를 호출합니다.

    EGLBoolean eglBindAPI(EGLenum api);
    • EGL rendering context 에서 사용할 rendering API(OpenGL, OpenGL ES, OpenVG)를 설정할 수 있습니다.
  4. eglChooseConfig 를 호출합니다.

    EGLBoolean eglChooseConfig(EGLDisplay display,
    						    EGLint const *attrib_list,
                                EGLConfig *configs,
                                EGLint config_size,
                                EGLint *num_config);
    • rendering API를 사용하여 EGL surface 로 렌더링하기 위해서는 작성한 프로그램에서 요구하는 렌더링 기능을 지원하는 적절한 EGL frame buffer configuration을 지정해야 합니다.
    • eglChooseConfig 는 파라미터 attrib_list 에 설정한 속성과 일치하는 EGLConfig 를 파라미터 configs 로 반환합니다.
  5. eglCreateContext 를 호출합니다.

    EGLContext eglCreateContext(EGLDisplay display,
    							 EGLConfig config,
                                 EGLContext share_context,
                                 EGLint const *attrib_list);
    • rendering API를 EGL surface 에 바인딩하려면 EGL rendering context 이 필요합니다.
    • eglCreateContext 를 호출하여 EGL rendering context 를 생성합니다.
  6. 네이티브 윈도우를 생성합니다.

    • EGL에서는 네이티브 윈도우를 생성할 수 없습니다. 따라서 각 플랫폼에 맞는 방식으로 네이티브 윈도우를 생성합니다.
  7. eglCreateWindowSurface 를 호출합니다.

    EGLSurface eglCreateWindowSurface(EGLDisplay display,
    								   EGLConfig config,
                                       NativeWindowType native_window,
                                       EGLint const *attrib_list);
    • 네이티브 윈도우로부터 EGL window surface 를 생성합니다.
    • eglCreateWindowSurfaceEGLSurface 를 반환합니다.
  8. eglMakeCurrent 를 호출합니다.

    EGLBoolean eglMakeCurrent(EGLDisplay display,
    						   EGLSurface draw,
                               EGLSurface read,
                               EGLContext context);
    • eglMakeCurrent 를 호출하여 현재 사용할 EGL rendering contextEGL surface 를 연결합니다.
    • 모든 rendering API 명령은 현재 연결된 context와 surface에서 사용됩니다.
    • eglMakeCurrent 를 호출하여 연결된 context와 surface는 이후에 다른 eglMakeCurrent 가 호출되기 전까지 연결이 유지됩니다.
  9. eglSwapBuffers 를 호출합니다.

    EGLBoolean eglSwapBuffers(EGLDisplay display,
    						   EGLSurface surface);
    • surface 가 이중 버퍼링 이상으로 설정되었다면 eglSwapBuffers 를 호출하여 렌더링된 결과를 디스플레이에 표시할 수 있습니다.
    • 이중 버퍼링의 경우 back buffer 에 렌더링을 한 뒤 eglSwapBuffer 를 호출하여 back buffer 가 front buffer 가 되고 front buffer 가 back buffer 가 되도록 바꿔줍니다.
    • surface 가 단일 버퍼의 window, pixmap, pixel buffer 라면 eglSwapBuffers 는 아무런 영향을 미치지 못합니다.

코드

#include <stdlib.h>
#include <unistd.h>
#include <EGL/egl.h>
#include <GLES/gl.h>

extern NativeWindowType createNativeWindow(void);

static EGLint const attribute_list[] = {
    EGL_RED_SIZE, 1,
    EGL_GREEN_SIZE, 1,
    EGL_BLUE_SIZE, 1,
    EGL_NONE
};

int main(int argc, char **argv) {
    EGLDisplay display;
    EGLConfig config;
    EGLContext context;
    EGLSurface surface;
    NativeWindowType native_window;
    EGLint num_config;

    /* 1. EGL display connection 을 얻습니다. */
    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

    /* 2. EGL display connection 을 초기화합니다. */
    eglInitialize(display, NULL, NULL);

    /* 3. 사용할 rendering API를 설정합니다. */
    eglBindAPI(EGL_OPENGL_ES_API);

    /* 4. EGL frame buffer configuration을 얻습니다. */
    eglChooseConfig(display, attribute_list, &config, 1, &num_config);

    /* 5. EGL rendering context를 생성합니다. */
    context = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);

    /* 6. native window를 생성합니다. */
    native_window = createNativeWindow();

    /* 7. EGL window surface를 생성합니다. */
    surface = eglCreateWindowSurface(display, config, native_window, NULL);

    /* 8. surface와 context를 연결합니다. */
    eglMakeCurrent(display, surface, surface, context);

    /* color buffer를 clear합니다. */
    glClearColor(1.0, 1.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();

    /* 9. back buffer와 front buffer를 스왑하여 화면에 보여줍니다. */
    eglSwapBuffers(display, surface);

    sleep(10);
    return EXIT_SUCCESS;
}

참고

0개의 댓글