最近我實現了一個簡單的Opengl程序組成的對象場景,我已經應用了大部分變換&投影矩陣,在這樣的情況下,我能夠rotate transform & scale objects, move my camera through z & x coordinates and applied perspective projection
然而,當涉及到相機旋轉的東西變得很奇怪,我的相機的旋轉矩陣只是一個旋轉矩陣,它可以使世界一致地旋轉,但是當我旋轉這個世界時,我會向上看; +y
;當我向前移動時,相機看起來並沒有朝着它所看的方向前進; as it is the case in FPS games
我的相機移動相對於世界空間,我知道,我很想念在x,y,z
座標指定的方向向量,但我無法將這些向量與我的相機(視圖變換)矩陣,大部分教程互聯網上任何描述它在一個框圖或使用傳統的gluLookAt()函數,我真的需要一個關於視圖轉換,特別是相機旋轉的簡要說明,以及我應該如何在我的矩陣中實現它,我的最終矩陣如下:Opengl視圖變換矩陣旋轉
resultTransform = perspectiveTrans * cameraTrans * modelTrans;
其中:
perspectiveTrans =僅施加透視投影變換
cameraTrans =是旋轉的組合,翻譯影響所有obj.s場景中的矩陣
modelTrans =是施加到模型轉換
Matrix4X4.cpp文件:
#include "Matrix4X4.h"
using namespace std;
////////////////////////////////// Constructor Declerations ////////////////////////////////
Matrix4X4::Matrix4X4()
{
setIdentity();
}
Matrix4X4::Matrix4X4(float value)
{
for(int i = 0 ; i < 4; i++)
for (int j = 0; j < 4; j++)
Matrix[i][j] = value;
}
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Destructor Decleration //////////////////////////////
Matrix4X4::~Matrix4X4()
{
}
///////////////////////////////////////////////////////////////////////////////////
/////////////////////// Set Identity Matrix /////////////////////////////////////////
void Matrix4X4::setIdentity()
{
Matrix[0][0] =1; Matrix[0][1] = 0; Matrix[0][2] = 0; Matrix[0][3] = 0;
Matrix[1][0] =0; Matrix[1][1] = 1; Matrix[1][2] = 0; Matrix[1][3] = 0;
Matrix[2][0] =0; Matrix[2][1] = 0; Matrix[2][2] = 1; Matrix[2][3] = 0;
Matrix[3][0] =0; Matrix[3][1] = 0; Matrix[3][2] = 0; Matrix[3][3] = 1;
}
///////////////////////////////////////////////////////////////////////////////////
///////////////////////// Set Translation Matrix //////////////////////////////////
Matrix4X4 Matrix4X4::setTranslation(float x,float y,float z)
{
Matrix[0][0] =1; Matrix[0][1] = 0; Matrix[0][2] = 0; Matrix[0][3] = x;
Matrix[1][0] =0; Matrix[1][1] = 1; Matrix[1][2] = 0; Matrix[1][3] = y;
Matrix[2][0] =0; Matrix[2][1] = 0; Matrix[2][2] = 1; Matrix[2][3] = z;
Matrix[3][0] =0; Matrix[3][1] = 0; Matrix[3][2] = 0; Matrix[3][3] = 1;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// Set Rotation Matrix ///////////////////////////////////////////
Matrix4X4 Matrix4X4::setRotation(float x,float y,float z)
{
Matrix4X4 xRot;
Matrix4X4 yRot;
Matrix4X4 zRot;
x = (float)x * 3.14/ 180.0;
y = (float)y * 3.14/ 180.0;
z = (float)z * 3.14/ 180.0;
xRot.Matrix[0][0] =1; xRot.Matrix[0][1] = 0; xRot.Matrix[0][2] = 0; xRot.Matrix[0][3] = 0;
xRot.Matrix[1][0] =0; xRot.Matrix[1][1] = cosf(x); xRot.Matrix[1][2] = -sinf(x); xRot.Matrix[1][3] = 0;
xRot.Matrix[2][0] =0; xRot.Matrix[2][1] = sinf(x); xRot.Matrix[2][2] = cosf(x); xRot.Matrix[2][3] = 0;
xRot.Matrix[3][0] =0; xRot.Matrix[3][1] = 0; xRot.Matrix[3][2] = 0; xRot.Matrix[3][3] = 1;
yRot.Matrix[0][0] = cosf(y); yRot.Matrix[0][1] = 0; yRot.Matrix[0][2] = -sinf(y); yRot.Matrix[0][3] = 0;
yRot.Matrix[1][0] =0; yRot.Matrix[1][1] = 1; yRot.Matrix[1][2] = 0; yRot.Matrix[1][3] = 0;
yRot.Matrix[2][0] = sinf(y); yRot.Matrix[2][1] = 0; yRot.Matrix[2][2] = cosf(y); yRot.Matrix[2][3] = 0;
yRot.Matrix[3][0] =0; yRot.Matrix[3][1] = 0; yRot.Matrix[3][2] = 0; yRot.Matrix[3][3] = 1;
zRot.Matrix[0][0] = cosf(z); zRot.Matrix[0][1] = -sinf(z); zRot.Matrix[0][2] = 0; zRot.Matrix[0][3] = 0;
zRot.Matrix[1][0] = sinf(z); zRot.Matrix[1][1] = cosf(z); zRot.Matrix[1][2] = 0; zRot.Matrix[1][3] = 0;
zRot.Matrix[2][0] =0; zRot.Matrix[2][1] = 0; zRot.Matrix[2][2] = 1; zRot.Matrix[2][3] = 0;
zRot.Matrix[3][0] =0; zRot.Matrix[3][1] = 0; zRot.Matrix[3][2] = 0; zRot.Matrix[3][3] = 1;
return (zRot * yRot * xRot) ;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////// Set Scale Matrix //////////////////////////////////////////
Matrix4X4 Matrix4X4::setScale(float x,float y,float z)
{
Matrix[0][0] =x; Matrix[0][1] = 0; Matrix[0][2] = 0; Matrix[0][3] = 0;
Matrix[1][0] =0; Matrix[1][1] = y; Matrix[1][2] = 0; Matrix[1][3] = 0;
Matrix[2][0] =0; Matrix[2][1] = 0; Matrix[2][2] = z; Matrix[2][3] = 0;
Matrix[3][0] =0; Matrix[3][1] = 0; Matrix[3][2] = 0; Matrix[3][3] = 1;
return *this;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Set Perspective Projection ///////////////////////////////////////
void Matrix4X4::setPerspective(float fov,float aRatio,float zNear,float zFar)
{
fov = (fov/2) * 3.14/180.0;
float tanHalfFOV = tanf(fov);
float zRange = zNear - zFar;
Matrix[0][0] =1.0f/(tanHalfFOV * aRatio); Matrix[0][1] = 0; Matrix[0][2] = 0; Matrix[0][3] = 0;
Matrix[1][0] =0; Matrix[1][1] = 1.0f/tanHalfFOV; Matrix[1][2] = 0; Matrix[1][3] = 0;
Matrix[2][0] =0; Matrix[2][1] = 0; Matrix[2][2] = (-zNear - zFar)/ zRange; Matrix[2][3] = 2* zFar * zNear/zRange;
Matrix[3][0] =0; Matrix[3][1] = 0; Matrix[3][2] = 1; Matrix[3][3] = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// Getters & Setters ////////////////////////////////////////////
float * Matrix4X4::getMat()
{
return (float *) Matrix;
}
float Matrix4X4::getMember(int x, int y) const
{
return Matrix[x][y];
}
void Matrix4X4::setMat(int row,int col,float value)
{
Matrix[row][col] = value;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////// (*) Operator Overload //////////////////////////////////////
Matrix4X4 operator * (const Matrix4X4 & lhs,const Matrix4X4 & rhs)
{
Matrix4X4 result;
for(int i = 0 ; i < 4; i++)
for (int j = 0; j < 4; j++)
result.setMat(i, j, lhs.getMember(i,0) * rhs.getMember(0, j) +
lhs.getMember(i,1) * rhs.getMember(1, j) +
lhs.getMember(i,2) * rhs.getMember(2, j) +
lhs.getMember(i,3) * rhs.getMember(3, j));
return result;
}
//////////////////////////////////////////////////////////////////////////////////////////////////
轉換代碼我在主塊使用:
SDL_PumpEvents();
for (int x = 0; x< 256; x++)
{
if (state[x] == 1)
{
if(x == 26)
tranForward -= 0.001;
if (x == 22)
tranForward += 0.001;
if (x == 4)
tranRight += 0.0009;
if (x == 7)
tranRight -= 0.0009;
if (x == 82)
lookUp += 0.02;
if (x == 81)
lookUp -= 0.02;
if (x == 80)
lookRight -= 0.02;
if (x == 79)
lookRight += 0.02;
}
}
modelTrans = Translation.setTranslation(0, 0, 5) * Scale.setScale(0.5, 0.5, 0.5);
camTrans = Rotation.setRotation(lookUp, lookRight, 0) * Translation.setTranslation(tranRight, 0, tranForward);
Projection.setPerspective(70, win.getWidth()/win.getHeight(), 0.1, 1000);
result = Projection * camTrans * modelTrans;
glUniformMatrix4fv(uniformloc, 1, GL_TRUE, result.getMat());
沒有看到特定的代碼,我最好的猜測是你的相機旋轉和翻譯是以錯誤的順序發生。做一個旋轉和一個翻譯與翻譯和旋轉的效果並不相同。 – user3256930
@ user3256930我添加了我的矩陣類和轉換乘法代碼,我使用了帶有運算符重載的自定義矩陣類。 – BulBul