Preface
In [previous notes](/articles/用 buffer 绘制多个点-webgl 笔记 5/), we used buffer to store multiple vertex data, then drew them all at once. Having solved the data input problem, we can now draw things slightly more complex than points, such as triangles, lines, rectangles, etc.
1. Primitives
Primitives are the smallest units used to compose complex models. WebGL can directly draw 7 basic graphics, which are the so-called primitives:
-
Isolated points
-
Isolated line segments
-
Continuous line segments
-
Continuous line loop
-
Isolated triangles
-
Triangle strip
-
Triangle fan
"Can directly draw", conversely means only these things can be directly drawn, while other slightly more complex ones must be constructed using these 7 primitives by ourselves, such as rectangles, hexagons, tetrahedrons, cubes... etc. can be figured out by assembling vertices, but more complex ones, such as cylinders, spheres, hemispheres... etc. need to export vertex data from professional modeling tools (such as 3ds max, maya, blender, etc.)
Constructing complex models usually uses triangle strips, or isolated triangles, such as using triangle strips to construct a sphere, like restoring a complete peeled apple skin, while using isolated triangles to construct a cube is purely piecing together
2. Drawing Primitives
When drawing isolated points before, the code ultimately responsible for drawing was just one line:
// Draw points
gl.drawArrays(gl.POINTS, 0, arrVtx.length / 2);
// gl.POINTS isolated points
// gl.LINES isolated line segments
// gl.LINE_STRIP continuous line segments
// gl.LINE_LOOP continuous line loop
// gl.TRIANGLES isolated triangles
// gl.TRIANGLE_STRIP triangle strip
// gl.TRIANGLE_FAN triangle fan
To draw other primitives, just modify the first parameter of gl.drawArrays, for detailed explanation of this function please see [attribute Variables and Vertex Shaders_WebGL Notes 2](/articles/attribute 变量与顶点着色器-webgl 笔记 2/#articleHeader9). Simply understood, the first parameter is used to tell WebGL system how to use the passed vertex data, whether to draw points, lines, or triangles
P.S. Actually, the first parameter affects the geometry assembly process before rasterization, at this time it will assemble the processed vertex data into geometric shapes according to the primitive specified by the parameter, then the rasterization process is to decompose geometric shapes into individual fragments (or pixels), then colored by fragment shader, after completion is the effect we finally see. The specific process from passing vertex data to drawing completion will be explained in detail in the next note about varying variables
3. Drawing Rectangles
There are 2 most direct ways:
-
6 vertices draw 2 triangles
-
4 vertices determine 2 triangle strips in triangle strip
Generally will consider saving vertex data, minimize the number of vertices passed in, to improve performance. So we adopt the latter method, main code as follows:
var arrVtx = new Float32Array([
-0.5, 0.5,
-0.5, 0.0,
0.5, 0.5,
0.5, 0.0
]);
// Draw rectangle
gl.drawArrays(gl.TRIANGLE_STRIP, 0, arrVtx.length / 2);
Looks still quite simple, actually the most critical problem in drawing complex graphics is vertex data source, rectangle vertices can be directly listed with pen, slightly more complex ones can be written out by drawing sketches, even more complex ones may need professional modeling tools. Export vertex data files from modeling tools, then parse files to get vertex data we need, of course, from the knowledge needed to master, drawing a sphere and drawing a rectangle have no difference
4. DEMO
For complete examples containing above code, please see:
-
7 types of primitives (change one every 2s): http://www.ayqy.net/temp/webgl/triangle/index.html
-
Rectangle: http://www.ayqy.net/temp/webgl/rectangle/index.html
5. Summary
Specifying primitives is to tell WebGL how to want to use the passed vertex data, then there's such a situation: pass in 5 vertices saying to draw isolated triangles, guess the result? Of course only drew 1 triangle, because the last 2 vertices cannot assemble a triangle, so cannot decompose individual fragments of this triangle, finally won't see it
From passing vertex data to image being drawn, the process in between is long but every step is critical, will explain in detail in next note
References
- "WebGL Programming Guide"
No comments yet. Be the first to share your thoughts.