我正在实现一个处理每个翻译/视图/模型/投影矩阵的渲染器(我不使用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矩阵作为旋转我仍然看起来相反。
我可以错过什么?我是否以正确的方式传递了正确的矩阵?
答案 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;