public abstract class AbstractSingleTexturedRenderer
extends AbstractRenderer
{
   int mTextureID;
   int mImageResourceId;
   Context mContext;

   public AbstractSingleTexturedRenderer(Context ctx,
                        int imageResourceId) {
      mImageResourceId = imageResourceId;
      mContext = ctx;
   }

   public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) {
      super.onSurfaceCreated(gl, eglConfig);
      gl.glEnable(GL10.GL_TEXTURE_2D);
      prepareTexture(gl);
   }
   private void prepareTexture(GL10 gl)
   {
      int[] textures = new int[1];
      gl.glGenTextures(1, textures, 0);
      mTextureID = textures[0];

      gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);

      gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                     GL10.GL_NEAREST);
      gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                     GL10.GL_TEXTURE_MAG_FILTER,
                     GL10.GL_LINEAR);
                     
      gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                     GL10.GL_CLAMP_TO_EDGE);
                     
      gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                     GL10.GL_CLAMP_TO_EDGE);
      
      gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                     GL10.GL_REPLACE);

      InputStream is = mContext.getResources()
                     .openRawResource(this.mImageResourceId);

      Bitmap bitmap;
      try {
         bitmap = BitmapFactory.decodeStream(is);
      } finally {
         try {
            is.close();
         } catch(IOException e) {
            // Ignore.
         }
      }
      GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
      bitmap.recycle();
   }
   
   public void onDrawFrame(GL10 gl)
   {
      gl.glDisable(GL10.GL_DITHER);

      gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
      GL10.GL_MODULATE);

      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
      gl.glMatrixMode(GL10.GL_MODELVIEW);
      gl.glLoadIdentity();
      GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

      gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
      gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
      gl.glActiveTexture(GL10.GL_TEXTURE0);

      gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
      gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                     GL10.GL_REPEAT);
                     
      gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                     GL10.GL_REPEAT);
      draw(gl);
   }
}
