我正在编写一个3D OpenGL应用程序,我的顶点平移矩阵存在问题。
这是我的顶点着色器:
attribute vec4 vInPos;
uniform mat4 kWorld;
uniform mat4 kProj;
void main( void )
{
vec4 world_pos = kWorld * vInPos;
gl_Position = kProj * world_pos;
}
我的所有矩阵都存储在行专业中,我使用左手透视矩阵作为我的投影矩阵。
问题是,当我通过矩阵平移顶点时,它在X轴和Y轴上以错误的方向移动,并被翻转。因此,按(100.0f,100.0f,100.0f)
进行翻译会使我的顶点在Z轴(远离相机)上以正确方式移动,但在X轴(向后)上向左移动,向下移动到Y轴(向后)。
以下是目前的情况:
FPS计数器应向上和向右,而不是向左。它显然也不应该被反映出来。基于我所读到的,这是发生的,因为OpenGL默认使用右手坐标系,但我不知道我能做些什么来解决这个问题。
我发现了一些试图解释它的文章,但我找不到任何解决方法。 This question提到OpenGL规范显示了坐标系的预期,但看了之后,我没有看到它对我有何帮助。
编辑: 作为参考,我的投影矩阵代码基于DirectX SDK。
编辑: 按照Nicol Bolas的建议,我现在正在使用gluPerspective中的矩阵,但我得到了相同的结果。
这是我用来设置矩阵的代码:
/* Vertex data for reference
float vertices[] =
{
{0.0f,0.0f,0.0f},
{5.0f,0.0f,0.0f},
{0.0f,5.0f,0.0f},
{5.0f,5.0f,0.0f},
}; */
float worldf[16];
float projf[16];
float fov = 60.0f;
float aspect = 1280.0f/720.0f;
float near = 1.0f;
float far = 1000.0f;
float f = 1.0f/tanf( (fov*6.2831f/360.0f)/2.0f );
/* Build world matrix */
memset(worldf, 0, sizeof(worldf));
worldf[0] = worldf[5] = worldf[10] = worldf[15] = 1.0f;
worldf[12] = 100.0f;
worldf[13] = 100.0f;
worldf[14] = -100.0f;
/* Build perspective matrix */
memset(projf, 0, sizeof(projf));
projf[0] = f/aspect;
projf[5] = f;
projf[10] = (far+near)/(near-far);
projf[14] = (2.0f*far*near)/(near-far);
projf[11] = -1.0f;
glUniformMatrix4fv(proj_uniform, 1, GL_FALSE, projf);
glUniformMatrix4fv(world_uniform, 1, GL_FALSE, worldf);
使用此代码,我的文字根本不显示。
编辑:不确定它是否相关,但我在OS X Snow Leopard上使用OpenGL 2.0。
答案 0 :(得分:1)
我正在使用左手透视矩阵
停止这样做。
同样重要的是,OpenGL和D3D的投影矩阵(剪辑空间)的输出不同。你不能只采用D3D投影矩阵,转置它,并期望GLSL接受输出就好了。
再次,查看gluPerspective并使用该矩阵。
Per Nicol Bolas的建议,我现在正在使用gluPerspective的矩阵,但我得到了相同的结果。
你可能还使用了一堆其他左手矩阵。您的模型到相机矩阵需要是右撇子。此外,您的顶点数据也需要右手。或者,您可以尝试从左手空间转换为右手空间,但除非您别无选择,否则我不会建议。
float f = 1.0f/tanf(fov/2.0f);
fov
是以度为单位的角度。 tanf
在弧度中占一个角度。 tanf
的{{1}}是负数,这意味着您的透视矩阵中的平截头体刻度为负数。这有效地反转了视图的X轴和Y轴。
你真正需要的是:
30.0f