opengl oblique projection

混江龙づ霸主 提交于 2019-12-03 15:07:32

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)).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!