Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 1 | page.title=OpenGL ES |
Joe Fernandez | 33baa5a | 2013-11-14 11:41:19 -0800 | [diff] [blame] | 2 | page.tags=games |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 3 | @jd:body |
| 4 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 5 | <div id="qv-wrapper"> |
| 6 | <div id="qv"> |
| 7 | <h2>In this document</h2> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 8 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 9 | <ol> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 10 | <li><a href="#basics">The Basics</a> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 11 | <ol> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 12 | <li><a href="#packages">OpenGL ES packages</a></li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 13 | </ol> |
| 14 | <li><a href="#manifest">Declaring OpenGL Requirements</a></li> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 15 | <li><a href="#coordinate-mapping">Mapping Coordinates for Drawn Objects</a> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 16 | <ol> |
| 17 | <li><a href="#proj-es1">Projection and camera in ES 1.0</a></li> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 18 | <li><a href="#proj-es2">Projection and camera in ES 2.0 and higher</a></li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 19 | </ol> |
| 20 | </li> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 21 | <li><a href="#faces-winding">Shape Faces and Winding</a></li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 22 | <li><a href="#compatibility">OpenGL Versions and Device Compatibility</a> |
| 23 | <ol> |
| 24 | <li><a href="#textures">Texture compression support</a></li> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 25 | <li><a href="#gl-extension-query">Determining OpenGL extensions</a></li> |
| 26 | <li><a href="#version-check">Checking OpenGL ES Version</a></li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 27 | </ol> |
| 28 | </li> |
| 29 | <li><a href="#choosing-version">Choosing an OpenGL API Version</a></li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 30 | </ol> |
| 31 | <h2>Key classes</h2> |
| 32 | <ol> |
| 33 | <li>{@link android.opengl.GLSurfaceView}</li> |
| 34 | <li>{@link android.opengl.GLSurfaceView.Renderer}</li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 35 | </ol> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 36 | <h2>Related samples</h2> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 37 | <ol> |
Scott Main | 19aad29 | 2011-10-18 16:57:32 -0700 | [diff] [blame] | 38 | <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLSurfaceViewActivity.html">GLSurfaceViewActivity</a></li> |
| 39 | <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/GLES20Activity.html">GLES20Activity</a></li> |
| 40 | <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/TouchRotateActivity.html">TouchRotateActivity</a></li> |
| 41 | <li><a |
| 42 | href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/graphics/CompressedTextureActivity.html">Compressed Textures</a></li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 43 | </ol> |
| 44 | <h2>See also</h2> |
| 45 | <ol> |
Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 46 | <li><a href="{@docRoot}training/graphics/opengl/index.html"> |
| 47 | Displaying Graphics with OpenGL ES</a></li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 48 | <li><a href="http://www.khronos.org/opengles/">OpenGL ES</a></li> |
| 49 | <li><a href="http://www.khronos.org/opengles/1_X/">OpenGL ES 1.x Specification</a></li> |
| 50 | <li><a href="http://www.khronos.org/opengles/2_X/">OpenGL ES 2.x specification</a></li> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 51 | <li><a href="http://www.khronos.org/opengles/3_X/">OpenGL ES 3.x specification</a></li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 52 | </ol> |
| 53 | </div> |
| 54 | </div> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 55 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 56 | <p>Android includes support for high performance 2D and 3D graphics with the Open Graphics Library |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 57 | (OpenGL®), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 58 | standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor of the OpenGL |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 59 | specification intended for embedded devices. Android supports several versions of the OpenGL ES |
| 60 | API:</p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 61 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 62 | <ul> |
| 63 | <li>OpenGL ES 1.0 and 1.1 - This API specification is supported by Android 1.0 and higher.</li> |
| 64 | <li>OpenGL ES 2.0 - This API specification is supported by Android 2.2 (API level 8) and higher. |
| 65 | </li> |
| 66 | <li>OpenGL ES 3.0 - This API specification is supported by Android 4.3 (API level 18) and higher. |
| 67 | </li> |
| 68 | </ul> |
| 69 | |
| 70 | <p class="caution"><strong>Caution:</strong> |
| 71 | Support of the OpenGL ES 3.0 API on a device requires an implementation of this graphics |
| 72 | pipeline provided by the device manufacturer. A device running Android 4.3 or higher <em>may |
| 73 | not support</em> the OpenGL ES 3.0 API. For information on checking what version of OpenGL ES |
| 74 | is supported at run time, see <a href="#version-check">Checking OpenGL ES Version</a>. |
| 75 | </p> |
| 76 | |
| 77 | <p class="note"><strong>Note:</strong> |
| 78 | The specific API provided by the Android framework is similar to the J2ME JSR239 OpenGL ES API, |
| 79 | but is not identical. If you are familiar with J2ME JSR239 specification, be alert for |
| 80 | variations.</p> |
| 81 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 82 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 83 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 84 | <h2 id="basics">The Basics</h2> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 85 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 86 | <p>Android supports OpenGL both through its framework API and the Native Development |
| 87 | Kit (NDK). This topic focuses on the Android framework interfaces. For more information about the |
Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 88 | NDK, see the <a href="{@docRoot}tools/sdk/ndk/index.html">Android NDK</a>. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 89 | |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 90 | <p>There are two foundational classes in the Android framework that let you create and manipulate |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 91 | graphics with the OpenGL ES API: {@link android.opengl.GLSurfaceView} and {@link |
| 92 | android.opengl.GLSurfaceView.Renderer}. If your goal is to use OpenGL in your Android application, |
| 93 | understanding how to implement these classes in an activity should be your first objective. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 94 | </p> |
| 95 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 96 | <dl> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 97 | <dt><strong>{@link android.opengl.GLSurfaceView}</strong></dt> |
| 98 | <dd>This class is a {@link android.view.View} where you can draw and manipulate objects using |
| 99 | OpenGL API calls and is similar in function to a {@link android.view.SurfaceView}. You can use |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 100 | this class by creating an instance of {@link android.opengl.GLSurfaceView} and adding your |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 101 | {@link android.opengl.GLSurfaceView.Renderer Renderer} to it. However, if you want to capture |
| 102 | touch screen events, you should extend the {@link android.opengl.GLSurfaceView} class to |
Scott Main | f05e34a | 2012-07-31 18:25:33 -0700 | [diff] [blame] | 103 | implement the touch listeners, as shown in OpenGL training lesson, |
| 104 | <a href="{@docRoot}training/graphics/opengl/touch.html">Responding to Touch Events</a>.</dd> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 105 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 106 | <dt><strong>{@link android.opengl.GLSurfaceView.Renderer}</strong></dt> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 107 | <dd>This interface defines the methods required for drawing graphics in a {@link |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 108 | android.opengl.GLSurfaceView}. You must provide an implementation of this interface as a |
| 109 | separate class and attach it to your {@link android.opengl.GLSurfaceView} instance using |
| 110 | {@link android.opengl.GLSurfaceView#setRenderer(android.opengl.GLSurfaceView.Renderer) |
| 111 | GLSurfaceView.setRenderer()}. |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 112 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 113 | <p>The {@link android.opengl.GLSurfaceView.Renderer} interface requires that you implement the |
| 114 | following methods:</p> |
| 115 | <ul> |
| 116 | <li> |
| 117 | {@link |
| 118 | android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.microedition.khronos.opengles.GL10, |
| 119 | javax.microedition.khronos.egl.EGLConfig) onSurfaceCreated()}: The system calls this |
| 120 | method once, when creating the {@link android.opengl.GLSurfaceView}. Use this method to perform |
| 121 | actions that need to happen only once, such as setting OpenGL environment parameters or |
| 122 | initializing OpenGL graphic objects. |
| 123 | </li> |
| 124 | <li> |
| 125 | {@link |
| 126 | android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.khronos.opengles.GL10) |
| 127 | onDrawFrame()}: The system calls this method on each redraw of the {@link |
| 128 | android.opengl.GLSurfaceView}. Use this method as the primary execution point for |
| 129 | drawing (and re-drawing) graphic objects.</li> |
| 130 | <li> |
| 131 | {@link |
| 132 | android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10, |
| 133 | int, int) onSurfaceChanged()}: The system calls this method when the {@link |
| 134 | android.opengl.GLSurfaceView} geometry changes, including changes in size of the {@link |
| 135 | android.opengl.GLSurfaceView} or orientation of the device screen. For example, the system calls |
| 136 | this method when the device changes from portrait to landscape orientation. Use this method to |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 137 | respond to changes in the {@link android.opengl.GLSurfaceView} container. |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 138 | </li> |
| 139 | </ul> |
| 140 | </dd> |
| 141 | </dl> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 142 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 143 | <h3 id="packages">OpenGL ES packages</h3> |
| 144 | <p>Once you have established a container view for OpenGL ES using {@link |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 145 | android.opengl.GLSurfaceView} and {@link android.opengl.GLSurfaceView.Renderer}, you can begin |
| 146 | calling OpenGL APIs using the following classes:</p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 147 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 148 | <ul> |
| 149 | <li>OpenGL ES 1.0/1.1 API Packages |
| 150 | <ul> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 151 | <li>{@link android.opengl} - This package provides a static interface to the OpenGL ES |
| 152 | 1.0/1.1 classes and better performance than the {@code javax.microedition.khronos} package |
| 153 | interfaces. |
| 154 | <ul> |
| 155 | <li>{@link android.opengl.GLES10}</li> |
| 156 | <li>{@link android.opengl.GLES10Ext}</li> |
| 157 | <li>{@link android.opengl.GLES11}</li> |
| 158 | <li>{@link android.opengl.GLES11Ext}</li> |
| 159 | </ul> |
| 160 | </li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 161 | <li>{@link javax.microedition.khronos.opengles} - This package provides the standard |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 162 | implementation of OpenGL ES 1.0/1.1. |
| 163 | <ul> |
| 164 | <li>{@link javax.microedition.khronos.opengles.GL10}</li> |
| 165 | <li>{@link javax.microedition.khronos.opengles.GL10Ext}</li> |
| 166 | <li>{@link javax.microedition.khronos.opengles.GL11}</li> |
| 167 | <li>{@link javax.microedition.khronos.opengles.GL11Ext}</li> |
| 168 | <li>{@link javax.microedition.khronos.opengles.GL11ExtensionPack}</li> |
| 169 | </ul> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 170 | </li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 171 | </ul> |
| 172 | </li> |
| 173 | <li>OpenGL ES 2.0 API Class |
| 174 | <ul> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 175 | <li>{@link android.opengl.GLES20 android.opengl.GLES20} - This package provides the |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 176 | interface to OpenGL ES 2.0 and is available starting with Android 2.2 (API level 8).</li> |
| 177 | </ul> |
| 178 | </li> |
| 179 | <li>OpenGL ES 3.0 API Class |
| 180 | <ul> |
| 181 | <li>{@link android.opengl.GLES30 android.opengl.GLES30} - This package provides the |
| 182 | interface to OpenGL ES 3.0 and is available starting with Android 4.3 (API level 18).</li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 183 | </ul> |
| 184 | </li> |
| 185 | </ul> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 186 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 187 | <p>If you want to start building an app with OpenGL ES right away, follow the |
| 188 | <a href="{@docRoot}training/graphics/opengl/index.html">Displaying Graphics with OpenGL ES</a> |
| 189 | class. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 190 | </p> |
| 191 | |
| 192 | <h2 id="manifest">Declaring OpenGL Requirements</h2> |
| 193 | <p>If your application uses OpenGL features that are not available on all devices, you must include |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 194 | these requirements in your <a |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 195 | href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a> file. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 196 | Here are the most common OpenGL manifest declarations:</p> |
| 197 | |
| 198 | <ul> |
| 199 | <li><strong>OpenGL ES version requirements</strong> - If your application only supports OpenGL ES |
| 200 | 2.0, you must declare that requirement by adding the following settings to your manifest as |
| 201 | shown below. |
| 202 | |
| 203 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 204 | <!-- Tell the system this app requires OpenGL ES 2.0. --> |
| 205 | <uses-feature android:glEsVersion="0x00020000" android:required="true" /> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 206 | </pre> |
| 207 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 208 | <p>Adding this declaration causes Google Play to restrict your application from being |
| 209 | installed on devices that do not support OpenGL ES 2.0. If your application is exclusively for |
| 210 | devices that support OpenGL ES 3.0, you can also specify this in your manifest:</p> |
| 211 | |
| 212 | <pre> |
| 213 | <!-- Tell the system this app requires OpenGL ES 3.0. --> |
| 214 | <uses-feature android:glEsVersion="0x00030000" android:required="true" /> |
| 215 | </pre> |
| 216 | |
| 217 | <p class="note"><strong>Note:</strong> |
| 218 | The OpenGL ES 3.0 API is backwards-compatible with the 2.0 API, which means you can be more |
| 219 | flexible with your implementation of OpenGL ES in your application. By declaring the OpenGL |
| 220 | ES 2.0 API as a requirement in your manifest, you can use that API version as a default, check |
| 221 | for the availability of the 3.0 API at run time and then use OpenGL ES 3.0 features if the |
| 222 | device supports it. For more information about checking the OpenGL ES version supported by a |
| 223 | device, see <a href="#version-check">Checking OpenGL ES Version</a>. |
| 224 | </p> |
| 225 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 226 | </li> |
| 227 | <li><strong>Texture compression requirements</strong> - If your application uses texture |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 228 | compression formats, you must declare the formats your application supports in your manifest file |
| 229 | using <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">{@code |
| 230 | <supports-gl-texture>}</a>. For more information about available texture compression |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 231 | formats, see <a href="#textures">Texture compression support</a>. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 232 | |
| 233 | <p>Declaring texture compression requirements in your manifest hides your application from users |
| 234 | with devices that do not support at least one of your declared compression types. For more |
Dirk Dougherty | 4d7bc655 | 2012-01-27 17:56:49 -0800 | [diff] [blame] | 235 | information on how Google Play filtering works for texture compressions, see the <a |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 236 | href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html#market-texture-filtering"> |
Dirk Dougherty | 4d7bc655 | 2012-01-27 17:56:49 -0800 | [diff] [blame] | 237 | Google Play and texture compression filtering</a> section of the {@code |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 238 | <supports-gl-texture>} documentation.</p> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 239 | </li> |
| 240 | </ul> |
| 241 | |
| 242 | |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 243 | <h2 id="coordinate-mapping">Mapping Coordinates for Drawn Objects</h2> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 244 | |
| 245 | <p>One of the basic problems in displaying graphics on Android devices is that their screens can |
| 246 | vary in size and shape. OpenGL assumes a square, uniform coordinate system and, by default, happily |
| 247 | draws those coordinates onto your typically non-square screen as if it is perfectly square.</p> |
| 248 | |
| 249 | <img src="{@docRoot}images/opengl/coordinates.png"> |
| 250 | <p class="img-caption"> |
| 251 | <strong>Figure 1.</strong> Default OpenGL coordinate system (left) mapped to a typical Android |
| 252 | device screen (right). |
| 253 | </p> |
| 254 | |
| 255 | <p>The illustration above shows the uniform coordinate system assumed for an OpenGL frame on the |
| 256 | left, and how these coordinates actually map to a typical device screen in landscape orientation |
| 257 | on the right. To solve this problem, you can apply OpenGL projection modes and camera views to |
| 258 | transform coordinates so your graphic objects have the correct proportions on any display.</p> |
| 259 | |
| 260 | <p>In order to apply projection and camera views, you create a projection matrix and a camera view |
| 261 | matrix and apply them to the OpenGL rendering pipeline. The projection matrix recalculates the |
| 262 | coordinates of your graphics so that they map correctly to Android device screens. The camera view |
| 263 | matrix creates a transformation that renders objects from a specific eye position.</p> |
| 264 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 265 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 266 | <h3 id="proj-es1">Projection and camera view in OpenGL ES 1.0</h3> |
| 267 | <p>In the ES 1.0 API, you apply projection and camera view by creating each matrix and then |
| 268 | adding them to the OpenGL environment.</p> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 269 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 270 | <ol> |
| 271 | <li><strong>Projection matrix</strong> - Create a projection matrix using the geometry of the |
| 272 | device screen in order to recalculate object coordinates so they are drawn with correct proportions. |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 273 | The following example code demonstrates how to modify the {@link |
| 274 | android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.microedition.khronos.opengles.GL10, |
| 275 | int, int) onSurfaceChanged()} method of a {@link android.opengl.GLSurfaceView.Renderer} |
| 276 | implementation to create a projection matrix based on the screen's aspect ratio and apply it to the |
| 277 | OpenGL rendering environment. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 278 | |
| 279 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 280 | public void onSurfaceChanged(GL10 gl, int width, int height) { |
| 281 | gl.glViewport(0, 0, width, height); |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 282 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 283 | // make adjustments for screen ratio |
| 284 | float ratio = (float) width / height; |
| 285 | gl.glMatrixMode(GL10.GL_PROJECTION); // set matrix to projection mode |
| 286 | gl.glLoadIdentity(); // reset the matrix to its default state |
| 287 | gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); // apply the projection matrix |
| 288 | } |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 289 | </pre> |
| 290 | </li> |
| 291 | |
| 292 | <li><strong>Camera transformation matrix</strong> - Once you have adjusted the coordinate system |
| 293 | using a projection matrix, you must also apply a camera view. The following example code shows how |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 294 | to modify the {@link |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 295 | android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.khronos.opengles.GL10) |
| 296 | onDrawFrame()} method of a {@link android.opengl.GLSurfaceView.Renderer} |
| 297 | implementation to apply a model view and use the |
| 298 | {@link android.opengl.GLU#gluLookAt(javax.microedition.khronos.opengles.GL10, float, float, float, |
| 299 | float, float, float, float, float, float) GLU.gluLookAt()} utility to create a viewing tranformation |
| 300 | which simulates a camera position. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 301 | |
| 302 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 303 | public void onDrawFrame(GL10 gl) { |
| 304 | ... |
| 305 | // Set GL_MODELVIEW transformation mode |
| 306 | gl.glMatrixMode(GL10.GL_MODELVIEW); |
| 307 | gl.glLoadIdentity(); // reset the matrix to its default state |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 308 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 309 | // When using GL_MODELVIEW, you must set the camera view |
| 310 | GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); |
| 311 | ... |
| 312 | } |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 313 | </pre> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 314 | </li> |
| 315 | </ol> |
| 316 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 317 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 318 | <h3 id="proj-es2">Projection and camera view in OpenGL ES 2.0 and higher</h3> |
| 319 | |
| 320 | <p>In the ES 2.0 and 3.0 APIs, you apply projection and camera view by first adding a matrix member |
| 321 | to the vertex shaders of your graphics objects. With this matrix member added, you can then |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 322 | generate and apply projection and camera viewing matrices to your objects.</p> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 323 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 324 | <ol> |
| 325 | <li><strong>Add matrix to vertex shaders</strong> - Create a variable for the view projection matrix |
| 326 | and include it as a multiplier of the shader's position. In the following example vertex shader |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 327 | code, the included {@code uMVPMatrix} member allows you to apply projection and camera viewing |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 328 | matrices to the coordinates of objects that use this shader. |
| 329 | |
| 330 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 331 | private final String vertexShaderCode = |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 332 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 333 | // This matrix member variable provides a hook to manipulate |
| 334 | // the coordinates of objects that use this vertex shader. |
| 335 | "uniform mat4 uMVPMatrix; \n" + |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 336 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 337 | "attribute vec4 vPosition; \n" + |
| 338 | "void main(){ \n" + |
| 339 | // The matrix must be included as part of gl_Position |
| 340 | // Note that the uMVPMatrix factor *must be first* in order |
| 341 | // for the matrix multiplication product to be correct. |
| 342 | " gl_Position = uMVPMatrix * vPosition; \n" + |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 343 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 344 | "} \n"; |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 345 | </pre> |
| 346 | <p class="note"><strong>Note:</strong> The example above defines a single transformation matrix |
| 347 | member in the vertex shader into which you apply a combined projection matrix and camera view |
| 348 | matrix. Depending on your application requirements, you may want to define separate projection |
| 349 | matrix and camera viewing matrix members in your vertex shaders so you can change them |
| 350 | independently.</p> |
| 351 | </li> |
| 352 | <li><strong>Access the shader matrix</strong> - After creating a hook in your vertex shaders to |
| 353 | apply projection and camera view, you can then access that variable to apply projection and |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 354 | camera viewing matrices. The following code shows how to modify the {@link |
| 355 | android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.microedition.khronos.opengles.GL10, |
| 356 | javax.microedition.khronos.egl.EGLConfig) onSurfaceCreated()} method of a {@link |
| 357 | android.opengl.GLSurfaceView.Renderer} implementation to access the matrix |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 358 | variable defined in the vertex shader above. |
| 359 | |
| 360 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 361 | public void onSurfaceCreated(GL10 unused, EGLConfig config) { |
| 362 | ... |
| 363 | muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); |
| 364 | ... |
| 365 | } |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 366 | </pre> |
| 367 | </li> |
| 368 | <li><strong>Create projection and camera viewing matrices</strong> - Generate the projection and |
| 369 | viewing matrices to be applied the graphic objects. The following example code shows how to modify |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 370 | the {@link android.opengl.GLSurfaceView.Renderer#onSurfaceCreated onSurfaceCreated()} and |
| 371 | {@link android.opengl.GLSurfaceView.Renderer#onSurfaceChanged onSurfaceChanged()} methods of a |
| 372 | {@link android.opengl.GLSurfaceView.Renderer} implementation to create camera view matrix and a |
| 373 | projection matrix based on the screen aspect ratio of the device. |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 374 | |
| 375 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 376 | public void onSurfaceCreated(GL10 unused, EGLConfig config) { |
| 377 | ... |
| 378 | // Create a camera view matrix |
| 379 | Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); |
| 380 | } |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 381 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 382 | public void onSurfaceChanged(GL10 unused, int width, int height) { |
| 383 | GLES20.glViewport(0, 0, width, height); |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 384 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 385 | float ratio = (float) width / height; |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 386 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 387 | // create a projection matrix from device screen geometry |
| 388 | Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); |
| 389 | } |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 390 | </pre> |
| 391 | </li> |
| 392 | |
| 393 | <li><strong>Apply projection and camera viewing matrices</strong> - To apply the projection and |
| 394 | camera view transformations, multiply the matrices together and then set them into the vertex |
Joe Fernandez | 8f134ea | 2011-08-18 10:56:38 -0700 | [diff] [blame] | 395 | shader. The following example code shows how modify the {@link |
| 396 | android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.microedition.khronos.opengles.GL10) |
| 397 | onDrawFrame()} method of a {@link android.opengl.GLSurfaceView.Renderer} implementation to combine |
| 398 | the projection matrix and camera view created in the code above and then apply it to the graphic |
| 399 | objects to be rendered by OpenGL. |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 400 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 401 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 402 | public void onDrawFrame(GL10 unused) { |
| 403 | ... |
| 404 | // Combine the projection and camera view matrices |
| 405 | Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 406 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 407 | // Apply the combined projection and camera view transformations |
| 408 | GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 409 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 410 | // Draw objects |
| 411 | ... |
| 412 | } |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 413 | </pre> |
| 414 | </li> |
| 415 | </ol> |
| 416 | <p>For a complete example of how to apply projection and camera view with OpenGL ES 2.0, see the <a |
Scott Main | f05e34a | 2012-07-31 18:25:33 -0700 | [diff] [blame] | 417 | href="{@docRoot}training/graphics/opengl/index.html">Displaying Graphics with OpenGL ES</a> class.</p> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 418 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 419 | |
Scott Main | 50e990c | 2012-06-21 17:14:39 -0700 | [diff] [blame] | 420 | <h2 id="faces-winding">Shape Faces and Winding</h2> |
| 421 | |
| 422 | <p>In OpenGL, the face of a shape is a surface defined by three or more points in three-dimensional |
| 423 | space. A set of three or more three-dimensional points (called vertices in OpenGL) have a front face |
| 424 | and a back face. How do you know which face is front and which is the back? Good question. The |
| 425 | answer has to do with winding, or, the direction in which you define the points of a shape.</p> |
| 426 | |
| 427 | <img src="{@docRoot}images/opengl/ccw-winding.png"> |
| 428 | <p class="img-caption"> |
| 429 | <strong>Figure 1.</strong> Illustration of a coordinate list which translates into a |
| 430 | counterclockwise drawing order.</p> |
| 431 | |
| 432 | <p>In this example, the points of the triangle are defined in an order such that they are drawn in a |
| 433 | counterclockwise direction. The order in which these coordinates are drawn defines the winding |
| 434 | direction for the shape. By default, in OpenGL, the face which is drawn counterclockwise is the |
| 435 | front face. The triangle shown in Figure 1 is defined so that you are looking at the front face of |
| 436 | the shape (as interpreted by OpenGL) and the other side is the back face.</p> |
| 437 | |
| 438 | <p>Why is it important to know which face of a shape is the front face? The answer has to do with a |
| 439 | commonly used feature of OpenGL, called face culling. Face culling is an option for the OpenGL |
| 440 | environment which allows the rendering pipeline to ignore (not calculate or draw) the back face of a |
| 441 | shape, saving time, memory and processing cycles:</p> |
| 442 | |
| 443 | <pre> |
| 444 | // enable face culling feature |
| 445 | gl.glEnable(GL10.GL_CULL_FACE); |
| 446 | // specify which faces to not draw |
| 447 | gl.glCullFace(GL10.GL_BACK); |
| 448 | </pre> |
| 449 | |
| 450 | <p>If you try to use the face culling feature without knowing which sides of your shapes are the |
| 451 | front and back, your OpenGL graphics are going to look a bit thin, or possibly not show up at all. |
| 452 | So, always define the coordinates of your OpenGL shapes in a counterclockwise drawing order.</p> |
| 453 | |
| 454 | <p class="note"><strong>Note:</strong> It is possible to set an OpenGL environment to treat the |
| 455 | clockwise face as the front face, but doing so requires more code and is likely to confuse |
| 456 | experienced OpenGL developers when you ask them for help. So don’t do that.</p> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 457 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 458 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 459 | <h2 id="compatibility">OpenGL Versions and Device Compatibility</h2> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 460 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 461 | <p>The OpenGL ES 1.0 and 1.1 API specifications have been supported since Android 1.0. |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 462 | Beginning with Android 2.2 (API level 8), the framework supports the OpenGL ES 2.0 API |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 463 | specification. OpenGL ES 2.0 is supported by most Android devices and is recommended for new |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 464 | applications being developed with OpenGL. OpenGL ES 3.0 is supported with Android 4.3 |
| 465 | (API level 18) and higher, on devices that provide an implementation of the OpenGL ES 3.0 API. |
| 466 | For information about the relative number of Android-powered devices |
| 467 | that support a given version of OpenGL ES, see the |
| 468 | <a href="{@docRoot}about/dashboards/index.html#OpenGL">OpenGL ES Version Dashboard</a>.</p> |
| 469 | |
| 470 | <p>Graphics programming with OpenGL ES 1.0/1.1 API is significantly different than using the 2.0 |
| 471 | and higher versions. The 1.x version of the API has more convenience methods and a fixed graphics |
| 472 | pipeline, while the OpenGL ES 2.0 and 3.0 APIs provide more direct control of the pipeline through |
| 473 | use of OpenGL shaders. You should carefully consider the graphics requirements and choose the API |
| 474 | version that works best for your application. For more information, see |
| 475 | <a href="#choosing-version">Choosing an OpenGL API Version</a>.</p> |
| 476 | |
| 477 | <p>The OpenGL ES 3.0 API provides additional features and better performance than the 2.0 API and is |
| 478 | also backward compatible. This means that you can potentially write your application targeting |
| 479 | OpenGL ES 2.0 and conditionally include OpenGL ES 3.0 graphics features if they are available. For |
| 480 | more information on checking for availability of the 3.0 API, see |
| 481 | <a href="#version-check">Checking OpenGL ES Version</a></p> |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 482 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 483 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 484 | <h3 id="textures">Texture compression support</h3> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 485 | |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 486 | <p>Texture compression can significantly increase the performance of your OpenGL application by |
| 487 | reducing memory requirements and making more efficient use of memory bandwidth. The Android |
| 488 | framework provides support for the ETC1 compression format as a standard feature, including a {@link |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 489 | android.opengl.ETC1Util} utility class and the {@code etc1tool} compression tool (located in the |
| 490 | Android SDK at {@code <sdk>/tools/}). For an example of an Android application that uses |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 491 | texture compression, see the {@code CompressedTextureActivity} code sample in Android SDK |
| 492 | ({@code <sdk>/samples/<version>/ApiDemos/src/com/example/android/apis/graphics/}).</p> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 493 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 494 | <p class="caution"><strong>Caution:</strong> The ETC1 format is supported by most Android devices, |
| 495 | but it not guaranteed to be available. To check if the ETC1 format is supported on a device, call |
| 496 | the {@link android.opengl.ETC1Util#isETC1Supported() ETC1Util.isETC1Supported()} method.</p> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 497 | |
| 498 | <p class="note"><b>Note:</b> The ETC1 texture compression format does not support textures with an |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 499 | transparency (alpha channel). If your application requires textures with transparency, you should |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 500 | investigate other texture compression formats available on your target devices.</p> |
| 501 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 502 | <p>The ETC2/EAC texture compression formats are guaranteed to be available when using the OpenGL ES |
| 503 | 3.0 API. This texture format offers excellent compression ratios with high visual quality and the |
| 504 | format also supports transparency (alpha channel).</p> |
| 505 | |
| 506 | <p>Beyond the ETC formats, Android devices have varied support for texture compression based on |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 507 | their GPU chipsets and OpenGL implementations. You should investigate texture compression support on |
kmccormick | 76dfc02 | 2013-04-03 12:41:12 -0700 | [diff] [blame] | 508 | the devices you are are targeting to determine what compression types your application should |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 509 | support. In order to determine what texture formats are supported on a given device, you must <a |
| 510 | href="#gl-extension-query">query the device</a> and review the <em>OpenGL extension names</em>, |
| 511 | which identify what texture compression formats (and other OpenGL features) are supported by the |
| 512 | device. Some commonly supported texture compression formats are as follows:</p> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 513 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 514 | <ul> |
| 515 | <li><strong>ATITC (ATC)</strong> - ATI texture compression (ATITC or ATC) is available on a |
| 516 | wide variety of devices and supports fixed rate compression for RGB textures with and without |
| 517 | an alpha channel. This format may be represented by several OpenGL extension names, for example: |
| 518 | <ul> |
| 519 | <li>{@code GL_AMD_compressed_ATC_texture}</li> |
| 520 | <li>{@code GL_ATI_texture_compression_atitc}</li> |
| 521 | </ul> |
| 522 | </li> |
| 523 | <li><strong>PVRTC</strong> - PowerVR texture compression (PVRTC) is available on a wide |
| 524 | variety of devices and supports 2-bit and 4-bit per pixel textures with or without an alpha channel. |
| 525 | This format is represented by the following OpenGL extension name: |
| 526 | <ul> |
| 527 | <li>{@code GL_IMG_texture_compression_pvrtc}</li> |
| 528 | </ul> |
| 529 | </li> |
| 530 | <li><strong>S3TC (DXT<em>n</em>/DXTC)</strong> - S3 texture compression (S3TC) has several |
| 531 | format variations (DXT1 to DXT5) and is less widely available. The format supports RGB textures with |
| 532 | 4-bit alpha or 8-bit alpha channels. This format may be represented by several OpenGL extension |
| 533 | names, for example: |
| 534 | <ul> |
| 535 | <li>{@code GL_OES_texture_compression_S3TC}</li> |
| 536 | <li>{@code GL_EXT_texture_compression_s3tc}</li> |
| 537 | <li>{@code GL_EXT_texture_compression_dxt1}</li> |
| 538 | <li>{@code GL_EXT_texture_compression_dxt3}</li> |
| 539 | <li>{@code GL_EXT_texture_compression_dxt5}</li> |
| 540 | </ul> |
| 541 | </li> |
| 542 | <li><strong>3DC</strong> - 3DC texture compression (3DC) is a less widely available format that |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 543 | supports RGB textures with an alpha channel. This format is represented by the following OpenGL |
| 544 | extension name: |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 545 | <ul> |
| 546 | <li>{@code GL_AMD_compressed_3DC_texture}</li> |
| 547 | </ul> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 548 | </li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 549 | </ul> |
| 550 | |
| 551 | <p class="warning"><strong>Warning:</strong> These texture compression formats are <em>not |
| 552 | supported</em> on all devices. Support for these formats can vary by manufacturer and device. For |
| 553 | information on how to determine what texture compression formats are on a particular device, see |
| 554 | the next section. |
| 555 | </p> |
| 556 | |
| 557 | <p class="note"><strong>Note:</strong> Once you decide which texture compression formats your |
| 558 | application will support, make sure you declare them in your manifest using <a |
| 559 | href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html"><supports-gl-texture> |
Dirk Dougherty | 4d7bc655 | 2012-01-27 17:56:49 -0800 | [diff] [blame] | 560 | </a>. Using this declaration enables filtering by external services such as Google Play, so that |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 561 | your app is installed only on devices that support the formats your app requires. For details, see |
| 562 | <a |
| 563 | href="{@docRoot}guide/topics/graphics/opengl.html#manifest">OpenGL manifest declarations</a>.</p> |
| 564 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 565 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 566 | <h3 id="gl-extension-query">Determining OpenGL extensions</h3> |
| 567 | <p>Implementations of OpenGL vary by Android device in terms of the extensions to the OpenGL ES API |
| 568 | that are supported. These extensions include texture compressions, but typically also include other |
| 569 | extensions to the OpenGL feature set.</p> |
| 570 | |
| 571 | <p>To determine what texture compression formats, and other OpenGL extensions, are supported on a |
| 572 | particular device:</p> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 573 | <ol> |
| 574 | <li>Run the following code on your target devices to determine what texture compression |
| 575 | formats are supported: |
| 576 | <pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 577 | String extensions = javax.microedition.khronos.opengles.GL10.glGetString( |
| 578 | GL10.GL_EXTENSIONS); |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 579 | </pre> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 580 | <p class="warning"><b>Warning:</b> The results of this call <em>vary by device model!</em> You |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 581 | must run this call on several target devices to determine what compression types are commonly |
| 582 | supported.</p> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 583 | </li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 584 | <li>Review the output of this method to determine what OpenGL extensions are supported on the |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 585 | device.</li> |
Joe Fernandez | a53afed | 2011-06-22 09:48:59 -0700 | [diff] [blame] | 586 | </ol> |
| 587 | |
| 588 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 589 | <h3 id="version-check">Checking OpenGL ES Version</h3> |
| 590 | |
| 591 | <p>There are several versions of the OpenGL ES available on Android devices. You can specify the |
| 592 | minimum version of the API your application requires in your <a href="#manifest">manifest</a>, but |
| 593 | you may also want to take advantage of features in a newer API at the same time. For example, |
| 594 | the OpenGL ES 3.0 API is backward-compatible with the 2.0 version of the API, so you may want to |
| 595 | write your application so that it uses OpenGL ES 3.0 features, but falls back to the 2.0 API if the |
| 596 | 3.0 API is not available.</p> |
| 597 | |
| 598 | <p>Before using OpenGL ES features from a version higher than the minimum required in your |
| 599 | application manifest, your application should check the version of the API available on the device. |
| 600 | You can do this in one of two ways:</p> |
| 601 | |
| 602 | <ol> |
| 603 | <li>Attempt create the higher-level OpenGL ES context ({@link android.opengl.EGLContext}) and |
| 604 | check the result.</li> |
| 605 | <li>Create a minimum-supported OpenGL ES context and check the version value.</li> |
| 606 | </ol> |
| 607 | |
| 608 | <p>The following example code demonstrates how to check the available OpenGL ES version by creating |
| 609 | an {@link android.opengl.EGLContext} and checking the result. This example shows how to check for |
| 610 | OpenGL ES 3.0 version:</p> |
| 611 | |
| 612 | <pre> |
| 613 | private static double glVersion = 3.0; |
| 614 | |
| 615 | private static class ContextFactory implements GLSurfaceView.EGLContextFactory { |
| 616 | |
| 617 | private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; |
| 618 | |
| 619 | public EGLContext createContext( |
| 620 | EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { |
| 621 | |
| 622 | Log.w(TAG, "creating OpenGL ES " + glVersion + " context"); |
| 623 | int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, (int) glVersion, |
| 624 | EGL10.EGL_NONE }; |
| 625 | // attempt to create a OpenGL ES 3.0 context |
| 626 | EGLContext context = egl.eglCreateContext( |
| 627 | display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); |
| 628 | return context; // returns null if 3.0 is not supported; |
| 629 | } |
| 630 | } |
| 631 | </pre> |
| 632 | |
| 633 | <p>If the {@code createContext()} method show above returns null, your code should create a OpenGL |
| 634 | ES 2.0 context instead and fall back to using only that API.</p> |
| 635 | |
| 636 | <p>The following code example demonstrates how to check the OpenGL ES version by creating a minimum |
| 637 | supported context first, and then checking the version string:</p> |
| 638 | |
| 639 | <pre> |
| 640 | // Create a minimum supported OpenGL ES context, then check: |
| 641 | String version = javax.microedition.khronos.opengles.GL10.glGetString( |
| 642 | GL10.GL_VERSION); |
| 643 | Log.w(TAG, "Version: " + version ); |
| 644 | // The version format is displayed as: "OpenGL ES <major>.<minor>" |
| 645 | // followed by optional content provided by the implementation. |
| 646 | </pre> |
| 647 | |
| 648 | <p>With this approach, if you discover that the device supports a higher-level API version, you |
| 649 | must destroy the minimum OpenGL ES context and create a new context with the higher |
| 650 | available API version.</p> |
| 651 | |
| 652 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 653 | <h2 id="choosing-version">Choosing an OpenGL API Version</h2> |
| 654 | |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 655 | <p>OpenGL ES 1.0 API version (and the 1.1 extensions), version 2.0, and version 3.0 all provide high |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 656 | performance graphics interfaces for creating 3D games, visualizations and user interfaces. Graphics |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 657 | progamming for OpenGL ES 2.0 and 3.0 is largely similar, with version 3.0 representing a superset |
| 658 | of the 2.0 API with additional features. Programming for the OpenGL ES 1.0/1.1 API versus OpenGL ES |
| 659 | 2.0 and 3.0 differs significantly, and so developers should carefully consider the following |
| 660 | factors before starting development with these APIs:</p> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 661 | |
| 662 | <ul> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 663 | <li><strong>Performance</strong> - In general, OpenGL ES 2.0 and 3.0 provide faster graphics |
| 664 | performance than the ES 1.0/1.1 APIs. However, the performance difference can vary depending on |
| 665 | the Android device your OpenGL application is running on, due to differences in hardware |
| 666 | manufacturer's implementation of the OpenGL ES graphics pipeline.</li> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 667 | <li><strong>Device Compatibility</strong> - Developers should consider the types of devices, |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 668 | Android versions and the OpenGL ES versions available to their customers. For more information |
| 669 | on OpenGL compatibility across devices, see the <a href="#compatibility">OpenGL Versions and |
| 670 | Device Compatibility</a> section.</li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 671 | <li><strong>Coding Convenience</strong> - The OpenGL ES 1.0/1.1 API provides a fixed function |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 672 | pipeline and convenience functions which are not available in the OpenGL ES 2.0 or 3.0 APIs. |
| 673 | Developers who are new to OpenGL ES may find coding for version 1.0/1.1 faster and more |
| 674 | convenient.</li> |
| 675 | <li><strong>Graphics Control</strong> - The OpenGL ES 2.0 and 3.0 APIs provide a higher degree |
| 676 | of control by providing a fully programmable pipeline through the use of shaders. With more |
| 677 | direct control of the graphics processing pipeline, developers can create effects that would be |
| 678 | very difficult to generate using the 1.0/1.1 API.</li> |
| 679 | <li><strong>Texture Support</strong> - The OpenGL ES 3.0 API has the best support for texture |
| 680 | compression because it guarantees availability of the ETC2 compression format, which supports |
| 681 | transparency. The 1.x and 2.0 API implementations usually include support for ETC1, however |
| 682 | this texture format does not support transparency and so you must typically provide resources |
| 683 | in other compression formats supported by the devices you are targeting. For more information, |
| 684 | see <a href="#textures">Texture compression support</a>.</li> |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 685 | </ul> |
Robert Ly | d2a4e69 | 2011-09-15 15:18:09 -0700 | [diff] [blame] | 686 | |
Joe Fernandez | 0664a8f | 2011-07-15 16:02:30 -0700 | [diff] [blame] | 687 | <p>While performance, compatibility, convenience, control and other factors may influence your |
| 688 | decision, you should pick an OpenGL API version based on what you think provides the best experience |
| 689 | for your users.</p> |
Joe Fernandez | b5c29e7 | 2013-07-09 12:20:36 -0700 | [diff] [blame] | 690 | |