[WebGL Primer] 16, drawing multiple models

Source: Internet
Author: User
Tags script tag

Note: The article is translated from http://wgld.org/, the original author Sambonja 広 (doxas), the article if there is my additional instructions, I will add [Lufy:], in addition, The WEBGL research is not deep enough, some professional words, if the translation is wrong, you are welcome to correct.


The results of this demo run


re-use of vertex caches

In the previous article, a new vertex attribute was added to the three vertices of the polygon, which applied color to the polygon. It is also known that the use of new VBO can give the vertex attributes a free expansion.
So, this time, challenge yourself to draw multiple models at the same time. However, not preparing the new VBO, but also using the last Vbo, that is, reusing VBO, only the coordinate transformation matrix, to draw multiple models.
So, the shader-related content is completely intact, using the last vertex shader and fragment shader, and the JavaScript code is not changing much, so let's focus on the part of the change.


re-use of coordinate transformation matrices

This time drawing multiple models, the coordinate transformation matrix correlation is also reused.
That is, in practice, to draw multiple models to different locations, the coordinate transformation matrix must be manipulated only the model transformation matrix, and determine the position of the lens of the view transformation matrix and determine the screen range of the projection transformation matrix two coordinate transformation matrix, can use the same one.
The steps are as follows, so you can do this by following the matrix.
? Prepare the view and projection two coordinate transformation matrices
? Multiply and save two matrices ahead of time (below, PV)
? Prepare the first model coordinate transformation matrix (below, M1)
? M1 and PV multiplied, passed to uniform
? Draw the first model
? prepare a second model coordinate transformation matrix (below, m2)
? m2 and PV multiplied, passed to uniform
? Draw a second model
? Refresh the context
Mainly, the view coordinate transformation matrix and the projection coordinate transformation matrix are multiplied and saved, and then when the model coordinate transformation matrix is ready, it is then multiplied with the previous result, passed to uniform, and then plotted.
So, take a look at the actual code.

Part of the code in >script.js

The generation and initialization of 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 (n, C.width/c.height, 0.1, PMatrix); M.multiply (PMatrix, V Matrix, Tmpmatrix);//move the Model coordinate transformation matrix of the first model m.translate (Mmatrix, [1.5, 0.0, 0.0], mmatrix);//Model X View x projection (first model) m.multiply ( Tmpmatrix, Mmatrix, Mvpmatrix);//The Coordinate transformation matrix is passed into the uniformlocation and plotted (the first model) GL.UNIFORMMATRIX4FV (Unilocation, False, Mvpmatrix); Gl.drawarrays (GL. Triangles, 0, 3);//move the Model coordinate transformation matrix of the second model m.identity (Mmatrix); M.translate (Mmatrix, [ -1.5, 0.0, 0.0], mmatrix);//Model X View x projection ( The second model) m.multiply (Tmpmatrix, Mmatrix, Mvpmatrix);//convert the coordinate transformation matrix into uniformlocation and draw (the second model) GL.UNIFORMMATRIX4FV ( Unilocation, False, Mvpmatrix); Gl.drawarrays (GL. Triangles, 0, 3);//Refresh Contextgl.flush ();
The point is, in order to temporarily save the view and the projection coordinate transformation matrix, a new Tmpmatrix is declared to use this method. Use mativ.multiply to multiply the view coordinate transformation matrix and the projected coordinate transformation matrix, and then save the results to Tmpmatrix.
Then, use Mativ.translate to manipulate the model coordinate transformation matrix, move the first model to the X direction 1.5, and then multiply the model coordinate transformation matrix and Tmpmatrix, pass it to uniform and draw.
The second model's coordinate matrix, in contrast to the previous one, moves in the x direction-1.5, and then, like the first, multiplies with Tmpmatrix, passes to uniform and plots.
Finally, refresh the context and draw two polygons on the canvas. This eliminates unnecessary code and draws two polygons using VBO and a subset of coordinate transformation matrices.
It is important to note that when you prepare the model coordinate transformation matrix for the second model, the matrix is initially initialized with Mativ.identity in the first place. If the mativ.translate is not initialized directly, it will be affected by the previous move, causing the result to change. After initialization, the operation is done to avoid errors like this.


Additional: Attribute properties added to the function

The last article also involved, when adding vertex attributes, if the corresponding processing function can improve efficiency, although the theme (drawing multiple models) is not related, but because the demo is functional, so a simple explanation.

>VBO Bindings related to

Binding VBO related Functions function Set_attribute (VBO, Attl, Atts) {    //handle the array obtained from the parameter for    (var i in Vbo) {        //bind cache        Gl.bindbuffer (GL. Array_buffer, Vbo[i]);                Set 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 and three parameters are arrays. Use for-in to loop through the properties in the Vbo and bind and add them. Generally, you need to prepare a lot of vbo, so the function here, you can omit a lot of code later.

Summary

This operation is the model coordinate transformation matrix, introduced the reuse Vbo, the view and the projection coordinate transformation matrix, carries on the multi-model drawing method.
Drawing a lot of simple models, graphics, like this one, you can make the processing more concise, avoid writing a lot of redundant code.
This time the demo,html code is exactly the same as the previous one, meaning that the vertex shader and fragment shader do not make any adjustments. There are some changes to the JavaScript code, so all the code is posted. In addition, in the last side of the article, add the demo link, with support for WebGL browser, you can directly open the link to see the effect.


Next, the model coordinate transformation matrix is further manipulated, and the model is processed in various ways.

>script.js all the Code

onload = function () {//Canvas object gets var c = document.getElementById (' canvas ');    C.width = 300;    C.height = 300; WebGL context gets var gl = c.getcontext (' WebGL ') | |        C.getcontext (' Experimental-webgl ');        Sets the color of the canvas initialization gl.clearcolor (0.0, 0.0, 0.0, 1.0);        Sets the depth gl.cleardepth (1.0) when the canvas is initialized; The initialization of the canvas gl.clear (GL. Color_buffer_bit | Gl.        Depth_buffer_bit);    Generation of vertex shader and fragment shader var v_shader = Create_shader (' vs ');        var f_shader = Create_shader (' FS ');        Program object generation and connection var PRG = Create_program (V_shader, F_shader);    Attributelocation gets the var attlocation = new Array (2);    Attlocation[0] = gl.getattriblocation (PRG, ' position ');    ATTLOCATION[1] = gl.getattriblocation (PRG, ' color '); Save the number of elements attribute to the array var attstride = new Array (2), attstride[0] = 3;attstride[1] = 4;//The position of the vertex to save the information array var vertex_position = [0.0, 1.0, 0.0, 1.0, 0.0, 0.0,-1.0, 0.0, 0.0];//Save the vertex's color intelligence array 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 Vbo and add Set_attribute ([Pos_vbo, Col_vbo], attlocation, attstride);        Get uniformlocation var unilocation = gl.getuniformlocation (PRG, ' Mvpmatrix ');    Generate var m = new Mativ () using minmatrix.js to the related processing//Mativ object of the matrix; The generation and initialization of 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 (n, C.width/c.height, 0.1, PMatrix); M.multiply (PMatrix, V Matrix, Tmpmatrix);//move the Model coordinate transformation matrix of the first model m.translate (Mmatrix, [1.5, 0.0, 0.0], mmatrix);//Model X View x projection (first model) m.multiply ( Tmpmatrix, Mmatrix, Mvpmatrix);//The Coordinate transformation matrix is passed into the uniformlocation and plotted (the first model) GL.UNIFORMMATRIX4FV (Unilocation, False, Mvpmatrix); Gl.drawaRrays (GL. Triangles, 0, 3);//move the Model coordinate transformation matrix of the second model m.identity (Mmatrix); M.translate (Mmatrix, [ -1.5, 0.0, 0.0], mmatrix);//Model X View x projection ( The second model) m.multiply (Tmpmatrix, Mmatrix, Mvpmatrix);//convert the coordinate transformation matrix into uniformlocation and draw (the second model) GL.UNIFORMMATRIX4FV ( Unilocation, False, Mvpmatrix); Gl.drawarrays (GL.        Triangles, 0, 3);//Refresh Contextgl.flush ();                Generate Shader function Create_shader (ID) {//variable var shader to hold the shader;                Gets the specified script tag from HTML based on id var scriptelement = document.getElementById (ID);                If the specified script tag does not exist, returns if (!scriptelement) {return;} Determine the type attribute of the script tag switch (scriptelement.type) {//vertex shader when case ' X-shader/x-ver Tex ': shader = Gl.createshader (gl.                Vertex_shader);                            Break Fragment shader when case ' x-shader/x-fragment ': shader = Gl.createshader (gl.                Fragment_shader);            Break Default:rEturn;                }//Assign the code in the tag to the generated shader Gl.shadersource (shader, Scriptelement.text);                Compiler shader Gl.compileshader (shader); Determine if the shader compiles successfully if (Gl.getshaderparameter (shader, GL.        Compile_status)) {//compile successfully, return the shader return shader;        }else{//compilation failed, pop-up error message alert (Gl.getshaderinfolog (shader)); }}///program object generation and shader connection functions function Create_program (VS, FS) {//Program object generation var programs = Gl.createprog                Ram ();        Assigns shader Gl.attachshader (program, VS) to the Application object;                Gl.attachshader (program, FS);                Connect the shader to the Gl.linkprogram (program); Determines if the connection to the shader is successful if (Gl.getprogramparameter (program, GL).                        Link_status)) {//successfully set the program object to a valid Gl.useprogram (Programs);        Returns the program object return to Programs;            }else{//If failure, pop-up error messageAlert (Gl.getprograminfolog (program));                }}//Generate VBO function Create_vbo (data) {//Generate cache object var Vbo = Gl.createbuffer (); Bind Cache Gl.bindbuffer (GL.                Array_buffer, VBO); Writes data to the cache Gl.bufferdata (GL. Array_buffer, new Float32array (data), GL.                Static_draw); Set the bound cache to an invalid Gl.bindbuffer (GL.                Array_buffer, NULL);    Returns the generated VBO return VBO; }//Bind VBO related functions function Set_attribute (VBO, Attl, Atts) {//Handle the array obtained from the parameter for (var i in Vbo) {//bind cache G L.bindbuffer (GL.                Array_buffer, Vbo[i]);                Set Attributelocation to valid Gl.enablevertexattribarray (Attl[i]); Notify and add Attributelocation gl.vertexattribpointer (Attl[i], atts[i], GL.    FLOAT, False, 0, 0); }}};

Demo to draw multiple models

http://wgld.org/s/sample_004/


reprint Please specify:Turn from Lufy_legend's blog Http://blog.csdn.net/lufy_legend


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.