2

我想在 OpenGL 中构建适当的相机转换,我有一个问题。

我构建了一个没有 OpenGL 的简单 3D 引擎,只是为了看看将世界简单地投影到屏幕上是多么困难。

在这个引擎中,我将 wiewer 放在 (0,0,0) 上,并将视线放在 (1,0,0) 上。ASDW 进行对象的翻译。鼠标围绕 (1,0,0),(0,1,0),(0,0,1) 旋转。

通过编写自己的 3D 引擎,我学到了很多东西。有了这些知识,我开始构建一个合适的基于 OpenGL 的 3D 引擎。

对于OpenGL中的相机转换,我制作了这段代码......

相机的轴定义了向上、向右、向前平移的位置。围绕全局轴进行旋转(我想围绕相机的轴旋转对象):(

glRotatef(camera_rot[0],1,0,0)
glRotatef(camera_rot[1],0,1,0)
glRotatef(camera_rot[2],0,0,1)

camera_rot[0]=0
camera_rot[1]=0
camera_rot[2]=0

glGetFloatv(GL_MODELVIEW_MATRIX, matrix)

glTranslatef(
matrix[0]*camera_tra[0],
matrix[4]*camera_tra[0],
matrix[8]*camera_tra[0])

glTranslatef(
matrix[1]*camera_tra[1],
matrix[5]*camera_tra[1],
matrix[9]*camera_tra[1])

glTranslatef(
matrix[2]*camera_tra[2],
matrix[6]*camera_tra[2],
matrix[10]*camera_tra[2])

camera_tra[0]=0
camera_tra[1]=0
camera_tra[2]=0

为什么 OpenGL 设计者没有将相机放在 (0,0,0) 中并在对象而不是相机上进行平移和旋转,这有点令人困惑。

我正在考虑在不使用 glTranslate 或 glRotation 的情况下手动应用转换,并将转换逻辑从我的 3D 引擎(我制作的)放入更改 glVertexe 坐标。所以每次在绘制函数中我都会改变 glVertexes 坐标。但是,如果我这样做,顶点将在我的转换后与相同的矩阵(ModelView 矩阵)相乘,并且我不希望在我的程序中进行无意义的计算。

那么我应该怎么做才能解决这个问题呢?如何为围绕相机轴的旋转制定最佳解决方案?

4

2 回答 2

2

YEEEEEES 我为本地相机轴制作了 YAW、ROLL、PITCH 旋转和平移:D

Down 是我负责转换的代码部分。

这是我的全局常量:

float camera_drot[3]={0,0,0};
float camera_dtra[3]={0,0,0};
float camera_place[3]={0,0,10};
float camera_right[3]={1,0,0};
float camera_up[3]={0,1,0};
float camera_forvard[3]={0,0,-1};

在我绘制对象之前:

if(camera_drot[0]!=0){    //ROTATE CAMERA_UP AND CAMERA_FORVARD AROUND CAMERA_RIGHT
    MYRotation(camera_right,camera_up,camera_drot[0]);
    MYRotation(camera_right,camera_forvard,camera_drot[0]);
    camera_drot[0]=0;}
if(camera_drot[1]!=0){    //ROTATE CAMERA_RIGHT AND CAMERA_FORVARD AROUND CAMERA_UP
    MYRotation(camera_up,camera_right,camera_drot[1]);
    MYRotation(camera_up,camera_forvard,camera_drot[1]);
    camera_drot[1]=0;}
if(camera_drot[2]!=0){    //ROTATE CAMERA_RIGHT AND CAMERA_UP AROUND CAMERA_FORWARD
    MYRotation(camera_forvard,camera_right,camera_drot[2]);
    MYRotation(camera_forvard,camera_up,camera_drot[2]);
    camera_drot[2]=0;}

if(camera_dtra[0]!=0){MYTranslation(camera_right,camera_dtra[0]);camera_dtra[0]=0;}
if(camera_dtra[1]!=0){MYTranslation(camera_up,camera_dtra[1]);camera_dtra[1]=0;}
if(camera_dtra[2]!=0){MYTranslation(camera_forvard,camera_dtra[2]);camera_dtra[2]=0;}

glLoadIdentity();
gluLookAt(
camera_place[0],camera_place[1],camera_place[2],
camera_place[0]+camera_forvard[0],camera_place[1]+camera_forvard[1],camera_place[2]+camera_forvard[2],
camera_up[0],camera_up[1],camera_up[2]);
}

这是我的函数 MYRotation 和 MYTranslation :)

static void MYRotation(float vector[3],float point[3],float fi){
    //ROTATE POINT AROUND VECTOR
    float i = point[0]; 
    float j = point[1];
    float k = point[2];
    float x = vector[0];
    float y = vector[1];
    float z = vector[2];

    point[0] = i*(x*x + (y*y + z*z)*cos(fi)) + k*(-x*z*(-1 + cos(fi)) + y*sin(fi)) + j*(-x*y*(-1 + cos(fi)) - z*sin(fi));
    point[1] = j*(y*y + (x*x + z*z)*cos(fi)) + k*(-y*z*(-1 + cos(fi)) - x*sin(fi)) + i*(-x*y*(-1 + cos(fi)) + z*sin(fi)); 
    point[2] = k*(z*z + (x*x + y*y)*cos(fi)) + j*(-y*z*(-1 + cos(fi)) + x*sin(fi)) + i*(-    x*z*(-1 + cos(fi)) - y*sin(fi));

    float normalize = pow(pow(point[0],2)+pow(point[1],2)+pow(point[2],2),-0.5);
    point[0]=point[0]*normalize;
    point[1]=point[1]*normalize;
    point[2]=point[2]*normalize;    
}
static void MYTranslation(float camera_axe[3],float camera_dtra){
    camera_place[0]+=camera_axe[0]*camera_dtra;
    camera_place[1]+=camera_axe[1]*camera_dtra;
    camera_place[2]+=camera_axe[2]*camera_dtra;}
于 2013-09-12T15:18:03.820 回答
1

哦,我忘记在 MYRotation 中进行标准化之前进行矢量校正。在程序中,计算错误不会给出正交向量。进行此更正至关重要!

完成后我会发布代码:)

于 2013-09-13T20:17:53.517 回答