[Android] 3D API, OpenGL ES – 1 : 초기화

안드로이드에서 3차원 그래픽을 위한 API는 OpenGL ES입니다. 꽤 오래전부터 3차원 그래픽 API인 OpenGL에 대해 관심이 많은 저로써는 모바일에서 3D API인 OpenGL ES에 대해서도 관심이 많았습니다. 해서 모바일 OS 중의 하나이면서.. 모바일 OS 중에서 가장 관심이 많은 안드로이드에서 3D API인 OpenGL ES에 대한 글을 체계적으로 남겨 보려고 합니다. 그중 가장 먼저 초기화입니다.

이 글의 대상은 안드로이드에 대한 기본적인 내용(Activity, View의 개념)에 대해 알고 있는 개발자 분입니다. 이클립스에서 새로운 안드로이드 프로젝트를 생성할 수 있으며 애뮬레이터이든.. 가지고 계시는 디바이스에서든.. 실행해 그 결과를 살펴보실수 있는 분에 한합니다. 아울러 OpenGL ES가 토대로 하고 있는 OpenGL API를 알고 있다면 매우 쉽게 이 글을 이해하실 수 있을 것입니다. OpenGL ES를 보시기 전에 먼저 OpenGL을 선행 학습하시면 이글을 훨씬 쉽게 이해할 수 있습니다.

먼저 Android Project를 생성합니다. 나타나는 대화상자에서 입력해야할 곳에 아래 그림을 참조해 입력하시기 바랍니다.

사용자 삽입 이미지
위와 같이 입력한 뒤에 Finish 버튼을 클릭하면 OpenGLES_Tutorial1Activity 라는 클래스가 생성됩니다. 여기서 다음과 같이 필드 변수 하나와 onCreate 매서드의 코드를 수정합니다.

package ogl.tutorial1;

import android.app.Activity;
import android.os.Bundle;

public class OpenGLES_Tutorial1Activity extends Activity {
    private MyView myView;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        myView = new MyView(this);
        
        setContentView(myView);
    }
}

MyView라는 View 파생 클래스를 하나 생성할 것인데.. 생성했다고 가정하고 일단 필드로써 정의해 onCreate에서 생성하고 setContentView로 지정했습니다. 여기까지는 안드로이드에서 일반적인 프로젝트를 생성하고 코딩하는 내용입니다. OpenGL ES의 내용은 아직 언급되지 않았구요. 이제 MyView 클래스 작성에서부터 OpenGL ES가 시작됩니다. MyView라는 새로운 클래스를 생성합니다.

사용자 삽입 이미지
상속받을 Superclass는 android.opengl 패키지의 GLSurfaceView라는 점이 중요합니다. 이 클래스는 View라는 클래스를 상속받는 클래스로 다음과 같은 책임을 가지는 클래스입니다.

  • OpenGL ES와 View 시스템을 연결
  • 서페이스에 OpenGL이 렌더링 될 수 있도록 EGLS Display를 관리함
  • Activity의 라이프 사이클과 함께 OpenGL ES가 작동하도록 함
  • 적당한 프레임버퍼의 픽셀 포맷 선택을 쉽게 해줌
  • 렌더링에 대한 별도의 스레드를 만들어 줌
  • OpenGL ES API 호출과 에러에 대한 검사를 위한 디버깅 도구 지원

MyView 클래스에 하나의 필드 변수를 추가하고 생성자를 다음과 같이 코딩합니다.

public class MyView extends GLSurfaceView {
    private MyRenderer renderer;

    public MyView(Context context) {
        super(context);
        renderer = new MyRenderer();
        setRenderer(renderer);
    }

    ....

MyRenderer라는 앞으로 추가할 또 다른 새로운 클래스에 대한 내부 필드를 선언했고 생성자에서 이 필드를 생성한 후 setRenderer로 렌더러로써 지정했습니다. 새롭게 추가할 MyRenderer라는 클래스를 생성합니다.

사용자 삽입 이미지
구현할 Interface를 지정해야 하는데.. android.opengl.GLServiceView 클래스의 Inner Interface인 Renderer 인터페이스를 추가합니다. Finish를 클릭합니다. 이 Renderer 인터페이스에서 구현해 줘야 하는 매서드는 총 3가지입니다.

  • onSufaceCreated – 초기화 코드 부분으로 렌더링 될때 변경되지 않는 것에 대한 설정 코드가 실행되면 적합하다. 화면을 지울 배경 색이나 z-buffer에 대한 활성화 여부 등등
  • onSurfaceChanged – 화면이 가로로 회전될때 등과 같이 화면의 크기가 변경될때 이와 관련된 코드가 실행되면 적합하다. 예를 들어서 Viewport의 크기 지정이라든지 카메라의 재설정 코드 등등
  • onDrawFrame – 프레임을 그리는 코드가 오면 적합하다.

구현해야할 매서드에 대해 내용을 파악했으니.. 이제 MyRenderer에 대한 코드를 작성해 보겠습니다. 색상에 대한 RGB값을 위해 3개의 float 변수를 추가하고 앞의 3개의 메서드를 구현해 보면 다음과 같습니다.

public class MyRenderer implements Renderer {
    private float red = 0.9f;
    private float green = 0.2f;
    private float blue = 0.2f;

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClearColor(red, green, blue, 1.0f);
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //.
    }

일단.. 이해를 쉽게 하기 위해 단순히 화면을 red, green, blue 필드값으로 지정된 색상으로 지우는 것이 그리는 것의 전부입니다. 즉 onDrawFrame에서는 배경을 Clear할 색상을 지정하기 위해 glClearColor 매서드를 사용했고 실제 지우는 함수는 glClear 입니다. 그리고 onSurfaceChanged에서는 뷰포트의 크기를 지정하는 glViewport를 호출하고 있습니다. onSurfaceCreated에서는 특별하 무엇가를 그리는 것이 없기 때문에 별다른 코드는 존재하지 않습니다. 하지만 무언가 3D 오브젝트를 그릴때 이 부분에 코드가 필요할 것입니다. 실행해 보면 다음과 같은 결과가 나타나게 됩니다.

사용자 삽입 이미지
여기에 잠시 응용을 해보겠습니다.. 사용자가 화면에 손을 대고 스크롤하면 색상이 스크롤한 내용에 따라 변경되게 말입니다. 색상에 대한 값이 MyRenderer에 정의되어 있고.. 사용자의 스크롤에 대한 이벤트는 MyView에서 발생하니.. MyRenderer의 색상값을 변경할 수 있는 매서드를 MyRenderer에 추가해해 줘야 합니다.

public void setColor(float r, float g, float b) {
    red = r;
    green = g;
    blue = b;
}

이제 MyView에 터치 이벤트를 작성합니다.

public boolean onTouchEvent(final MotionEvent event) {
    queueEvent(new Runnable() {
        public void run() {
            renderer.setColor(
                event.getX()/getWidth(), event.getY()/getHeight(), 1.0f
            );
        }
    });
  
    return true;
}

네.. 화면에 손을 터치하면 터치된 좌표값을 통해 색상값을 재설정합니다. OpenGL에서 색상값은 0~1.0까지이므로 이 값의 범위에 맞춰주고 있습니다. 실행해서 손을 터치하거나 스크롤해보면 색상값이 그에 따라 변하는 것을 살펴볼 수 있습니다.

“[Android] 3D API, OpenGL ES – 1 : 초기화”에 대한 11개의 댓글

    1. 네~ ^^ 강좌를 시작했습니다.
      일단 저질러 놓고.. 수습차원에서 강좌를 진행하려구요. ^^;;
      이 소식을 GpgStudy에 알려 주셔서 감사합니다.

    1. 늘 블로그에 방문하면 가장 올리고 싶은 글이 안드로이드에서 OpenGL ES인데요, 분발해야겠습니다..

    1. 안드로이드에서 라이브월페이퍼 쪽 개발은 제가 아직 아는바가 없습니다. 기회가 닿으면 초기화 강좌로도 올려보도록 하겠습니다.

    1. OpenGL은 3D 그래픽에 대한 오픈된 표준 API인지라.. 모든 플랫폼에서 사용되는 API는 거의 비슷합니다. 단지 플랫폼에 따른 초기화 부분이 상이합니다.

  1. 오, 찾고있던 opengl es 강좌네요. 평소에 덧글을 안 남기는 저이기는 하나, 워낙 3d에 관심이 많은 터라, 포스팅 하시는데 응원하는 차원에서 댓글 남깁니다… 감사합니다!!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다