2d versus 3d graphics
From Android Wiki
Android uses quite different APIs for 2D versus 3D graphics. The 2D graphics API is built on the Skia graphics library that Google acquired along with the company that created it. The 3D graphics API is OpenGL-ES, the “embeddable” subset of the well-known cross-platform OpenGL 3D graphics API.
The 2D graphics engine is completely integrated into the UI, and is used for all on-screen drawing of windows, widgets etc. For example, to create your own custom widget, it is easy enough to subclass View, do whatever custom rendering you want in its onDraw method and event handling in onTouchEvent.
3D graphics is not quite so seamlessly integrated. The easiest way to do an on-screen 3D display is to subclass GLSurfaceView, in addition to which you need to provide a custom subclass of GLSurfaceView.Renderer which does the actual setup and drawing.
A GLSurfaceView offers two “render modes”, selected by calling setRenderMode: RENDERMODE_CONTINUOUSLY in which your Renderer is continually called to render the scene (the default), and RENDERMODE_WHEN_DIRTY where your Renderer is only invoked when you do a requestRender. Note this is quite different from normal 2D widgets, which are only (re)drawn in response to an invalidate call.
Note the difference in coordinate systems: in the 2D graphics API, y-coordinates increase downwards, while in OpenGL they increase upwards.
The available graphics primitives are more limited in 3D. Whereas in 2D you have complex entities like text, Paths, Drawables and Pictures, in 3D you just have points, lines and triangles. In particular, all object surfaces must be constructed out of triangles; curved surfaces are approximated to a limited extent by subdividing into smaller triangles, but more importantly by enabling smooth shading, which fools the eye into seeing continuous gradations instead of angular facets.
It is possible to use 2D graphics in 3D, by rendering a 2D image to a Bitmap, which is then used as a texture on an object surface in 3D.
Also note that OpenGL is strictly an on-screen real-time rendering API: it defines no “file format” for storing scenes/models in persistent storage, and it doesn’t support CPU-intensive functions like ray-tracing, radiosity and the like.
OpenGL-ES Versus Regular OpenGL
OpenGL-ES leaves out various capabilities of OpenGL which were deemed to have too high an overhead of implementation in an embedded environment. OpenGL-ES 1.1 is based on OpenGL 1.5, among the differences being:
- No Begin/End grouping and associated calls for individually specifying vertex info: instead, you must use the xxxPointer calls to pass entire buffers of coordinates at a time, and then draw them with DrawArrays (selecting contiguous subarrays) or DrawElements (selecting individual array elements by index).
- Only 2D textures, no 3D or 1D.
- No support for polygons other than triangles.
- ES adds the option to specify coordinates etc as fixed-point values (calls with an x suffix) instead of floating-point (f suffix).
android.opengl Versus khronos.opengles
Android provides two alternative styles of OpenGL API calls: the khronos.opengles calls are method calls off explicit GL objects, whereas the android.opengl calls are all static, and implicitly refer to a current GL context.
It looks like the latter are now the preferred form, since the addition of support for OpenGL-ES 2.0 in API level 8 (Android 2.2) was done only in the android.opengl style, not the khronos.opengles style.
EGL is an API for giving direct control over creation of OpenGL contexts that render to on-screen windows, offscreen pixmaps, or additional graphics-card memory. GLSurfaceView provides a simple wrapper to save you using it directly, but you can still do so in cases where this isn’t flexible enough (like when you want to do offscreen rendering).
More notes on EGL usage are here.
Documentation on OpenGL, OpenGL-ES and EGL can be found at khronos.org.