Opengl中矩阵和perspective/ortho的相互转换

Opengl中矩阵和perspective/ortho的相互转换

定义矩阵

Opengl变换需要用四维矩阵。我们来定义这样的矩阵。

+BIT祝威+悄悄在此留下版了个权的信息说:

四维向量

首先,我们定义一个四维向量vec4。

  1     /// <summary>
  2     /// Represents a four dimensional vector.
  3     /// </summary>
  4     public struct vec4
  5     {
  6         public float x;
  7         public float y;
  8         public float z;
  9         public float w;
 10
 11         public float this[int index]
 12         {
 13             get
 14             {
 15                 if (index == 0) return x;
 16                 else if (index == 1) return y;
 17                 else if (index == 2) return z;
 18                 else if (index == 3) return w;
 19                 else throw new Exception("Out of range.");
 20             }
 21             set
 22             {
 23                 if (index == 0) x = value;
 24                 else if (index == 1) y = value;
 25                 else if (index == 2) z = value;
 26                 else if (index == 3) w = value;
 27                 else throw new Exception("Out of range.");
 28             }
 29         }
 30
 31         public vec4(float s)
 32         {
 33             x = y = z = w = s;
 34         }
 35
 36         public vec4(float x, float y, float z, float w)
 37         {
 38             this.x = x;
 39             this.y = y;
 40             this.z = z;
 41             this.w = w;
 42         }
 43
 44         public vec4(vec4 v)
 45         {
 46             this.x = v.x;
 47             this.y = v.y;
 48             this.z = v.z;
 49             this.w = v.w;
 50         }
 51
 52         public vec4(vec3 xyz, float w)
 53         {
 54             this.x = xyz.x;
 55             this.y = xyz.y;
 56             this.z = xyz.z;
 57             this.w = w;
 58         }
 59
 60         public static vec4 operator +(vec4 lhs, vec4 rhs)
 61         {
 62             return new vec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w);
 63         }
 64
 65         public static vec4 operator +(vec4 lhs, float rhs)
 66         {
 67             return new vec4(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs);
 68         }
 69
 70         public static vec4 operator -(vec4 lhs, float rhs)
 71         {
 72             return new vec4(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs, lhs.w - rhs);
 73         }
 74
 75         public static vec4 operator -(vec4 lhs, vec4 rhs)
 76         {
 77             return new vec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w);
 78         }
 79
 80         public static vec4 operator *(vec4 self, float s)
 81         {
 82             return new vec4(self.x * s, self.y * s, self.z * s, self.w * s);
 83         }
 84
 85         public static vec4 operator *(float lhs, vec4 rhs)
 86         {
 87             return new vec4(rhs.x * lhs, rhs.y * lhs, rhs.z * lhs, rhs.w * lhs);
 88         }
 89
 90         public static vec4 operator *(vec4 lhs, vec4 rhs)
 91         {
 92             return new vec4(rhs.x * lhs.x, rhs.y * lhs.y, rhs.z * lhs.z, rhs.w * lhs.w);
 93         }
 94
 95         public static vec4 operator /(vec4 lhs, float rhs)
 96         {
 97             return new vec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs);
 98         }
 99
100         public float[] to_array()
101         {
102             return new[] { x, y, z, w };
103         }
104
105         /// <summary>
106         /// 归一化向量
107         /// </summary>
108         /// <param name="vector"></param>
109         /// <returns></returns>
110         public void Normalize()
111         {
112             var frt = (float)Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
113
114             this.x = x / frt;
115             this.y = y / frt;
116             this.z = z / frt;
117             this.w = w / frt;
118         }
119
120         public override string ToString()
121         {
122             return string.Format("{0:0.00},{1:0.00},{2:0.00},{3:0.00}", x, y, z, w);
123         }
124     }

vec4

四维矩阵

然后,我们定义一个四维矩阵mat4。它用4个vec4表示,每个vec4代表一个列向量。(这是glm中的定义)

  1     /// <summary>
  2     /// Represents a 4x4 matrix.
  3     /// </summary>
  4     public struct mat4
  5     {
  6         public override string ToString()
  7         {
  8             if (cols == null)
  9             { return "<null>"; }
 10             var builder = new System.Text.StringBuilder();
 11             for (int i = 0; i < cols.Length; i++)
 12             {
 13                 builder.Append(cols[i]);
 14                 builder.Append(" + ");
 15             }
 16             return builder.ToString();
 17             //return base.ToString();
 18         }
 19         #region Construction
 20
 21         /// <summary>
 22         /// Initializes a new instance of the <see cref="mat4"/> struct.
 23         /// This matrix is the identity matrix scaled by <paramref name="scale"/>.
 24         /// </summary>
 25         /// <param name="scale">The scale.</param>
 26         public mat4(float scale)
 27         {
 28             cols = new[]
 29             {
 30                 new vec4(scale, 0.0f, 0.0f, 0.0f),
 31                 new vec4(0.0f, scale, 0.0f, 0.0f),
 32                 new vec4(0.0f, 0.0f, scale, 0.0f),
 33                 new vec4(0.0f, 0.0f, 0.0f, scale),
 34             };
 35         }
 36
 37         /// <summary>
 38         /// Initializes a new instance of the <see cref="mat4"/> struct.
 39         /// The matrix is initialised with the <paramref name="cols"/>.
 40         /// </summary>
 41         /// <param name="cols">The colums of the matrix.</param>
 42         public mat4(vec4[] cols)
 43         {
 44             this.cols = new[] { cols[0], cols[1], cols[2], cols[3] };
 45         }
 46
 47         public mat4(vec4 a, vec4 b, vec4 c, vec4 d)
 48         {
 49             this.cols = new[]
 50             {
 51                 a, b, c, d
 52             };
 53         }
 54
 55         /// <summary>
 56         /// Creates an identity matrix.
 57         /// </summary>
 58         /// <returns>A new identity matrix.</returns>
 59         public static mat4 identity()
 60         {
 61             return new mat4
 62             {
 63                 cols = new[]
 64                 {
 65                     new vec4(1,0,0,0),
 66                     new vec4(0,1,0,0),
 67                     new vec4(0,0,1,0),
 68                     new vec4(0,0,0,1)
 69                 }
 70             };
 71         }
 72
 73         #endregion
 74
 75         #region Index Access
 76
 77         /// <summary>
 78         /// Gets or sets the <see cref="vec4"/> column at the specified index.
 79         /// </summary>
 80         /// <value>
 81         /// The <see cref="vec4"/> column.
 82         /// </value>
 83         /// <param name="column">The column index.</param>
 84         /// <returns>The column at index <paramref name="column"/>.</returns>
 85         public vec4 this[int column]
 86         {
 87             get { return cols[column]; }
 88             set { cols[column] = value; }
 89         }
 90
 91         /// <summary>
 92         /// Gets or sets the element at <paramref name="column"/> and <paramref name="row"/>.
 93         /// </summary>
 94         /// <value>
 95         /// The element at <paramref name="column"/> and <paramref name="row"/>.
 96         /// </value>
 97         /// <param name="column">The column index.</param>
 98         /// <param name="row">The row index.</param>
 99         /// <returns>
100         /// The element at <paramref name="column"/> and <paramref name="row"/>.
101         /// </returns>
102         public float this[int column, int row]
103         {
104             get { return cols[column][row]; }
105             set { cols[column][row] = value; }
106         }
107
108         #endregion
109
110         #region Conversion
111
112         /// <summary>
113         /// Returns the matrix as a flat array of elements, column major.
114         /// </summary>
115         /// <returns></returns>
116         public float[] to_array()
117         {
118             return cols.SelectMany(v => v.to_array()).ToArray();
119         }
120
121         /// <summary>
122         /// Returns the <see cref="mat3"/> portion of this matrix.
123         /// </summary>
124         /// <returns>The <see cref="mat3"/> portion of this matrix.</returns>
125         public mat3 to_mat3()
126         {
127             return new mat3(new[] {
128             new vec3(cols[0][0], cols[0][1], cols[0][2]),
129             new vec3(cols[1][0], cols[1][1], cols[1][2]),
130             new vec3(cols[2][0], cols[2][1], cols[2][2])});
131         }
132
133         #endregion
134
135         #region Multiplication
136
137         /// <summary>
138         /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> vector.
139         /// </summary>
140         /// <param name="lhs">The LHS matrix.</param>
141         /// <param name="rhs">The RHS vector.</param>
142         /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns>
143         public static vec4 operator *(mat4 lhs, vec4 rhs)
144         {
145             return new vec4(
146                 lhs[0, 0] * rhs[0] + lhs[1, 0] * rhs[1] + lhs[2, 0] * rhs[2] + lhs[3, 0] * rhs[3],
147                 lhs[0, 1] * rhs[0] + lhs[1, 1] * rhs[1] + lhs[2, 1] * rhs[2] + lhs[3, 1] * rhs[3],
148                 lhs[0, 2] * rhs[0] + lhs[1, 2] * rhs[1] + lhs[2, 2] * rhs[2] + lhs[3, 2] * rhs[3],
149                 lhs[0, 3] * rhs[0] + lhs[1, 3] * rhs[1] + lhs[2, 3] * rhs[2] + lhs[3, 3] * rhs[3]
150             );
151         }
152
153         /// <summary>
154         /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> matrix.
155         /// </summary>
156         /// <param name="lhs">The LHS matrix.</param>
157         /// <param name="rhs">The RHS matrix.</param>
158         /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns>
159         public static mat4 operator *(mat4 lhs, mat4 rhs)
160         {
161             mat4 result = new mat4(
162                 new vec4(
163                     lhs[0][0] * rhs[0][0] + lhs[1][0] * rhs[0][1] + lhs[2][0] * rhs[0][2] + lhs[3][0] * rhs[0][3],
164                     lhs[0][1] * rhs[0][0] + lhs[1][1] * rhs[0][1] + lhs[2][1] * rhs[0][2] + lhs[3][1] * rhs[0][3],
165                     lhs[0][2] * rhs[0][0] + lhs[1][2] * rhs[0][1] + lhs[2][2] * rhs[0][2] + lhs[3][2] * rhs[0][3],
166                     lhs[0][3] * rhs[0][0] + lhs[1][3] * rhs[0][1] + lhs[2][3] * rhs[0][2] + lhs[3][3] * rhs[0][3]
167                     ),
168                 new vec4(
169                     lhs[0][0] * rhs[1][0] + lhs[1][0] * rhs[1][1] + lhs[2][0] * rhs[1][2] + lhs[3][0] * rhs[1][3],
170                     lhs[0][1] * rhs[1][0] + lhs[1][1] * rhs[1][1] + lhs[2][1] * rhs[1][2] + lhs[3][1] * rhs[1][3],
171                     lhs[0][2] * rhs[1][0] + lhs[1][2] * rhs[1][1] + lhs[2][2] * rhs[1][2] + lhs[3][2] * rhs[1][3],
172                     lhs[0][3] * rhs[1][0] + lhs[1][3] * rhs[1][1] + lhs[2][3] * rhs[1][2] + lhs[3][3] * rhs[1][3]
173                     ),
174                 new vec4(
175                     lhs[0][0] * rhs[2][0] + lhs[1][0] * rhs[2][1] + lhs[2][0] * rhs[2][2] + lhs[3][0] * rhs[2][3],
176                     lhs[0][1] * rhs[2][0] + lhs[1][1] * rhs[2][1] + lhs[2][1] * rhs[2][2] + lhs[3][1] * rhs[2][3],
177                     lhs[0][2] * rhs[2][0] + lhs[1][2] * rhs[2][1] + lhs[2][2] * rhs[2][2] + lhs[3][2] * rhs[2][3],
178                     lhs[0][3] * rhs[2][0] + lhs[1][3] * rhs[2][1] + lhs[2][3] * rhs[2][2] + lhs[3][3] * rhs[2][3]
179                     ),
180                 new vec4(
181                     lhs[0][0] * rhs[3][0] + lhs[1][0] * rhs[3][1] + lhs[2][0] * rhs[3][2] + lhs[3][0] * rhs[3][3],
182                     lhs[0][1] * rhs[3][0] + lhs[1][1] * rhs[3][1] + lhs[2][1] * rhs[3][2] + lhs[3][1] * rhs[3][3],
183                     lhs[0][2] * rhs[3][0] + lhs[1][2] * rhs[3][1] + lhs[2][2] * rhs[3][2] + lhs[3][2] * rhs[3][3],
184                     lhs[0][3] * rhs[3][0] + lhs[1][3] * rhs[3][1] + lhs[2][3] * rhs[3][2] + lhs[3][3] * rhs[3][3]
185                     )
186                     );
187
188             return result;
189         }
190
191         public static mat4 operator *(mat4 lhs, float s)
192         {
193             return new mat4(new[]
194             {
195                 lhs[0]*s,
196                 lhs[1]*s,
197                 lhs[2]*s,
198                 lhs[3]*s
199             });
200         }
201
202         #endregion
203
204         /// <summary>
205         /// The columms of the matrix.
206         /// </summary>
207         private vec4[] cols;
208     }

mat4

+BIT祝威+悄悄在此留下版了个权的信息说:

矩阵与ortho的转换

从ortho到矩阵

根据传入的参数可以获得一个代表平行投影的矩阵。

 1         /// <summary>
 2         /// Creates a matrix for an orthographic parallel viewing volume.
 3         /// </summary>
 4         /// <param name="left">The left.</param>
 5         /// <param name="right">The right.</param>
 6         /// <param name="bottom">The bottom.</param>
 7         /// <param name="top">The top.</param>
 8         /// <param name="zNear">The z near.</param>
 9         /// <param name="zFar">The z far.</param>
10         /// <returns></returns>
11         public static mat4 ortho(float left, float right, float bottom, float top, float zNear, float zFar)
12         {
13             var result = mat4.identity();
14             result[0, 0] = (2f) / (right - left);
15             result[1, 1] = (2f) / (top - bottom);
16             result[2, 2] = -(2f) / (zFar - zNear);
17             result[3, 0] = -(right + left) / (right - left);
18             result[3, 1] = -(top + bottom) / (top - bottom);
19             result[3, 2] = -(zFar + zNear) / (zFar - zNear);
20             return result;
21         }

从矩阵到ortho

反过来,当我们手上有一个矩阵时,我们可以分析出这个矩阵是由ortho用怎样的参数计算得到的。(当然,并非所有矩阵都能用ortho计算出来)

 1         /// <summary>
 2         /// 如果此矩阵是glm.ortho()的结果,那么返回glm.ortho()的各个参数值。
 3         /// </summary>
 4         /// <param name="matrix"></param>
 5         /// <param name="left"></param>
 6         /// <param name="right"></param>
 7         /// <param name="bottom"></param>
 8         /// <param name="top"></param>
 9         /// <param name="zNear"></param>
10         /// <param name="zFar"></param>
11         /// <returns></returns>
12         public static bool TryParse(this mat4 matrix,
13             out float left, out float right, out float bottom, out float top, out float zNear, out float zFar)
14         {
15             {
16                 float negHalfLeftRight = matrix[3, 0] / matrix[0, 0];
17                 float halfRightMinusLeft = 1.0f / matrix[0][0];
18                 left = -(halfRightMinusLeft + negHalfLeftRight);
19                 right = halfRightMinusLeft - negHalfLeftRight;
20             }
21
22             {
23                 float negHalfBottomTop = matrix[3, 1] / matrix[1, 1];
24                 float halfTopMinusBottom = 1.0f / matrix[1, 1];
25                 bottom = -(halfTopMinusBottom + negHalfBottomTop);
26                 top = halfTopMinusBottom - negHalfBottomTop;
27             }
28
29             {
30                 float halfNearFar = matrix[3, 2] / matrix[2, 2];
31                 float negHalfFarMinusNear = 1.0f / matrix[2, 2];
32                 zNear = negHalfFarMinusNear + halfNearFar;
33                 zFar = halfNearFar - negHalfFarMinusNear;
34             }
35
36             if (matrix[0, 0] == 0.0f || matrix[1, 1] == 0.0f || matrix[2, 2] == 0.0f)
37             {
38                 return false;
39             }
40
41             if (matrix[1, 0] != 0.0f || matrix[2, 0] != 0.0f
42                 || matrix[0, 1] != 0.0f || matrix[2, 1] != 0.0f
43                 || matrix[0, 2] != 0.0f || matrix[1, 2] != 0.0f
44                 || matrix[0, 3] != 0.0f || matrix[1, 3] != 0.0f || matrix[2, 3] != 0.0f)
45             {
46                 return false;
47             }
48
49             if (matrix[3, 3] != 1.0f)
50             {
51                 return false;
52             }
53
54             return true;
55         }

矩阵与perpspective的转换

从perspective到矩阵

根据传入的参数可以获得一个代表透视投影的矩阵。

 1         /// <summary>
 2         /// Creates a perspective transformation matrix.
 3         /// </summary>
 4         /// <param name="fovy">The field of view angle, in radians.</param>
 5         /// <param name="aspect">The aspect ratio.</param>
 6         /// <param name="zNear">The near depth clipping plane.</param>
 7         /// <param name="zFar">The far depth clipping plane.</param>
 8         /// <returns>A <see cref="mat4"/> that contains the projection matrix for the perspective transformation.</returns>
 9         public static mat4 perspective(float fovy, float aspect, float zNear, float zFar)
10         {
11             var result = mat4.identity();
12             float tangent = (float)Math.Tan(fovy / 2.0f);
13             float height = zNear * tangent;
14             float width = height * aspect;
15             float l = -width, r = width, b = -height, t = height, n = zNear, f = zFar;
16             result[0, 0] = 2.0f * n / (r - l);// = 2.0f * zNear / (2.0f * zNear * tangent * aspect)
17             result[1, 1] = 2.0f * n / (t - b);// = 2.0f * zNear / (2.0f * zNear * tangent)
18             //result[2, 0] = (r + l) / (r - l);// = 0.0f
19             //result[2, 1] = (t + b) / (t - b);// = 0.0f
20             result[2, 2] = -(f + n) / (f - n);
21             result[2, 3] = -1.0f;
22             result[3, 2] = -(2.0f * f * n) / (f - n);
23             result[3, 3] = 0.0f;
24
25             return result;
26         }

从矩阵到perspective

反过来,当我们手上有一个矩阵时,我们可以分析出这个矩阵是由perpspective用怎样的参数计算得到的。(当然,并非所有矩阵都能用perpspective计算出来)

 1         /// <summary>
 2         /// 如果此矩阵是glm.perspective()的结果,那么返回glm.perspective()的各个参数值。
 3         /// </summary>
 4         /// <param name="matrix"></param>
 5         /// <param name="fovy"></param>
 6         /// <param name="aspectRatio"></param>
 7         /// <param name="zNear"></param>
 8         /// <param name="zFar"></param>
 9         /// <returns></returns>
10         public static bool TryParse(this mat4 matrix,
11             out float fovy, out float aspectRatio, out float zNear, out float zFar)
12         {
13             float tanHalfFovy = 1.0f / matrix[1, 1];
14             fovy = 2 * (float)(Math.Atan(tanHalfFovy));
15             //aspectRatio = 1.0f / matrix[0, 0] / tanHalfFovy;
16             aspectRatio = matrix[1, 1] / matrix[0, 0];
17             zNear = matrix[3, 2] / (1 - matrix[2, 2]);
18             zFar = matrix[3, 2] / (1 + matrix[2, 2]);
19
20             if (matrix[0, 0] == 0.0f || matrix[1, 1] == 0.0f || matrix[2, 2] == 0.0f)
21             {
22                 return false;
23             }
24
25             if (matrix[1, 0] != 0.0f || matrix[3, 0] != 0.0f
26                 || matrix[0, 1] != 0.0f || matrix[3, 1] != 0.0f
27                 || matrix[0, 2] != 0.0f || matrix[1, 2] != 0.0f
28                 || matrix[0, 3] != 0.0f || matrix[1, 3] != 0.0f || matrix[3, 3] != 0.0f)
29             {
30                 return false;
31             }
32
33             if (matrix[3, 2] != -1.0f)
34             {
35                 return false;
36             }
37
38             return true;
39         }

+BIT祝威+悄悄在此留下版了个权的信息说:

总结

本篇就写这些,今后再写一些相关的内容。

时间: 2024-08-03 15:59:27

Opengl中矩阵和perspective/ortho的相互转换的相关文章

OpenGL中平移、旋转、缩放矩阵堆栈操作

在OpenGL中,图元的几何变换均为线性变换,通过矩阵变换实现.OpenGL中的坐标用齐次坐标表示,即(x,y,z)表示成(x',y',z',h),其中x=x'/h; y=y'/h; z=z'/h. 通常h取1. 比如空间中的点(2,3,4),在OpenGL中将表示成(2,3,4,1). 齐次坐标表示方式适合于矩阵运算,也很方便地表示了无穷远的点,比如(1,0,0,0)就表示x轴上无穷远的点,因为1/0是无穷大,这里约定0/0=0. 例:点(1,1,1)将该向量平移变换(2,3,4)个单位,得到

(转)思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用问题:左乘/右乘,行优先/列优先,...

转自:http://www.cnblogs.com/soroman/archive/2008/03/21/1115571.html 思考:矩阵及变换,以及矩阵在DirectX和OpenGL中的运用1.矩阵和线性变换:一一对应 矩阵是用来表示线性变换的一种工具,它和线性变换之间是一一对应的.考虑线性变换:a11*x1 + a12*x2 + ...+a1n*xn = x1'a21*x1 + a22*x2 + ...+a2n*xn = x2'...am1*x1 + am2*x2 + ...+amn*x

CSharpGL(6)在OpenGL中绘制UI元素

CSharpGL(6)在OpenGL中绘制UI元素 主要内容 学习使用IUILayout接口及其机制,以实现在OpenGL中绘制UI元素. 以SimpleUIAxis为例演示如何使用IUILayout. 下载 您可以在(https://github.com/bitzhuwei/CSharpGL)找到最新的源码.欢迎感兴趣的同学fork之. 什么是OpenGL中的UI元素 您可以在源码中找到SimpleUIAxis这一示例. 如上图所示,有5个坐标轴,中间那个是一个普通的三维模型(元素),作为对照

OpenGL投影矩阵(Projection Matrix)构造方法

(翻译,图片也来自原文) 一.概述 绝大部分计算机的显示器是二维的(a 2D surface).在OpenGL中一个3D场景需要被投影到屏幕上成为一个2D图像(image).这称为投影变换(参见这或这),需要用到投影矩阵(projection matrix). 首先,投影矩阵会把所有顶点坐标从eye coordinates(观察空间,eye space或view space)变换到裁剪坐标(clip coordinated,属于裁剪空间,clip space).然后,这些裁剪坐标被变换到标准化设

OpenGL中实现双缓冲技术

在OpenGL中实现双缓冲技术的一种简单方法: 1.在调用glutInitDisplayMode函数时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);.这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲. 2. 调用glutDisplayFunc(display)注册回调函数时, 在回调函数中所有绘制操作完成后调用glutSwapBuffers()交换两个缓冲区指针. 3. 调用

OpenGL中的颜色混合功能(一)

我们知道,材料属性和光照参数可以极大地增加图形的逼真度,但除此之外,我们在对现实世界进行建模时,有许多效果是通过混合颜色的方式实现的.透明的物体,像是玻璃水杯,在它后面发射过来的光会与透明物体的颜色混合在一起.这种透明在OpenGL中的实现方式,是通过首先绘制背景物体,然后把前景物体(比如水杯)与颜色缓冲区中已经存在的颜色进行混合而实现的.在这一过程中,颜色的alpha值成分发挥了重要作用. 颜色的混合功能 在一般情况下,OpenGL在渲染时把颜色值存放在颜色缓冲区中,把每个片段(像素)的深度值

OpenGL投影矩阵

概述 透视投影 正交投影 概述 计算机显示器是一个2D平面.OpenGL渲染的3D场景必须以2D图像方式投影到计算机屏幕上.GL_PROJECTION矩阵用于该投影变换.首先,它将所有定点数据从观察坐标转换到裁减坐标.接着,这些裁减坐标通过除以w分量的方式转换到归一化设备坐标(NDC). 因此,我们需要记住一点:裁减变换(视锥剔除)与NDC变换都保存在GL_PROJECTION矩阵中.下述章节描述如何从6个限定参数(左.右.下.上.近平面.远平面)构建投影矩阵. 注意,视锥剔除(裁减)在裁减坐标

opengl中场景变换|2D与3D互转换(转)

opengl中场景变换|2D与3D互转换 我们生活在一个三维的世界——如果要观察一个物体,我们可以: 1.从不同的位置去观察它.(视图变换) 2.移动或者旋转它,当然了,如果它只是计算机里面的物体,我们还可以放大或缩小它.(模型变换) 3.如果把物体画下来,我们可以选择:是否需要一种“近大远小”的透视效果.另外,我们可能只希望看到物体的一部分,而不是全部(剪裁).(投影变换) 4.我们可能希望把整个看到的图形画下来,但它只占据纸张的一部分,而不是全部.(视口变换) 这些,都可以在OpenGL中实

OpenGL中坐标系的理解(一)

在OpenGL中,存在着至少存在着三种矩阵,对应着函数glMatrixMode()的三个参数:GL_MODELVIEW,GL_PROJECTION,GL_TEXTURE. 以下主要描述GL_MODELVIEW(模型视图矩阵)的个人理解. 在OpenGL中空间中点的三维坐标是使用行向量表示的,虽然与列向量相比存储结构并没有发生变化,但在坐标变换(即矩阵乘法)中会有很大不同.大家都知道一个4X4的矩阵可以表示三维坐标的平移,旋转变换.例如一矩阵R表示一个旋转加平移变换,空间中一点P(x, y, z)