summaryrefslogtreecommitdiffstats
path: root/docs/html/resources/articles/glsurfaceview.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/resources/articles/glsurfaceview.jd')
-rw-r--r--docs/html/resources/articles/glsurfaceview.jd268
1 files changed, 268 insertions, 0 deletions
diff --git a/docs/html/resources/articles/glsurfaceview.jd b/docs/html/resources/articles/glsurfaceview.jd
new file mode 100644
index 0000000..57403ea
--- /dev/null
+++ b/docs/html/resources/articles/glsurfaceview.jd
@@ -0,0 +1,268 @@
+page.title=Introducing GLSurfaceView
+@jd:body
+
+
+<p>The {@link android android.opengl.GLSurfaceView} class makes it
+easier for you to use OpenGL ES rendering in your applications by:</p>
+
+<ul>
+<li>Providing the glue code to connect OpenGL ES to the {@link
+android.view.View} system.</li>
+<li>Providing the glue code to make OpenGL ES work with the {@link
+android.app.Activity} life-cycle.</li>
+<li>Making it easy to choose an appropriate frame buffer pixel format.</li>
+<li>Creating and managing a separate rendering thread, to enable smooth
+animation.</li>
+<li>Providing easy-to-use debugging tools for tracing OpenGL ES API calls and
+checking for errors.</li>
+</ul>
+
+<p>GLSurfaceView is a good base for building an application that uses OpenGL ES
+for part or all of its rendering. A 2D or 3D action game would be a good
+candidate, as would a 2D or 3D data visualization application such as <a
+href="http://www.youtube.com/watch?v=4PRfVKzuUJ4&amp;fmt=18" title="Google Maps
+StreetView">Google Maps StreetView</a>.</p>
+
+<h3>A simple GLSurfaceView application</h3>
+
+<p>Here's the source code to the simplest possible OpenGL ES application:</p>
+
+<pre>package com.example.android.apis.graphics;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.app.Activity;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+
+public class ClearActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGLView = new GLSurfaceView(this);
+ mGLView.setRenderer(new ClearRenderer());
+ setContentView(mGLView);
+ }
+
+ &#64;Override
+ protected void onPause() {
+ super.onPause();
+ mGLView.onPause();
+ }
+
+ &#64;Override
+ protected void onResume() {
+ super.onResume();
+ mGLView.onResume();
+ }
+
+ private GLSurfaceView mGLView;
+}
+
+class ClearRenderer implements GLSurfaceView.Renderer {
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing special.
+ }
+
+ public void onSurfaceChanged(GL10 gl, int w, int h) {
+ gl.glViewport(0, 0, w, h);
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+ }
+}</pre>
+
+<p>This program doesn't do much: it clears the screen to black on every frame.
+But it is a complete OpenGL application that correctly implements the
+Android activity life-cycle. It pauses rendering when the activity is
+paused, and resumes it when the activity is resumed. You could use this
+application as the basis for non-interactive demonstration programs.
+Just add more OpenGL calls to the <code>ClearRenderer.onDrawFrame()</code> method.
+Notice that you don't even need to subclass the <code>GLSurfaceView</code> view.</p>
+
+<p>The {@link android.opengl.GLSurfaceView.Renderer} interface has three methods:</p>
+
+<ul>
+<li>The
+<code>onSurfaceCreated()</code> method is called at the start of rendering, and
+whenever the OpenGL ES drawing context has to be recreated. (The
+drawing context is typically lost and recreated when the activity is
+paused and resumed.) <code>OnSurfaceCreated()</code> is a good place to create
+long-lived OpenGL resources such as textures.</li>
+<li>The <code>onSurfaceChanged()</code>
+method is called when the surface changes size. It's a good place to
+set your OpenGL viewport. You may also want to set your camera here, if
+it's a fixed camera that doesn't move around the scene.</li>
+<li>The <code>onDrawFrame()</code> method is called every frame, and is
+responsible for drawing the scene. You would typically start by calling
+<code>glClear</code> to clear the framebuffer, followed by other OpenGL ES calls
+to draw the current scene.</li>
+</ul>
+
+<h3>How about user input?</h3>
+
+<p>If you want an interactive application (such as a game), you will typically
+subclass <code>GLSurfaceView</code>, because that's an easy way of obtaining
+input events. Here's a slightly longer example showing how to do that:</p>
+
+<pre>package com.google.android.ClearTest;
+
+import javax.microedition.khronos.egl.EGLConfig;
+import javax.microedition.khronos.opengles.GL10;
+
+import android.app.Activity;
+import android.content.Context;
+import android.opengl.GLSurfaceView;
+import android.os.Bundle;
+import android.view.MotionEvent;
+
+public class ClearActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mGLView = new ClearGLSurfaceView(this);
+ setContentView(mGLView);
+ }
+
+ &#64;Override
+ protected void onPause() {
+ super.onPause();
+ mGLView.onPause();
+ }
+
+ &#64;Override
+ protected void onResume() {
+ super.onResume();
+ mGLView.onResume();
+ }
+
+ private GLSurfaceView mGLView;
+}
+
+class ClearGLSurfaceView extends GLSurfaceView {
+ public ClearGLSurfaceView(Context context) {
+ super(context);
+ mRenderer = new ClearRenderer();
+ setRenderer(mRenderer);
+ }
+
+ public boolean onTouchEvent(final MotionEvent event) {
+ queueEvent(new Runnable(){
+ public void run() {
+ mRenderer.setColor(event.getX() / getWidth(),
+ event.getY() / getHeight(), 1.0f);
+ }});
+ return true;
+ }
+
+ ClearRenderer mRenderer;
+}
+
+class ClearRenderer implements GLSurfaceView.Renderer {
+ public void onSurfaceCreated(GL10 gl, EGLConfig config) {
+ // Do nothing special.
+ }
+
+ public void onSurfaceChanged(GL10 gl, int w, int h) {
+ gl.glViewport(0, 0, w, h);
+ }
+
+ public void onDrawFrame(GL10 gl) {
+ gl.glClearColor(mRed, mGreen, mBlue, 1.0f);
+ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
+ }
+
+ public void setColor(float r, float g, float b) {
+ mRed = r;
+ mGreen = g;
+ mBlue = b;
+ }
+
+ private float mRed;
+ private float mGreen;
+ private float mBlue;
+}</pre>
+
+<p>This application clears the screen for every frame. When you tap on the
+screen, it sets the clear color based on the (x,y) coordinates of your touch
+event. Note the use of <code>queueEvent()</code> in
+<code>ClearGLSurfaceView.onTouchEvent()</code>. The <code>queueEvent()</code>
+method is used to safely communicate between the UI thread and the rendering
+thread. If you prefer, you can use some other Java cross-thread communication
+technique, such as synchronized methods on the <code>Renderer</code> class
+itself. However, queueing events is often the simplest way of dealing with
+cross-thread communication.</p>
+
+<h3>Other GLSurfaceView samples</h3>
+
+<p>Tired
+of just clearing the screen? You can find more interesting samples in
+the API Demos sample included in the Android SDK. All the OpenGL ES samples have been
+converted to use the <code>GLSurfaceView</code> view:</p>
+
+<ul>
+<li>GLSurfaceView - a spinning triangle</li>
+<li>Kube - a cube puzzle demo</li>
+<li>Translucent GLSurfaceView - shows how to display 3D graphics on a translucent background</li>
+<li>Textured Triangle - shows how to draw a textured 3D triangle</li>
+<li>Sprite Text - shows how to draw text into a texture and then composite it into a 3D scene</li>
+<li>Touch Rotate - shows how to rotate a 3D object in response to user input.</li>
+</ul>
+
+<h3>Choosing a surface</h3>
+
+<p><code>GLSurfaceView</code>
+helps you choose the type of surface to render to. Different Android
+devices support different types of surfaces, with no common subset.
+This makes it tricky problem to choose the best available surface on
+each device. </p>
+
+<p>By default, <code>GLSurfaceView</code> tries to find a surface that's as
+close as possible to a 16-bit RGB frame buffer with a 16-bit depth
+buffer. Depending upon your application's needs you may want to change
+this behavior. For example, the Translucent GLSurfaceView sample needs
+an Alpha channel in order to render translucent data. <code>GLSurfaceView</code>
+provides an overloaded <code>setEGLSurfaceChooser()</code> method to give
+you control over which surface type is chosen:</p>
+
+<dl>
+<dt><code>setEGLConfigChooser(boolean needDepth)</code></dt>
+<dd>Choose a config that's closest to R5G6B5 with or without a 16-bit framebuffer</dd>
+<dt><code>setEGLConfigChooser(int redSize, int greenSize,int blueSize,
+int alphaSize,int depthSize, int stencilSize)</code></dt>
+<dd>Choose the config with the fewest number of bits per pixel that has at least
+as many bits-per-channel as specified in the constructor.</dd>
+<dt><code>setEGLConfigChooser(EGLConfigChooser configChooser)</code></dt>
+<dd>Allow total control over choosing a configuration. You pass in your own
+implementation of <code>EGLConfigChooser</code>, which gets to inspect the
+device's capabilities and choose a configuration.</dd>
+</dl>
+
+<h3>Continuous rendering versus render-when-dirty</h3>
+
+<p>Most 3D applications, such as games or simulations, are continuously
+animated. But some 3D applications are more reactive: they wait passively until
+the user does something, and then react to it. For those types of applications,
+the default <code>GLSurfaceView</code> behavior of continuously redrawing the
+screen is a waste of time. If you are developing a reactive application, you can
+call <code>GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY)</code>, which
+turns off the continuous animation. Then you call
+<code>GLSurfaceView.requestRender()</code> whenever you want to re-render.</p>
+
+<h3>Help With debugging</h3>
+
+<p><code>GLSurfaceView</code> has a handy built-in feature for debugging OpenGL ES
+applications: the <code>GLSurfaceView.setDebugFlags()</code> method can be used
+to enable logging and/or error checking your OpenGL ES calls. Call this method
+in your <code>GLSurfaceView</code>'s constructor, before calling
+<code>setRenderer()</code>:</p>
+
+<pre>public ClearGLSurfaceView(Context context) {
+ super(context);
+ // Turn on error-checking and logging
+ setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);
+ mRenderer = new ClearRenderer();
+ setRenderer(mRenderer);
+}</pre> \ No newline at end of file