4. Let the triangle move
We need to interact. But to interact, you must first have interactive content. In the next chapter, we will use a keyboard to control triangle rotation. But in this chapter, we first make some preparations: Let the triangle rotate itself without interaction; and, a little bit of code is organized, separate the data preparation code and drawing code into different JS functions.
The triangle we defined previously exceeded the range [-1.0, + 1.0] during rotation. Therefore, I halved the triangle.
The JS function for loading data is loaddata (), and The JS function for plotting is renderscene (). The loaddata function returns an integer. 0 indicates that the load is successful, and other values indicate that an error is encountered. The renderscene function does not return values. We will continue to improve these two functions in the future.
We use a timer to increase the angle of the triangle rotation by 10 at a certain time, and then re-draw the entire scene based on this angle (call renderscene ).
In the renderscene function, we calculate the conversion matrix based on the rotation angle, and then pass the conversion matrix to the uniform variable of the vertex shader. Inside the vertex shader, use the received uniform matrix to perform vertex conversion. For more information about 3D conversion, matrix, vector computing, and so on, please find your own materials (generally, 3D programming books (such as OpenGL and DirectX) will be available, more professional, let's go to the math book ).
The JS file "glMatrix-0.9.5.js" is required to calculate the conversion matrix. It provides several vector and matrix classes and encapsulates some operations. For descriptions of various classes and their operations, refer to my "function reference: glmatrix. js".
The integrated source code is as follows:
<HTML>
<Head>
<Meta http-equiv = "Content-Type" content = "text/html; charset = gb2312">
<SCRIPT type = "text/JavaScript" src = "glMatrix-0.9.5.js"> </SCRIPT>
<SCRIPT id = "shader-Vs" type = "X-shader/X-vertex">
Attribute vec3 v3position;
Uniform mat4 um4rotate;
Varying vec2 v_texcoord;
Void main (void)
{
Vec4 v4pos = um4rotate * vec4 (v3position, 1.0 );
V_texcoord = vec2 (v4pos. x + 1.0)/2.0, 1.0-(v4pos. Y + 1.0)/2.0 );
Gl_position = v4pos;
// V_texcoord = vec2 (v3position. x + 1.0)/2.0, 1.0-(v3position. Y + 1.0)/2.0 );
// Gl_position = um4rotate * vec4 (v3position, 1.0 );
}
</SCRIPT>
<SCRIPT id = "shader-Fs" type = "X-shader/X-fragment">
# Ifdef gl_fragment_precision_high
Precision highp float;
# Else
Precision mediump float;
# Endif
Uniform sampler2d s_texture;
Varying vec2 v_texcoord;
Void main (void)
{
Gl_fragcolor = texture2d (s_texture, v_texcoord );
}
</SCRIPT>
<SCRIPT>
Function shadersourcefromscript (scriptid)
{
VaR shaderscript = Document. getelementbyid (scriptid );
If (shaderscript = NULL) Return "";
VaR sourcecode = "";
VaR child = shaderscript. firstchild;
While (child)
{
If (child. nodetype = Child. text_node) sourcecode + = Child. textcontent;
Child = Child. nextsibling;
}
Return sourcecode;
}
VaR webgl = NULL;
VaR vertexshaderobject = NULL;
VaR fragmentshaderobject = NULL;
VaR programobject = NULL;
VaR trianglebuffer = NULL;
VaR v3positionindex = 0;
VaR textureobject = NULL;
VaR samplerindex =-1;
VaR integer = 300;
VaR angle = 0;
VaR um4rotateindex =-1;
Function loaddata ()
{
VaR jsarraydata = [
0.0, 0.5, 0.0, // top Vertex
-0.5,-0.5, 0.0, // left Vertex
0.5, 0.0, 0.0]; // right Vertex
Trianglebuffer = webgl. createbuffer ();
Webgl. bindbuffer (webgl. array_buffer, trianglebuffer );
Webgl. bufferdata (webgl. array_buffer, new float32array (jsarraydata), webgl. static_draw );
Textureobject = webgl. createtexture ();
Webgl. bindtexture (webgl. texture_2d, textureobject );
VaR IMG = Document. getelementbyid ('mytexture ');
Webgl. teximage2d (webgl. texture_2d, 0, webgl. RGB, webgl. RGB, webgl. unsigned_byte, IMG );
Return 0;
}
Function renderscene ()
{
Webgl. clearcolor (0.0, 0.0, 0.0, 1.0 );
Webgl. Clear (webgl. color_buffer_bit );
Webgl. bindbuffer (webgl. array_buffer, trianglebuffer );
Webgl. enablevertexattribarray (v3positionindex );
Webgl. vertexattribpointer (v3positionindex, 3, webgl. Float, false, 0, 0 );
Webgl. texparameteri (webgl. texture_2d, webgl. texture_min_filter, webgl. Nearest );
Webgl. texparameteri (webgl. texture_2d, webgl. texture_mag_filter, webgl. Nearest );
Webgl. texparameteri (webgl. texture_2d, webgl. texture_wrap_s, webgl. clamp_to_edge );
Webgl. texparameteri (webgl. texture_2d, webgl. texture_wrap_t, webgl. clamp_to_edge );
Webgl. activetexture (webgl. texture0 );
Webgl. bindtexture (webgl. texture_2d, textureobject );
Webgl. uniform1i (samplerindex, 0 );
VaR m4rotate = mat4.create ();
Mat4.identity (m4rotate );
Mat4.rotatez (m4rotate, angle * Math. PI/180 );
Webgl. uniformmatrix4fv (um4rotateindex, false, m4rotate );
Webgl. drawarrays (webgl. triangles, 0, 3 );
}
Function rotatetriangle ()
{
Angle + = 10;
If (angles> = 360) angle-= 360;
Renderscene ();
}
Function Init ()
{
VaR mycanvasobject = Document. getelementbyid ('mycanvas ');
Webgl = mycanvasobject. getcontext ("experimental-webgl ");
Webgl. viewport (0, 0, mycanvasobject. clientwidth, mycanvasobject. clientheight );
Vertexshaderobject = webgl. createshader (webgl. vertex_shader );
Fragmentshaderobject = webgl. createshader (webgl. fragment_shader );
Webgl. shadersource (vertexshaderobject, shadersourcefromscript ("shader-"));
Webgl. shadersource (fragmentshaderobject, shadersourcefromscript ("shader-Fs "));
Webgl. compileshader (vertexshaderobject );
Webgl. compileshader (fragmentshaderobject );
If (! Webgl. getshaderparameter (vertexshaderobject, webgl. compile_status) {alert (webgl. getshaderinfolog (vertexshaderobject); return ;}
If (! Webgl. getshaderparameter (fragmentshaderobject, webgl. compile_status) {alert (webgl. getshaderinfolog (fragmentshaderobject); return ;}
Programobject = webgl. createprogram ();
Webgl. attachshader (programobject, vertexshaderobject );
Webgl. attachshader (programobject, fragmentshaderobject );
Webgl. bindattriblocation (programobject, v3positionindex, "v3position ");
Webgl. linkprogram (programobject );
If (! Webgl. getprogramparameter (programobject, webgl. link_status) {alert (webgl. getprograminfolog (programobject); return ;}
Samplerindex = webgl. getuniformlocation (programobject, "s_texture ");
Um4rotateindex = webgl. getuniformlocation (programobject, "um4rotate ");
Webgl. useprogram (programobject );
If (loaddata ()! = 0) {alert ("error: loaddata ()! "); Return ;}
Window. setinterval ("rotatetriangle ()", interval );
}
</SCRIPT>
</Head>
<Body onload = 'init () '>
<Canvas id = "mycanvas" style = "border: 1px solid red;" width = '600px 'Height = '0000p'> </canvas>
</Body>
</Html>
The running result is as follows:
They do not seem to rotate along with triangles. That is to say, triangles always play a transparent role at any time, display the image content in the region. If you comment out the three lines in the vertex coloring tool:
Vec4 v4pos = um4rotate * vec4 (v3position, 1.0 );
V_texcoord = vec2 (v4pos. x + 1.0)/2.0, 1.0-(v4pos. Y + 1.0)/2.0 );
Gl_position = v4pos;
Uncomment the following two lines:
// V_texcoord = vec2 (v3position. x + 1.0)/2.0, 1.0-(v3position. Y + 1.0)/2.0 );
// Gl_position = um4rotate * vec4 (v3position, 1.0 );
The effect you see is that the image on the triangle rotates with the triangle: