OpenGL ES (OpenGL for Embedded Systems) is a subset of the OpenGL three-dimensional graphics API, designed for embedded devices such as mobile phones, PDAs, and game consoles. The API is defined by Khronos Group, Khronos is a graphic hardware and software industry Association, which focuses on the open standards of graphics and multimedia.
Go GOLANG.ORG/X/MOBILE/GL This package is based on OpenGL ES 2, documentation in: HTTPS://GODOC.ORG/GOLANG.ORG/X/MOBILE/GL
Khronos's API documentation in https://www.khronos.org/opengles/sdk/docs/man/
In the example of Gomobile, the basic example (source code in: https://github.com/golang/mobile/tree/master/example), for example, its performance is as follows,
Note that this is done at different aspect ratios under the Mac, zooming in or out of the window size, and this triangle will automatically change according to the ratio.
The source code analysis is as follows:
Triangle Coordinate definition:
Vertex (vertex)
Vertices are the smallest constituent elements used in 3D modeling, with vertices defined as two or more places to rendezvous. In a 3D model, a vertex can be shared by multiple edges, polygons, or polygons. A vertex can also represent a point light or camera's location.
Defines the three vertices of the triangle and the corresponding code implementation:
This converts the coordinates of float to a byte array, which will be passed into the graphics process of OpenGL ES.
This is not defined as a fixed pixel size, but rather a size relative to the screen size (the screen size is 2*2, explained later).
Using OpenGL to draw graphics requires defined items
Using OpenGL ES 2.0 to draw a well-defined shape requires more code, because you need to provide a lot of detail about the graphics rendering process. Specifically, you must define the following:
- Vertex shader (Vertex Shader): OpenGL ES code used to render shape vertices.
- Fragment shader (Fragment Shader): Uses color or texture to render the OpenGL ES code of the shape's surface.
- Program: An OpenGL ES object that contains the shaders you want to use to draw one or more graphics.
You need at least one vertex shader to draw a shape, and a fragment shader to paint the shape. These shaders must be compiled and then added to an OpenGL ES program and used to draw shapes.
Programs (program)
In order to draw your graphics, you must compile the shader code, add them to an OpenGL ES program object, and then execute the link. When you draw an object, the above steps are performed only once.
Here the specific meanings of the vertex shader and fragment shader are analyzed later.
The shader contains the OpenGL shading Language (GLSL) code, which must first be compiled before it can be used in an OpenGL environment. To compile the code, you need to create an auxiliary method in your renderer class, and we can see that the gomobile helps us encapsulate this method in Createprogram:
The following code is the code for Golang.org/x/mobile/exp/gl/glutil.
Note: compiling OpenGL ES shaders and link operations is a huge drain on CPU cycles and processing time, so you should avoid repeating these things. When building your app, you should make sure that they are created only once and cached for later use.
Pass value to OpenGL
Although we already have the data, OpenGL is not able to use them directly. OpenGL has some limitations on the memory it can read. You can allocate your vertex data on demand, but the memory is not directly visible to OpenGL. Therefore, the first step is to allocate OpenGL-visible memory and populate our data. This is done by caching objects (buffer object, hereinafter referred to as Bo).
A cache object, which is a linear array of memory, managed and allocated by OpenGL based on user requests. The contents of this piece of memory can be controlled by the user, but the user can only control it indirectly. You can think of buffer object as an array in GPU memory.
The GPU can read it quickly, so storing data inside it has a performance advantage.
We already have the vertex data in front of it, and the problem is that it's in our RAM instead of OpenGL memory. To move him to OpenGL memory, you need to do the above three lines of code:
The first line creates a buffer object. At this time we have not allocated him any space.
In the second row, the Bindbuffer function binds the newly created Bo to the Array_buffer context.
In the third line, we do the work of allocating space + data copy in OpenGL through the Bufferdata function.
When this function is finished, the data for the vertex is in the Bo. The last parameter of this function can be the lower face value:
- Static_draw saved data content is only defined once by the program, and the GL Draw command can be used multiple times. This is the example code used in this article.
- Dynamic_draw saved data content will be repeatedly defined by the program, the GL Draw command can be used multiple times.
Later we see that Triangledata is no longer being passed to OpenGL, because this parameter is reused later.
Pipe switch
With the definition of vertices, the next step is how to pass them to the OpenGL ES Library, and OpenGL ES provides a mechanism to become a "pipe pipeline" that defines some "switches" to control some of the features supported by OpenGL ES, which are turned off by default. If you need to use OpenGL ES for these features, you need to explicitly tell OpenGL "pipeline" to open the required features.
For this example, you need to tell OpenGL library to open Vertex buffer to use the vertex coordinate buffer.
Note that after you have finished using a feature, you should turn off this feature to prevent subsequent actions:
Vertex shader
The vertexshader in this example is the vertex shader
Version 100 here is the GLSL es for the OpenGL es 2.0 used by Android, IOS, and WebGL. Reference: http://blog.csdn.net/u013467442/article/details/46765335
Uniform VEC2 Offset;
attribute VEC4 position;
is two input parameters, uniform marked read-only, attribute is dedicated to vertex shader, read only.
The VEC2 flag contains only 2 floating-point vectors, and the VEC4 is labeled with 4 floating-point vectors.
Gl_position is the position vector where the vertex shader cuts the output of the space. If you want to make the screen render something gl_position must be used. Otherwise we can't see anything.
Note that the coordinate system of the gl_position is not the same as that of the cell phone screen coordinates. Its coordinate system is the right-hand coordinate. See later.
Vertex Shader Position Assignment
The position (attribute type) in GLSL is the original coordinates of the model, that is, the triangledata here,
The position variable in go is the position pointer.
The corresponding code is as follows:
Glctx. Getattriblocation returns the position of the specified property variable.
Returns the location of a attribute variable.
In getattriblocation This function completes the mapping bundle.
The assignment code is below:
The declaration for this function is as follows:
Assigning a value directly to Vertexattribpointer is not supported, you need to use Bindbuffer to bind the data buffer, and then use Bufferdata to populate the values. This example assigns a value to the Static_draw at initialization, that is, the assignment can be reused later.
Direct use of Vertexattribpointer to load data in OpenGL is not supported via the GO bindings. Instead, use Bindbuffer with a array_buffer and then fill it using Bufferdata.
The Stride argument specifies the byte offset between consecutive vertex attributes.
Assignment of Offset
GLSL offset is only a uniform type, so the assignment is much simpler.
Set up an association pointer to go and OpenGL
Assignment, direct assignment, no above position so much curved around.
Position calculation of vertices
Several values used in the calculation:
1, Touchx, touchy contact position.
The default Touchx, touchy is in the center of the screen, and when a touch event occurs, it is the corresponding position of the screen. Whichever is the actual pixel on the screen.
The coordinate system of the screen is the origin point in the upper-left corner, the x-axis to the right, and the y-axis downward.
2, Sz. WIDTHPX, Sz. The actual size size of the heightpx screen.
The corresponding coordinates are also as follows. WIDTHPX is width, heightpx is length.
3. Offset value passed into OpenGL
Offset.x the contact position of the relative screen width touchx/float32 (sz. WIDTHPX)
Offset.y the contact position of the screen height of the project Touchy/float32 (SZ. HEIGHTPX)
Their values are between 0-1.
4. The position value passed into OpenGL.
This value is the value of triangledata, but the transfer method is a bit around.
5, OpenGL actual operation of the OFFSET4
This is the transformation of the coordinate system.
VEC4 Offset4 = VEC4 (2.0*offset.x-1.0, 1.0-2.0*offset.y, 0, 0);
X magnified twice times,
We're going to put the following pixel-based coordinate system (0 to 1 long and wide)
Convert to the following OpenGL coordinate system (used in OpenGL, length 1 to 1).
The conversion algorithm is the above, twice times minus one, because the y-axis involves flipping, and then add a negative number outside.
6, the actual location of OpenGL
Drawing the model in the OFFSET4 position is the actual location of the model.
Gl_position = Position + offset4;
Note that here we draw the triangle top left point is above, not down, model we directly use this coordinate system of OpenGL.
Since the coordinate system is from 1 to 1, the length of 0.4 is 1/5, we can see the triangle, the length of the screen size is 1/5.
Fragment shader
Settings for image colors
Fragmentshader
is the fragment shader.
The precision is used to determine the default precision modifier, precision mediump float; Basically equivalent to medium precision.
Reference: http://blog.csdn.net/wangyuchun_799/article/details/7752322
Uniform VEC4 Color is a read-only, 4 floating-point vector color.
The color assignment process of the drawing
Binding relationships
When the app starts, the binding relationship is completed
Assign value
Assign a value each time you need to paint.
Render (Render)
Now that we've defined the polygons, here's how to draw (render) the polygon using the API of OpenGL ES. OpenGL ES provides two types of methods to draw a spatial geometry:
Drawarrays are drawn using Vetexbuffer, and the order of vertices is specified in the order of VertexBuffer.
Drawelements can redefine the order of vertices, and the order of vertices is specified by indices Buffer.
We've defined the vertex array in front, so we'll use drawarrays to draw the polygon.
At the same vertex, the geometry can be defined differently, such as three vertices, which can represent three separate points or a triangle, which requires the mode parameter to indicate the basic type of geometry to be drawn.
For the geometry type of each mode please refer to: http://www.imobilebbs.com/wordpress/archives/1512
coordinate system coordinate system
OpenGL uses the right-hand coordinate system, the right-handed system of judgment: in the spatial Cartesian coordinates, the right thumb to the positive direction of the x-axis, the index finger pointing to the positive direction of the Y axis, if the middle finger can point to the positive direction of the z axis, it is called the right-hand Cartesian coordinate system.
Coordinate transformation
The conversion of the coordinate system involved in the OpenGL drawing process is similar.
Figure from: http://zhangwenli.com/blog/2015/08/28/opengl-matrix-transformations/
Use E. External Avoid multiple brush screen painting
if Glctx = = Nil | | e.external {
As we are actively painting as fast as
We can (usually fps), skip any paint
Events sent by the system.
Continue
}
Display FPS Debug information
Resources:
Package GL Documentation
Https://godoc.org/golang.org/x/mobile/gl
Android OpenGL ES Development tutorial from getting started to mastering here is the knowledge of OpenGL ES 1.1
http://blog.csdn.net/mapdigit/article/details/7526556
Drawing shapes
Http://hukai.me/android-training-course-in-chinese/graphics/opengl/draw.html
OpenGL ES2 Learning Tutorial 4--shader language
1190000004410579
Go Mobile Example Basic source code Analysis