So let’s take a look at what are the basic primitives in OpenGL?

Primitive type Enumerated values describe
point GL_POINTS Each vertex is a separate point on the screen
line GL_LINES Each pair of vertices defines a line segment
Wire belt (not closed) GL_LINE_STRIP A line drawn from the first vertex through each successive vertex
Line loop (closed) GL_LINE_LOOP A line drawn from the first vertex through each successive vertex, connecting the last vertex to the first vertex
triangle GL_TRIANGLES A new triangle is defined for every three vertices
Triangle strip GL_TRIANGLE_STRIP A group of triangles that share vertices on a strip
Triangle fan GL_TRIANGLE_FAN A group of triangles fan-shaped around a dot and sharing adjacent vertices

Through this table, we already know the basic geometric primitives under OpenGL, the way they are formed, the enumerated values they represent. Now let’s learn from a more basic point of view of OpenGL pixel rendering.

Based primitives

Point 1.

Points are the most basic primitives and the simplest images. In OpenGL, points are called vertices and are usually represented by a three-dimensional coordinate of the form (x, y, z). Each particular vertex is just a single point on the screen. In general, points in OpenGL will be drawn as a single pixel. In fact, points can be smaller. Although they may be small enough, they are not infinitesimally small. Function to set the size of a point:

void glPointSize(GLfloat size);
Copy the code

This is the simplest and most common way to set the size of a point, where size must be greater than 0.0f and the default is 1.0F in “pixels”. The concrete implementation is as follows:

1. Set point size glPointSize(5.0f); Note that OpenGL is a state machine. If you change the point size to 5.0F, all of its points will change to 5.0F under the OpenGL scenario, so after setting the current point, we will restore it to its original state of 1.0f.2. Sets the point size range and the interval between points GLfloatSizes [2] = {4.0 2.0 f, f}; GLfloatStep = 1.0 f; Getfloatv (GL_POINT_SIZE_RANGE,sizes); // Set two dots in the range 2 to 4, spaced 1. glGetFloatv(GL_POINT_GRAULARITY,&step); 4. Set point size glEnable(GL_PROGRAM_POINT_SIZE) by using program point size mode; This mode allows us to programmatically set point sizes in vertex shaders and geometry shaders. Shader built-in variable: gl_PointSize; Gl_PointSize = 5.0; gl_PointSize = 5.0;Copy the code

Line 2.

One step further than a point is an independent line segment, which is an element formed by connecting two vertices. By default, the width of a line segment is one pixel, and the only way to change a line segment is to set the width of the line segment by glLineWidth

GlLineWidth (4.5 f); // Set the width of the independent line segment to 4.5f(pixels);Copy the code

(1) Independent line segment: element type parameter –GL_LINES (2) Line segments are connected from end to end but not closed at the end: Line strip (broken line), element type parameter –GL_LINE_STRIP (3) Line segments are connected end to end and the final seal is closed: Line loop (figure), element type parameter –GL_LINE_LOOP The corresponding figure of these three connection modes is shown as the following figure:

3. The triangle

3.1 Drawing a Triangle

Triangles are probably the most popular primitives, but they are also the simplest solid polygons, with only three sides. Triangles are now the only polygon supported in OpenGL. Every three vertices define a new triangle, and all other polygons can be made of triangles. (Triangles are also the most popular form of rasterized hardware.) Here are two triangles, using GL_TRIANGLES:

2. The way triangles surround

A combination in the order and direction specified by the vertices is called a wrap. From the figure above we know that the two polygons in the figure above revolve clockwise. We can change the direction of the wrap by changing the order of the vertices. If we reverse the order of vertices V4 and V5 of the triangle on the left in the figure above, and then draw from vertex V3, the triangle will circle counterclockwise.

Inverse is plus, and cis is minus

So why are there heads and tails? For example: if you have a particularly thin piece of square post-it paper, we can think of it as a square, then the paper will still have two sides, the front and back of the paper. If we make a cube with 6 square post-it notes of the same size, then every side of the cube is a square, and the square has two sides. Suppose that the part you can see outwards is the front, and the part you can’t see inwards is the back.

In OpenGL we also need to distinguish between heads and tails, and we can also tell OpenGL that polygons circled clockwise by vertices are tails by glFrontFace(GL_CW), To tell OpenGL that polygons circling counterclockwise by vertex setting order are faces.

Set the reason for this is that by default, the OpenGL rendering 3 d object will draw on both sides, but in fact we are observing objects, a lot of surface is invisible to the us, such as the direction of the object itself polygon, sheltered situation has led some polygons between some objects are not visible, so in order to improve the performance, We need to weed out these unnecessary drawings.

glEnable(GL_CULL_FACE); // start culling glCullFace(); // The parameters can be GL_FRONT, GL_BACK, GL_FRONT_AND_BACK,Copy the code

3. Triangle belt

We can draw multiple triangles linked together to form multiple faces or polygons. Using the GL_TRIANGLE_STRIP primitives, you can save a lot of time by drawing a series of connected polygons.

Advantages of using triangle strips instead of specifying the vertices of each triangle separately: 1. After specifying a triangle with the first three vertices, you only need to specify one vertex to draw a second triangle. This method can save code and data storage space when drawing a large number of triangles. Improved computing performance and bandwidth savings. Fewer vertices, faster transfer time from memory to the graphics card, and fewer vertices participating in the transformation.

4. Triangle fan

For many surfaces or shapes, we will need to draw several triangles connected together. In this case, we can use the GL_TRIANGLE_FAN element to draw a group of triangles connected around a central point, namely the triangle fan.

5. Drawing method

From the above we know that in three dimensions every polygon has two faces (front and back). Different drawing modes can be set for each surface: the common polygon drawing modes are: GL_FILL, GL_LINE, GL_POINT, and hollow pattern filling (the last one is special). The default drawing mode in OpenGL is: Fill. We use the glPolygonMode() function to specify the mode:

void glPolygonMode(GLenum face,GLenum mode); GlPolygonMode (GL_FRONT, GL_FILL); glPolygonMode(GL_FRONT, GL_FILL); // Set front to fill mode glPolygonMode(GL_BACK, GL_LINE); GlPolygonMode (GL_FRONT_AND_BACK, GL_POINT); // Set both sides to verticesCopy the code

4. A tool class (container) GLBatch

The GLTools library includes a simple container class called GLBatch, which can be used as a simple batch container for the seven most commonly used primiprimians, and it knows how to render primiprimians when using any of the storage shaders supported by GL_ShaderManager.

void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0); Parameter 1:2: primitive parameters vertices parameter 3: a set or two set of texture coordinates (optional) / / copy the vertex data (a weight from 3 x, y, z of vertex arrays) void GLBatch: : CopyVerterxData3f (GLfloat*vVerts) // replicate surface normal data void GLBatch::CopyNormalDataf(GL)float*vNorms); // Copy color data void GLBatch::CopyColorData4f(GLfloat*vColors); / / copy texture coordinates data void GLBatch: : CopyTexCoordData2f (GLFloat * vTextCoords, GLuint u iTextureLayer); Void GLBatch::End(void);Copy the code