OpenGL ES is a subset of the OpenGL three-dimensional graphics API designed for embedded devices such as mobile phones, PDAs, and game consoles. OPhone currently supports OpenGL ES 1.0, OpenGL ES 1.0 is based on the OpenGL 1.3 specification and OpenGL ES 1.1 is based on OpenGL 1.5 specification. This paper mainly introduces the basic steps of using OpenGL ES to draw graphics.
The content of this article is composed of three parts. First, the programming interface of OpenGL ES is obtained through EGL, then the basic concept of constructing 3D program is introduced; Finally, an application example.
OpenGL ES is essentially a state machine for graphics rendering pipelines, while EGL is used to monitor these states and maintain the outer layers of frame buffers and other rendering surfaces. Figure 1 is a typical EGL system layout diagram. The EGL Windows design is based on the familiar Native interface for OpenGL on Microsoft Windows (WGL) and UNIX (GLX), which is closer to the latter. The status of the OpenGL ES graphics pipeline is stored in a context of EGL management. Frame buffers and other rendering rendering surfaces are created, managed, and destroyed through the EGL API. EGL also controls and provides access to device display and possible device rendering configuration.
Figure 1
OpenGL ES require a rendering context and rendering surface. The rendering context stores the state information for OpenGL ES and renders the rendering surface for the drawing of entities. The actions required for EGL prior to writing OpenGL ES are:
The query device can support the display handle and initialize it.
Create a render surface to draw an OpenGL ES graph.
Creates a render context. EGL needs to create an OpenGL ES rendering context to associate to a render surface.
EGL in OPhone includes 4 classes, namely Egldisplay: Display handle, Eglconfig: Configuration class; Eglcontext: Render context, Class and eglsurface: A rendered view class.
EGL can be considered as an intermediate layer between OpenGL ES and the local window system. The local window system refers to the Gnu/linux X Window System, or Mac OX X's quartz. EGL needs to communicate with the underlying window system before EGL determines the type of render surface. Because of the different Windows systems on different operating systems, EGL provides a transparent window type, i.e. Egldisplay. It abstracts a variety of window systems. So first you create and initialize a Egldisplay object.
Eglcontext static method Getegl Obtain EGL instance
EGL10 EGL = (EGL10) Eglcontext.getegl ();
Create Egldisplay, Egl_default_display get the default local window System type
egldisplay dpy = Egl.eglgetdisplay (EGL10. Egl_default_display);
Initialize EGLDISPLA at the same time to obtain version number
int[] Version = new int[2];
Egl.eglinitialize (dpy, version);
Each egldisplay needs to be initialized before it can be used. Initializing Egldisplay can also get the implementation version number of EGL in the system. Through the version number, reasonable use of the corresponding OpenGL ES API, you can write a good compatibility program to adapt to more equipment and provide maximum portability. Initialize the function prototype:
Boolean eglinitialize (Egldisplay display, int[] major_minor)
The
display in which is a valid Egldisplay instance. When the function call completes, the Major_minor is given the current EGL version number. For example EGL1.0, major_minor[0] for 1,major_minor[1] is 0. Eglsurface contains all the information related to the EGL render surface. There are two ways to query Eglsurface configuration information, one is to query all the configuration information, choose one of the most suitable, and the other is to specify good configuration information, the system gives the best matching results. The second method is generally used. The user specifies the desired configuration through configspec, and the function Eglchooseconfig returns the best configuration list through the parameter configs. Then, using the obtained configs, call Eglcreatecontext to create a rendering context that returns the Eglcontext structure. The creation of the render surface eglsurface is accomplished through a function eglcreatewindowsurface. An application can create multiple eglcontext. Eglmakecurrent is the binding of a rendering context to the render surface. The query function Eglgetcurrentcontext, Eglgetcurrentdisplay, and eglgetcurrentsurface are used to obtain the rendering context, display handle, and render surface of the current system, respectively. Finally, the Eglcontext static method GETGL get the programming interface of OpenGL ES. The following program fragment summarizes the above content.
EGL10 EGL = (EGL10) Eglcontext.getegl ();
Egldisplay dpy = Egl.eglgetdisplay (EGL10. Egl_default_display); int[] Version = new int[2];
Egl.eglinitialize (dpy, version);
Int[] Configspec = {
EGL10. Egl_red_size, 5,
EGL10. Egl_green_size, 6,
EGL10. Egl_blue_size, 5,
EGL10. Egl_depth_size,
EGL10. Egl_none
};
eglconfig[] configs = new eglconfig[1];
int[] Num_config = new int[1];
Egl.eglchooseconfig (Dpy, Configspec, configs, 1, num_config);
Eglconfig config = configs[0];
Eglcontext context = Egl.eglcreatecontext (dpy, config,
EGL10. Egl_no_context, null);
Eglsurface surface = egl.eglcreatewindowsurface (dpy, config,
sholder, null);
Egl.eglmakecurrent (dpy, surface, surface, context);
GL10 gl = (GL10) CONTEXT.GETGL ();
Points for building 3D graphics
Point is the basis for building a 3D model. The internal computations of OpenGL Es are based on dots. Points can also indicate the position of the light source, the position of the object. Generally we use a set of floating-point numbers to represent points. For example, the 4 vertices of a square can be expressed as:
Float vertices[] = {
-1.0f, 1.0f, 0.0f,///left Upper
-1.0f, -1.0f, 0.0f,//lower left
1.0f, -1.0f, 0.0f,///lower-right
1.0f, 1.0f, 0.0f,//upper right
};
In order to improve performance, floating point numbers need to be stored in a byte buffer. So the following actions are available:
Bytebuffer VBB = Bytebuffer.allocatedirect (Vertices.length * 4);
Vbb.order (Byteorder.nativeorder ());
Floatbuffer vertexbuffer = Vbb.asfloatbuffer ();
Vertexbuffer.put (vertices);
Vertexbuffer.position (0);
where Byteorder.nativeorder () is to get native byte order. OpenGL ES has functions to manipulate graphics rendering pipelines, and the use status of these function functions is turned off by default. Enabling and closing these functions can be done using Glenableclientstate, gldisableclientstate.
Specifies that a fixed-point array needs to be enabled
Gl.glenableclientstate (Gl10.gl_vertex_array);
Description enables array type and byte buffering, type Gl_float
Gl.glvertexpointer (3, gl10.gl_float, 0, VertexBuffer);
Close vertex array when no longer needed
Gl.gldisableclientstate (Gl10.gl_vertex_array);
Side
The edge is a line connecting two dots, which is the edge of the polygon surface.
Polygon
A polygon is a single closed ring formed by an edge. OpenGL es in the polygon must be a convex polygon, that is, in the interior of the polygon arbitrarily take two points, if the connection between the two points of the line is in the changeable interior, this polygon is a convex polygon. You need to specify the direction of rendering when drawing a polygon, which is clockwise and counterclockwise. Because the direction determines the orientation of the polygon, that is, front and back. Avoiding rendering the shaded parts can improve program performance effectively. The function Glfrontface defines the orientation of the render vertex.
Set CCW direction to "positive", CCW is counterclockwise, counterclockwise
Glfrontface (GL_CCW);
Set the CW direction to "front", CW is clockwise, clockwise
Glfrontface (GL_CW);
Rendering
With the above concept explained, now to do the most important work-rendering. Rendering is an image that converts an entity specified by an object's coordinates into a frame buffer. There is a close relationship between image and vertex coordinates. This relationship is given by drawing patterns. Commonly used to draw patterns have gl_points, Gl_line_strip,
Gl_line_loop, Gl_lines, Gl_triangles, Gl_triangle_strip, Gl_triangle_fan. The following are described separately:
Gl_points: Each vertex is treated as a point, vertex n is defined as point N, a total of n points are drawn.
Gl_lines: Each vertex as a separate segment, vertex 2n-1 and 2n have a total of n to define the nth segments, a total of N/2 line line. , if n is odd, the last vertex is ignored.
Gl_line_strip: Draws a group of segments that are sequentially connected from the first vertex to the last vertex, and the nth and n+1 vertices define the segment n, which draws a total of N-1 line segments.
Gl_line_loop: Draws a set of segments that are connected sequentially from the first vertex to the last vertex, and then the last vertex is connected to the first vertex. The nth and n+1 vertices define the segment n, and then the last segment is defined by the vertex N and 1, drawing a total of n line segments.
Gl_triangles: Each of the three vertices as a separate triangle. Vertex 3n-2,3n-1 and 3n define the nth triangle, drawing a total of n/3 triangles.
Gl_triangle_strip: Draws a set of connected triangles. For odd-numbered N, vertex n,n+1 and n+2 define nth triangles, and for even-N, vertex n+1,n and n+2 define nth triangles, with a total of N-2 triangles drawn.
Gl_triangle_fan: Draws a set of connected triangles. Triangles are determined by the first vertex and the vertices that are given after it. Vertex 1,n+1 and n+2 define the nth triangle, drawing a total of N-2 triangles.
Draw function:
void Gldrawarrays (int mode, int a, count of int)
void gldrawelements (int mode, int count, int type, Buffer indices)
Gldrawarrays creates a sequence of geometric entities, using the array elements in each array that start with first, to count–1, and mode is the drawing pattern.
Gldrawelements uses the count elements to define a sequence of entities, type is the data types in the indices array, mode is the drawing mode, and the indices array stores the top
The index value of the point.
Application examples
Use the content explained above to give a program to draw a 3D sphere on a ophone. The effect chart is as follows:
Figure 2 Spherical example
The main drawing program:
Static private Floatbuffer vertex;//vertex corresponding byte buffer static private floatbuffer normal;//vector corresponding byte buffer float[] Lightpos = new float [] {10.0f, 10.0f, 10.0f, 1.0f};//Light source coordinates private static final int step = 24;//private static final float RADIUS = 1.0f;//half Path protected void init (GL10 gl) {gl.glclearcolor (0.0f, 0.0f, 0.0f, 1.0f);/Set Background color GL.GLLIGHTFV (gl10.gl_light0, Gl10.gl_po
Sition, Lightpos, 0); Gl.glenable (gl10.gl_lighting);//Enable Illumination gl.glenable (GL10.GL_LIGHT0); Open the light source GL.GLCLEARDEPTHF (1.0f),//Set the depth cache Gl.gldepthfunc (gl10.gl_lequal),//Set the depth cache comparison function, Gl_
LEqual indicates that the depth cache value of the new pixel is less than the depth cache value equal to the current pixel gl.glenable (gl10.gl_depth_test) by depth test;//enable depth caching gl.glenable (gl10.gl_cull_face); Gl.glshademodel (Gl10.gl_smooth);//Set Shadow mode Gl_smooth} protected void Drawframe (GL10 GL) {gl.glclear (gl10.gl_color_
Buffer_bit |
Gl10.gl_depth_buffer_bit);
Gl.glmatrixmode (Gl10.gl_modelview);
Gl.glloadidentity (); Glu.glulookat (GL, 0, 0, 7f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);//Drawsphere (GL, RADIUS, step, step); Draw spherical} public static void Glulookat (GL10 GL, float Eyex, float eyey, float eyez, float centerx, float centery, float centerz, float upX, float upy, float upz)
It accepts three sets of coordinates, namely eye, center, and up. Eye the position of our eyes in the world coordinate system, center represents the coordinates of the point where the eye "looks", the up coordinate represents the direction of the observer itself, and if the observation point is likened to our eyes, then this up indicates whether we are standing or inverted or a certain angle, here is the upright way, So it's {0,1,0}.
private static void Drawsphere (GL10 gl, float radius, int stacks, int slices) {Vertex=allocatefloatbuffer (4* 6 * stacks
* (slices+1));
Normal=allocatefloatbuffer (4* 6 * stacks * (slices+1));
int I, j, triangles;
float Slicestep, Stackstep;
Stackstep = ((float) math.pi)/stacks;
Slicestep = 2.0f * ((float) math.pi)/slices; for (i = 0; i < stacks; ++i) {Float a = i * stackstep; float B = a + stackstep; float s0 = (float) math.sin (a); float s
1 = (float) Math.sin (b);
float C0 = (float) math.cos (a);
float C1 = (float) math.cos (b);
Float NV; for (j = 0; J <= slices; ++j) {Float c = j * SLICESTEP; float x = (float) math.cos (c); float y = (float) math.sin (c); NV
=x * S0;
Normal.put (NV);
Vertex.put (NV * radius);
Nv=y * S0;
Normal.put (NV);
Vertex.put (NV * radius);
NV=C0;
Normal.put (NV);
Vertex.put (NV * radius);
Nv=x * S1;
Normal.put (NV);
Vertex.put (NV * radius);
Nv=y * S1;
Normal.put (NV);
Vertex.put (NV * radius);
NV=C1;
Normal.put (NV);
Vertex.put (NV * radius); } normal.position (0);
Vertex.position (0);
Gl.glvertexpointer (3, gl10.gl_float, 0, Vertex);
Gl.glnormalpointer (gl10.gl_float, 0, normal);
Gl.glenableclientstate (Gl10.gl_vertex_array);
Gl.glenableclientstate (Gl10.gl_normal_array);
Triangles = (slices + 1) * 2;
for (i = 0; I < stacks i++) gl.gldrawarrays (Gl10.gl_triangle_strip, I * triangles, triangles);
Gl.gldisableclientstate (Gl10.gl_vertex_array);
Gl.gldisableclientstate (Gl10.gl_normal_array);
private static Floatbuffer allocatefloatbuffer (int capacity) {Bytebuffer VBB = Bytebuffer.allocatedirect (capacity);
Vbb.order (Byteorder.nativeorder ());
return Vbb.asfloatbuffer ();
}
Summarize:
This paper introduces the basic concepts and methods of using OpenGL ES to draw graphs in ophone. There are many other things in OpenGL es, such as textures, lighting and materials, mixing, fog, masking, reflection, loading of 3D models, and so on. The OpenGL ES function can be used to draw rich graphics application and game interface.