JavaScript-WebGL2學習筆記
阿新 • • 發佈:2018-11-19
在前一篇WebGL的基礎上修改了程式碼,使之符合WebGL2規範。
<html> <head> <!-- Date: 2018-3-16 Author: kagula Prologue: WebGL2的例子 Prologue: Description: 網上太多WebGL資料,為了避免混餚,我們在原本WebGL的基礎上瞭解WebGL2, 這裡還是用兩個三角形拼出一個彩色的正方形. Original: [1]https://my.oschina.net/thesadabc/blog/1592866 測試環境 [1]Chrome 65.0.3325.162 [2]nginx 1.12.2 --> <title>第一個Webgl2程式</title> <meta charset="utf-8"> <!-- gl-matrix version 2.4.0 from http://glmatrix.net/ --> <script type="text/javascript" src="/gl-matrix-min.js"></script> <script type="text/javascript" src="/kagula/webgl_helper.js"></script> </head> <body> <canvas id="glCanvas" width="640" height="480"></canvas> </body> </html> <script> main(); //弄4個頂點, 4個顔色, 用來演示render流程! function initBuffers(gl) { // Create a buffer for the square's positions. const positionBuffer = gl.createBuffer(); // Select the positionBuffer as the one to apply buffer // operations to from here out. gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Now create an array of positions for the square. const positions = [ 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, ]; // Now pass the list of positions into WebGL to build the // shape. We do this by creating a Float32Array from the // JavaScript array, then use it to fill the current buffer. gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); //給每個頂點弄一個顔色 const colors = [ 1.0, 1.0, 1.0, 1.0, // white 1.0, 0.0, 0.0, 1.0, // red 0.0, 1.0, 0.0, 1.0, // green 0.0, 0.0, 1.0, 1.0, // blue ]; const colorBuffer = gl.createBuffer();//建立gl快取,但是不指定快取型別. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);//指定olorBuffer的型別為gl.ARRAY_BUFFER //緩衝區物件中的資料只指定1次,但是常常使用。這種模式下,OpenGL會將資料放在能夠快速渲染的地方。 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); return { position: positionBuffer, color: colorBuffer, }; } function main() { //選擇器的使用 //http://www.runoob.com/jsref/met-document-queryselector.html const canvas = document.querySelector("#glCanvas"); // Initialize the GL context //為了獲取WebGL2上下文,getContext方法傳入的引數是"webgl2",而不是"webgl". const gl = canvas.getContext("webgl2"); // Only continue if WebGL is available and working if (!gl) { alert("Unable to initialize WebGL. Your browser or machine may not support it."); return; } //OpenGL ES 3.0 不支援多維陣列 //對傳入的陣列大小有限制 console.log("gl.MAX_VERTEX_UNIFORM_VECTORS=" + gl.MAX_VERTEX_UNIFORM_VECTORS + ", gl.MAX_FRAGMENT_UNIFORM_VECTORS=" + gl.MAX_FRAGMENT_UNIFORM_VECTORS); // Vertex shader program //WebGL2的著色器語言支援原本WebGL1的GLSL 100 ,同時也支援GLSL 300 es //要使用GLSL 300 es,需要在著色器程式碼中顯示宣告 //版本宣告的程式碼需要在頂點著色器和片元著色器中同時指定, 版本宣告的程式碼必須嚴格在第一行. //在webgl 1.0中 attribute表示輸入,varying表示輸入輸出. //現在要改為用/in out標記輸入,輸出. const vsSource = `#version 300 es in vec4 aVertexPosition; in vec4 aVertexColor;//從外部拿到顏色,不做任何處理,丟給vColor. uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; //從aVertexColor拿到的顏色直接給vColor, //由vColor傳給Fragment Shader. out lowp vec4 vColor; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; vColor = aVertexColor;//什麼都不做,只是為了把從外部得到的color傳遞給Fragment Shader. } `; // Fragment shader, 相當於pixel shader //varying被in代替 //在GLSL 100 中,我們通過給內建變數gl_FragColor賦值來設定片元的輸出顏色 //而在GLSL 300 es中,需要自己定義一個輸出顏色的變數,並在main函式中設定顏色值 const fsSource = `#version 300 es precision highp float;//必須要為float型別指定精度 in lowp vec4 vColor;//從vertex shader得到的顏色放在這裡。 out vec4 myOutputColor; void main() { myOutputColor = vColor; } `; //裝配shader到shaderProgram中去 const shaderProgram = initShaderProgram(gl, vsSource, fsSource); //為了讓外部的資料能統一傳到shanderProgram中去,新建programInfo物件。 //vertexPosition => aVertexPosition位置 //projectionMatrix => uProjectionMatrix位置 //modelViewMatrix => uModelViewMatrix位置 //... const programInfo = { program: shaderProgram, attribLocations: { vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'), vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'), }, uniformLocations: { projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), }, }; //initBuffers(gl)返回要render的vertex. drawScene(gl, programInfo, initBuffers(gl)); }//main </script>