1

私はすでに c++ と OpenGL でいくつかのプロジェクトを行っていますが、今は html5 と WebGL で簡単なプロジェクトを作成しています。

問題は、カメラを回転させた後、動きが常にデフォルトの軸に沿っており、回転した軸に沿っていないことです。例: 前に進む -> 問題ありません。カメラを右に 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));

そして、これは私がキーイベントを処理する方法です (currentlyPressedKeys は最後の入力を保存する配列です):

// 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 と何が違うのか理解できません。

4

1 に答える 1

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 でどのように機能したかですが、今では正しいです。

于 2013-08-27T13:46:14.513 に答える