[Getting started with WebGL] 16th, drawing multiple models and webgl Models

Source: Internet
Author: User

[Getting started with WebGL] 16th, drawing multiple models and webgl Models

Note: The article is translated from http://wgld.org/, the original author shanbenya (doxas). If I have additional instructions in the article, I will add [lufy:]. In addition, the research on webgl is not in-depth enough, and some professional words are required, if the translation is incorrect, please correct me.


Running result of this demo


Reuse of vertex Cache

In the previous article, the new vertex attribute "color" was added to the three vertices of the polygon, And the Polygon was colored. We also know that using the new VBO can freely expand the vertex attributes.
So, this time we will challenge creating multiple models at the same time. However, if you do not prepare a new VBO, you can also use the last VBO. That is to say, if you reuse VBO, you can only operate on the coordinate transformation matrix to draw multiple models.
Therefore, the content related to the coloring tool remains unchanged, and the last Vertex coloring tool and fragment coloring tool are used completely. There are not many javascript code changes. The following describes the changes.


Reuse of coordinate transformation matrix

Multiple models are drawn this time, and the coordinate transformation matrix is also reused.
That is to say, in reality, when multiple models are drawn to different locations, the coordinate transformation matrix that must be operated is only the model transformation matrix, the view transformation matrix that determines the camera position and the projection transformation matrix that determines the screen range can both use the same coordinate transformation matrix.
Follow the steps below to operate the matrix.
Prepare two coordinate transformation matrices: View and projection.
Then multiply the two matrices and save them (below, pv)
Prepare the first model coordinate transformation matrix (below, m1)
Multiply m1 and pv to uniform
・ Draw the first Model
Prepare the second model coordinate transformation matrix (below, m2)
Multiply between m2 and pv and pass them to uniform.
・ Draw the second model
Refreshing refresh context
The main difference is that the view coordinate transformation matrix and the projection coordinate transformation matrix are multiplied and saved in advance. After the model coordinate transformation matrix is ready, it is multiplied by the previous results, passed to the uniform, and then drawn.
Let's take a look at the actual code.

> Some code in script. js

// Generate and initialize various matrices. var mMatrix = m. identity (m. create (); var vMatrix = m. identity (m. create (); var pMatrix = m. identity (m. create (); var tmpMatrix = m. identity (m. create (); var mvpMatrix = m. identity (m. create (); // view x projection coordinate transformation matrix m. lookAt ([0.0, 0.0, 3.0], [0, 0, 0], [0, 1, 0], vMatrix); m. perspective (90, c. width/c. height, 0.1, 100, pMatrix); m. multiply (pMatrix, vMatrix, tmpMatrix); // move the model coordinate transformation matrix m of the first model. translate (mMatrix, [1.5, 0.0, 0.0], mMatrix); // model x view x projection (first model) m. multiply (tmpMatrix, mMatrix, mvpMatrix); // transfer the coordinate transformation matrix to the uniformLocation and draw (the first model) gl. uniformMatrix4fv (uniLocation, false, mvpMatrix); gl. drawArrays (gl. TRIANGLES, 0, 3); // move the model coordinate transformation matrix m of the second model. identity (mMatrix); m. translate (mMatrix, [-1.5, 0.0, 0.0], mMatrix); // model x view x projection (second model) m. multiply (tmpMatrix, mMatrix, mvpMatrix); // transfers the coordinate transformation matrix to the uniformLocation and draws (the second model) gl. uniformMatrix4fv (uniLocation, false, mvpMatrix); gl. drawArrays (gl. TRIANGLES, 0, 3); // refresh contextgl. flush ();
The key point is that, in order to temporarily Save the view and projection coordinate transformation matrix, a usage method like tmpMatrix is newly defined. Use matIV. multiply To multiply the view coordinate transformation matrix and projection coordinate transformation matrix, and save the result to tmpMatrix.
Then, use matIV. translate to operate the model coordinate transformation matrix, move the first model to the X direction by 1.5, and then multiply the model coordinate transformation matrix and tmpMatrix to uniform for plotting.
The coordinate matrix of the second model, opposite to the previous one, moves-1.5 to the X direction, and then, like the first one, multiplied by tmpMatrix, passes it to uniform for plotting.
Finally, refresh the context and draw two polygon on the canvas. In this way, using VBO and some coordinate transformation matrices saves unnecessary code and draws two polygon.
When preparing the coordinate transformation matrix for the second model, you must first use matIV. identity to initialize the matrix. If matIV. translate is directly used without initialization, it will be affected by the previous move, resulting in a change in the result. After initialization, perform operations to avoid errors like this.


Additional: added attribute function

The previous article also mentioned that when adding vertex attributes, it can improve efficiency if the corresponding processing function is used, although it has nothing to do with this topic (drawing multiple models, however, because the demo is functional, let's give a brief explanation.

> VBO binding

// Bind the VBO-related function set_attribute (vbo, attL, attS) {// process the Array (var I in vbo) obtained from the parameter {// bind the cache gl. bindBuffer (gl. ARRAY_BUFFER, vbo [I]); // sets attributeLocation to valid gl. enableVertexAttribArray (attL [I]); // notify and add attributeLocation gl. vertexAttribPointer (attL [I], attS [I], gl. FLOAT, false, 0, 0 );}}
This function has three parameters, all of which are arrays. Use ~ In to loop the attributes in VBO and bind and add them. Generally, you need to prepare many vbrs. Therefore, you can use this function to omit a lot of code in the future.

Summary

This operation is the model coordinate transformation matrix. It introduces how to repeatedly draw multiple models using the VBO, view, and projection coordinate transformation matrix.
When drawing many simple models and graphs, like this practice, the processing can be simplified to avoid writing a lot of unnecessary code.
In this demo, the HTML code is exactly the same as the previous one, that is, the vertex and fragment pasters have not been adjusted. Javascript code has some changes, so all code is pasted. In addition, the demo link is added at the end of the article. If you have a browser that supports WebGL, you can directly open the link to check the effect.


Next time, we will further operate on the model coordinate transformation matrix to process the drawn model in a variety of ways.

> All script. js Code

Onload = function () {// obtain var c = document from the canvas object. getElementById ('canvas '); c. width = 300; c. height = 300; // obtain var gl = c from the context of webgl. getContext ('webgl ') | c. getContext ('experimental-webgl '); // you can specify the color of the canvas. clearColor (0.0, 0.0, 0.0, 1.0); // sets the depth of gl during canvas initialization. clearDepth (1.0); // initialize gl for canvas. clear (gl. COLOR_BUFFER_BIT | gl. DEPTH_BUFFER_BIT); // generate var v_shader = create_sha for vertex pasters and fragment pasters Der ('vs '); var f_shader = create_shader ('fs'); // generate and connect the program object var prg = create_program (v_shader, f_shader ); // attributeLocation var attLocation = new Array (2); attLocation [0] = gl. getAttribLocation (prg, 'position'); attLocation [1] = gl. getAttribLocation (prg, 'color'); // Save the element prime attribute to the Array var attStride = new Array (2); attStride [0] = 3; attStride [1] = 4; // array that stores vertex location intelligence var vertex_position = [0.0, 1.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0]; // array of color intelligence for storing vertices var vertex_color = [1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0]; // generate VBO var pos_vbo = create_vbo (position); var col_vbo = create_vbo (color ); // bind the VBO and add set_attribute ([pos_vbo, col_vbo], attLocation, attStride); // obtain the uniformLocation var uniLocation = gl. getUniformLocation (prg, 'mvpmatrix '); // use minMatrix. processing of matrix by js/ /Generate var m = new matIV () for the matIV object; // generate and initialize various matrices var mMatrix = m. identity (m. create (); var vMatrix = m. identity (m. create (); var pMatrix = m. identity (m. create (); var tmpMatrix = m. identity (m. create (); var mvpMatrix = m. identity (m. create (); // view x projection coordinate transformation matrix m. lookAt ([0.0, 0.0, 3.0], [0, 0, 0], [0, 1, 0], vMatrix); m. perspective (90, c. width/c. height, 0.1, 100, pMatrix); m. multiply (pMatrix, vMatrix, tmpMatrix ); // Move the model coordinate transformation matrix m of the first model. translate (mMatrix, [1.5, 0.0, 0.0], mMatrix); // model x view x projection (first model) m. multiply (tmpMatrix, mMatrix, mvpMatrix); // transfer the coordinate transformation matrix to the uniformLocation and draw (the first model) gl. uniformMatrix4fv (uniLocation, false, mvpMatrix); gl. drawArrays (gl. TRIANGLES, 0, 3); // move the model coordinate transformation matrix m of the second model. identity (mMatrix); m. translate (mMatrix, [-1.5, 0.0, 0.0], mMatrix); // model x view x projection (second model) m. multiply (tmpMatrix, mMatrix, mvpMatrix); // convert coordinates The matrix is passed into the uniformLocation and the drawing (second model) gl. uniformMatrix4fv (uniLocation, false, mvpMatrix); gl. drawArrays (gl. TRIANGLES, 0, 3); // refresh contextgl. flush (); // generate the colorant function create_shader (id) {// used to save the variable var shader of the colorant; // obtain the specified script tag var scriptElement = document from HTML based on the id. getElementById (id); // if the specified script tag does not exist, if (! ScriptElement) {return;} // identifies the type attribute switch (scriptElement. type) {// case 'x-shader/x-vertex ': shader = gl. createShader (gl. VERTEX_SHADER); break; // case 'x-shader/x-fragment ': shader = gl. createShader (gl. FRAGMENT_SHADER); break; default: return;} // assign the code in the label to the generated sprite gl. shaderSource (shader, scriptElement. text); // compile the gl. compileShader (shader); // checks whether the coloring er has been compiled successfully if (gl. getShaderParameter (shader, gl. COMPILE_STATUS) {// If compilation is successful, return shader;} else {// If compilation fails, the error message alert (gl. getShaderInfoLog (shader);} // function of the program object generation and coloring machine connection function create_program (vs, fs) {// var program = gl generated by the program object. createProgram (); // assign the coloring machine gl to the program object. attachShader (program, vs); gl. attachShader (program, fs); // connect the shader to gl. linkProgram (program); // determines whether the connection of the shadow is successful if (gl. getProgramParameter (program, gl. LINK_STATUS) {// if the program object is successfully set to valid gl. useProgram (program); // return the program object return program;} else {// if it fails, the error message alert (gl. getProgramInfoLog (program);} // generate the VBO function create_vbo (data) {// generate the cache object var vbo = gl. createBuffer (); // bind the cache gl. bindBuffer (gl. ARRAY_BUFFER, vbo); // write data to the cache gl. bufferData (gl. ARRAY_BUFFER, new Float32Array (data), gl. STATIC_DRAW); // sets the bound cache to invalid gl. bindBuffer (gl. ARRAY_BUFFER, null); // return the generated VBO return vbo;} // bind the VBO-related function set_attribute (vbo, attL, attS) {// process the array obtained from the parameter for (var I in vbo) {// bind the cache gl. bindBuffer (gl. ARRAY_BUFFER, vbo [I]); // sets attributeLocation to valid gl. enableVertexAttribArray (attL [I]); // notify and add attributeLocation gl. vertexAttribPointer (attL [I], attS [I], gl. FLOAT, false, 0, 0 );}}};

Demo for drawing multiple models

Http://wgld.org/s/sample_004/


Reprinted Please note:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.