Android 애플리케이션에서 OpenGL ES로 그래픽을 그리려면 그래픽의 뷰 컨테이너를 만들어야 합니다. 이렇게 하는 더 간단한 방법 중 하나는 GLSurfaceView
와 GLSurfaceView.Renderer
를 모두 구현하는 것입니다. GLSurfaceView
는 OpenGL로 그린 그래픽의 뷰 컨테이너이며 GLSurfaceView.Renderer
는 이 뷰 내에 그려지는 항목을 제어합니다. 이러한 클래스에 관한 자세한 내용은 OpenGL ES 개발자 가이드를 참고하세요.
GLSurfaceView
는 OpenGL ES 그래픽을 애플리케이션에 통합하는 한 가지 방법일 뿐입니다. 이 방법은 전체 화면 또는 전체 화면에 가까운 그래픽 뷰에서 선택하면 적합합니다.
레이아웃의 작은 부분에 OpenGL ES 그래픽을 통합하려는 개발자는 TextureView
를 살펴봐야 합니다. 직접 개발하는 실제 개발자는 SurfaceView
를 사용하여 OpenGL ES 뷰를 빌드할 수도 있지만, 그러려면 상당한 양의 추가 코드를 작성해야 합니다.
이 과정에서는 간단한 애플리케이션 활동에서 GLSurfaceView
및 GLSurfaceView.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을 시작하는 데 도움이 더 필요한 경우 다음 과정으로 이동하여 몇 가지 힌트를 더 확인하세요.