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