OSDN Git Service

docs: OpenGL Tutorials
authorJoe Fernandez <joefernandez@google.com>
Wed, 22 Jun 2011 21:25:04 +0000 (14:25 -0700)
committerJoe Fernandez <joefernandez@google.com>
Sat, 25 Jun 2011 00:20:25 +0000 (17:20 -0700)
Change-Id: I2d06990277d48facc46f5ea9ea4ec784ece93264

docs/html/images/opengl/coordinates.png [new file with mode: 0644]
docs/html/images/opengl/helloopengl-es10-1.png [new file with mode: 0644]
docs/html/images/opengl/helloopengl-es10-2.png [new file with mode: 0644]
docs/html/images/opengl/helloopengl-es20-1.png [new file with mode: 0644]
docs/html/images/opengl/helloopengl-es20-2.png [new file with mode: 0644]
docs/html/resources/resources-data.js
docs/html/resources/tutorials/opengl/opengl-es10.jd [new file with mode: 0644]
docs/html/resources/tutorials/opengl/opengl-es20.jd [new file with mode: 0644]

diff --git a/docs/html/images/opengl/coordinates.png b/docs/html/images/opengl/coordinates.png
new file mode 100644 (file)
index 0000000..7180cd5
Binary files /dev/null and b/docs/html/images/opengl/coordinates.png differ
diff --git a/docs/html/images/opengl/helloopengl-es10-1.png b/docs/html/images/opengl/helloopengl-es10-1.png
new file mode 100644 (file)
index 0000000..bdfbcdb
Binary files /dev/null and b/docs/html/images/opengl/helloopengl-es10-1.png differ
diff --git a/docs/html/images/opengl/helloopengl-es10-2.png b/docs/html/images/opengl/helloopengl-es10-2.png
new file mode 100644 (file)
index 0000000..c07dabb
Binary files /dev/null and b/docs/html/images/opengl/helloopengl-es10-2.png differ
diff --git a/docs/html/images/opengl/helloopengl-es20-1.png b/docs/html/images/opengl/helloopengl-es20-1.png
new file mode 100644 (file)
index 0000000..44abe77
Binary files /dev/null and b/docs/html/images/opengl/helloopengl-es20-1.png differ
diff --git a/docs/html/images/opengl/helloopengl-es20-2.png b/docs/html/images/opengl/helloopengl-es20-2.png
new file mode 100644 (file)
index 0000000..22fa52c
Binary files /dev/null and b/docs/html/images/opengl/helloopengl-es20-2.png differ
index 097d004..f71307e 100644 (file)
@@ -762,6 +762,26 @@ var ANDROID_RESOURCES = [
     }
   },
   {
+    tags: ['tutorial', 'gl', 'new'],
+    path: 'tutorials/opengl/opengl-es10.html',
+    title: {
+      en: 'Hello OpenGL ES 1.0'
+    },
+    description: {
+      en: 'The basics of implementing an application using the OpenGL ES 1.0 APIs.'
+    }
+  },
+  {
+    tags: ['tutorial', 'gl', 'new'],
+    path: 'tutorials/opengl/opengl-es20.html',
+    title: {
+      en: 'Hello OpenGL ES 2.0'
+    },
+    description: {
+      en: 'The basics of implementing an application using the OpenGL ES 2.0 APIs.'
+    }
+  },
+  {
     tags: ['tutorial', 'testing'],
     path: 'tutorials/testing/helloandroid_test.html',
     title: {
diff --git a/docs/html/resources/tutorials/opengl/opengl-es10.jd b/docs/html/resources/tutorials/opengl/opengl-es10.jd
new file mode 100644 (file)
index 0000000..d18a547
--- /dev/null
@@ -0,0 +1,409 @@
+page.title=Hello OpenGL ES 1.0
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
+@jd:body
+
+
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    
+    <ol>
+      <li><a href="#creating">Creating an OpenGL ES 1.0 Application</a></li>
+      <li>
+        <a href="#drawing">Drawing Graphic Elements</a>
+        <ol>
+          <li><a href="#define-triangle">Defining a Triangle</a></li>
+          <li><a href="#draw-triangle">Draw the Triangle</a></li>
+        </ol>
+      </li>
+      <li><a href="#projection-and-views">Using Projection and Views</a></li>
+      <li><a href="#motion">Adding Motion</a></li>
+      <li><a href="#resources">Additional Resources</a></li>
+      
+    </ol>
+    <h2 id="code-samples-list">Related Samples</h2>
+    <ol>
+      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+index.html">API Demos - graphics</a></li>
+      <li><a
+        href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li>
+    </ol>
+    <h2>See also</h2>
+    <ol>
+      <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
+      <li><a href="{@docRoot}resources/tutorials/opengl/opengl-es20.html">Hello OpenGL
+ES 2.0</a></li>
+    </ol>
+    </div>
+  </div>
+
+<p>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:</p>
+
+<ul>
+  <li>Creating an application using {@link android.opengl.GLSurfaceView} and {@link
+android.opengl.GLSurfaceView.Renderer}</li>
+  <li>Defining a graphic object and drawing it</li>
+  <li>Defining and applying an projection and view</li>
+  <li>Applying rotation to the drawn object</li>
+</ul>
+
+<p>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.</p>
+
+<p>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 <a
+href="{@docRoot}guide/topics/graphics/opengl.html#compatibility">3D with OpenGL</a> document.</p>
+
+
+<h2 id="creating">Creating an OpenGL ES 1.0 Application</h2>
+
+<p>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.<p>
+<p>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 <a href="{@docRoot}guide/topics/graphics/opengl.html">3D
+with OpenGL</a> document.</p>
+
+<p>To create an application that uses OpenGL ES 1.0:</p>
+  
+<ol>
+  <li>Start a new Android project with an Activity called <code>HelloOpenGLES10</code>. 
+    
+    <p class="note"><b>Note:</b> If you have not created a basic Android application yet, follow the
+      <a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a> instructions
+      to familiarize yourself with the process.</p>
+  </li>
+  
+  <li>Modify the <code>HelloOpenGLES10</code> class as follows:
+<pre>
+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;    
+  
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        mGLView = new HelloOpenGLSurfaceView(this);
+        setContentView(mGLView);
+    }
+    
+    &#64;Override
+    protected void onPause() {
+        super.onPause();
+        mGLView.onPause();
+    }
+    
+    &#64;Override
+    protected void onResume() {
+        super.onResume();
+        mGLView.onResume();
+    }
+    
+}
+  
+class HelloOpenGLES10SurfaceView extends GLSurfaceView {
+
+    public HelloOpenGLES10SurfaceView(Context context){
+        super(context);
+        setRenderer(new HelloOpenGLES10Renderer());
+    }
+
+}
+</pre>
+    <p>This Activity class creates a basic container for a {@link android.opengl.GLSurfaceView}.</p>
+  </li>
+
+  <li>Create the following class <code>HelloOpenGLES10Renderer</code>, which implements the 
+    {@link android.opengl.GLSurfaceView.Renderer} interface:
+
+<pre>
+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);
+    }
+  
+}
+</pre>
+  </li>
+</ol>
+
+<p>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.</p>
+
+<p>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.</p>
+
+<h2 id="drawing">Drawing Graphic Elements</h2>
+
+<p>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.</p>
+
+<p class="note"><b>Note:</b> The following instructions build on the previous section, so if you
+have not been following along, go back to the <a href="#get-started">previous section</a> and catch
+up.</p>
+
+<h3 id="define-triangle">Defining a Triangle</h3>
+
+<p>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.</p>
+  
+<p>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.</p> 
+
+<p>To define a vertex array for a triangle:</p>
+
+<ol>
+  <li>In your <code>HelloOpenGLES10Renderer</code> class, add new member variable to contain the
+vertices of a triangle shape:
+<pre>
+    private FloatBuffer triangleVB;
+</pre>
+  </li>
+
+  <li>Create a method, <code>initShapes()</code> which populates this member variable:
+<pre>
+    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);
+    
+    }
+</pre>
+    <p>This method defines a two-dimensional triangle shape with three equal sides.</p>
+  </li>
+  <li>Modify your <code>onSurfaceCreated()</code> method to initialize your triangle: 
+    <pre>
+    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();
+    }
+</pre>
+  <p class="warning"><strong>Warning:</strong> Shapes and other static objects should be initialized
+    once in your <code>onSurfaceCreated()</code> method for best performance. Avoid initializing the
+    new objects in <code>onDrawFrame()</code>, as this causes the system to re-create the objects
+    for every frame redraw and slows down your application.
+  </p>
+  </li>
+
+</ol>
+
+<h3 id="draw-triangle">Draw the Triangle</h3>
+
+<p>Now that you have defined a shape to draw, you can use the OpenGL APIs to draw the
+object.</p>
+
+<p>To draw the triangle with OpenGL:</p>
+  
+<ol>
+  <li>Before you can draw your triangle, you must tell OpenGL that you are using vertex arrays.
+    Modify your <code>onSurfaceCreated()</code> method to enable vertex arrays.
+<pre>
+    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);
+    }
+</pre>
+    <p>At this point, you are ready to draw the triangle object in the OpenGL frame.</p>
+  </li>
+  
+  <li>Modify your <code>onDrawFrame()</code> method to draw the triangle.
+<pre>
+    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);
+    }
+</pre>
+    <p><b>Note:</b> 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 <a href="#motion">later section</a>, we add motion to the object to
+      justify this use of processing power.</p>
+  </li>
+</ol>
+
+<p id="squashed-triangle">Try running this example application on your emulator or test device and
+you should see something like this:</p>
+
+<img src="{@docRoot}images/opengl/helloopengl-es10-1.png">
+
+<p>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
+<a href="#projection-and-views">next section</a>.</p>
+
+<h2 id="projection-and-views">Using Projection and Views</h2>
+
+<p>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&#8212;by default&#8212;OpenGL
+happily maps a perfectly square, uniform coordinate system onto your typically non-square
+screen.</p>
+
+<img src="{@docRoot}images/opengl/coordinates.png">
+
+<p>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.</p>
+
+<p>To use a projection transformation on your triangle:</p>
+<ol>
+  <li>Modify your <code>onSurfaceChanged()</code> 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.
+<pre>
+  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);
+  }  
+</pre>
+  </li>
+
+  <li>Next, modify your <code>onDrawFrame()</code> 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()}.
+<pre>
+    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
+        ...
+    }
+</pre>
+  </li>
+</ol>
+
+<p>Try running this updated application on your emulator or test device and you should see something
+like this:</p>
+
+<img src="{@docRoot}images/opengl/helloopengl-es10-2.png">
+
+<p>Now that you have applied this transformation, the triangle has three equal sides, instead of the
+squashed display in the <a href="#squashed-triangle">earlier version</a>.</p>
+
+<h2 id="motion">Adding Motion</h2>
+
+<p>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.</p>
+
+<p>To add rotation to your triangle:</p>
+<ul>
+  <li>Modify your <code>onDrawFrame()</code> method to rotate the triangle object:
+<pre>
+    public void onDrawFrame(GL10 gl) {
+        ...    
+        // When using GL_MODELVIEW, you must set the view point
+        GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);        
+    
+        // Create a rotation for the triangle
+        long time = SystemClock.uptimeMillis() % 4000L;
+        float angle = 0.090f * ((int) time);
+        gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);        
+        
+        // Draw the triangle
+        ...
+    }
+</pre>
+  </li>
+</ul>
+
+<p>Run the application with this code and your triangle should rotate around its center.</p>
+
+<!--
+  <h2>TouchScreen Interaction</h2>
+  Optional extra (using code from API examples)
+  -->
+
+<h2 id="resources">Additional Resources</h2>
+
+<p>Be sure to check out the OpenGL ES code samples are available in the
+<a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html">API
+Demos</a> sample application and listed in <a href="#code-samples-list">Related Samples</a>
+sidebar above.
+</p>
diff --git a/docs/html/resources/tutorials/opengl/opengl-es20.jd b/docs/html/resources/tutorials/opengl/opengl-es20.jd
new file mode 100644 (file)
index 0000000..5cdc343
--- /dev/null
@@ -0,0 +1,514 @@
+page.title=Hello OpenGL ES 1.0
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
+@jd:body
+
+
+<div id="qv-wrapper">
+  <div id="qv">
+    <h2>In this document</h2>
+    
+    <ol>
+      <li><a href="#creating">Creating an OpenGL ES 2.0 Application</a></li>
+      <li>
+        <a href="#drawing">Drawing Graphic Elements</a>
+        <ol>
+          <li><a href="#define-triangle">Defining a Triangle</a></li>
+          <li><a href="#draw-triangle">Draw the Triangle</a></li>
+        </ol>
+      </li>
+      <li><a href="#projection-and-views">Using Projection and Views</a></li>
+      <li><a href="#motion">Adding Motion</a></li>
+      <li><a href="#resources">Additional Resources</a></li>
+      
+    </ol>
+    <h2 id="code-samples-list">Related Samples</h2>
+    <ol>
+      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+index.html">API Demos - graphics</a></li>
+      <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/
+GLES20Activity.html">OpenGL ES 2.0 Example</a></li>
+    </ol>
+    <h2>See also</h2>
+    <ol>
+      <li><a href="{@docRoot}guide/topics/graphics/opengl.html">3D with OpenGL</a></li>
+      <li><a href="{@docRoot}resources/tutorials/opengl/opengl-es10.html">Hello OpenGL
+ES 1.0</a></li>
+    </ol>
+    </div>
+  </div>
+
+<p>This tutorial shows you how to create a simple Android application that uses OpenGL ES 2.0 and
+perform some basic operations using the OpenGL ES 2.0 API, including:</p>
+
+<ul>
+  <li>Creating an application using {@link android.opengl.GLSurfaceView} and {@link
+android.opengl.GLSurfaceView.Renderer}</li>
+  <li>Defining a graphic object and drawing it</li>
+  <li>Defining and applying an projection and view</li>
+  <li>Applying rotation to the drawn object</li>
+</ul>
+
+<p>This tutorial demonstrates use of the OpenGL ES 2.0 API. Beginning with Android 2.2 (API Level
+8), the framework supports OpenGL ES 2.0.</p>
+
+<p>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).For more information about compatibility for OpenGL versions and Android devices,
+see the <a href="{@docRoot}guide/topics/graphics/opengl.html#compatibility">3D with OpenGL</a>
+document.</p>
+
+
+<h2 id="creating">Creating an OpenGL ES 1.0 Application</h2>
+
+<p>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.<p>
+<p>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 <a href="{@docRoot}guide/topics/graphics/opengl.html">3D
+with OpenGL</a> document.</p>
+
+<p>To create an application that uses OpenGL ES 2.0:</p>
+  
+<ol>
+  <li>Start a new Android project with an Activity called <code>HelloOpenGLES20</code>. 
+    
+    <p class="note"><b>Note:</b> If you have not created a basic Android application yet, follow the
+      <a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a> instructions
+      to familiarize yourself with the process.</p>
+  </li>
+  
+  <li>Modify the <code>HelloOpenGLES20</code> class as follows:
+<pre>
+package com.example.android.apis.graphics;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class HelloOpenGLES20 extends Activity {
+  
+    private GLSurfaceView mGLView;    
+  
+    &#64;Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        
+        mGLView = new HelloOpenGLES20SurfaceView(this);
+        setContentView(mGLView);
+    }
+    
+    &#64;Override
+    protected void onPause() {
+        super.onPause();
+        mGLView.onPause();
+    }
+    
+    &#64;Override
+    protected void onResume() {
+        super.onResume();
+        mGLView.onResume();
+    }
+}
+  
+class HelloOpenGLES20SurfaceView extends GLSurfaceView {
+
+    public HelloOpenGLES20SurfaceView(Context context){
+        super(context);
+        
+        // Create an OpenGL ES 2.0 context.
+        setEGLContextClientVersion(2);
+
+        setRenderer(new HelloOpenGLES20Renderer());
+    }
+}
+</pre>
+    <p>This Activity class creates a basic container for a {@link android.opengl.GLSurfaceView}.</p>
+  </li>
+
+  <li>Create the following class <code>HelloOpenGLES20Renderer</code>, which implements the 
+    {@link android.opengl.GLSurfaceView.Renderer} interface:
+
+<pre>
+package com.example.android.apis.graphics;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+
+public class HelloOpenGLES20Renderer implements GLSurfaceView.Renderer {
+  
+    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+    
+        // Set the background frame color
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+    }
+    
+    public void onDrawFrame(GL10 unused) {
+    
+        // Redraw background color
+        GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+    }
+    
+    public void onSurfaceChanged(GL10 unused, int width, int height) {
+        GLES20.glViewport(0, 0, width, height);
+    }
+  
+}
+</pre>
+  </li>
+</ol>
+
+<p>These classes create a simple Android application which displays a grey screen using OpenGL
+ES 2.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
+2.0.</p>
+
+<p>If your application only supports OpenGL ES 2.0, then you should declare that your application
+  requires OpenGL ES 2.0 by adding the following settings to your <a                       
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a></code> file as
+shown below.</p>
+
+<pre>
+...
+    &lt;/application&gt;
+    
+    &lt;!-- Tell the system that you need ES 2.0. --&gt;
+    &lt;uses-feature android:glEsVersion="0x00020000" android:required="true" /&gt;
+
+&lt;/manifest&gt;
+</pre>
+
+<p>Adding this declaration hides your application from devices that do not support OpenGL ES 2.0
+in the Android Market.</p>
+  
+<p>If you are familiar with the OpenGL ES APIs, these preceding classes and the AndroidManifest.xml
+declaration should give you enough information to start using the OpenGL ES 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.</p>
+
+
+<h2 id="drawing">Drawing Graphic Elements</h2>
+
+<p>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
+OpenGL ES 2.0 API.</p>
+
+<p class="note"><b>Note:</b> The following instructions build on the previous section, so if you
+have not been following along, go back to the <a href="#get-started">previous section</a> and catch
+up.</p>
+
+<h3 id="define-triangle">Defining a Triangle</h3>
+
+<p>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.</p>
+  
+<p>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.</p> 
+
+<p>To define a vertex array for a triangle:</p>
+
+<ol>
+  <li>In your <code>HelloOpenGLES20Renderer</code> class, add new member variable to contain the
+vertices of a triangle shape:
+<pre>
+    private FloatBuffer triangleVB;
+</pre>
+  </li>
+
+  <li>Create a method, <code>initShapes()</code> which populates this member variable:
+<pre>
+    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);
+    
+    }
+</pre>
+    <p>This method defines a two-dimensional triangle shape with three equal sides.</p>
+  </li>
+  <li>Modify your <code>onSurfaceCreated()</code> method to initialize your triangle:
+<pre>
+    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+    
+        // Set the background frame color
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        
+        // initialize the triangle vertex array
+        initShapes();
+    }
+</pre>
+  <p class="warning"><strong>Warning:</strong> Shapes and other static objects should be initialized
+    once in your <code>onSurfaceCreated()</code> method for best performance. Avoid initializing the
+    new objects in <code>onDrawFrame()</code>, as this causes the system to re-create the objects
+    for every frame redraw and slows down your application.
+  </p>
+  </li>
+
+</ol>
+
+<h3 id="draw-triangle">Draw the Triangle</h3>
+
+<p>Now that you have defined a shape to draw, you can now use the OpenGL APIs to draw the
+  object. In order to do this with OpenGL ES 2.0, you must define a vertex shader and a
+fragment shader to describe how to draw your shape.</p>
+
+<p>To draw the triangle with OpenGL:</p>
+  
+<ol>
+  <li>In your <code>HelloOpenGLES20Renderer</code> class, define a vertex shader and a fragment
+shader.
+<pre>
+    private final String vertexShaderCode = 
+        "attribute vec4 vPosition;    \n" +
+        "void main(){         \n" +
+        " gl_Position = vPosition;  \n" +
+        "}                \n";
+    
+    private final String fragmentShaderCode = 
+        "precision mediump float; \n" +
+        "void main(){       \n" +
+        " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" +
+        "} \n";
+</pre>
+  </li>
+  <li>In your <code>HelloOpenGLES20Renderer</code> class, create a method for loading the shaders.
+<pre>
+    private int loadShader(int type, String shaderCode){
+    
+        int shader = GLES20.glCreateShader(type);
+        
+        GLES20.glShaderSource(shader, shaderCode);
+        GLES20.glCompileShader(shader);
+        
+        return shader;
+    }
+</pre>
+  </li>
+  
+  <li>Add the following members to your <code>HelloOpenGLES20Renderer</code> class for an OpenGL
+Program.
+<pre>
+    private int mProgram;
+    private int maPositionHandle;
+</pre>
+  </li>
+  
+  <li>Modify your <code>onSurfaceCreated()</code> method to load the shaders and attach them to a
+OpenGL Program.
+<pre>
+    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+    
+        // Set the background frame color
+        GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
+        
+        // initialize the triangle vertex array
+        initShapes();
+        
+        // Create shaders for shape and attach to program
+        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
+        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
+        
+        mProgram = GLES20.glCreateProgram();
+        GLES20.glAttachShader(mProgram, vertexShader);
+        GLES20.glAttachShader(mProgram, fragmentShader);
+        GLES20.glLinkProgram(mProgram);
+        
+        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+    }
+</pre>
+    <p>At this point, you are ready to draw the triangle object in the OpenGL frame.</p>
+  </li>
+  
+  <li>Modify your <code>onDrawFrame()</code> method to draw the triangle.
+<pre>
+    public void onDrawFrame(GL10 unused) {
+        
+        // Redraw background color
+        GLES20.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+    
+        // Specify a program with shaders
+        GLES20.glUseProgram(mProgram);
+        
+        // Prepare the triangle data
+        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, triangleVB);
+        GLES20.glEnableVertexAttribArray(maPositionHandle);
+        
+        // Draw the triangle
+        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
+    }
+</pre>
+    <p><b>Note:</b> 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 <a href="#motion">later section</a>, we add motion to the object to
+      justify this use of processing power.</p>
+  </li>
+</ol>
+
+<p id="squashed-triangle">Try running this example application on your emulator or test device and
+you should see something like this:</p>
+
+<img src="{@docRoot}images/opengl/helloopengl-es20-1.png">
+
+<p>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
+<a href="#projection-and-views">next section</a>.</p>
+
+<h2 id="projection-and-views">Using Projection and Views</h2>
+
+<p>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&#8212;by default&#8212;OpenGL
+happily maps a perfectly square, uniform coordinate system onto your typically non-square
+screen.</p>
+
+<img src="{@docRoot}images/opengl/coordinates.png">
+  
+<p>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.</p>
+
+<p>To use a projection transformation on your triangle:</p>
+<ol>
+  <li>Add the following members to your <code>HelloOpenGLES20Renderer</code> class.
+<pre>
+    private int muMVPMatrixHandle;
+    private float[] mMVPMatrix = new float[16];
+    private float[] mMMatrix = new float[16];
+    private float[] mVMatrix = new float[16];
+    private float[] mProjMatrix = new float[16];
+</pre>
+    </li>
+    <li>Modify your <code>vertexShaderCode</code> string to add a variable for a model view
+projection matrix.
+<pre>
+    private final String vertexShaderCode = 
+        "uniform mat4 uMVPMatrix;   \n" +
+        "attribute vec4 vPosition;  \n" +
+        "void main(){               \n" +
+        " gl_Position = uMVPMatrix * vPosition; \n" +
+        "}  \n";
+</pre>
+    </li>
+    <li>Modify your <code>onSurfaceChanged()</code> method to reference the <code>uMVPMatrix</code>
+shader variable you added and define a view transformation matrix.
+<pre>
+    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
+        ...
+        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
+        
+        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+        Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+    }
+</pre>
+    </li>
+    <li>Next, modify your <code>onSurfaceChanged()</code> method to calculate the device screen
+ration and create a projection matrix.
+<pre>
+    public void onSurfaceChanged(GL10 unused, int width, int height) {
+        GLES20.glViewport(0, 0, width, height);
+        
+        float ratio = (float) width / height;
+        Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
+    }  
+</pre>
+    </li>
+    <li>Finally, modify your <code>onDrawFrame()</code> method to apply the transformation.
+<pre>
+    public void onDrawFrame(GL10 unused) {
+        ...
+        // Apply a ModelView Projection transformation
+        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+        
+        // Draw the triangle
+        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);        
+    }
+</pre>
+    </li>
+  </ol>
+  
+<p>Try running this updated application on your emulator or test device and you should see
+something like this:</p>
+  
+  <img src="{@docRoot}images/opengl/helloopengl-es20-2.png">
+    
+<p>Now that you have applied this transformation, the triangle has three equal sides, instead of the
+squashed display in the <a href="#squashed-triangle">earlier version</a>.</p>
+
+
+<h2 id="motion">Adding Motion</h2>
+
+<p>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.</p>
+
+<p>To add rotation to your triangle:</p>
+<ol>
+  <li>Add an additional tranformation matrix member to your <code>HelloOpenGLES20Renderer</code>
+class.
+    <pre>
+      private float[] mMMatrix = new float[16];
+    </pre>
+    </li>  <li>Modify your <code>onDrawFrame()</code> method to rotate the triangle object:
+<pre>
+    public void onDrawFrame(GL10 gl) {
+        ...
+    
+        // Create a rotation for the triangle
+        long time = SystemClock.uptimeMillis() % 4000L;
+        float angle = 0.090f * ((int) time);
+        Matrix.setRotateM(mMMatrix, 0, angle, 0, 0, 1.0f);
+        Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+        Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+        
+        // Apply a ModelView Projection transformation
+        //Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);
+        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+        
+        // Draw the triangle
+        ...
+    }
+</pre>
+  </li>
+</ol>
+
+<p>Run the application with this code and your triangle should rotate around its center.</p>
+
+<!--
+  <h2>TouchScreen Interaction</h2>
+  Optional extra (using code from API examples)
+  -->
+
+<h2 id="resources">Additional Resources</h2>
+
+<p>Be sure to check out the OpenGL ES code samples are available in the
+<a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/index.html">API
+Demos</a> sample application and listed in <a href="#code-samples-list">Related Samples</a>
+sidebar above.
+</p>