I want to create a oblique (cavalier) projection in OpenGL. I know this operation is not default supported and instead I need a Shear Matrix and then make an Orthogonal Projection.
Can you tell me what are the OpenGl steps / functions that I have to make?
I've not used a oblique/cavalier projection before, but the following should give you an idea of how to proceed:
Create a 4x4 shear matrix,
H(θ, Φ) = | 1, 0, -cot(θ), 0 |
| 0, 1, -cot(Φ), 0 |
| 0, 0, 1, 0 |
| 0, 0, 0, 1 |
θ being the shear in X, Φ being the shear in Y, and Z being left alone.
(ref: slide 11 of http://www.cs.unm.edu/~angel/CS433/LECTURES/CS433_17.pdf)
Multiply that by your orthographic projection,
| 2/(r-l), 0, 0, -(r+l)/(r-l) |
| 0, 2/(t-b), 0, -(t+b)/(t-b) |
| 0, 0, 2/(f-n), -(f+n)/(f-n) |
| 0, 0, 0, 1 |
(described by, left, right, bottom, top, near and far)
(ref: http://en.wikipedia.org/wiki/Orthographic_projection_%28geometry%29)
OpenGL then allows you to upload this matrix directly (as an array of 16 floats) via the function glLoadMatrixf():
GLfloat proj[16] = { ... };
glMatrixMode(GL_PROJECTION); // Make sure we're modifying the *projection* matrix
glLoadMatrixf(proj); // Load the projection
For a more in depth look at how viewing and transformations work in OpenGL, I'd refer you to Chapter 3 of the OpenGL "Red Book". There they use glOrtho() to create and apply an orthographic projection.
Edit:
As datenwolf points out, bear in mind that the matrix elements in OpenGL are specified in column major order.
OpenGL allows you to specify arbitrary projection matrices. Construct the desired projection matrix yourself to map the incoming vertices into the range -1 to 1 in each dimension, then load it using
GLfloat custrom_projection[16] = {
...
};
glMatrixMode(GL_PROJECTION);
glLoadMatrix(custom_projection);
OpenGL indexes the matrix elements in colum major order, i.e.
0 4 8 12
1 5 9 13
2 6 10 14
3 7 11 15
Since the so-called oblique projection is obtained by rotating the projection plain by a certain angle away from the right one, which produces nothing but a lengthened image along the rotation axis, I think it suffices to just scale the normal orthogonal projection along that axis, by a factor of \csc\theta. This claim can be proven by trigonometry equalities, e.g., \sin\theta+\cos\theta \cot\theta=\csc\theta. If your oblique projection is specified by the \theta and \phi like in luke's answer, the axis angle can be computed as a trigonometry exercise based on this two angles, say, \arctan(\tan\theta\sqrt(1+\cot^2\phi)).
来源:https://stackoverflow.com/questions/6100614/opengl-oblique-projection