一、前言
?????? 終于到了第五章了,貌似開始越來越復雜了。
?
二、正文
??????? Example1:使用一個緩沖區去賦值多個頂點數據(包含坐標及點大小)
function initVertexBuffers(gl) {var verticesSizes = new Float32Array([0.0, 0.5, 10.0, -0.5, -0.5, 20.0, 0.5, -0.5, 30.0 ]);var n = 3; var vertexSizeBuffer = gl.createBuffer(); if (!vertexSizeBuffer) {console.log('Failed to create the buffer object');return -1;} gl.bindBuffer(gl.ARRAY_BUFFER, vertexSizeBuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesSizes, gl.STATIC_DRAW);var FSIZE = verticesSizes.BYTES_PER_ELEMENT;var a_Position = gl.getAttribLocation(gl.program, 'a_Position');if (a_Position < 0) {console.log('Failed to get the storage location of a_Position');return -1;}gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 3, 0);gl.enableVertexAttribArray(a_Position);
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');if(a_PointSize < 0) {console.log('Failed to get the storage location of a_PointSize');return -1;}gl.vertexAttribPointer(a_PointSize, 1, gl.FLOAT, false, FSIZE * 3, FSIZE * 2);gl.enableVertexAttribArray(a_PointSize); gl.bindBuffer(gl.ARRAY_BUFFER, null);return n; }
????????
????????? Example2:使用varying變量從頂點著色器傳輸顏色信息給片元著色器
var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec4 a_Color;\n' + //attribute變量'varying vec4 v_Color;\n' + // varying變量'void main() {\n' +' gl_Position = a_Position;\n' +' gl_PointSize = 10.0;\n' +' v_Color = a_Color;\n' + // 將attribute變量賦給varying變量'}\n'; var FSHADER_SOURCE =
'#ifdef GL_ES\n' +'precision mediump float;\n' + '#endif GL_ES\n' +
'varying vec4 v_Color;\n' + //同名varying變量'void main() {\n' +' gl_FragColor = v_Color;\n' + //!!!!!'}\n';
function initVertexBuffers(gl) {var verticesColors = new Float32Array([// 頂點坐標 與 顏色0.0, 0.5, 1.0, 0.0, 0.0, -0.5, -0.5, 0.0, 1.0, 0.0, 0.5, -0.5, 0.0, 0.0, 1.0, ]);var n = 3; var vertexColorBuffer = gl.createBuffer(); if (!vertexColorBuffer) {console.log('Failed to create the buffer object');return false;} gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);var FSIZE = verticesColors.BYTES_PER_ELEMENT;var a_Position = gl.getAttribLocation(gl.program, 'a_Position');if (a_Position < 0) {console.log('Failed to get the storage location of a_Position');return -1;}gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);gl.enableVertexAttribArray(a_Position); var a_Color = gl.getAttribLocation(gl.program, 'a_Color');if(a_Color < 0) {console.log('Failed to get the storage location of a_Color');return -1;}gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);gl.enableVertexAttribArray(a_Color); return n; }
?
?????? Example3:紋理(將圖片的紋理賦給webgl對象)
var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec2 a_TexCoord;\n' + // 聲明一個attribute變量'varying vec2 v_TexCoord;\n' + // 聲明一個varying變量'void main() {\n' +' gl_Position = a_Position;\n' +' v_TexCoord = a_TexCoord;\n' + // attribute變量賦給varying變量'}\n'; var FSHADER_SOURCE ='#ifdef GL_ES\n' +'precision mediump float;\n' +'#endif\n' +
'uniform sampler2D u_Sampler;\n' +'varying vec2 v_TexCoord;\n' +'void main() {\n' +
// texture2D(sampler2D sampler, vec2 coord)
// (紋理單元編號,紋理坐標) 這里是賦值的關鍵' gl_FragColor = texture2D(u_Sampler, v_TexCoord);\n' + '}\n';function main() { var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);if (!gl) {console.log('Failed to get the rendering context for WebGL');return;}if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {console.log('Failed to intialize shaders.');return;}// 設置頂點緩存var n = initVertexBuffers(gl);if (n < 0) {console.log('Failed to set the vertex information');return;} gl.clearColor(0.0, 0.0, 0.0, 1.0);// 設置紋理if (!initTextures(gl, n)) {console.log('Failed to intialize the texture.');return;} }function initVertexBuffers(gl) {var verticesTexCoords = new Float32Array([//webgl頂點坐標, 紋理坐標相應點-0.5, 0.5, 0.0, 1.0,-0.5, -0.5, 0.0, 0.0,0.5, 0.5, 1.0, 1.0,0.5, -0.5, 1.0, 0.0,]);var n = 4;
// 創建緩存區對象var vertexTexCoordBuffer = gl.createBuffer();if (!vertexTexCoordBuffer) {console.log('Failed to create the buffer object');return -1;} gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;var a_Position = gl.getAttribLocation(gl.program, 'a_Position');if (a_Position < 0) {console.log('Failed to get the storage location of a_Position');return -1;}gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);gl.enableVertexAttribArray(a_Position);
// 將紋理坐標分配給該存儲位置并開啟var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');if (a_TexCoord < 0) {console.log('Failed to get the storage location of a_TexCoord');return -1;} gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);gl.enableVertexAttribArray(a_TexCoord); return n; }function initTextures(gl, n) {
// Step1:設置紋理對象var texture = gl.createTexture(); if (!texture) {console.log('Failed to create the texture object');return false;}// Step2: 獲取u_Sampler(取樣器)存儲位置var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');if (!u_Sampler) {console.log('Failed to get the storage location of u_Sampler');return false;}
// Step3: 創建圖片對象var image = new Image(); if (!image) {console.log('Failed to create the image object');return false;} image.onload = function(){ loadTexture(gl, n, texture, u_Sampler, image); };image.src = '../resources/sky.jpg';return true; }function loadTexture(gl, n, texture, u_Sampler, image) {
// Step1:對圖像進行y軸反轉gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
// Step2: 開啟0號紋理單元(textunit0~7) gl.activeTexture(gl.TEXTURE0);
// Step3: 綁定紋理對象(target,texture)
// target可以是:gl.TEXTURE或gl.TEXTURE_CUBE_MAP gl.bindTexture(gl.TEXTURE_2D, texture);// Step4: 設置紋理參數(target,pname,param)
// gl.TEXTURE_MAG_FILTER (紋理放大) 默認值: gl.LINEAR
// gl.TEXTURE_MIN_FILTER (紋理縮小) 默認值: gl.NEAREST_MIPMAP_LINEAR
// gl.TEXTURE_WRAP_S (紋理水平填充) 默認值: gl.REPEAT(平鋪式)
// gl.MIRRORED_REPEAT (鏡像對稱)
// gl.CLAMP_TO_EDGE (使用紋理圖像邊緣值)
// gl.TEXTURE_WRAP_T (紋理垂直填充) 默認值: gl.REPEAT
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Step5:配置紋理圖片(target,level,internalformat,format,type,image)
// level: 0
// internalformat:圖像的內部格式
// format: 紋理數據的格式,必須與internalformat一致
// type: 紋理數據的類型
// image:包含紋理的圖像的image對象gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
// Step6:將0號紋理傳遞至取樣器gl.uniform1i(u_Sampler, 0);gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); }
?
三、結尾
?????? 以上代碼均來自《WebGL編程指南》。
?