A GLSurfaceView.Renderer that uses the Android-specific android.opengl.GLESXXX static OpenGL ES APIs. : OpenGL « 2D Graphics « Android






A GLSurfaceView.Renderer that uses the Android-specific android.opengl.GLESXXX static OpenGL ES APIs.

   
/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package app.test;
import static android.opengl.GLES10.*;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

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

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.os.SystemClock;

/**
 * A GLSurfaceView.Renderer that uses the Android-specific
 * android.opengl.GLESXXX static OpenGL ES APIs. The static APIs expose more of
 * the OpenGL ES features than the javax.microedition.khronos.opengles APIs, and
 * also provide a programming model that is closer to the C OpenGL ES APIs,
 * which may make it easier to reuse code and documentation written for the C
 * OpenGL ES APIs.
 * 
 */
class StaticTriangleRenderer implements GLSurfaceView.Renderer {

  public interface TextureLoader {
    /**
     * Load a texture into the currently bound OpenGL texture.
     */
    void load(GL10 gl);
  }

  public StaticTriangleRenderer(Context context) {
    init(context, new RobotTextureLoader());
  }

  public StaticTriangleRenderer(Context context, TextureLoader loader) {
    init(context, loader);
  }

  private void init(Context context, TextureLoader loader) {
    mContext = context;
    mTriangle = new Triangle();
    mTextureLoader = loader;
  }

  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    /*
     * By default, OpenGL enables features that improve quality but reduce
     * performance. One might want to tweak that especially on software
     * renderer.
     */
    glDisable(GL_DITHER);

    /*
     * Some one-time OpenGL initialization can be made here probably based
     * on features of this particular context
     */
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);

    glClearColor(.5f, .5f, .5f, 1);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    /*
     * Create our texture. This has to be done each time the surface is
     * created.
     */

    int[] textures = new int[1];
    glGenTextures(1, textures, 0);

    mTextureID = textures[0];
    glBindTexture(GL_TEXTURE_2D, mTextureID);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    mTextureLoader.load(gl);
  }

  public void onDrawFrame(GL10 gl) {
    /*
     * By default, OpenGL enables features that improve quality but reduce
     * performance. One might want to tweak that especially on software
     * renderer.
     */
    glDisable(GL_DITHER);

    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    /*
     * Usually, the first thing one might want to do is to clear the screen.
     * The most efficient way of doing this is to use glClear().
     */

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    /*
     * Now we're ready to draw some 3D objects
     */

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mTextureID);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    long time = SystemClock.uptimeMillis() % 4000L;
    float angle = 0.090f * ((int) time);

    glRotatef(angle, 0, 0, 1.0f);

    mTriangle.draw(gl);
  }

  public void onSurfaceChanged(GL10 gl, int w, int h) {
    glViewport(0, 0, w, h);

    /*
     * Set our projection matrix. This doesn't have to be done each time we
     * draw, but usually a new projection needs to be set when the viewport
     * is resized.
     */

    float ratio = (float) w / h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustumf(-ratio, ratio, -1, 1, 3, 7);
  }

  private Context mContext;
  private Triangle mTriangle;
  private int mTextureID;
  private TextureLoader mTextureLoader;

  private class RobotTextureLoader implements TextureLoader {
    public void load(GL10 gl) {
      InputStream is = mContext.getResources().openRawResource(
          R.raw.robot);
      Bitmap bitmap;
      try {
        bitmap = BitmapFactory.decodeStream(is);
      } finally {
        try {
          is.close();
        } catch (IOException e) {
          // Ignore.
        }
      }

      GLUtils.texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);
      bitmap.recycle();
    }
  }

  static class Triangle {
    public Triangle() {

      // Buffers to be passed to gl*Pointer() functions
      // must be direct, i.e., they must be placed on the
      // native heap where the garbage collector cannot
      // move them.
      //
      // Buffers with multi-byte datatypes (e.g., short, int, float)
      // must have their byte order set to native order

      ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4);
      vbb.order(ByteOrder.nativeOrder());
      mFVertexBuffer = vbb.asFloatBuffer();

      ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4);
      tbb.order(ByteOrder.nativeOrder());
      mTexBuffer = tbb.asFloatBuffer();

      ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2);
      ibb.order(ByteOrder.nativeOrder());
      mIndexBuffer = ibb.asShortBuffer();

      // A unit-sided equilateral triangle centered on the origin.
      float[] coords = {
          // X, Y, Z
          -0.5f, -0.25f, 0, 0.5f, -0.25f, 0, 0.0f, 0.559016994f, 0 };

      for (int i = 0; i < VERTS; i++) {
        for (int j = 0; j < 3; j++) {
          mFVertexBuffer.put(coords[i * 3 + j] * 2.0f);
        }
      }

      for (int i = 0; i < VERTS; i++) {
        for (int j = 0; j < 2; j++) {
          mTexBuffer.put(coords[i * 3 + j] * 2.0f + 0.5f);
        }
      }

      for (int i = 0; i < VERTS; i++) {
        mIndexBuffer.put((short) i);
      }

      mFVertexBuffer.position(0);
      mTexBuffer.position(0);
      mIndexBuffer.position(0);
    }

    public void draw(GL10 gl) {
      glFrontFace(GL_CCW);
      glVertexPointer(3, GL_FLOAT, 0, mFVertexBuffer);
      glEnable(GL_TEXTURE_2D);
      glTexCoordPointer(2, GL_FLOAT, 0, mTexBuffer);
      glDrawElements(GL_TRIANGLE_STRIP, VERTS, GL_UNSIGNED_SHORT,
          mIndexBuffer);
    }

    private final static int VERTS = 3;

    private FloatBuffer mFVertexBuffer;
    private FloatBuffer mTexBuffer;
    private ShortBuffer mIndexBuffer;
  }
}

public class Test extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mGLView = new GLSurfaceView(this);
    mGLView.setRenderer(new StaticTriangleRenderer(this));
    /*
     * ImageView imageView = new ImageView(this);
     * imageView.setImageResource(R.raw.robot); setContentView(imageView);
     */
    setContentView(mGLView);
  }

  @Override
  protected void onPause() {
    super.onPause();
    mGLView.onPause();
  }

  @Override
  protected void onResume() {
    super.onResume();
    mGLView.onResume();
  }

  private GLSurfaceView mGLView;
}

   
    
    
  








Related examples in the same category

1.Wrapper activity demonstrating the use of GLSurfaceView, a view that uses OpenGL drawing into a dedicated surface.
2.Check for OpenGL ES 2.0 support at runtime, and then use either OpenGL ES 1.0 or OpenGL ES 2.0, as appropriate.
3.Wrapper activity demonstrating the use of {@link GLSurfaceView}, a view that uses OpenGL drawing into a dedicated surface.
4.Demonstrate how to use the OES_texture_cube_map extension, available on some high-end OpenGL ES 1.x GPUs.
5.OpenGL objects
6.OpenGL Sprite Text Activity
7.An OpenGL ES renderer based on the GLSurfaceView rendering framework.
8.OpenGL Utils
9.Graphics API supports both OpenGL and Android 2D rendering targets efficiently through the same interface
10.OpenGL ES version of a sprite
11.OpenGL Utils 2
12.Demonstrate how to use ETC1 format compressed textures.