page.title=Hello OpenGL ES 1.0 parent.title=Tutorials parent.link=../../browser.html?tag=tutorial @jd:body

In this document

  1. Creating an OpenGL ES 1.0 Application
  2. Drawing Graphic Elements
    1. Defining a Triangle
    2. Draw the Triangle
  3. Using Projection and Views
  4. Adding Motion
  5. Additional Resources

Related Samples

  1. API Demos - graphics
  2. GLSurfaceViewActivity

See also

  1. 3D with OpenGL
  2. Hello OpenGL ES 2.0

This tutorial shows you how to create a simple Android application that uses OpenGL ES 1.0 and perform some basic operations using the OpenGL ES 1.0 API, including:

This tutorial demonstrates use of the OpenGL ES 1.0 API. Both the OpenGL ES 1.0 and the ES 1.1 API are supported by the Android framework since release 1.0 (API Level 1). The OpenGL ES 1.1 API is an extention of the 1.0 API, and it's capabilities are beyond the scope of this tutorial.

Beginning with Android 2.2 (API Level 8), the framework supports OpenGL ES 2.0. For more information about compatibility for OpenGL versions and Android devices, see the 3D with OpenGL document.

Creating an OpenGL ES 1.0 Application

OpenGL applications for Android have the same basic structure as other applications, however OpenGL applications use {@link android.opengl.GLSurfaceView} where other, non-OpenGL applications use the {@link android.view.View} or {@link android.view.SurfaceView} class.

To get started using OpenGL in your Android application, you must implement both a {@link android.opengl.GLSurfaceView} and a {@link android.opengl.GLSurfaceView.Renderer}. The {@link android.opengl.GLSurfaceView} is the main view type for the OpenGL applications and the {@link android.opengl.GLSurfaceView.Renderer} controls what is drawn within that view. For more information about these classes, see the 3D with OpenGL document.

To create an application that uses OpenGL ES 1.0:

  1. Start a new Android project with an Activity called HelloOpenGLES10.

    Note: If you have not created a basic Android application yet, follow the Hello World Tutorial instructions to familiarize yourself with the process.

  2. Modify the HelloOpenGLES10 class as follows:
    package com.example.android.apis.graphics;
    
    import android.app.Activity;
    import android.content.Context;
    import android.opengl.GLSurfaceView;
    import android.os.Bundle;
    
    public class HelloOpenGLES10 extends Activity {
      
        private GLSurfaceView mGLView;    
      
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            
            mGLView = new HelloOpenGLSurfaceView(this);
            setContentView(mGLView);
        }
        
        @Override
        protected void onPause() {
            super.onPause();
            mGLView.onPause();
        }
        
        @Override
        protected void onResume() {
            super.onResume();
            mGLView.onResume();
        }
        
    }
      
    class HelloOpenGLES10SurfaceView extends GLSurfaceView {
    
        public HelloOpenGLES10SurfaceView(Context context){
            super(context);
            setRenderer(new HelloOpenGLES10Renderer());
        }
    
    }
    

    This Activity class creates a basic container for a {@link android.opengl.GLSurfaceView}.

  3. Create the following class HelloOpenGLES10Renderer, which implements the {@link android.opengl.GLSurfaceView.Renderer} interface:
    package com.example.android.apis.graphics;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.opengl.GLSurfaceView;
    
    public class HelloOpenGLES10Renderer implements GLSurfaceView.Renderer {
    
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            // Set the background frame color
            gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        }
        
        public void onDrawFrame(GL10 gl) {
            // Redraw background color
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        }
        
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
        }
      
    }
    

These classes create a simple Android application which displays a grey screen using OpenGL ES 1.0 calls. While this application does not do anything very interesting, by creating these two classes, you have layed the foundation needed to start drawing graphic elements with OpenGL ES 1.0.

If you are familiar with the OpenGL ES APIs, these two classes should give you enough information to start using the OpenGL ES 1.0 API and creating graphics. However, if you need a bit more help getting started with OpenGL, head on to the next sections for a few more tips.

Drawing Graphic Elements

Once you have implemented a {@link android.opengl.GLSurfaceView.Renderer}, the next step is to draw something on it. This section shows you how to define and draw a basic triangle shape with the Android OpenGL ES 1.0 API.

Note: The following instructions build on the previous section, so if you have not been following along, go back to the previous section and catch up.

Defining a Triangle

OpenGL allows you to define objects using coordinates in three-dimensional space. So, before you can draw a triangle, you must define its coordinates. In OpenGL, the typical way to do this is to define a vertex array for the coordinates.

By default, OpenGL ES assumes a coordinate system where 0,0,0 (X,Y,Z) specifies the center of the {@link android.opengl.GLSurfaceView} frame, 1,1,0 is the top right corner of the frame and -1,-1,0 is bottom left corner of the frame.

To define a vertex array for a triangle:

  1. In your HelloOpenGLES10Renderer class, add new member variable to contain the vertices of a triangle shape:
        private FloatBuffer triangleVB;
    
  2. Create a method, initShapes() which populates this member variable:
        private void initShapes(){
        
            float triangleCoords[] = {
                // X, Y, Z
                -0.5f, -0.25f, 0,
                 0.5f, -0.25f, 0,
                 0.0f,  0.559016994f, 0
            }; 
            
            // initialize vertex Buffer for triangle  
            ByteBuffer vbb = ByteBuffer.allocateDirect(
                    // (# of coordinate values * 4 bytes per float)
                    triangleCoords.length * 4); 
            vbb.order(ByteOrder.nativeOrder());
            triangleVB = vbb.asFloatBuffer();
            triangleVB.put(triangleCoords);
            triangleVB.position(0);
        
        }
    

    This method defines a two-dimensional triangle shape with three equal sides.

  3. Modify your onSurfaceCreated() method to initialize your triangle:
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        
            // Set the background frame color
            gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
            
            // initialize the triangle vertex array
            initShapes();
        }
    

    Warning: Shapes and other static objects should be initialized once in your onSurfaceCreated() method for best performance. Avoid initializing the new objects in onDrawFrame(), as this causes the system to re-create the objects for every frame redraw and slows down your application.

Draw the Triangle

Now that you have defined a shape to draw, you can use the OpenGL APIs to draw the object.

To draw the triangle with OpenGL:

  1. Before you can draw your triangle, you must tell OpenGL that you are using vertex arrays. Modify your onSurfaceCreated() method to enable vertex arrays.
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        
            // Set the background frame color
            gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
            
            // initialize the triangle vertex array
            initShapes();
            
            // Enable use of vertex arrays
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        }
    

    At this point, you are ready to draw the triangle object in the OpenGL frame.

  2. Modify your onDrawFrame() method to draw the triangle.
        public void onDrawFrame(GL10 gl) {
            // Redraw background color
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        
            // Draw the triangle
            gl.glColor4f(0.63671875f, 0.76953125f, 0.22265625f, 0.0f);
            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVB);
            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        }
    

    Note: Since the triangle is stationary at this point, the system is redrawing the object repeatedly in exactly the same place and so is not the most efficient use of the OpenGL graphics pipeline. In a later section, we add motion to the object to justify this use of processing power.

Try running this example application on your emulator or test device and you should see something like this:

There are a few problems with this example. First of all, it's not going to impress your friends. Secondly, the triangle is a bit squashed and changes shape when you change the screen orientation of the test device. The reason the shape is skewed is due to the fact that the object is being rendered in a frame which is not perfectly square. We fix that problem in the next section.

Using Projection and Views

OpenGL Projection and Views provide a way to calculate the coordinates of graphic objects in realistic proportions on graphics displays of any size. One of the basic problems in displaying graphics is that Android device displays are typically not square and—by default—OpenGL happily maps a perfectly square, uniform coordinate system onto your typically non-square screen.

The illustration above shows the uniform coordinate system assumed for an OpenGL frame on the left, and how these coordinates actually map to a typical device screen in landscape orientation on the right. To solve this problem, you can apply OpenGL projection modes and views to transform object coordinates so your graphic objects have the correct proportions on any display.

To use a projection transformation on your triangle:

  1. Modify your onSurfaceChanged() method to enable {@link javax.microedition.khronos.opengles.GL10#GL_PROJECTION GL10.GL_PROJECTION} mode, calculate the screen ratio and apply the ratio as a transformation of the object coordinates.
      public void onSurfaceChanged(GL10 gl, int width, int height) {
          gl.glViewport(0, 0, width, height);
          
          // make adjustments for screen ratio
          float ratio = (float) width / height;
          gl.glMatrixMode(GL10.GL_PROJECTION);
          gl.glLoadIdentity();
          gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);
      }  
    
  2. Next, modify your onDrawFrame() method to apply the {@link javax.microedition.khronos.opengles.GL10#GL_MODELVIEW GL_MODELVIEW} mode and set a view point for the display using {@link android.opengl.GLU#gluLookAt(javax.microedition.khronos.opengles.GL10, float, float, float, float, float, float, float, float, float) GLU#gluLookAt()}.
        public void onDrawFrame(GL10 gl) {
            // Redraw background color
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
            
            // Set GL_MODELVIEW transformation mode
            gl.glMatrixMode(GL10.GL_MODELVIEW);
            gl.glLoadIdentity();
            
            // When using GL_MODELVIEW, you must set the view point
            GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
            
            // Draw the triangle
            ...
        }
    

Try running this updated application on your emulator or test device and you should see something like this:

Now that you have applied this transformation, the triangle has three equal sides, instead of the squashed display in the earlier version.

Adding Motion

While it may be interesting exercise to create static graphic objects with OpenGL ES, chances are you want at least some of your objects to move. In this section, we add motion to to our triangle by rotating it.

To add rotation to your triangle:

Run the application with this code and your triangle should rotate around its center.

Additional Resources

Be sure to check out the OpenGL ES code samples are available in the API Demos sample application and listed in Related Samples sidebar above.