问题
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?
回答1:
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.
回答2:
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
回答3:
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