OpenGL ES 환경 빌드

Android 애플리케이션에서 OpenGL ES로 그래픽을 그리려면 그래픽의 뷰 컨테이너를 만들어야 합니다. 이렇게 하는 더 간단한 방법 중 하나는 GLSurfaceViewGLSurfaceView.Renderer를 모두 구현하는 것입니다. GLSurfaceView는 OpenGL로 그린 그래픽의 뷰 컨테이너이며 GLSurfaceView.Renderer는 이 뷰 내에 그려지는 항목을 제어합니다. 이러한 클래스에 관한 자세한 내용은 OpenGL ES 개발자 가이드를 참고하세요.

GLSurfaceView는 OpenGL ES 그래픽을 애플리케이션에 통합하는 한 가지 방법일 뿐입니다. 이 방법은 전체 화면 또는 전체 화면에 가까운 그래픽 뷰에서 선택하면 적합합니다. 레이아웃의 작은 부분에 OpenGL ES 그래픽을 통합하려는 개발자는 TextureView를 살펴봐야 합니다. 직접 개발하는 실제 개발자는 SurfaceView를 사용하여 OpenGL ES 뷰를 빌드할 수도 있지만, 그러려면 상당한 양의 추가 코드를 작성해야 합니다.

이 과정에서는 간단한 애플리케이션 활동에서 GLSurfaceViewGLSurfaceView.Renderer의 최소 구현을 완료하는 방법을 설명합니다.

매니페스트에서 OpenGL ES 사용 선언

애플리케이션에서 OpenGL ES 2.0 API를 사용하려면 매니페스트에 다음 선언을 추가해야 합니다.

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

애플리케이션에서 텍스처 압축을 사용하는 경우 호환되는 기기에만 설치되도록 앱에서 지원하는 압축 형식도 선언해야 합니다.

<supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
<supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />

텍스처 압축 형식에 관한 자세한 내용은 OpenGL 개발자 가이드를 참고하세요.

OpenGL ES 그래픽의 활동 만들기

OpenGL ES를 사용하는 Android 애플리케이션에는 사용자 인터페이스가 있는 다른 애플리케이션과 동일한 활동이 있습니다. 다른 애플리케이션과의 주요 차이점은 활동의 레이아웃에 배치하는 것입니다. 많은 애플리케이션에서 TextView, Button, ListView를 사용할 수 있지만 OpenGL ES를 사용하는 앱에는 GLSurfaceView을 추가할 수도 있습니다.

다음 코드 예에서는 GLSurfaceView를 기본 뷰로 사용하는 활동의 최소 구현을 보여줍니다.

Kotlin

class OpenGLES20Activity : Activity() {

    private lateinit var gLView: GLSurfaceView

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = MyGLSurfaceView(this)
        setContentView(gLView)
    }
}

Java

public class OpenGLES20Activity extends Activity {

    private GLSurfaceView gLView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create a GLSurfaceView instance and set it
        // as the ContentView for this Activity.
        gLView = new MyGLSurfaceView(this);
        setContentView(gLView);
    }
}

참고: OpenGL ES 2.0에는 Android 2.2 (API 수준 8) 이상이 필요하므로 Android 프로젝트에서 이 API 이상을 타겟팅해야 합니다.

GLSurfaceView 객체 빌드

GLSurfaceView는 OpenGL ES 그래픽을 그릴 수 있는 특수 뷰입니다. 자체적인 기능은 많지 않습니다. 객체의 실제 그리기는 이 뷰에 설정한 GLSurfaceView.Renderer에서 제어됩니다. 실제로 이 객체의 코드는 매우 간단하므로 확장을 건너뛰고 수정되지 않은 GLSurfaceView 인스턴스를 만들고 싶을 수 있지만 그러면 안 됩니다. 터치 이벤트를 캡처하려면 이 클래스를 확장해야 합니다. 이 내용은 터치 이벤트에 응답 과정에서 다룹니다.

GLSurfaceView의 필수 코드는 매우 적으므로 빠른 구현을 위해 이 코드를 사용하는 활동에서 내부 클래스를 만드는 것이 일반적입니다.

Kotlin

import android.content.Context
import android.opengl.GLSurfaceView

class MyGLSurfaceView(context: Context) : GLSurfaceView(context) {

    private val renderer: MyGLRenderer

    init {

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2)

        renderer = MyGLRenderer()

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer)
    }
}

Java

import android.content.Context;
import android.opengl.GLSurfaceView;

class MyGLSurfaceView extends GLSurfaceView {

    private final MyGLRenderer renderer;

    public MyGLSurfaceView(Context context){
        super(context);

        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        renderer = new MyGLRenderer();

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(renderer);
    }
}

GLSurfaceView 구현에 추가할 수 있는 또 다른 선택적 추가사항은 GLSurfaceView.RENDERMODE_WHEN_DIRTY 설정을 사용하여 그리기 데이터가 변경될 때만 뷰를 그리도록 렌더링 모드를 설정하는 것입니다.

Kotlin

// Render the view only when there is a change in the drawing data
renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY

Java

// Render the view only when there is a change in the drawing data
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

이 설정을 사용하면 requestRender()를 호출할 때까지 GLSurfaceView 프레임을 다시 그리지 않습니다. 이렇게 하면 이 샘플 앱에 더 효율적입니다.

렌더기 클래스 빌드

OpenGL ES를 사용하는 애플리케이션 내에서 GLSurfaceView.Renderer 클래스 또는 렌더기를 구현하는 것부터 흥미로운 작업이 시작됩니다. 이 클래스는 연결된 GLSurfaceView에 그려지는 내용을 제어합니다. GLSurfaceView에 그리는 내용과 방법을 파악하기 위해 Android 시스템에서 호출하는 메서드에는 세 가지가 있습니다.

  • onSurfaceCreated() - 뷰의 OpenGL ES 환경을 설정하기 위해 한 번 호출됩니다.
  • onDrawFrame() - 뷰를 다시 그릴 때마다 호출됩니다.
  • onSurfaceChanged() - 기기의 화면 방향이 변경되는 경우와 같이 뷰의 도형이 변경되면 호출됩니다.

다음은 OpenGL ES 렌더기의 기본적인 구현으로, GLSurfaceView에 검은색 배경만 그립니다.

Kotlin

import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

import android.opengl.GLES20
import android.opengl.GLSurfaceView

class MyGLRenderer : GLSurfaceView.Renderer {

    override fun onSurfaceCreated(unused: GL10, config: EGLConfig) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f)
    }

    override fun onDrawFrame(unused: GL10) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
    }

    override fun onSurfaceChanged(unused: GL10, width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)
    }
}

Java

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyGLRenderer implements GLSurfaceView.Renderer {

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }

    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

실행할 작업은 이것뿐입니다. 위의 코드 예에서는 OpenGL을 사용하여 검은색 화면을 표시하는 간단한 Android 애플리케이션을 만듭니다. 이 코드는 그다지 흥미로운 동작을 하지 않지만 이러한 클래스를 만들면 OpenGL로 그래픽 요소 그리기를 시작하는 데 필요한 기반을 마련할 수 있습니다.

참고: OpenGL ES 2.0 API를 사용할 때 이러한 메서드에 GL10 매개변수가 있는 이유가 궁금할 수 있습니다. 이러한 메서드 서명은 Android 프레임워크 코드를 더 단순하게 유지하기 위해 단순히 2.0 API에 재사용됩니다.

OpenGL ES API에 익숙하다면 이제 앱에서 OpenGL ES 환경을 설정하고 그래픽 그리기를 시작할 수 있습니다. 그러나 OpenGL을 시작하는 데 도움이 더 필요한 경우 다음 과정으로 이동하여 몇 가지 힌트를 더 확인하세요.