1

I've already done some projects with c++ and OpenGL, now I'm creating a simple project with html5 and WebGL.

The problem is, after I rotate the camera, the movement is always along the default axes and not along the rotated ones. For example: I move forward -> no problem, I rotate the camera by 90 degrees right -> no problem, now I aspect that, if I go forward, the camera goes right on the world axes (so in front of the camera, as an FPS game) but the camera goes always towards the starting z axis (the starting forward axis). The weird thing is that my code worked well with OpenGL and now works no more with webGL.

The main part of the code is written in JavaScript. I use the "glMatrix-0.9.5.min" library to simplify matrix calculation.

These are the variables to save the camera state:

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;

This is the part in which I calculate the model view matrix and pass it to the shader:

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));

And this is how I handle the key events (currentlyPressedKeys is an array in which I save the last input):

// 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;
}   

Finally, this is the simple vertex shader (the perspective matrix was simply calculated with the 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;
}

I can't understand what could be the difference from OpenGL, any idea?

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 回答