OpenGL方向。 (以z为负的身份轮换)

时间:2012-02-25 23:01:28

标签: opengl view model matrix axis

我正在实现一个处理每个翻译/视图/模型/投影矩阵的渲染器(我不使用glRotate / glTranslate等)。

我在正z轴上放置了几个蓝色物体,在正x轴上放置了一些红色物体(所以我应该能够看到左边的红色物体和前面的蓝色物体,使用我的身份旋转相机)。这是右手方向,对吗?

问题是我必须绕y轴转180度才能看到我的物体。看起来身份轮换在-z中。

我正在构建我的View矩阵,取相机矩阵的反转[Rot Tr]然后我将它放在一个数组中,然后将它传递给我的着色器。

对于对象(世界矩阵),我只是将矩阵[Rot Tr]按列方式传递给着色器。我应该否定翻译吗?

投影矩阵现在用于构建在顶点着色器中,因为我正在努力完成。你可以在下面我正在做

position = proj*view*model*gl_Vertex;

目前我使用gl_Vertex(我在加载单位矩阵作为我的场景对象后使用了glutSolidCube)。

uniform mat4 view;
uniform mat4 model;

varying vec4 pos;

void main()
{   

pos = gl_Vertex;


float aspect = 1.0;
float fovy = 1.5;
float f = 1.0 / tan(fovy * 0.5);
float near = 1.0;
float far = 100.0;
float tt = 1.0 / (near - far);

mat4 proj = mat4(f/aspect, 0.0, 0.0, 0.0,
        0.0, f, 0.0, 0.0,
        0.0, 0.0, (near+far)*tt, -1.0,
        0.0, 0.0, 2.0*near*far*tt, 0.0);

gl_Position = proj * view * model * pos;
}

在我的片段着色器中,我设置了color = pos,这样我就能看到轴的颜色,颜色看起来是正确的。我认为对象被正确地放置在场景中但是使用Identity矩阵作为旋转我仍然看起来相反。

我可以错过什么?我是否以正确的方式传递了正确的矩阵?

3 个答案:

答案 0 :(得分:2)

右手坐标系始终向下看-Z轴。如果+ X向右移动,+ Y向上移动(这是所有 OpenGL的工作方式),并且视图与Z轴对齐,那么+ Z必须朝观众。如果视图向下看+ Z轴,那么空间将是左撇子。

答案 1 :(得分:0)

  

问题是我必须绕y轴转180度才能看到我的物体。看起来身份轮换在-z。

是的。为glOrtho和glFrustum提供的形式为OpenGL的坐标系是右手(右手拿拇指,拇指向右,食指向上,然后食指指向你)。如果你按照那些建模你的矩阵计算,那么你也会得到一个右手系统。

答案 2 :(得分:0)

好吧,昨晚彻底重写了这篇文章,如果你还没有提出自己的解决方案或其他提出类似问题的人,我希望你发现它很有用。

默认情况下,前向矢量向下看-Z,右向量向下看+ X,向上向量向下看+ Y.

当你决定构建自己的世界时,如果你拥有一个128x128的X,Z世界并且你在64x64的中间位置,那么你看起来并不重要,任何玩家如何知道他们被旋转0度或180度。他们根本不会。

现在你提到你不喜欢glRotatef和glTranslatef。我也不会使用处理向量和矩阵数学的方法。首先,我使用一种方法来跟踪向前,向上和向右矢量。因此,想象一下你自己在一个圆圈中转动,这是你旋转你的前向矢量。因此,当一名球员想让我们说直线跑。你将沿着前向矢量的X,Z移动它们,但是我们说它们也想要向右移动。那么你仍然会沿着前向矢量移动它们,但是想象从前向矢量取下90度。因此,如果我们面向45度,我们指向-Z和-X象限。因此,扫射将使我们进入-Z和+ X象限。要做到这一点,你可以简单地否定罪的价值。以下两者的例子,但这可以不同地做,下面是粗略的例子,以更好地解释上述内容。

Position.X -= Forward.X; //Run Forward.
Position.Z -= Forward.Z;

Position.X += Forward.Z; //Run Backwards.
Position.Z += Forward.Z 

Position.X += Forward.X; //Strafe Right.
Position.Z -= Forward.Z;

Position.X -= Forward.X; //Strafe Left.
Position.Z += Forward.Z;

下面是我初始化视图矩阵的方法。这些只是执行一次,不要把它放在任何循环代码中。

glMatrixMode(GL_MODELVIEW);

view_matrix[4] =  0.0f; //UNUSED.

view_matrix[3] =  0.0F; //UNUSED. 
view_matrix[7] =  0.0F; //UNUSED. 
view_matrix[11] = 0.0F; //UNUSED. 
view_matrix[15] = 1.0F; //UNUSED.

update_view();
glLoadMatrix(view_matrix);

然后这是update_view()方法。这只是在视图矩阵更改期间调用。

public void update_view()
{
    view_matrix[0] =  Forward[0];
    view_matrix[1] =  Up[1] *  Forward[1];
    view_matrix[2] =  Up[0] * -Forward[1];

    view_matrix[5] =  Up[0];
    view_matrix[6] =  Up[1];

    view_matrix[8] =  Forward[1];
    view_matrix[9] =  Up[1] * -Forward[0];
    view_matrix[10] = Up[0] *  Forward[0];
}

位置向量是matricies [12],[13]和[14]并且被否定。您可以选择存储这些,或者只使用矩阵[12],[13],[14]作为位置矢量。

view_matrix[12] =  -Position.x;
view_matrix[13] =  -Position.y;
view_matrix[14] =  -Position.z;