• 全部
  • 问答

计算裁减视图体的六个面是怎么推倒出来的?

弟十六 2004-10-30 10:20:16
在OpenGL中是用模型视图矩阵左乘投影矩阵,得到的矩阵结果中行相减得到透视视图体六个面的法线向量,这一步是怎么来的呢?
我知道这不是几句话说得完的,谁知道相关的文章链接给出一个就行,谢谢。
...全文
53 点赞 收藏 4
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
潘李亮 2004-11-03
偶的毕业论文里有详细介绍。
http://xreal.51.net/simnature/
回复
flmn 2004-11-02

float m_Frustum[6][4];
这个私有变量保存了六个面的直线方程Ax+By+Cz+d=0中的ABCD

float proj[16];
float modl[16];
float clip[16];

// glGetFloatv() is used to extract information about our OpenGL world.
// Below, we pass in GL_PROJECTION_MATRIX to abstract our projection matrix.
// It then stores the matrix into an array of [16].
glGetFloatv( GL_PROJECTION_MATRIX, proj );

// By passing in GL_MODELVIEW_MATRIX, we can abstract our model view matrix.
// This also stores it in an array of [16].
glGetFloatv( GL_MODELVIEW_MATRIX, modl );

// Now that we have our modelview and projection matrix, if we combine these 2 matrices,
// it will give us our clipping planes. To combine 2 matrices, we multiply them.

clip[ 0] = modl[ 0] * proj[ 0] + modl[ 1] * proj[ 4] + modl[ 2] * proj[ 8] + modl[ 3] * proj[12];
clip[ 1] = modl[ 0] * proj[ 1] + modl[ 1] * proj[ 5] + modl[ 2] * proj[ 9] + modl[ 3] * proj[13];
clip[ 2] = modl[ 0] * proj[ 2] + modl[ 1] * proj[ 6] + modl[ 2] * proj[10] + modl[ 3] * proj[14];
clip[ 3] = modl[ 0] * proj[ 3] + modl[ 1] * proj[ 7] + modl[ 2] * proj[11] + modl[ 3] * proj[15];

clip[ 4] = modl[ 4] * proj[ 0] + modl[ 5] * proj[ 4] + modl[ 6] * proj[ 8] + modl[ 7] * proj[12];
clip[ 5] = modl[ 4] * proj[ 1] + modl[ 5] * proj[ 5] + modl[ 6] * proj[ 9] + modl[ 7] * proj[13];
clip[ 6] = modl[ 4] * proj[ 2] + modl[ 5] * proj[ 6] + modl[ 6] * proj[10] + modl[ 7] * proj[14];
clip[ 7] = modl[ 4] * proj[ 3] + modl[ 5] * proj[ 7] + modl[ 6] * proj[11] + modl[ 7] * proj[15];

clip[ 8] = modl[ 8] * proj[ 0] + modl[ 9] * proj[ 4] + modl[10] * proj[ 8] + modl[11] * proj[12];
clip[ 9] = modl[ 8] * proj[ 1] + modl[ 9] * proj[ 5] + modl[10] * proj[ 9] + modl[11] * proj[13];
clip[10] = modl[ 8] * proj[ 2] + modl[ 9] * proj[ 6] + modl[10] * proj[10] + modl[11] * proj[14];
clip[11] = modl[ 8] * proj[ 3] + modl[ 9] * proj[ 7] + modl[10] * proj[11] + modl[11] * proj[15];

clip[12] = modl[12] * proj[ 0] + modl[13] * proj[ 4] + modl[14] * proj[ 8] + modl[15] * proj[12];
clip[13] = modl[12] * proj[ 1] + modl[13] * proj[ 5] + modl[14] * proj[ 9] + modl[15] * proj[13];
clip[14] = modl[12] * proj[ 2] + modl[13] * proj[ 6] + modl[14] * proj[10] + modl[15] * proj[14];
clip[15] = modl[12] * proj[ 3] + modl[13] * proj[ 7] + modl[14] * proj[11] + modl[15] * proj[15];

// Now we actually want to get the sides of the frustum. To do this we take
// the clipping planes we received above and extract the sides from them.

// This will extract the RIGHT side of the frustum
m_Frustum[RIGHT][A] = clip[ 3] - clip[ 0];
m_Frustum[RIGHT][B] = clip[ 7] - clip[ 4];
m_Frustum[RIGHT][C] = clip[11] - clip[ 8];
m_Frustum[RIGHT][D] = clip[15] - clip[12];

// Now that we have a normal (A,B,C) and a distance (D) to the plane,
// we want to normalize that normal and distance.

// Normalize the RIGHT side
NormalizePlane(m_Frustum, RIGHT);

// This will extract the LEFT side of the frustum
m_Frustum[LEFT][A] = clip[ 3] + clip[ 0];
m_Frustum[LEFT][B] = clip[ 7] + clip[ 4];
m_Frustum[LEFT][C] = clip[11] + clip[ 8];
m_Frustum[LEFT][D] = clip[15] + clip[12];

// Normalize the LEFT side
NormalizePlane(m_Frustum, LEFT);

// This will extract the BOTTOM side of the frustum
m_Frustum[BOTTOM][A] = clip[ 3] + clip[ 1];
m_Frustum[BOTTOM][B] = clip[ 7] + clip[ 5];
m_Frustum[BOTTOM][C] = clip[11] + clip[ 9];
m_Frustum[BOTTOM][D] = clip[15] + clip[13];

// Normalize the BOTTOM side
NormalizePlane(m_Frustum, BOTTOM);

// This will extract the TOP side of the frustum
m_Frustum[TOP][A] = clip[ 3] - clip[ 1];
m_Frustum[TOP][B] = clip[ 7] - clip[ 5];
m_Frustum[TOP][C] = clip[11] - clip[ 9];
m_Frustum[TOP][D] = clip[15] - clip[13];

// Normalize the TOP side
NormalizePlane(m_Frustum, TOP);

// This will extract the BACK side of the frustum
m_Frustum[BACK][A] = clip[ 3] - clip[ 2];
m_Frustum[BACK][B] = clip[ 7] - clip[ 6];
m_Frustum[BACK][C] = clip[11] - clip[10];
m_Frustum[BACK][D] = clip[15] - clip[14];

// Normalize the BACK side
NormalizePlane(m_Frustum, BACK);

// This will extract the FRONT side of the frustum
m_Frustum[FRONT][A] = clip[ 3] + clip[ 2];
m_Frustum[FRONT][B] = clip[ 7] + clip[ 6];
m_Frustum[FRONT][C] = clip[11] + clip[10];
m_Frustum[FRONT][D] = clip[15] + clip[14];

// Normalize the FRONT side
NormalizePlane(m_Frustum, FRONT);
回复
houdy 2004-10-31
在gametutorials.com中的例子中,他说将模型视图矩阵左乘投影矩阵得到Clipping Plane,这个Clipping Plane是什么?
回复
houdy 2004-10-31
我也想知道,不知道为什么可以那样做。
不知道这样做对不对,大家帮我看看:
在《3D游戏于计算机图形学中的数学方法》一书中的4.3.2节中,它推导出了OpenGL的摄像机空间所看到的视截体的6个平面的平面向量
平面 <N,D>
近 <0,0,-1,-n>
远 <0,0,1,f>
...
...
下 <0, e/sqrt( e*e+a*a ), -a/sqrt( e*e+a*a ), 0>
然后用模型视图矩阵左乘投影矩阵,然后通过计算出的结果,将这写面转化到世界坐标中。
不知道这样做的结果是否和上面提到的方法一致。
回复
发帖
游戏开发
创建于2007-08-27

7916

社区成员

游戏开发相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2004-10-30 10:20
社区公告
暂无公告