четверг, 7 апреля 2011 г.

OpenGL ES 2.0 на android. Начало

Пожалуй, самое главное отличие версий OpenGL ES 1.x и 2.0 - это появление в версии 2.0 pipeline with programmable shading, то есть шейдеров (shaders). Почти все красоты современных игр сделаны с использованием шейдеров. В  OpenGL ES шейдеры бывают двух типов: Vertex shaders и Fragment shaders. Описание и использование OpenGL ES 2.0 можно найти в книге OpenGL®ES 2.0 Programming Guide.

Реализация OpenGL ES 2.0 в android, используя java классы, появляется начиная с версии android 2.2. Создать приложение для android очень просто, а вот отладку производить не очень, так как эмулятор не имеет поддержки OpenGL ES 2.0 (по крайней мере, я не смог этого добить на данный момент, а сейчас у меня есть устройство с поддержкой второй версии, и эмулятор не требуется :-) )

Под катом, как написать простое приложение на  OpenGL ES 2.0 для android

Нам потребуется eclipse, android sdk.

Для создания простейшего приложения, нам потребуется наследовать GLSurfaceView и реализовать интерфейс GLSurfaceView.Renderer. GLSurfaceView - это реализация SurfaceView, которая использует поверхность для отображения результатов OpenGL прорисовки. GLSurfaceView.Renderer интерфейс ответственен за прорисовку.

Важно вызвать

setEGLContextClientVersion(2);

иначе все возможности OpenGL ES 2.0 будут не доступны. В конструкторе поверхности создается реализованный рендерер MyGLRenderer.

Собственно класс SimpleOpenGlView:

public class SimpleOpenGlView extends GLSurfaceView {
  private MyGLRenderer mRenderer=null;
  public SimpleOpenGlView(Context context) {
    super(context);
    mRenderer = new MyGLRenderer(context);
    setEGLContextClientVersion(2);
    setRenderer(mRenderer);
  }
}



А вот класс MyGLRenderer

public class MyGLRenderer implements GLSurfaceView.Renderer {
 private Context mContext=null; 
 public MyGLRenderer(Context context) {
  mContext=context;
 } 
 @Override
 public void onDrawFrame(GL10 glUnused) {  
  GLES20.glClearColor(0.2f, 0.7f, 0.5f, 1.0f);
        GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
 }
 @Override
 public void onSurfaceChanged(GL10 glUnused, int width, int height) {
  GLES20.glViewport(0, 0, width, height);
 }
 @Override
 public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
 }
}

Реализованный метод onDrawFrame вызывается каждый раз, когда отрисовывается кадр, onSurfaceChanged вызывается, например, когда размеры поверхности меняются, например, когда устройство поворачивается в пространстве на 90 градусов  и изменяется обзор. onSurfaceCreated  вызывается когда поверхность создается или пересоздается.

Как можно заметить, у методов есть параметр glUnused. Он не используется, так как предоставляет доступ к функционалу  OpenGL ES 1.x, вместо него используем статические функции GLES20. В результате выполнения приложения получается зеленоватый экран.

Да, и не забываем установить нашу поверхность как основной View в главном Activity



mGLView = new SimpleOpenGlView(this);
setContentView(mGLView);

Во вложении ссылка на шаблон проекта для android


4 комментария:

  1. эм... ниче не понятно, мона хотя б коменты к коду добавить

    ОтветитьУдалить
  2. Куда не глянь везде убогий тормозной Java. Бедные процессоры.
    На C++ планируется добавить?

    ОтветитьУдалить
    Ответы
    1. Ну не такой уж и убогий. Не думаю, что шейдеры, вызванные через яву, будут отличаться по скорости, если через ndk

      Удалить
    2. Весь OpenGL Es дергается через Jit (нативный код). А шейдера вообще выполняются на ГПУ на си. Не все так плохо =)
      А вообще мое имхо, что на си/с++ нужно выносить только самые критичные и узкие куски.

      Удалить