从版本3.3中的OpenGL获取Projection Matrix

时间:2016-06-15 17:10:39

标签: opengl freeglut

出于兼容性原因,我必须混合旧的和现代的OpenGL代码。我想从OpenGL检索当前的投影和模型视图矩阵,通过使用统一变量将其传递给着色器。

以下代码显示我尝试仅对投影矩阵执行此操作。它按预期工作:

float m[16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, aspect, 0.01f, 2.0f);
glGetFloatv(GL_PROJECTION_MATRIX, m);

在这些行之后,Matrix m包含标识。我使用以下代码检查了这个:

printf("%f %f %f %f\n", m[0], m[4], m[8],  m[12]);
printf("%f %f %f %f\n", m[1], m[5], m[9],  m[13]);
printf("%f %f %f %f\n", m[2], m[6], m[10], m[14]);
printf("%f %f %f %f\n", m[3], m[7], m[11], m[15]);

我使用freeglut创建了上下文,并使用以下代码显式请求了OpenGL 3.3上下文:

...
glutInitContextVersion(3, 3);
glutCreateWindow(title);

当我将版本更改为OpenGL 2.0时,上面的代码按预期工作。上面的每个版本都会产生上述问题。

我正在使用 Intel Corporation Broadwell-U集成显卡开发Xubuntu。

有人可以解释这种行为吗?有人可以提供解决方案吗?

1 个答案:

答案 0 :(得分:1)

> = OpenGL-3.3兼容性配置文件是一项可选功能,并不要求实际支持它。大多数OpenGL实现实际上都不支持兼容性配置文件。值得注意的例外是NVidia和AMD的专有驱动程序。因此,将OpenGL-3.3与传统内容混合在一起对所有系统都无法可靠地工作。

但你为什么这样做

float m[16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, aspect, 0.01f, 2.0f);
glGetFloatv(GL_PROJECTION_MATRIX, m);

......根本没有?首先,GLU不是OpenGL的一部分,GLU函数只是内部调用OpenGL函数的小助手。无论如何,gluPerspective函数非常简单,通过OpenGL进行往返只是为了得到矩阵很尴尬(说实话是触发我的呕吐反射)。

核心gluPerspective正在确定glFrustum的参数:

void gluPerspective(
    double fov,
    double aspect,
    double znear, float zfar)
{
    double const height = znear * tanf(fovyInDegrees * M_PI / 360.0);
    double const width = height * aspect;
    glFrustum(-width, width, -height, height, znear, zfar);
}

这就是它的全部。 glFrustum本身也很简单。

void glFrustum(double l, double r, double b, double t, double n, double f)
{
    double M[4][4];
    M[0][0] = 2.f*n/(r-l);
    M[0][1] = M[0][2] = M[0][3] = 0.f;

    M[1][1] = 2.*n/(t-b);
    M[1][0] = M[1][2] = M[1][3] = 0.f;

    M[2][0] = (r+l)/(r-l);
    M[2][1] = (t+b)/(t-b);
    M[2][2] = -(f+n)/(f-n);
    M[2][3] = -1.f;

    M[3][2] = -2.f*(f*n)/(f-n);
    M[3][0] = M[3][1] = M[3][3] = 0.f;
    glMultMatrixd(&M[0][0]);
}

重写这个以将矩阵指针作为参数然后可以直接传递给制服,这是微不足道的。