2013-08-27 39 views
1

我已經用C++和OpenGL完成了一些項目,現在我正在用html5和WebGL創建一個簡單的項目。攝像頭旋轉後的WebGL翻譯(作爲FPS)

問題是,在我旋轉相機之後,移動總是沿着默認軸線而不是沿着旋轉的軸線移動。例如:我向前移動 - >沒問題,我將相機向右旋轉90度 - >沒問題,現在我認爲,如果我向前走,相機就會在世界軸上向右移動(所以在相機前方,作爲FPS遊戲),但攝像機始終朝向起始z軸(開始的前軸)。奇怪的是我的代碼在OpenGL上運行良好,現在不再使用webGL。

代碼的主要部分是用JavaScript編寫的。我使用「glMatrix-0.9.5.min」庫來簡化矩陣計算。

這些是保存照相機狀態變量:

var px = 0.0, py = 2.0, pz = 10.0, ang = 0.0, elev = 0.0, roll = 0.0; 
var DELTA_ANG = 0.5, DELTA_MOVE = 0.5; 

這是在其中予計算模型視圖矩陣並將它傳遞到着色器中的一部分:

mat4.identity(mvMatrix);  
mat4.translate(mvMatrix, [-px, -py, -pz], mvMatrix); 
mat4.rotateX(mvMatrix, degToRad(elev), mvMatrix); 
mat4.rotateY(mvMatrix, degToRad(-ang), mvMatrix); 
mat4.rotateZ(mvMatrix, degToRad(roll), mvMatrix); 
gl.uniformMatrix4fv(shaderProgram.mv_matrix, false, new Float32Array(mvMatrix)); 

這是我如何處理關鍵事件(當前壓縮關鍵字是我保存最後輸入的數組):

// rotations  
if(currentlyPressedKeys[J]) 
{ 
    ang -= DELTA_ANG; 
} 
if(currentlyPressedKeys[L]) 
{ 
    ang += DELTA_ANG; 
} 
if(currentlyPressedKeys[I]) 
{ 
    elev += DELTA_ANG; 
} 
if(currentlyPressedKeys[K]) 
{ 
    elev -= DELTA_ANG; 
} 
if(currentlyPressedKeys[E]) 
{ 
    roll += DELTA_ANG; 
} 
if(currentlyPressedKeys[Q]) 
{ 
    roll -= DELTA_ANG; 
} 

// movements 
if(currentlyPressedKeys[A]) 
{ 
    px -= DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
} 
if(currentlyPressedKeys[D]) 
{ 
    px += DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
} 
if(currentlyPressedKeys[W]) 
{ 
    px += DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
} 
if(currentlyPressedKeys[S]) 
{ 
    px -= DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
}  

// height 
if(currentlyPressedKeys[R]) 
{ 
    py += DELTA_MOVE; 
} 
if(currentlyPressedKeys[F]) 
{ 
    py -= DELTA_MOVE; 
} 

最後,這是簡單的頂點着色器(透視矩陣簡單地與mat4.perspective計算):

attribute vec3 position; 
attribute vec3 normal; 
attribute vec2 uv; 

uniform mat4 p_matrix, mv_matrix;  

varying vec3 f_position; 
varying vec3 f_normal; 
varying vec2 f_uv; 

void main() { 
    gl_Position = p_matrix * mv_matrix * vec4(position, 1.0); 
    f_position = position; 
    f_normal = normal; 
    f_uv = uv; 
} 

我不明白,這可能是由OpenGL的,任何想法有什麼區別?

回答

0

我解決了,問題是我忘了計算攝像頭位置的一些組件。 這是正確的代碼:

// movements 
if(currentlyPressedKeys[A]) 
{  
    px -= DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    px -= DELTA_MOVE * Math.cos(roll * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.sin(elev * Math.PI/180.0);   
} 
if(currentlyPressedKeys[D]) 
{ 
    px += DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    px += DELTA_MOVE * Math.cos(roll * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
} 
if(currentlyPressedKeys[W]) 
{ 
    px += DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    px += DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    pz -= DELTA_MOVE * Math.cos(elev * Math.PI/180.0);   
} 
if(currentlyPressedKeys[S]) 
{ 
    px -= DELTA_MOVE * Math.sin(ang * Math.PI/180.0); 
    px -= DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    py += DELTA_MOVE * Math.sin(elev * Math.PI/180.0); 
    py -= DELTA_MOVE * Math.sin(roll * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.cos(ang * Math.PI/180.0); 
    pz += DELTA_MOVE * Math.cos(elev * Math.PI/180.0); 
}  

的謎就是它在OpenGL如何工作,但現在它是正確的。