For compatibility reasons I have to mix old and modern OpenGL code. I would like to retrieve the current projection- and modelview-matrix from OpenGL to pass it to the shader by using a uniform-variable.
The following code shows my attempt to do that for the projection-matrix only. It does not work as intended:
float m[16];
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, aspect, 0.01f, 2.0f);
glGetFloatv(GL_PROJECTION_MATRIX, m);
After these lines Matrix m contains the identity. I checked this using the following code:
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]);
I created the context using freeglut and explicitly requested an OpenGL 3.3 context using the following code:
...
glutInitContextVersion(3, 3);
glutCreateWindow(title);
When I change the version to OpenGL 2.0 the code above works as expected. Every version above produces the described problem.
I'm working on Xubuntu using an Intel Corporation Broadwell-U Integrated Graphics.
Can someone explain this behaviour? Can someone offer a solution?
The >=OpenGL-3.3 compatibility profiles are an optional feature and there's no requirement to actually support it. Most OpenGL implementations actually don't support the compatibility profiles. The notable exceptions are the proprietary drivers of NVidia and AMD. Hence mixing OpenGL-3.3 with legacy stuff will not work reliably for all systems.
But why are you doing that
float m[16]; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, aspect, 0.01f, 2.0f); glGetFloatv(GL_PROJECTION_MATRIX, m);
… at all? First and foremost GLU is not part of OpenGL and GLU functions are just little helpers that internally call OpenGL functions. Anyway the gluPerspective function is extremely simple and the roundtrip through OpenGL just to get the matrix well is awkward (and to be honest is triggering my gag reflex).
At its core gluPerspective is determining parameters for 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);
}
That's all it does. glFrustum itself is very simple as well.
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]);
}
It's trivial to rewrite this to take a pointer to a matrix as a parameter which you then can directly pass to a uniform.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With