中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

凡科互動游戲怎么修改程序seo招聘網(wǎng)

凡科互動游戲怎么修改程序,seo招聘網(wǎng),網(wǎng)站備案 網(wǎng)站建設(shè)方案書需要寫嗎,廈門做網(wǎng)站哪家強目錄 鼠標(biāo)控制物體旋轉(zhuǎn) 如何實現(xiàn)物體旋轉(zhuǎn) 示例程序(RotateObject.js) 代碼詳解 示例效果 鼠標(biāo)控制物體旋轉(zhuǎn) 有時候,WebGL程序需要讓用戶通過鼠標(biāo)操作三維物體。這一節(jié)來分析示例程序RotateObject,該程序允許用戶通過拖動&…

目錄

鼠標(biāo)控制物體旋轉(zhuǎn)?

如何實現(xiàn)物體旋轉(zhuǎn)

示例程序(RotateObject.js)

代碼詳解

示例效果


鼠標(biāo)控制物體旋轉(zhuǎn)?

有時候,WebGL程序需要讓用戶通過鼠標(biāo)操作三維物體。這一節(jié)來分析示例程序RotateObject,該程序允許用戶通過拖動(即按住左鍵移動)鼠標(biāo)旋轉(zhuǎn)三維物體。為了簡單,示例程序中的三維物體是一個立方體,但拖曳鼠標(biāo)旋轉(zhuǎn)物體的方法卻適用于所有物體。下圖顯示了程序的運行效果,立方體上貼有紋理圖像。

如何實現(xiàn)物體旋轉(zhuǎn)

我們已經(jīng)知道如何旋轉(zhuǎn)二維圖形或三維物體了:就是使用模型視圖投影矩陣來變換頂點的坐標(biāo)?,F(xiàn)在需要使用鼠標(biāo)來控制物體旋轉(zhuǎn),就需要根據(jù)鼠標(biāo)的移動情況創(chuàng)建旋轉(zhuǎn)矩陣,更新模型視圖投影矩陣,并對物體的頂點坐標(biāo)進(jìn)行變換。?

我們可以這樣來實現(xiàn):在鼠標(biāo)左鍵按下時記錄鼠標(biāo)的初始坐標(biāo),然后在鼠標(biāo)移動的時候用當(dāng)前坐標(biāo)減去初始坐標(biāo),獲得鼠標(biāo)的位移,然后根據(jù)這個位移來計算旋轉(zhuǎn)矩陣。顯然,我們需要監(jiān)聽鼠標(biāo)的移動事件,并在事件響應(yīng)函數(shù)中計算鼠標(biāo)的位移、旋轉(zhuǎn)矩陣,從而旋轉(zhuǎn)立方體。下面看一下示例程序。

示例程序(RotateObject.js)

如下顯示了示例程序的代碼,如你所見,著色器部分沒什么特別的。頂點著色器使用模型視圖投影矩陣變換頂點坐標(biāo)(第7行),并向片元著色器傳入紋理坐標(biāo)以映射紋理(第8行)。

var VSHADER_SOURCE ='attribute vec4 a_Position;\n' +'attribute vec2 a_TexCoord;\n' +'uniform mat4 u_MvpMatrix;\n' +'varying vec2 v_TexCoord;\n' +'void main() {\n' +'  gl_Position = u_MvpMatrix * a_Position;\n' +'  v_TexCoord = a_TexCoord;\n' +'}\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' +'  gl_FragColor = texture2D(u_Sampler, v_TexCoord);\n' +'}\n';function main() {var canvas = document.getElementById('webgl');var gl = getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n = initVertexBuffers(gl);gl.clearColor(0.0, 0.0, 0.0, 1.0);gl.enable(gl.DEPTH_TEST);var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');var viewProjMatrix = new Matrix4();viewProjMatrix.setPerspective(30.0, canvas.width / canvas.height, 1.0, 100.0);viewProjMatrix.lookAt(3.0, 3.0, 7.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);// 注冊事件處理函數(shù)var currentAngle = [0.0, 0.0]; // 繞z軸旋轉(zhuǎn)角度,繞y軸旋轉(zhuǎn)角度initEventHandlers(canvas, currentAngle);if (!initTextures(gl)) return  // 設(shè)置紋理var tick = function() {   // Start drawingdraw(gl, n, viewProjMatrix, u_MvpMatrix, currentAngle);requestAnimationFrame(tick, canvas);};tick();
}function initVertexBuffers(gl) {//    v6----- v5//   /|      /|//  v1------v0|//  | |     | |//  | |v7---|-|v4//  |/      |///  v2------v3var vertices = new Float32Array([   // Vertex coordinates1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,    // v0-v1-v2-v3 front1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,    // v0-v3-v4-v5 right1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,    // v0-v5-v6-v1 up-1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,    // v1-v6-v7-v2 left-1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,    // v7-v4-v3-v2 down1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0     // v4-v7-v6-v5 back]);var texCoords = new Float32Array([   // Texture coordinates1.0, 1.0,   0.0, 1.0,   0.0, 0.0,   1.0, 0.0,    // v0-v1-v2-v3 front0.0, 1.0,   0.0, 0.0,   1.0, 0.0,   1.0, 1.0,    // v0-v3-v4-v5 right1.0, 0.0,   1.0, 1.0,   0.0, 1.0,   0.0, 0.0,    // v0-v5-v6-v1 up1.0, 1.0,   0.0, 1.0,   0.0, 0.0,   1.0, 0.0,    // v1-v6-v7-v2 left0.0, 0.0,   1.0, 0.0,   1.0, 1.0,   0.0, 1.0,    // v7-v4-v3-v2 down0.0, 0.0,   1.0, 0.0,   1.0, 1.0,   0.0, 1.0     // v4-v7-v6-v5 back]);// Indices of the verticesvar indices = new Uint8Array([0, 1, 2,   0, 2, 3,    // front4, 5, 6,   4, 6, 7,    // right8, 9,10,   8,10,11,    // up12,13,14,  12,14,15,    // left16,17,18,  16,18,19,    // down20,21,22,  20,22,23     // back]);var indexBuffer = gl.createBuffer();if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position')) return -1; // Vertex coordinatesif (!initArrayBuffer(gl, texCoords, 2, gl.FLOAT, 'a_TexCoord')) return -1;// Texture coordinatesgl.bindBuffer(gl.ARRAY_BUFFER, null);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);return indices.length;
}function initEventHandlers(canvas, currentAngle) {var dragging = false;         // 是否在拖動var lastX = -1, lastY = -1;   // 鼠標(biāo)的開始位置canvas.onmousedown = function(ev) {   // Mouse is pressedvar x = ev.clientX, y = ev.clientY;// 如果鼠標(biāo)在canvas內(nèi)就開始拖動var rect = ev.target.getBoundingClientRect();if (rect.left <= x && x < rect.right && rect.top <= y && y < rect.bottom) {lastX = x; lastY = y;dragging = true;}};canvas.onmouseup = function(ev) { dragging = false;  }; // Mouse is releasedcanvas.onmousemove = function(ev) { // Mouse is movedvar x = ev.clientX, y = ev.clientY;if (dragging) {var factor = 100/canvas.height; // The rotation ratiovar dx = factor * (x - lastX);var dy = factor * (y - lastY);// 將x軸旋轉(zhuǎn)角度限制為-90到90度currentAngle[0] = Math.max(Math.min(currentAngle[0] + dy, 90.0), -90.0);currentAngle[1] = currentAngle[1] + dx; // 拿y軸舉例,鼠標(biāo)水平移動,物體會以Y軸旋轉(zhuǎn),所以水平的移動距離直接影響y軸要轉(zhuǎn)動角度}lastX = x, lastY = y;};
}var g_MvpMatrix = new Matrix4(); // 模型視圖投影矩陣
function draw(gl, n, viewProjMatrix, u_MvpMatrix, currentAngle) {// 計算模型視圖投影矩陣并將其傳遞給u_MvpMatrixg_MvpMatrix.set(viewProjMatrix);g_MvpMatrix.rotate(currentAngle[0], 1.0, 0.0, 0.0); // 繞x軸旋轉(zhuǎn)g_MvpMatrix.rotate(currentAngle[1], 0.0, 1.0, 0.0); // 繞y軸旋轉(zhuǎn)gl.uniformMatrix4fv(u_MvpMatrix, false, g_MvpMatrix.elements);gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);     // 清除顏色|深度緩沖gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);   // 畫畫
}function initArrayBuffer(gl, data, num, type, attribute) {var buffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, buffer);gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);var a_attribute = gl.getAttribLocation(gl.program, attribute);gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);gl.enableVertexAttribArray(a_attribute);return true;
}function initTextures(gl) {var texture = gl.createTexture(); // 創(chuàng)建溫麗麗對象var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler'); // 獲取uSampler的存儲位置(_S)var image = new Image();image.onload = function(){ loadTexture(gl, texture, u_Sampler, image); };image.src = '../resources/sky.jpg';return true;
}function loadTexture(gl, texture, u_Sampler, image) {gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);  // 翻轉(zhuǎn)圖像Y坐標(biāo)// 激活紋理單元0gl.activeTexture(gl.TEXTURE0);// 將紋理對象綁定到2維目標(biāo)(先綁定到紋理單元)gl.bindTexture(gl.TEXTURE_2D, texture);// 設(shè)置紋理參數(shù)gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);// 將圖像設(shè)置為紋理,設(shè)置圖像參數(shù)gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);// 將紋理單元0傳遞到uSamplergl.uniform1i(u_Sampler, 0);
}

代碼詳解

首先,main()函數(shù)計算出了初始的模型視圖投影矩陣(第29~31行)。程序?qū)⒏鶕?jù)鼠標(biāo)位移來實時更新該矩陣。?

然后,鼠標(biāo)移動事件響應(yīng)函數(shù)實現(xiàn)了用鼠標(biāo)旋轉(zhuǎn)三維物體的邏輯。currentAngle變量表示當(dāng)前的旋轉(zhuǎn)角度,它是一個數(shù)組,因為物體的旋轉(zhuǎn)需要被分解為繞x軸旋轉(zhuǎn)和繞y軸旋轉(zhuǎn)兩步,因此需要兩個角度值(第34行)。真正注冊事件響應(yīng)函數(shù)的過程發(fā)生在initEventHandlers()函數(shù)中(第35行)。真正繪制的過程發(fā)生在tick()函數(shù)中(第37行)。

initEventHandler()函數(shù)的任務(wù)是注冊鼠標(biāo)響應(yīng)事件函數(shù)(第87行),包括:鼠標(biāo)左鍵按下事件(第91行)、鼠標(biāo)左鍵松開事件(第101行),以及鼠標(biāo)移動事件(第103行)。

當(dāng)鼠標(biāo)左鍵被按下時,首先檢查鼠標(biāo)是否在<canvas>元素內(nèi)部(第95行),如果是,就將鼠標(biāo)左鍵按下時的位置坐標(biāo)保存到lastX和lastY變量中(第96行),并將dragging變量賦值為true,表示拖曳操作(即按住鼠標(biāo)左鍵移動)開始了。

鼠標(biāo)左鍵被松開時,表示拖曳操作結(jié)束了,將dragging變量賦值為false(第101行)。

鼠標(biāo)移動事件響應(yīng)函數(shù)最為重要(第103行):首先檢查dragging變量,判斷當(dāng)前是否處于拖動狀態(tài)。如果不在拖曳狀態(tài),說明是鼠標(biāo)的正常移動(左鍵松開狀態(tài)下的移動),那就什么都不做。如果處于拖曳狀態(tài),就計算出當(dāng)前鼠標(biāo)(相對于上次鼠標(biāo)移動事件觸發(fā)時)的移動距離,即位移值,并將結(jié)果保存在dx和dy變量中(第107~108行)。注意,位移值在存入變量前按比例縮小了,這樣dx和dy的值就與<canvas>自身的大小無關(guān)了。有了鼠標(biāo)當(dāng)前的位移dx和dy,就可以根據(jù)這兩個值計算出當(dāng)前三維物體(相對于上次鼠標(biāo)移動事件觸發(fā)時)在x軸和y軸上的旋轉(zhuǎn)角度值(第110和111行)。而且,程序還將物體在y軸上的旋轉(zhuǎn)角度限制在正負(fù)90度之間,這樣做的原因僅僅是為了展示技巧,你也可以將其刪掉。最后,把當(dāng)前鼠標(biāo)的位置坐標(biāo)賦值給lastX和lastY。

一旦成功地將鼠標(biāo)的移動轉(zhuǎn)化為旋轉(zhuǎn)矩陣,我們就可以用旋轉(zhuǎn)矩陣更新物體的狀態(tài)(第121~122行)。當(dāng)程序再次調(diào)用tick()函數(shù)進(jìn)行繪制時,就繪制出了旋轉(zhuǎn)后的物體。

示例效果

http://www.risenshineclean.com/news/60649.html

相關(guān)文章:

  • 什么網(wǎng)站可以做英語題銀徽seo
  • 四川建設(shè)廳網(wǎng)站排名sem優(yōu)化軟件
  • 水稻網(wǎng)站做go分析網(wǎng)絡(luò)營銷有本科嗎
  • jquery特效網(wǎng)站百度推廣后臺登錄首頁
  • 最好的網(wǎng)站建設(shè)用途上海seo推廣服務(wù)
  • 做自己的網(wǎng)站推廣普通話手抄報模板可打印
  • 濰坊網(wǎng)站建設(shè) 濰坊做網(wǎng)站廣東佛山疫情最新情況
  • 深圳市網(wǎng)站建設(shè)公司深圳百度快速排名提升
  • 香港網(wǎng)站建設(shè)展覽營銷策劃書
  • 做網(wǎng)站需要什么材料網(wǎng)站制作費用多少
  • 時時彩平臺網(wǎng)站怎么做怎么讓某個關(guān)鍵詞排名上去
  • 可以直接玩游戲的網(wǎng)站韓國網(wǎng)站
  • 東營網(wǎng)站制作公司杭州網(wǎng)站
  • 簡單網(wǎng)站建設(shè)模板下載百度關(guān)鍵詞怎么做排名
  • 河南疫情防控最新政策今日頭條新聞搜狗關(guān)鍵詞優(yōu)化軟件
  • 網(wǎng)站的困難app拉新推廣代理平臺
  • 凱天建設(shè)發(fā)展集團(tuán)有限公司網(wǎng)站盤多多網(wǎng)盤資源庫
  • 品牌網(wǎng)站開發(fā)動態(tài)模塊廣州專業(yè)seo公司
  • 工程公司是做什么的谷歌seo排名技巧
  • 推廣網(wǎng)站掙錢windows優(yōu)化大師手機版
  • 臺州響應(yīng)式建站seo外鏈建設(shè)方法
  • 網(wǎng)站列表頁怎么做內(nèi)鏈搜索引擎排行榜
  • 網(wǎng)站之間的差異seo技術(shù)是干什么的
  • 設(shè)計logo怎么收費泰安seo培訓(xùn)
  • 公司網(wǎng)站設(shè)計案例發(fā)外鏈軟件
  • 有什么做門窗展廳的設(shè)計網(wǎng)站百度收錄權(quán)重
  • 領(lǐng)手工在家做的網(wǎng)站2019廣告推廣的軟件
  • 購卡網(wǎng)頁怎么制作關(guān)鍵詞優(yōu)化軟件
  • 靜態(tài)做網(wǎng)站百度推廣官方網(wǎng)站登錄入口
  • 社交網(wǎng)站百度搜索推廣費用