Home People Research Blog Courses Links Search Download
NCHC

Blog

Blog 最新文章

  1. Visual Studio 的遠端偵錯:Windows
    2021/03/24 14:45
  2. Visual Studio 2019 16.9 支援使用 OpenMP LLVM
    2021/03/03 13:52
  3. Valve 推出完全支援 OpenXR 的 SteamVR 1.16.8
    2021/02/25 09:43

Blog 最新回應

  1. 加入斜體文字...
    2021/02/07 21:06
  2. 加入斜體文字...
    2021/02/07 21:06
  3. 加入斜體文字...
    2021/02/07 21:06

Keyword 關鍵字

Windows MR OpenNI2 Kinect OpenCV javascript ASUS Xtion Pandas OpenGL VR HoloLens 2 OpenXR MR VR WebGL C++17 Vulkan Boost C++11 C++14 C++ Java HTC Vive Focus C++14 OpenVR Oculus Rift S CubeX NiTE2 GitLab 資料視覺化 svn 開放資料 Docker Python OpenNI Qt Oculus git Oculus Quest 2 3D立體 PHP OpenCL HTC Vive Pro C++20 CUDA 開放資料 iFlyover xml OpenMP 資訊地圖 3d print HTC Vive Docker Python Valve Index Pandas

類別:技術相關 » 技術研究
文章發表|我要回應|RSS訂閱

WebGL 範例:簡單的互動操作

基本上還是延續上一篇的立體方塊的範例繼續寫下去了∼在上一篇的例子是完成了一個會自動旋轉的立體方塊,而在這一篇則是讓使用者可以透過滑鼠和鍵盤,做簡單的操作。

在 WebGL 裡的事件觸發與控制,主要是透過 JavaScript 來做的,所以其實所要加入的程式,主要都是 JavaScript 的部分;而這個範例裡使用的方法,是當使用者觸發了特訂的事件後,再透過去修改一些內部的變數,進而影響到最後畫出來的結果。

首先先來看 diaplay() 部分的變化:

function display()
{
  // Clear the canvas
  gWGL.clear( gWGL.COLOR_BUFFER_BIT | gWGL.DEPTH_BUFFER_BIT );
  
  // Compute a model/view matrix.
  gWGL.mvpMatrix.makeIdentity();
  gWGL.mvpMatrix.rotate( gAngleY, 0, 1, 0 );
  gWGL.mvpMatrix.rotate( gAngleX, 1, 0, 0 );
  gWGL.mvpMatrix.translate( 0, 0, gZpos );
  
  // Coompute the model-view * projection matrix
  gWGL.mvpMatrix.multRight( gWGL.ProjectionMatrix );
  // pass the matrix into shader
  gWGL.uniformMatrix4fv( gWGL.u_mvpMatrixLoc, false, gWGL.mvpMatrix.getAsWebGLFloatArray() );
  
  // Draw the cube
  gWGL.drawElements( gWGL.TRIANGLES, gWGL.RenderObject.numIndices, gWGL.UNSIGNED_BYTE, 0 );
  
  // Finish up.
  gWGL.flush();
}

這邊和之前的程式主要的差異有兩部分,其中一部分就是上方黃色的區域,這部分的程式是變成透過 gAngleY、gAngleX、gZPos 三個變數來計算 model view matrix;另一部分則是將本來 diaplay() 最後面,用來計算 currentAngle、以做到自動旋轉的程式拿掉了。而也由於這兩部分的修改,所以本來的全域變數 currentAngle 和 incAngle 都用不到了∼相對的,則是要宣告 gAngleY、gAngleX、gZPos 這三個新的變數。

而在 display() 這樣修改後,之後要用來作互動的 JavaScript 程式只要去修改 gAngleY、gAngleX、gZPos 這三個變數的值,就可以做到簡單的互動了!

在這個範例,由於只是要做最簡單的互動測試,所以只會針對兩種 event 做處理,其中一個是 Canvas、也就是 WebGL 繪製區域的 mouse move 事件(onmousemove),另一個則是整個網頁的鍵盤輸入事件(onkeydown);如果有需要的話,其實也是可以再額外定義不同事件的處理函式,不過在這邊就先不提了。

而這部分的程式,主要是要在主程式 RunWebGL() 裡,加上對於事件處理的設定。

function RunWebGL()
{
  // try to get WebGL Context
  try
  {
    gCanvas = document.getElementById( "canvas_object" );
    gWGL = gCanvas.getContext( "experimental-webgl" );
  }
  catch( e )
  {
    alert( "WebGL 初始化失敗" );
    return;
  }
  
  // set event handle
  gCanvas.onmousemove = mouseMove;
  document.onkeydown = keyboardEvent;
  // setup viewport
  gWGL.viewport( 0, 0, gCanvas.width, gCanvas.height );
  ...

這部分的程式就是上方黃色的區塊,第一行是設定當滑鼠游標在 gCanvas 上移動時,就去執行 mouseMove() 這個函式;而第二行則是設定當按下鍵盤時,就去執行 keyboardEvent() 這個函式。

而 mouseMove() 所做的事實際上是根據滑鼠游標的位置,來修改 gAngleY、gAngleX 的值,進而做到立體方塊的旋轉;他的程式碼如下:

function mouseMove( ev )
{
  var w = gCanvas.width / 2, h = gCanvas.height / 2;
  gAngleY = 90 * ( ev.clientX - gCanvas.offsetLeft - w ) / w;
  gAngleX = 90 * ( ev.clientY - gCanvas.offsetTop - h ) / h;
}

這邊的程式主要是會計算出滑鼠位置(ev.clientX / ev.clientY)和 canvas 的中心點的差,然後再把他調整成 -1 ~ 1 的值,之後再乘上 90 度;所以最後所得到的 gAngleX 和 gAngleY 的值會根據滑鼠的位置,而在 -90 ~ 90 之間。

不過有一點要注意的是,由於這是比較簡單的範例,所以 canvas 本身的位置可以直接用 ( gCanvas.offsetLeft, gCanvas.offsetTop ) 來計算;但是如果網頁設計的複雜些的話,有可能會要需要做其他較複雜的處理,才能真正算出他的位置。

而 keyboardEvent() 則是用來接收鍵盤按下的事件,在這個範例裡,只有針對 Page Up 和 Page Down 兩個鈕做處理,用來做物體的拉遠、拉近控制;他的程式碼如下:

function keyboardEvent( ev )
{
  switch( ev.keyCode )
  {
  case 33: //page up
    gZPos  = 0.1;
    break;
    
  case 34: //page down
    gZPos -= 0.1;
    break;
  }
}

這部分的程式,基本上就是在按下 Page Up 時,把 gZPos 的值變大,在按下 Page Down 時,把 gZPos 的值變小了∼

而最後的網頁,則可以在這裡下載。

張貼者:heresy於2010/04/15 14:10 下午有0則回應,瀏覽次數:2,275次

-- TOP --

我要回應
* 身份  訪客 (暱稱:)
 本篇文章作者 (帳號:密碼:)
* 內容      
很高興 悲傷 震驚 疑惑 大笑 發瘋 傷心
* 留言密碼 (請輸入下方圖片中去除前、後位數的數字,共五碼。)
說明 1. * 表示必填欄位。
2. 不支援HTML Tag。
   

-- TOP --

© Visualization and Interactive Media Laboratory of NCHC, 2007 - 2021, All Rights Reserved. Contact E-mail